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?
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?
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.