0

I'm trying to modify a C++ program using ollydb and cheat engine.

For whatever reason I want to remove a memory address and replace it with the number 0 (or anything that ends in the same result).

There are four spots in the code I need to replace with 0.

Here is my problem:

CPU Disasm Before

01411E38  |.  8BD0          MOV EDX,EAX
01411E3A      3315 0020A701 XOR EDX,DWORD PTR DS:[1A72000]
01411E40  |.  8995 B8FCFFFF MOV DWORD PTR SS:[EBP-348],EDX

Changed to:

01411E38  |.  8BD0          MOV EDX,EAX
01411E3A      83F2 00       XOR EDX,00000000
01411E3D      90            NOP
01411E3E      90            NOP
01411E3F      90            NOP
01411E40  |.  8995 B8FCFFFF MOV DWORD PTR SS:[EBP-348],EDX

Upon saving/reloading:

01111E38   .  8BD0          MOV EDX,EAX
01111E3A      83            DB 83
01111E3B      F2            DB F2
01111E3C   .  00906090      DD 90609000
01111E40  /.  8995 B8FCFFFF MOV DWORD PTR SS:[EBP-348],EDX

So why does changing
XOR EDX,DWORD PTR DS:[1A72000]
to
XOR EDX,0

work when i make the changes, but if I save the exe and reload it, the modified assembly is changed/broken.

Tom Aranda
  • 5,919
  • 11
  • 35
  • 51
Chillowak
  • 21
  • 2
  • Buggy tool. Anyway, just pad the whole instruction to `NOP`. Better question is, why did you get `90 60 90` instead of `90 90 90` in the file? – Jester Dec 14 '17 at 03:02
  • 6
    Because there is still a fixup record targeting those bytes. Program images are not binary dumps. They are far more complicated. Notice that the location was 01411E38 when you patched it, but 01111E38 when it was reloaded. That is why one of the 90 changed to 60. – Raymond Chen Dec 14 '17 at 03:06
  • 4
    @RaymondChen ha, nice one! A 2 byte `jmp` should take care of it then :) – Jester Dec 14 '17 at 03:23
  • Other option is to modify the last write `mov [ebp-348]` to store originating `eax` value instead of modified `edx` (and keep the `xor` intact) ... if the further code does not hold on `edx`, and will reload it from the stack later. Would need to see larger part of code to see which kind of change would work. – Ped7g Dec 14 '17 at 09:18
  • (but Jester suggestion of 2B `jmp` to jump over the patched bytes is even better, finally realized what he meant) – Ped7g Dec 14 '17 at 09:27

1 Answers1

2

Thanks for the help.

Because there is still a fixup record targeting those bytes. Program images are not binary dumps. They are far more complicated. Notice that the location was 01411E38 when you patched it, but 01111E38 when it was reloaded. That is why one of the 90 changed to 60.

– Raymond Chen

@RaymondChen ha, nice one! A 2 byte jmp should take care of it then :)

– Jester

Replaced

XOR EDX,DWORD PTR DS:[1A72000]

with

JMP 01411E40
Chillowak
  • 21
  • 2
  • 2
    You could also replace it with `CMP EDX, DWORD PTR DS:[1A72000]`. i.e. just change the opcode to `cmp`, and it will still decode correctly and load from the same address (because `cmp` and `xor` are both 1-byte opcode + modr/m encoding), but will **only write flags** instead of also writing EDX. (I learned this trick of [using `cmp` or `test` as a sort-of-NOP from Ira Baxter's answer](https://stackoverflow.com/questions/10765317/can-assembled-asm-code-result-in-more-than-a-single-possible-way-except-for-off)). But `jmp` works too. Of course it's actually a `rel8`, not absolute... – Peter Cordes Dec 15 '17 at 11:31