0

I am using OllyDbg to modify an application but I am quite new in assembly language, I need to place an MD5 hash in a memory address, the destination memory address is stored in EAX. How can I do it?

enter image description here

The hash that I need to insert is dba2d8bf7063faf1275e693661bc9651. I have tried in the following way:

MOV DWORD PTR DS:[EAX],32616264
MOV DWORD PTR DS:[EAX+4],66623864
MOV DWORD PTR DS:[EAX+8],33363037
MOV DWORD PTR DS:[EAX+12],31666166
MOV DWORD PTR DS:[EAX+16],65353732
MOV DWORD PTR DS:[EAX+20],36333936
MOV DWORD PTR DS:[EAX+24],63623136
MOV DWORD PTR DS:[EAX+28],31353639

But it is very long and very inefficient in my opinion. I have also tried saving the hash in another address and moving it to where I need it with the MOV instruction but I can not make it work:

MOV DWORD PTR DS:[EAX], 012B2C60

Where 012B2C60 is the hash address.

Another problem that happens to me is that the yellow underlined bytes are modified when I start the program (I guess they must be dynamic addresses) so what I write in that address is modified when the program starts, how can I prevent this from happening?

enter image description here

Joseph
  • 335
  • 1
  • 3
  • 13

2 Answers2

1

BTW, why do you need to copy 32 bytes? MD5 hashes are 16 bytes. Are you copying an ASCII representation of it?

MOV DWORD PTR DS:[EAX], 012B2C60

You can't copy memory to memory without modifying registers. Also, a sequence of 8 dword mov instructions with a 32-bit absolute address wouldn't be any shorter even if it was encodeable, because each instruction would need the 012B2C60 address.


If you can clobber an XMM or YMM register (or save/restore it on the stack), you can copy 32 bytes using 2 XMM SSE load/store pairs, or a single AVX vmovdqu ymm4, [012B2C60] / vmovdqu [eax], ymm4

If performance matters in the program after you do this, use AVX if the surrounding code is already using AVX. Otherwise use SSE movups with an XMM register. (Avoid AVX/SSE transition stalls or Skylake false dependencies).

Instead of AVX or SSE, you could implement a memcpy by pushing esi, edi, and ecx and using ecx=8 / rep movsd, then restoring regs. (For edi you could xchg eax, edi before rep movsd, then sub edi, 32, then xchg again. For performance IDK if that's any better than push/pop to save/restore it along with the others, though.

Or if you don't have to save registers, rep movsd is nice for code size for run-once efficiency.

If your code to do this only runs once at program startup, then unless code-size is a real issue, it's probably easiest to use immediate data instead of copying. It's not great for total space efficiency, because each dword of data needs 3 extra bytes: opcode, modrm, and disp8 (except for the first one which uses a bare [eax] addressing mode. push has better density for immediate data, but can only push onto the stack.

64-bit mode helps only slightly; mov r64, imm64 is 10 bytes, but only works with a register destination.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Thanks, yes, it is an ASCII representation, I chose to move the bytes using the XMM registry, in this way I can move the 32 bytes with only two commands. But I still have the problem of the addresses that I mention in the first publication... – Joseph Dec 05 '17 at 00:17
  • @Manuel23: 4 instructions: 2 load / 2 store. (And the word you want is "registers", not ["registry"](http://www.dictionary.com/browse/registry)). – Peter Cordes Dec 05 '17 at 00:24
  • @Manuel23: I don't understand what problem you're having with addresses. `movdqu xmm0, [012B2C60]` or `[012B2C60+16]` to load, and you already have the address in `eax` so you can store with `[eax]` and `[eax+16]` addressing modes. – Peter Cordes Dec 05 '17 at 00:25
  • @Manuel23: Oh, your last paragraph. That looks like a relocation / fixup for the executable being loaded at a different address from the one it's expecting. Are you replacing some existing code that had an address at that location? – Peter Cordes Dec 05 '17 at 00:27
  • Yes, if you look at the first image, I have set NOP to a complete function, but 8 bytes remain with a yellow underline, those bytes are modified when the application is restarted, ruining my modifications – Joseph Dec 05 '17 at 00:39
  • @Manuel23: You should have said that in text as well as posting a zoomed-out image. I read the text and didn't see anything unclear that made me think I needed to refer to the image. Anyway, yes, if you NOPed some code that previously included an address, the Windows program-loader will still add the relocation offset to those bytes. If your code has a fixed load address, you could account for that and use data like `x - y + 0x90909090` or something so the final result of the relocation is 4 NOPs. Or use a long-NOP so those 4 bytes are part of the unused disp32 in a `0F F0` NOP. – Peter Cordes Dec 05 '17 at 00:54
  • Yes, sorry, I speak Spanish and it is being very difficult for me to try to explain this in English. Is it possible to remove the relocation offset of those bytes? I would like to use those bytes to write new commands... – Joseph Dec 05 '17 at 01:11
  • @Manuel23: IDK how easy it is to edit the symbol / relocation table in the PE headers to remove that relocation. Is this a DLL, or can you just disable ASLR if it's an executable so it will be loaded at the same address every time? If position-dependent code is ok, then you can work around the relocation by using `0x90909090 - relocation`, where `relocation` is the amount that's added when the program loads. So on disk the bytes will be "wrong", but when loaded the fixup will make them what you want them to be. It doesn't have to be NOPs; can be anything. – Peter Cordes Dec 05 '17 at 01:21
  • @Manuel23: Editing the PE header would be much cleaner, though, so try to do that. (No idea how, I don't do Windows or binary editing, I just know how dynamic linking and ASLR works.) – Peter Cordes Dec 05 '17 at 01:23
0
  • store your hash code in the bottom of your code segment. usually you can see many free bytes in code segment that never changes. they are zero. data segment is for your global variables so they may changes but code segment bytes never changes.
  • use memcpy function to copy these bytes to your destination memory address.
Amir
  • 1,638
  • 19
  • 26