PDA

View Full Version : Ollydbg overwrites code when editing instructions


universalis
July 21st, 2012, 11:35
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:
2613
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".
2614

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.

blabberer
July 21st, 2012, 14:12
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:


1) Address 12345670 opcode $$$$$ mov # # , #### say 5 byte stream
2) +5 = 12345675 opcode $$$$$ mov ## , #### original second instruction



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

aqrit
July 21st, 2012, 14:20
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"

universalis
August 8th, 2012, 07:38
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:

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
005EBE41 8886 C1000000 MOV BYTE PTR DS:[ESI+C1],AL
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

aqrit
August 8th, 2012, 13:20
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

universalis
August 9th, 2012, 05:34
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.

aqrit
August 9th, 2012, 10:44
Code:
XOR ECX,ECX

CL is zero ...