JMP, um die absolute Adresse (op-codes)
Ich versuche, code zu einer exe-packer/protector als eine Art des Lernens mehr über assembler, c++, und wie PE-Dateien arbeiten. Ich habe derzeit arbeite daran haben, so dass der Abschnitt mit den EP ist XORed mit ein Schlüssel und ein neuer Abschnitt erstellt wird, enthält mein Entschlüsselungs-code. Alles funktioniert Super, außer wenn ich versuche, JMP, um die original-EP nach der Entschlüsselung.
Grundsätzlich habe ich hierzu:
DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint;
//-- snip -- //
crypted.put(0xE9);
crypted.write((char*)&orginalEntryPoint, sizeof(DWORD));
Aber anstatt es zu springen, um den Einstiegspunkt, ollydbg zeigt, dass dieser code zerlegt:
00404030 .-E9 00100000 JMP 00405035 ; should be 00401000 =[
und wenn ich versuche es manuell ändern in olly den neuen opcode zeigt sich als
00404030 -E9 CBCFFFFF JMP crypted.00401000
Wo hast 0xCBCFFFFF kommen? Wie würde ich generieren, die von der C++ - Seite?
InformationsquelleAutor Christopher Tarquini | 2009-10-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, dass
E9
ist ein opcode für einen relativen Sprung: der operand gibt eine relative Distanz zu sprang, plus oder minus aus dem Anfang der nächsten Anweisung.Wollen Sie den Operanden zum spezifizieren einer absoluten Adresse, Sie müssen einen anderen opcode.
dies kann Ihnen bei Ihrer Suche helfen: ref.x86asm.net
Sprünge sind in der Regel relativ. Es gibt einen opcode
EA
für einen Sprung zu einem absoluten weit-Adresse und die opcodes für die Sprünge, um eine indirekte Adresse (wo der operand gibt die Speicherposition, welches die Adresse enthält, werden gesprungen).Dies trifft die Frage nicht beantworten, nur bestätigt, dass die OP hatte die falsche Antwort.
Die Frage war, "Wo hast 0xCBCFFFFF kommen?" Sowieso scheinbar das OP verstanden, die Antwort, und/oder war damit zufrieden
EA
im Kommentar.InformationsquelleAutor ChrisW
den Sie verwenden könnten:
oder
Dieser und der nächsten bis-zu-16
ret
Anweisungen zurück oben auf dem Aufruf-Baum höher als diese Tiefe wird mispredict, es sei denn, Sie waren geschoben, vor der Rückkehr-Adresse Prädiktor-stack durch einen tieferen Ruf der Tiefe. (Aktuelle CPUs haben in der Regel eine 16-Eintrag Prädiktor stack).relative
E9
jmp
- Codierung wird wie folgt verwendet:push + ret ist die kleinste Lösung, wenn Sie haben, VA Adresse und das Bild wird nicht verlegt, aber es ist immer noch 6 bytes, so ist es größer als eine direkte
jmp rel32
.Register-indirekt ist wohl die effizienteste, wenn Sie nicht verwenden können, eine normale direkte
jmp
.push
/ret
Unwucht wird die return-Adresse Prädiktor stack.mov eax,addr
/jmp eax
ist nur 1 byte mehr, und nicht haben, dass problem. Siehe auch Call eine absolute Zeiger in x86-Maschinencode.Ich bin auf der Suche nach eine ähnliche Methode für die 64-bit-Adressraum, mit op-codes.
InformationsquelleAutor Bartosz Wójcik
opcode für absolute indirekten Sprung FF + 4byte Adresse. Dies ist in den meisten Fällen für jumptables von gespeicherten Adressen in den Daten.
Absolute Adressen benötigen Umzug, wenn nicht geladen wird, um die erwartete Adresse, so dass relative Adressen werden in der Regel bevorzugt. Code für relative Sprünge ist auch 2 bytes kleiner.
Intel-Optimierung-Handbuch sagt, dass die cpu rechnet mit call und ret werden paarweise verwendet, so dass die ret-ohne einen Anruf vorgeschlagen, in Antwort 2 verursachen würde, was Sie rufen ein "performance-Einbußen".
Auch, wenn der code konnte nicht geladen werden an die gleiche Adresse, die der compiler angenommen, die ret würde wahrscheinlich zu einem Absturz des Programms. Es wäre sicherer, die Berechnung einer relativen Adresse.
es macht immer noch Sinn, da
FF
ist der opcode, und wir kennen die Eselsbrücke istjmp
. Könnte es seinFF /4
oderFF /5
da Sie beide springen absoluten indirekt-nämlich ein in der Nähe und der andere weit springen. Aber ja,FF 25 aa bb cc dd
ist, wie würden Sie beobachtenFF /4
(die häufiger von den beiden) in Maschinen-code.Der Letzte Absatz ist nicht richtig:
push imm32
/ret
wird nicht Abstürzen, die Verlagerung der code verändert nicht die absolute Ziel-Adresse, dieret
springt an. Das problem ist die performance: unbalancing die return-Adresse-stack wird einige zukünftige Erträge mispredict. Einmov reg,imm32
+ 2-byte-register-indirekt zu springen, ist wahrscheinlich Ihre beste Wette (anstatt laden ein Zeiger aus dem Speicher) wenn aus irgendeinem Grund kann man nicht einfach codieren einesjmp rel32
eine bekannte Adresse. Call eine absolute Zeiger in x86-Maschinencode.Es wäre schön zu erwähnen, eine passende jmp opcode für 64-bit-Modus als auch.
InformationsquelleAutor Ann