简体   繁体   中英

Assembly - cmp doesn't work

I'm trying to replace an unicode string (its length is 8) in assembly with some other. The address of the string beginning increased by 0x10 and is stored in EDI. I know the string value, but its address is changing, so I can't replace it by address. I'm using Code Injection in Cheat Engine. That code works:

alloc(newmem,4096)
label(returnhere)
label(originalcode)
label(exit)

newmem:

repe movsb
cmp edi,0341E340
jne originalcode
mov [edi-10],31
mov [edi-0E],32
mov [edi-0C],33
mov [edi-0A],34
mov [edi-08],35
mov [edi-06],36
mov [edi-04],37
mov [edi-02],38

originalcode:

jmp MSVCR120.memcpy+53

exit:
jmp returnhere

"MSVCR120.dll"+F20C:
jmp newmem
nop
nop
returnhere:

but that doesn't:

alloc(newmem,8192)
label(returnhere)
label(originalcode)
label(exit)

newmem:

repe movsb

cmp [edi-10],41
jne originalcode
cmp [edi-0E],42
jne originalcode
cmp [edi-0C],43
jne originalcode
cmp [edi-0A],44
jne originalcode
cmp [edi-08],45
jne originalcode
cmp [edi-06],46
jne originalcode
cmp [edi-04],47
jne originalcode
cmp [edi-02],48
jne originalcode

mov [edi-10],31
mov [edi-0E],32
mov [edi-0C],33
mov [edi-0A],34
mov [edi-08],35
mov [edi-06],36
mov [edi-04],37
mov [edi-02],38

originalcode:

jmp MSVCR120.memcpy+53

exit:
jmp returnhere

"MSVCR120.dll"+F20C:
jmp newmem
nop
nop
returnhere:

Of course both codes could be assembled, but the second one does nothing (it can't go through the comparison part). I'm sure the values I compare are good, because I've set a breakpoint when edi is 0341E340. What's more, when I execute the first and the second code (together, to be sure the value is right) it also doesn't work. Cheat Engine treats constants as hex values (exactly what I want) and it doesn't understand if I write, for example, 0Ch. So how should I compare the values?

cmp edi,0341E340 compares value in edi ( no memory access ) with something, what was supposed to be hexadecimal constant, I guess.

cmp [edi-10],41 compares value at address edi-10 ( content of memory ) with 41. From this instruction format it's not clear, whether byte or dword value is compared.

But in any case, the two are doing something completely different.

If you do for example:

; preparing test values + memory content for examples
mov edi,bufferAddress ; pointer to some writeable free memory
mov [edi],byte 41     ; all values are decimal
mov [edi+1],byte 1
; then these will evaluate as "equal" (ZF=1)
cmp edi,bufferAddress
cmp [edi],byte 41
cmp [edi],word 256+41  ; x86 little-endian
; these will evaluate as "not equal" (ZF=0)
cmp edi,bufferAddress+1
cmp [edi],word 41  ; on [edi+1] is "1" instead of 0

So it's completely confusing, why you even mix those two examples together.

Whether the second case works depends on the content of memory. Whether the first works depends on the value in edi (probably some buffer address).

The problem was Cheat Engine was treating constants as 4 bytes, not 1 byte. I had to write it like:

cmp [edi-10],00320031
jne originalcode
cmp [edi-0C],00340033
jne originalcode
cmp [edi-08],00360035
jne originalcode
cmp [edi-04],00380037
jne originalcode

Now it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM