2012-10-27 12 views
6

Ich arbeite an einem Hausaufgabenprojekt mit einer "Bombe" geschrieben in kompilierten c, die ich rückentwickeln muss, um 5 Saiten zu entwickeln, die jede der fünf "Phasen" der Bombe entwaffnen. Ich stecke gerade auf Phase 3 und versuche, die von gdb für diese Funktion erzeugte Assembly (x86, AT & T Syntax, glaube ich) zu übersetzen. Was ich bis jetzt herausgefunden habe, ist, dass es versucht, eine Reihe von sechs Zahlen als Benutzereingabe zu nehmen und sie nach einigen Kriterien zu beurteilen, aber das ist, wo ich es verliere. Die Funktion ist wie folgt (mit meiner versuchten Pseudocode-Übersetzung daneben).Übersetzen Assembly zu Pseudocode

0x08048816 <phase_3+0>: push %ebp 
0x08048817 <phase_3+1>: mov %esp,%ebp 
0x08048819 <phase_3+3>: push %edi 
0x0804881a <phase_3+4>: push %ebx 
0x0804881b <phase_3+5>: sub $0x30,%esp 
0x0804881e <phase_3+8>: lea -0x24(%ebp),%eax        
0x08048821 <phase_3+11>: mov %eax,0x4(%esp)       
0x08048825 <phase_3+15>: mov 0x8(%ebp),%eax       
0x08048828 <phase_3+18>: mov %eax,(%esp)        
0x0804882b <phase_3+21>: call 0x8048d2c <read_six_numbers> 
0x08048830 <phase_3+26>: mov -0x24(%ebp),%eax      eax = p1 
0x08048833 <phase_3+29>: cmp $0x1,%eax        if eax != 1 
0x08048836 <phase_3+32>: je  0x804883d <phase_3+39>     explode bomb 
0x08048838 <phase_3+34>: call 0x8048fec <explode_bomb>    else 
0x0804883d <phase_3+39>: movl $0x1,-0xc(%ebp)      ebp[-12] = 1 
0x08048844 <phase_3+46>: jmp 0x804888a <phase_3+116>    while ebp[-12] < 5 { 
0x08048846 <phase_3+48>: mov -0xc(%ebp),%eax       eax = ebp[-12] 
0x08048849 <phase_3+51>: mov -0x24(%ebp,%eax,4),%eax     {magic} 
0x0804884d <phase_3+55>: mov %eax,%ebx        ebx = eax 
0x0804884f <phase_3+57>: mov -0xc(%ebp),%eax       eax = ebp[-12] 
0x08048852 <phase_3+60>: sub $0x1,%eax         eax -= 1 
0x08048855 <phase_3+63>: mov -0x24(%ebp,%eax,4),%eax     {magic} 
0x08048859 <phase_3+67>: mov %eax,%edx        edx = eax 
0x0804885b <phase_3+69>: mov 0x804a6d8,%eax       eax = 0x804a6d8 
0x08048860 <phase_3+74>: mov $0xffffffff,%ecx      ecx = 255 
0x08048865 <phase_3+79>: mov %eax,-0x2c(%ebp)       ebp[-12] = eax 
0x08048868 <phase_3+82>: mov $0x0,%eax         eax = 0 
0x0804886d <phase_3+87>: cld       
0x0804886e <phase_3+88>: mov -0x2c(%ebp),%edi       edi = ebp[-12] 
0x08048871 <phase_3+91>: repnz scas %es:(%edi),%al      {deep magic} 
0x08048873 <phase_3+93>: mov %ecx,%eax        eax = ecx 
0x08048875 <phase_3+95>: not %eax          eax = -eax 
0x08048877 <phase_3+97>: sub $0x1,%eax         eax -= 1 
0x0804887a <phase_3+100>: imul %edx,%eax        eax *= edx 
0x0804887d <phase_3+103>: cmp %eax,%ebx        if (eax != ebx) 
0x0804887f <phase_3+105>: je  0x8048886 <phase_3+112>      explode_bomb 
0x08048881 <phase_3+107>: call 0x8048fec <explode_bomb>     else 
0x08048886 <phase_3+112>: addl $0x1,-0xc(%ebp)       ebp[-12] += 1 
0x0804888a <phase_3+116>: cmpl $0x5,-0xc(%ebp) 
0x0804888e <phase_3+120>: jle 0x8048846 <phase_3+48>    } 
0x08048890 <phase_3+122>: add $0x30,%esp 
0x08048893 <phase_3+125>: pop %ebx 
0x08048894 <phase_3+126>: pop %edi 
0x08048895 <phase_3+127>: pop %ebp 
0x08048896 <phase_3+128>: ret 

Ich bin zumindest ein wenig (wenn auch nicht viel) zuversichtlich, in den meisten dieser; Die Linien, die absolut sicher sind, sind die drei Linien, die momentan als "magisch" markiert sind - phase_3 + 51, phase_3 + 63 und phase_3 + 91 (die beiden mov-Linien mit seltsamer Syntax und der repnz). Ich habe keine der beiden Syntaxen gesehen und kann nicht herausfinden, welche Suchbegriffe verwendet werden, um sie nachzuschlagen.

Irgendwelche allgemeinen (und/oder vernichtenden) Kritiken meines Versuchs dazu? Offensichtliche Orte, wo ich von den Schienen gehe? Offensichtlich, da dies Hausaufgaben sind, brauche ich niemanden, der mir die Antwort gibt; Ich möchte nur wissen, ob meine Interpretation im Allgemeinen gut ist (und was diese drei Zeilen bedeuten, dass ich davon verwirrt bin).

