Page 1 of 1

Ollydbg overwrites code when editing instructions

Posted: Sat Jul 21, 2012 11:35 am
by universalis
I'm a newbie when it comes to this kind of stuff so please forgive me. As I'm trying to change values for some instructions when debugging a program I'm sometimes out of luck. If I change a value for the first instruction then the next instruction gets messed up. I believe this has to do with not using equal bytes.

This is a original screenshot:
[ATTACH]2613[/ATTACH]
And this is a screenshot where I have tried to change "MOV BYTE PTR DS:[ESI+C1],AL" to "MOV BYTE PTR DS:[ESI+0C1],2"
but this also changes "MOV EDX,DWORD PTR DS:[9BBAA4]" to "ADC EAX,9BBAA4".
[ATTACH]2614[/ATTACH]

Do you have any idea of how I could change "MOV BYTE PTR DS:[ESI+C1],AL" to for example "MOV BYTE PTR DS:[ESI+0C1],2" without overwriting the other code?

Edit: Sorry for posting in the wrong forum, should be in the OllyDbg Support Forums even if this is a newbie question.

Posted: Sat Jul 21, 2012 2:12 pm
by blabberer
if the instruction stream is larger than space available you dont have any option other than writing a detour with a jmp to some code cave write your instructions and jump back to the original second instruction

some thing like belwo

Code: Select all

[b]
1)  Address         12345670   opcode $$$$$        mov # # , ####   say 5 byte stream
2)              +5 = 12345675   opcode  $$$$$         mov ## , ####    original second instruction
[/b]
you want to overwrite the five byte instruction at address 12345670 with a 6 byte stream say opcode $$$$$$

you dont have space there so you would need to find a place (normally there would be holes in the end of code section (padded with 00 ))

say your code cave is at 123456A0 (about 30 bytes below)

you would need to do something like

jmp 123456A0 at 12345670 (original instruction ) olly normally would nop the remaining unused byte
ie at 12345670 there were $$$$$ now after doing jmp 12346670 (this is a short jump so opcode stream would be 2 bytes


so after you did this the $$$$$ at 12345670 would become $$<nop.nop.nop>

at 123456a0

you write your new 6byte opcode stream
and at 123456a6 you write jmp 12345675 (you are jumping back to original second instruction which is ok to continue the flow)

this is a simple example

sometimes it may happen you need to write too much and you dont have a hole that would fit all the stuff
in such cases you can add a section at the end whose size can be chosen at will to suit your needs
if you dont want to add section you can write a detour which will allocate memory and dynamically write stuff to the allocated memory and execute from there
the options open up if you start thinking

Posted: Sat Jul 21, 2012 2:20 pm
by aqrit
it could seen better by expanding the second column a little more
or by selecting the "Fill with NOPS" checkbox in the assemble dialog, for a more sane behavior

the disassembly posted can be re-written in place in order to shrink it
for example the four "mov byte" instructions (C0,C1,C2,C3) could all be combined into one instruction "MOV DWORD [ESI+C0], 01030200"

Posted: Wed Aug 08, 2012 7:38 am
by universalis
Thanks for the great help!
Found a code segment with NOPs that I tried to overwrite with my code. So I take a jump (code: JMP 005EBE47 = address i want to jump to) and after a few lines jumps back (again with JMP ...) to where I originally was. But it looks like the jump code never runs. Only want it to run once. What could be the problem?

Didnt know how to make the jump so tried this trick with merging instructions but I dont know if I got it right. aqrit's example works great so decided to try it for some other code...

Code: Select all

005EBDE0  /$ 56             PUSH ESI
005EBDE1  |. 8BF1           MOV ESI,ECX
005EBDE3  |. B8 02000000    MOV EAX,2
005EBDE8  |. B2 03          MOV DL,3
005EBDEA  |. 33C9           XOR ECX,ECX
005EBDEC  |. 57             PUSH EDI
005EBDED  |. 66:8946 3C     MOV WORD PTR DS:[ESI+3C],AX
005EBDF1  |. 8896 C2000000  MOV BYTE PTR DS:[ESI+C2],DL
005EBDF7  |. C686 C3000000 >MOV BYTE PTR DS:[ESI+C3],1
005EBDFE  |. 8886 C4000000  MOV BYTE PTR DS:[ESI+C4],AL
005EBE04  |. 66:898E AB0000>MOV WORD PTR DS:[ESI+AB],CX
005EBE0B  |. 66:898E DB0000>MOV WORD PTR DS:[ESI+DB],CX
005EBE12  |. C646 42 01     MOV BYTE PTR DS:[ESI+42],1
005EBE16  |. C686 C5000000 >MOV BYTE PTR DS:[ESI+C5],1
005EBE1D  |. 8886 C6000000  MOV BYTE PTR DS:[ESI+C6],AL
005EBE23  |. 8896 C7000000  MOV BYTE PTR DS:[ESI+C7],DL
005EBE29  |. 888E C8000000  MOV BYTE PTR DS:[ESI+C8],CL
005EBE2F  |. 888E BF000000  MOV BYTE PTR DS:[ESI+BF],CL
005EBE35  |. 888E C0000000  MOV BYTE PTR DS:[ESI+C0],CL
005EBE3B  |. 8886 BE000000  MOV BYTE PTR DS:[ESI+BE],AL
[color="#FF0000"]005EBE41     8886 C1000000  MOV BYTE PTR DS:[ESI+C1],AL[/color]
005EBE47  |. 8B3D 6CF89C00  MOV EDI,DWORD PTR DS:[9CF86C]
005EBE4D  |. 808E D9000000 >OR BYTE PTR DS:[ESI+D9],40
005EBE54  |. 51             PUSH ECX
...
Tried merging C1, C2, C3 because I want to change the value for C1 to 4 so I used "MOV DWORD [ESI+C1], 010304". Would this be the same as
MOV BYTE PTR DS:[ESI+C1],4
MOV BYTE PTR DS:[ESI+C2],DL (DL = 3?)
MOV BYTE PTR DS:[ESI+C3],1

Posted: Wed Aug 08, 2012 1:20 pm
by aqrit
:( this is exactly same, you just changed the value of C1 from 2 to 4

on x86 a DWORD == 4 bytes
also read:
http://en.wikipedia.org/wiki/Endianness#Little-endian

Posted: Thu Aug 09, 2012 5:34 am
by universalis
You are right.. silly me. I dont know the value of C0 (=CL) but I know what AL is so I can use MOV DWORD instruction for C1,C2,C3,C4.

Btw, I figured out how to use the jumps. Im simply using 3 jumps and it seems to work.

Posted: Thu Aug 09, 2012 10:44 am
by aqrit

Code: Select all

XOR ECX,ECX
CL is zero ...