2016-08-06 23 views
0

Ich kämpfe um herauszufinden, wie ein bestimmter Block funktionieren würde. Mit der folgenden Adresse auf dem HeapAssembly memory und looping

004B0000 73 6D 67 66 74 smgft 

und folgende Montag:

77A701B8 xor eax, eax 
77A701BA mov ecx, 4 
77A701BF lea edi, DWORD PTR DS:[ecx+4B0000] 
77A701C5 xor DWORD PTR DS:[edi], ecx 
77A701C5 loopd short ntdll.77A701BF 

Das Problem ist, den Wert des fünf Bytes auf dem Heap in ASCII zur Verfügung zu stellen, nachdem die Anweisungen ausgeführt haben. Was ich daraus verstehen kann, ist wie folgt

xor eax, eax; 0 aus eax

mov ecx, 4; Satz ecx 4

lea edi, dword ptr ds: [ecx + 4b0000]; Dies lädt in EDI, was auch immer bei ecx + 4b0000 gespeichert ist, also 4b0004. Ich bin mir nicht sicher, was das alles bringen würde. Ich bin nicht einmal sicher, was 4b0000 bekommen würde, da es 5 Bytes ist. mgft oder smgf? Ich denke, smgf? Und wie beeinflusst das + 4h das? Macht es 736D676678?

xoder dword ptr ds: [edi], ecx; Also das wird xor 4h mit dem neu geladenen dword bei edi, aber was macht es damit im loopd?

loopd kurz ntdll.77A701BF; Das ist also eine "Schleife, die gleich ist", aber ich bin mir nicht sicher, was das bedeutet mit einem X oder darüber. Und dekrementiert es Ecx? Aber dann springt es zurück zur Spurlinie.

+0

Es ist eine "loop", nicht "loope" (Schleife während gleich), so ist es egal, EFLAGS (welche xor setzt). Weitere Informationen finden Sie unter http://www.felixcloutier.com/x86/LOOP:LOOPcc.html –

Antwort

4

Die lea edi, dword ptr ds:[ecx+4b0000] lädt den Wert ecx+0x004b0000 in EDI, und Speicher überhaupt nicht zugegriffen. Die Anweisung loop ist wie "ecx = ecx - 1; if(ecx != 0) goto ntdll.77A701BF".

Nicht, dass dieser Code kann abgerollt werden, so daß es:

xor eax, eax 

    lea edi, DWORD PTR DS:[4+0x004B0000] 
    xor DWORD PTR DS:[edi], 0x00000004 

    lea edi, DWORD PTR DS:[3+0x004B0000] 
    xor DWORD PTR DS:[edi], 0x00000003 

    lea edi, DWORD PTR DS:[2+0x004B0000] 
    xor DWORD PTR DS:[edi], 0x00000002 

    lea edi, DWORD PTR DS:[1+0x004B0000] 
    xor DWORD PTR DS:[edi], 0x00000001 

    xor ecx,ecx 

die mehr optimiert werden kann, so wird es:

xor BYTE PTR DS:[0x004B0004], 0x04 
    xor BYTE PTR DS:[0x004B0003], 0x03 
    xor BYTE PTR DS:[0x004B0002], 0x02 
    xor BYTE PTR DS:[0x004B0001], 0x01 

    xor eax, eax  ;May be unnecessary if value unused by later code 
    mov edi,0x004B0001 ;May be unnecessary if value unused by later code 
    xor ecx, ecx  ;May be unnecessary if value unused by later code 

die ein wenig mehr optimiert werden kann durch die Kombination von die XORs:

xor DWORD PTR DS:[0x004B0001], 0x04030201 

    xor eax, eax  ;May be unnecessary if value unused by later code 
    mov edi,0x004B0001 ;May be unnecessary if value unused by later code 
    xor ecx, ecx  ;May be unnecessary if value unused by later code 

Hinweis: Ja, das ist eine Fehlstellung XOR, aber wahrscheinlich schneller als mehrere kleinere ausgerichtete XORs auf modernen CPUs, da es keine Cache-Zeilengrenze überschreitet.

Im Wesentlichen; Die gesamte Schleife kann auf einen einzigen Befehl reduziert werden.

+0

Auch wenn es eine Cache-Zeilengrenze überschreitet, wäre es wahrscheinlich für die meisten Arten von Umgebungscode auf den meisten CPUs schneller als 4 Byte des Speicherziel-Byte. (Speicher-Ziel-ALU-Insins dekodieren immer zu mehreren UPs auf Intel-CPUs). Wenn es eine Seitengrenze (auf Pre-Skylake) überquerte, würden separate XORs für die Latenz gewinnen, aber immer noch nicht für den Durchsatz, es sei denn, diese langsame Anweisung würde später die Ausführung außerhalb der Reihenfolge stoppen. –

+0

was bedeutet, dass der Inhalt des Speichers in '004B0000 73 6C 65 65 70 sleep' umgewandelt wird – Ped7g