Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine the location of disassembled code within an executable?

I've got an executable file (C++, i386, compiled under MacOS/X Tiger, if it matters) that contains a bug. The fix for the bug is straightforward -- there's a place in the code where it calls fork() and it shouldn't. Because the fix is simple, and because recompiling the executable from scratch would be difficult at this point (don't ask), I'd like to just patch the executable/binary file directly.

As a first step towards that, I ran "otool -tV MyExecutableName" on my executable, and voila, I found this in the disassembly output:

./MyExecutableName:
(__TEXT,__text) section
[... many lines omitted ...]
0002ce0d        subl    $0x10,%esp
0002ce10        calll   0x0051adac
0002ce15        movzbl  0x14(%ebp),%esi
0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    $0x00,%eax
0002ce21        jll     0x0002cf02
0002ce27        jle     0x0002ce34
[... many more lines omitted ...]

So what I'd like to do is replace the opcode at line 0002ce19, so that instead of calll'ing _fork, it simply jumps unconditionally to the failure case (i.e. it should act as if fork() had returned -1)

Unfortunately, I'm a complete newbie at disassembly/binary patching, so I'm not sure how to go about doing this. In particular, my questions are:

1) What bytes should I write into locations 0002ce19 through 0002xe1d to get what I want? I assume it would be the assembled equivalent of "jmp 0x0002cf02", but how do I figure out what those bytes are?

2) The offsets printed by "otool -tV" appear to be offsets into the __TEXT segment of the executable. How can I figure out the byte-delta between the printed offsets and the top of the file, so that I can edit/patch the correct bytes within the file?

Thanks for any advice you can give!

like image 687
Jeremy Friesner Avatar asked Oct 30 '09 04:10

Jeremy Friesner


1 Answers

I'm not familiar with the MacOS/X but I can give you some hints.

The proper way to fix it, is to use a disassembler to patch your file.

0002ce19        calll   0x00850ac9

can be replaced with

0002ce19        movl   eax, -1 ; mov eax, 0xFFFFFFFF

The offsets you see are relative, so you can not find them in the file.
For example, jll 0x0002cf02 is actually jll 0x000000DF

If I'm correct, the below code block

0002ce19        calll   0x00850ac9      ; symbol stub for: _fork
0002ce1e        cmpl    $0x00,%eax
0002ce21        jll     0x0002cf02
0002ce27        jle     0x0002ce34

will have this assembled form (20 bytes):

0x  E8   AB3C8200
    83F8 00
    0F8C DF000000
    0F84 0B000000

If that sequence is unique in the file then you can try to change the E8AB3C8200 to B8FFFFFFFF, if you can't use a disassembler.

like image 158
Nick Dandoulakis Avatar answered Oct 03 '22 02:10

Nick Dandoulakis