Vielen Dank für jede Hilfe!

* EDIT ***

Die read_six_numbers Funktion disassembliert, wie folgt:

0x08048d2c <read_six_numbers+0>: push %ebp 
0x08048d2d <read_six_numbers+1>: mov %esp,%ebp 
0x08048d2f <read_six_numbers+3>: push %esi 
0x08048d30 <read_six_numbers+4>: push %ebx 
0x08048d31 <read_six_numbers+5>: sub $0x30,%esp 
0x08048d34 <read_six_numbers+8>: mov 0xc(%ebp),%eax 
0x08048d37 <read_six_numbers+11>: add $0x14,%eax 
0x08048d3a <read_six_numbers+14>: mov 0xc(%ebp),%edx 
0x08048d3d <read_six_numbers+17>: add $0x10,%edx 
0x08048d40 <read_six_numbers+20>: mov 0xc(%ebp),%ecx 
0x08048d43 <read_six_numbers+23>: add $0xc,%ecx 
0x08048d46 <read_six_numbers+26>: mov 0xc(%ebp),%ebx 
0x08048d49 <read_six_numbers+29>: add $0x8,%ebx 
0x08048d4c <read_six_numbers+32>: mov 0xc(%ebp),%esi 
0x08048d4f <read_six_numbers+35>: add $0x4,%esi 
0x08048d52 <read_six_numbers+38>: mov %eax,0x1c(%esp) 
0x08048d56 <read_six_numbers+42>: mov %edx,0x18(%esp) 
0x08048d5a <read_six_numbers+46>: mov %ecx,0x14(%esp) 
0x08048d5e <read_six_numbers+50>: mov %ebx,0x10(%esp) 
0x08048d62 <read_six_numbers+54>: mov %esi,0xc(%esp) 
0x08048d66 <read_six_numbers+58>: mov 0xc(%ebp),%eax 
0x08048d69 <read_six_numbers+61>: mov %eax,0x8(%esp) 
0x08048d6d <read_six_numbers+65>: movl $0x804965d,0x4(%esp) 
0x08048d75 <read_six_numbers+73>: mov 0x8(%ebp),%eax 
0x08048d78 <read_six_numbers+76>: mov %eax,(%esp) 
0x08048d7b <read_six_numbers+79>: call 0x80485a4 <[email protected]> 
0x08048d80 <read_six_numbers+84>: mov %eax,-0xc(%ebp) 
0x08048d83 <read_six_numbers+87>: cmpl $0x5,-0xc(%ebp) 
0x08048d87 <read_six_numbers+91>: jg  0x8048d8e <read_six_numbers+98> 
0x08048d89 <read_six_numbers+93>: call 0x8048fec <explode_bomb> 
0x08048d8e <read_six_numbers+98>: add $0x30,%esp 
0x08048d91 <read_six_numbers+101>: pop %ebx 
0x08048d92 <read_six_numbers+102>: pop %esi 
0x08048d93 <read_six_numbers+103>: pop %ebp 
0x08048d94 <read_six_numbers+104>: ret  
+1

Wenn es Assembler ist ... müssten die Leute nicht die Architektur kennen? Wie x86? – FoolishSeth

+0

@FoolishSeth definitiv x86 –

+0

Eine Notiz in der Frage hinzugefügt - es ist x86, AT & T-Syntax. – rosalindwills

Antwort

7
mov -0x24(%ebp,%eax,4),%eax 

Die obige Anweisung ein Element eines Array zugreift. Dies nennt man SIB Adressierung in x86, für Scale, Index, Base. Es gibt auch eine Offset-Komponente. Das Array basiert auf einer Adresse, die durch das Basisregister (hier EBP) plus einem Offset bestimmt wird (wenn ein Rahmenzeiger verwendet wird, werden lokale Variablen, einschließlich Arrays, als ein Offset vom Rahmenzeiger adressiert). Die Elementnummer befindet sich im Indexregister (EAX hier). Die Größe jedes Elements wird durch die Skala (4 hier) bestimmt.

mov 0x804a6d8,%eax 
mov $0xffffffff,%ecx 
mov %eax,-0x2c(%ebp) 
mov $0x0,%eax 
cld       
mov -0x2c(%ebp),%edi 
repnz scas %es:(%edi),%al 
mov %ecx,%eax 
not %eax 
sub $0x1,%eax 

Dies ist nur strlen(0x805a6d8). ES:EDI zeigt auf eine zu überprüfende Zeichenfolge (Vergleich mit einem Referenzbyte) unter 0x804a6d8. AL enthält das zu scannende Zeichen: 0 - ASCII NUL. cld legt die Richtung für den Scan fest: aufsteigend (std würde den Scan absteigend machen). ECX wird initialisiert auf ~0 = -1: alle Bits 1. repnz wiederholt die scas (SCAN STRING) Anweisung, die ECX dekrementiert, während ECX nicht Null ist (was nicht passieren wird, da ECX groß genug ist, das zu verhindern) und der Scan nicht erfolgreich ist (NZ, während der Scan (Vergleich zwischen der Zeichenkette und der Referenz-AL) hat das Null-Flag nicht gesetzt). Danach enthält ECX-1-(steps in the scan). NOT macht das (steps in the scan). SUB macht das (steps in the scan) - 1 = (length of string not including the terminating NUL). Auch erklärt unter http://www.int80h.org/strlen/.

+0

Wow, danke. Dies ist sehr nützlich. Vielen Dank! – rosalindwills