JMP zu absoluter Adresse (op-Codes)
-
20-09-2019 - |
Frage
Ich bin zu Code versucht, eine exe-Packer / Beschützer als eine Möglichkeit, mehr über Assembler, C ++, und wie PE-Dateien. Ich habe zur Zeit hätte arbeiten sie so der Abschnitt den EP enthält, mit einem Schlüssel XOR-verknüpft wird und ein neuer Abschnitt erstellt, die meinen Entschlüsselungscode enthält. Alles klappt toll, außer wenn ich versuche, und JMP auf den ursprünglichen EP nach der Entschlüsselung.
Im Grunde ich dies tun:
DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint;
// -- snip -- //
crypted.put(0xE9);
crypted.write((char*)&orginalEntryPoint, sizeof(DWORD));
Aber anstatt es auf den Eintrittspunkt Springen, OllyDbg zeigt, dass dieser Code Disassembliert an:
00404030 .-E9 00100000 JMP 00405035 ; should be 00401000 =[
und wenn ich versuche, es in olly den neuen Opcode zeigt manuell ändern sich als
00404030 -E9 CBCFFFFF JMP crypted.00401000
Wo haben 0xCBCFFFFF gekommen? Wie würde ich das von der C ++ Seite generieren?
Lösung
ich denke, dass E9
ist ein Opcode für einen relativen Sprung. Sein Operand gibt einen relativen Abstand gesprungen werden, plus oder minus von Beginn des nächsten Befehls
Wenn Sie die Operanden wollen eine absolute Adresse angeben, würden Sie einen anderen Operationscode benötigen.
Andere Tipps
Sie können verwendet werden:
mov eax,DESTINATION_VA
jmp eax ; pick any register the destination doesn't care about
oder
push DESTINATION_VA
ret ; not recommended for performance
Dieses und die nächsten up-to-16 ret
Anweisungen auf der Aufrufstruktur zurück höher als diese Tiefe wird falsche Vorhersage, es sei denn, sie werden durch eine tiefere Anruf Tiefe vor der Rückkehr-Adresse Prädiktor Stapel geschoben wurden. (Aktuelle CPUs haben in der Regel einen 16-Eintrag Prädiktor-Stack).
E9 href="http://felixcloutier.com/x86/JMP.html" rel="nofollow noreferrer"> jmp
Codierung wie folgt verwendet wird:
CURRENT_RVA: jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)])
Push + ret ist die kleinste Lösung, wenn Sie VA-Adresse und das Bild nicht verschoben wird, aber es ist immer noch 6 Bytes so ist es größer als eine direkte jmp rel32
.
Register-indirekt ist wahrscheinlich die am effizientesten, wenn Sie nicht eine normale direkte jmp
verwenden können.
Opcode für absoluten indirekten Sprung FF + 4 Byte-Adresse. Dies wird am häufigsten verwendet für jumptables von Adressen in Daten gespeichert werden.
Absolute Adressen tun Umzug benötigen, wenn sie nicht auf die erwartete Adresse geladen, so relative Adressen im allgemeinen bevorzugt. Code für die relative Sprünge ist auch 2 Bytes kleiner ist.
Intels Optimierung Handbuch erklärt, dass die CPU erwartet rufen und ret zu paarweise verwendet werden, so dass die ret ohne Aufruf in Antwort vorgeschlagen 2 führen würde, was sie eine „Leistungseinbuße“ nennen.
Auch wenn der Code nicht auf die gleiche Adresse geladen wurde, dass der Compiler angenommen, würde die ret wahrscheinlich das Programm zum Absturz bringen. Es wäre sicherer, eine relative Adresse zu berechnen.