Sign up here and you can log into the forum!

WDTVExt disassembly 101

Have a question about devices internals, memory layout, reverse engineering, etc---This is the place for anything so technical that it would cause a n00b's head to 'splode

Re: WDTVExt disassembly 101   

Postby mad_ady » Tue Dec 09, 2014 2:34 am

Small update - I uploaded my work (source code, experiments, ida files, custom scripts) to svn: http://svn.wdlxtv.com/listing.php?repname=misc&path=%2Fmips-disassembly-functions%2F&#a0e2d2a0bfb12746c57a98f1af9202e56
Feel free to play with them, especially:
Code: Select all
mips-jump-calculator.pl - calculates the jump instruction encoded as a hex string you need to use to jump to a specific address
mips-jump-patcher.pl - will generate a IDA dif file to patch a binary. It allows you to specify two addresses per line - the first address is where the code is to be injected, the second address is where you want to jump to.


I also started analysis of wdtvext. I noticed something extra, that is probably equally important. All functions begin by calling _mcount(). The call to _mcount is added by gcc -pg (adding profiling support). As you can imagine, the extra calls to mcount will add to execution time, so, we might need a bulk method to remove these calls. I'm thinking of a binary script to search through libext.so and to look for this instruction sequence:
Code: Select all
.text:0002895C 028                 la      $t9, _mcount     # Load Address
.text:00028960 028                 jalr    $t9 ; _mcount    # debugging mcount()


Which coresponds with this hex string:
Code: Select all
F0 95 99 8F 09 F8 20 03


_mcount() is at offset "00854A78". So, we should replace these calls with nops, and we could win something with regard to performance. There's something else. Before these two instructions I also have an extra instruction:
Code: Select all
.text:00028958 020                 addiu   $sp, -8          # Allocate 8 bytes on the stack

So, it allocates 8 bytes, calls mcount() and goes on to execute the rest. However, when the function ends it never explicitly deallocates those 8 bytes! It just de-allocates whatever it allocated in the beginning. So, we have two options:
1. We have a memory leak of 8 bytes at each function call
2. mcount() consumes or deallocates those 8 bytes itself, which means we shouldn't allocate them if we intend to skip the function

I will think of a generic way to go through the file and replace all instances of this set of instructions with nop (either export data from IDA in text form and parse it and use that to identify the section in the file that needs patching, or use a binary string search...). This method might also be practical to replace the calls to trace_method_enter and trace_method_leave in bulk...

I'll keep you posted, and probably need testers to validate that the code doesn't crash/is consistent.

Let me know if you have ideas/suggestions
User avatar
mad_ady
Developer
 
Posts: 4545
Joined: Fri Nov 05, 2010 9:08 am
Location: Bucharest, Romania

Re: WDTVExt disassembly 101   

Postby kroetkroet » Tue Dec 09, 2014 3:55 am

Count me in for testing, as I'm not using WDTVExt at all (yet) :lol:

As long as it doesn't require calling my mother-in-law, I do whatever it takes :D
WDLXTV-fan! - In case you need further assistance: read our WIKI, search our Forum and most of all: donate 'something' to b-rad for his great efforts!!!
User avatar
kroetkroet
Beta Tester
 
Posts: 1006
Joined: Mon Apr 05, 2010 11:53 pm

Re: WDTVExt disassembly 101   

Postby mad_ady » Tue Dec 09, 2014 5:52 am

Sorry, KroetKroet - no promises about mother dearest...
User avatar
mad_ady
Developer
 
Posts: 4545
Joined: Fri Nov 05, 2010 9:08 am
Location: Bucharest, Romania

Re: WDTVExt disassembly 101   

Postby kroetkroet » Tue Dec 09, 2014 10:02 am

Image
WDLXTV-fan! - In case you need further assistance: read our WIKI, search our Forum and most of all: donate 'something' to b-rad for his great efforts!!!
User avatar
kroetkroet
Beta Tester
 
Posts: 1006
Joined: Mon Apr 05, 2010 11:53 pm

Re: WDTVExt disassembly 101   

Postby mad_ady » Wed Dec 10, 2014 3:42 am

I finished my analysis of mcount() and generated two patches for libext to remove mcount() calls from the library. I replaced 216 calls to mcount(). If it doesn't crash, it should improve performance (not sure if it is noticeable).

There are some technical details in the beta thread http://forum.wdlxtv.com/viewtopic.php?f=38&t=9027&p=72411#p72411.
If any of you want to discuss such asm details, let's do this on this thread.

I also uploaded my scripts that I used for patching to svn (misc/mips-dissasembly-functions branch).

Here's how I used them:
  • I exported a html file from IDA with the disassembled code. I needed to have these options active before exporting:
    #IDA should be configured like this before export:
    # Options -> General -> Display disassembly line parts
    # * Line prefixes
    # * Stack pointer
    # * Comments
    # * Repeatable comments
    # * Auto comments
  • I edited mips-asm-patcher.pl and added the instruction sequence I wanted replaced inside @sequence:
    Code: Select all
    my @sequence = (
    'addiu   $sp, -8',
    'la      $t9, _mcount',
    'jalr    $t9 ; _mcount',
    );
  • I ran this command to produce a list of offsets to be patched with nops later. The offsets correspond to the instructions in @sequence:
    Code: Select all
    $ mips-asm-patcher.pl libext.html > libext_mcount_patch_3instructions.offsets
  • I piped the offsets to mips-jump-patcher
    Code: Select all
    $ cat libext_mcount_patch_3instructions.offsets | mips-jump-patcher.pl 0 libext.so > libext_mcount_patch_3instructions.dif
  • I applied the dif with idadif:
    Code: Select all
    $ idadif.py libext.so libext_mcount_patch_3instructions.dif
Cheers!
User avatar
mad_ady
Developer
 
Posts: 4545
Joined: Fri Nov 05, 2010 9:08 am
Location: Bucharest, Romania

Previous

Return to WDTV Live

Who is online

Users browsing this forum: No registered users and 2 guests

cron