2016-11-01 2 views
1

Ich versuche, diese Linie Bei der Montage, wie kann ich einen 5-Byte-Befehl in einen 3-Byte-Raum im Debugger hinzufügen

zu

0041DE91 | mov eax, 10 

Aber der Anweisung zu ändern

0041DE91 | 8B 46 64     | mov eax,dword ptr ds:[esi+64] 
0041DE94 | 83 C4 0C     | add esp,C         
0041DE97 | 83 F8 01     | cmp eax,1         
das war 3 Byte belegt 5 Bytes und Leckagen in den beiden Adressen darunter:

0041DE91 | B8 0A 00 00 00   | mov eax,10          
0041DE96 | 0C 83     | or al,83          
0041DE98 | F8      | clc          

Ist es möglich, dies in einem Debugger ein zu tun vorkompiliertes Programm?

+0

nein. nicht ohne den Rest des Codes NACH dem Einfügepunkt zu hacken, um alles um 2 Byte zu verschieben. oder in der Hoffnung, dass ein anderes Register eine Null enthält, so dass Sie dort keine 32-Bit "Null" einbetten müssen. –

+0

Jetzt denkst du. Ich brauche eine Nummer, die nicht Null im Register ist. – user5389726598465

+0

warum nicht 'xor eax, eax'? das wird das Register auf null setzen, nur ein oder zwei Bytes benutzen. –

Antwort

4

In 32-Bit-Code (wo es keine ist clobber) Sie können imm8 Konstanten in Registern (uneffizient) mit 3 Bytes bewegen:

push 10  ; 2B 
pop eax  ; 1B 

Sie können auch 1 in ein Register erhalten in 3B

xor eax, eax ; 2B 
inc eax  ; 1B 

Oder gegeben andere Register der bekannten Inhalt:

lea eax, [ecx+/-imm8] ; 3B 

Weitere Code-Golf/code-size-Optimierung Tricks:

xor eax,eax ; 2B 
cdq    ; 1B to zero edx as well 

xchg eax, ecx ; 1B. Shorter than MOV if you want ecx=eax and can trash eax (or both parts are actually useful) 

Viele davon sind für 16-Bit- und 64-Bit-Code als auch. Siehe zum Beispiel meine adler32 in 32B of x86-64 machine code, and the x86-16 version.

+0

Sie sagten im Kommentar _Shorter als MOV, wenn Sie ecx = eax_ wollen, aber Sie verwenden generische _xchg eax, r32_ im Code. Vielleicht meintest du _xchg eax, ecx_, um dem Kommentar zu entsprechen. –

+0

@MichaelPetch: danke, ich schrieb zuerst ecx, änderte es dann zu generisch. Aber ich denke, du hast Recht, es funktioniert besser mit einem bestimmten Beispiel, über das du im Kommentar sprechen kannst. (was ich vergessen habe zu aktualisieren, xD) –

+0

Die ersten beiden sehen vielversprechend aus, ich werde morgen versuchen müssen, wenn ich aufwache. Ich könnte einfach eax erhöhen, da ich weiß, dass es Null ist, aber ich könnte auch ein Register verwenden, das eine Adresse enthält (von der ich weiß, dass sie nicht negativ ist) wie esi oben. Viele Möglichkeiten, es jetzt zu tun, da hat mich jemand zum Nachdenken gebracht. – user5389726598465

4

Wenn Sie um diesen 3-Byte-Bereich noch Platz haben, können Sie den neuen Code dort platzieren und einen nahen Sprung machen, tun, was Sie brauchen, und zurückspringen.

Diese Technik wird zum Implementieren von Hot-Patching in Windows verwendet. Es wird gemacht, indem MOV EDI, EDI als 2-Byte NOP am Anfang der Funktion gesetzt wird. Dann, wenn die Funktion gepatcht werden muss, die sie ersetzen, dass „NOP“ mit einem JMP $-5 und einem vollen Sprung auf die neue Funktion in dem 5 Byte vor der Funktion

So, jetzt im Grunde brauchen Sie

mov eax, dword ptr ds:[esi+64] 
add esp, C 
cmp eax, 1 
ändern

bis

jmp new_instruction 
continue: 
    add esp, C 
    cmp eax, 1 
... 
new_instruction: 
    move eax, 10 
    jmp continue 
Verwandte Themen