codice:
=== BLOCCO ZERO: jump a 6 ===
00000000 EB 04 jmp 0x00000006 salta a 6
=== FINE BLOCCO ZERO ===
/------- questa roba sembra non essere mai richiamata --------\
00000002 AF scas eax, es:[edi]
00000003 C2 BF A3 ret 0xA3BF
\-------------------------------------------------------------/
=== PRIMO BLOCCO: inizializzazione stack e array 0-255 ===
00000006 81 EC 00 01 00 00 sub esp, 0x00000100 alloca 256 bytes sullo stack, ESP al -256
0000000C 31 C9 xor ecx, ecx 0 in ecx (e quindi CL=0)
--- inizio primo loop ---
registro di loop: CL (loword ECX)
iterazioni: 256 (da CL=0 a overflow)
0000000E 88 0C 0C mov [esp+ecx], cl copia il contenuto di CL in [esp+ecx]=[256+CL] <------+
00000011 FE C1 inc cl incrementa CL=low word di ECX (aggiornando i flag) |
00000013 75 F9 jnz 0x0000000E se i flag della CPU non sono a 0 salta a -------------+ ;
di fatto, il loop incrementa CL finché non torna a 0
lo stack si riempie dei numeri passati in rassegna
+-----+ <-- cima dello stack
| 255 |
| 254 |
| 253 |
| 252 |
///////
| 0 | <-- ESP
+-----+
--- fine primo loop ---
=== FINE PRIMO BLOCCO ===
=== SECONDO BLOCCO: introiaggio array 0-255 ===
v--- da qui CL è 0, quindi [esp+ecx] è al valore prima dell'overflow (=255)
00000015 31 C0 xor eax, eax 0 in eax
00000017 BA EF BE AD DE mov edx, 0xDEADBEEF copia 0xDEADBEEF in edx (hexspeech e forse riferimento allo stack di Windows :) )
--- inizio secondo loop ---
registro di loop: CL
iterazioni: 256 (da CL=0 a overflow)
0000001C 02 04 0C add al, [esp+ecx] aggiunge ad AL (loword di EAX) il contenuto di [ESP+ECX]
prima iterazione: AL=0, ECX=0, [ESP+ECX]=0
0000001F 00 D0 add al, dl aggiunge ad AL DL (loword di EDX)
prima iterazione: AL=0, DL=EF => AL=EF
00000021 C1 CA 08 ror edx, 0x08 ruota a destra EDX di 8 bit (DEADBEEF => EFDEADBE)
00000024 8A 1C 0C mov bl, [esp+ecx] copia in BL (loword di EBX) [ESP+ECX]
prima iterazione: [ESP+ECX]=0, BL=0
00000027 8A 3C 04 mov bh, [esp+eax] copia in BH (hiword di EBX) [ESP+EAX]
prima iterazione: EAX=EF => [ESP+EAX]=EF, BH=EF; EBX=EF00
0000002A 88 1C 04 mov [esp+eax], bl copia in ESP+EAX BL
prima iterazione: [ESP+EAX]=[ESP+EF]=0
0000002D 88 3C 0C mov [esp+ecx], bh ...
prima iterazione: [ESP+ECX]=[ESP]=0
00000030 FE C1 inc cl incrementa CL (+flags...)
00000032 75 E8 jnz 0x0000001C se non siamo a zero (=overflow di CL) salta a 1c (altro giro, casino maggiore)
=> qui lo stack sarà ormai un casino
00000034 E9 5C 00 00 00 jmp 0x00000095 salta diretto a 95
=== FINE SECONDO BLOCCO === (terzo a 95)
(il terzo è semplicemente una function call al quarto
NB: sullo stack abbiamo aggiunto 9c (indirizzo di ritorno) )
Stato noto:
ECX=0
EAX: dio solo sa cosa ci sia dentro
EDX: partiva come DEADBEEF, ruotato 256 volte di 8 bit, è ancora DEADBEEF
=== INIZIO QUARTO BLOCCO: ===
00000039 0E push cs 0 in cima allo stack
0000003A 38 1C 30 cmp [eax+esi], bl Inutile? I flags saranno aggiornati dalle inc...
0000003D 40 inc eax
0000003E 00 00 add [eax], al
00000040 00 5C 58 3D add [eax+ebx*2+0x3D], bl
00000044 41 inc ecx
00000045 41 inc ecx
00000046 41 inc ecx
00000047 41 inc ecx
00000048 75 43 jnz 0x0000008D Jump a blocco 5 (exit(0))
0000004A 58 pop eax
0000004B 3D 42 42 42 42 cmp eax, 0x42424242 <--- qui c'è un chiaro riferimento geek :)
00000050 75 3B jnz 0x0000008D Jump a blocco 5 (exit(0))
00000052 5A pop edx
00000053 89 D1 mov ecx, edx
00000055 89 E6 mov esi, esp
00000057 89 DF mov edi, ebx
00000059 29 CF sub edi, ecx
0000005B F3 A4 repz movs es:[edi], ds:[esi]
0000005D 89 DE mov esi, ebx
0000005F 89 D1 mov ecx, edx
00000061 89 DF mov edi, ebx
00000063 29 CF sub edi, ecx
00000065 31 C0 xor eax, eax
00000067 31 DB xor ebx, ebx
00000069 31 D2 xor edx, edx
--- terzo loop ---
Registro controllato: ECX
0000006B FE C0 inc al
0000006D 02 1C 06 add bl, [esi+eax]
00000070 8A 14 06 mov dl, [esi+eax]
00000073 8A 34 1E mov dh, [esi+ebx]
00000076 88 34 06 mov [esi+eax], dh
00000079 88 14 1E mov [esi+ebx], dl
0000007C 00 F2 add dl, dh
0000007E 30 F6 xor dh, dh
00000080 8A 1C 16 mov bl, [esi+edx]
00000083 8A 17 mov dl, [edi]
00000085 30 DA xor dl, bl
00000087 88 17 mov [edi], dl
00000089 47 inc edi
0000008A 49 dec ecx
0000008B 75 DE jnz 0x0000006B
--- fine terzo loop ---
Quando ECX è finalmente zero, fall-through sul quinto blocco e exit(0)
=== INIZIO QUINTO BLOCCO: syscall *NIX (int 80) ===
0000008D 31 DB xor ebx, ebx 0 in EAX e EBX
0000008F 89 D8 mov eax, ebx
00000091 FE C0 inc al EAX=1 => syscall 1 => exit
00000093 CD 80 int 0x80 Interrupt 80 - syscall Linux (exit(0))
=== FINE QUINTO BLOCCO ===
Se non siamo su un sistema *NIX (quindi non c'è supporto per exit(0) con int 0x80, EAX=1, EBX=0) fall through sul terzo blocco
(quindi chiamate ricorsive infinite)
=== TERZO (mini)BLOCCO: function call a 39 ===
00000095 90 nop
00000096 90 nop
00000097 E8 9D FF FF FF call 0x00000039 Chiama 39 come funzione
Push di 9C sullo stack come indirizzo di ritorno
(su ESP-1=-256 rispetto alla cima dello stack)
=== FINE TERZO (mini)BLOCCO ===
/---- Così ad occhio qui non ci si può arrivare. ----\
0000009C 41 inc ecx
0000009D 41 inc ecx
0000009E 41 inc ecx
0000009F 41 inc ecx
\----------------------------------------------------/
Bene, vado a dormire.