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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top