2012-10-27 38 views
6

Tôi đang làm việc trên một dự án bài tập về nhà liên quan đến một "quả bom" được viết trong biên dịch c mà tôi phải đảo ngược kỹ sư để tìm ra 5 chuỗi sẽ giải giáp mỗi năm "giai đoạn" của quả bom. Tôi đang mắc kẹt trên giai đoạn 3 ngay bây giờ, cố gắng dịch các hội đồng (x86, AT & T cú pháp tôi tin) được sản xuất bởi gdb cho chức năng đó. Những gì tôi đã có thể tìm ra cho đến nay là nó đang cố gắng để có một chuỗi sáu số như người dùng đầu vào và đánh giá chúng trên một số tiêu chí, nhưng đó là nơi tôi đang mất nó. Các chức năng như sau (với bản dịch giả của tôi cố gắng bên cạnh nó).Biên dịch sang mã giả

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 

Tôi ít nhất là một chút (mặc dù không nhiều) tự tin trong hầu hết điều này; các dòng mà tôi hoàn toàn chắc chắn là sai là ba dòng hiện được đánh dấu là "ma thuật" - phase_3 + 51, phase_3 + 63, và phase_3 + 91 (hai dòng mov với cú pháp lạ và repnz). Tôi đã không nhìn thấy một trong hai cú pháp xung quanh nhiều và tôi không thể tìm ra những thuật ngữ tìm kiếm để sử dụng để tìm chúng.

Bất kỳ phê phán chung (và/hoặc scathing) nào về nỗ lực của tôi về điều này? Rõ ràng nơi tôi sẽ đi ra khỏi đường ray? Rõ ràng, vì đây là bài tập về nhà tôi không cần ai đó đưa cho tôi câu trả lời; Tôi chỉ muốn biết liệu diễn giải của tôi có nói chung hay không (và ba dòng đó có nghĩa là tôi bị bối rối).

Cảm ơn bạn rất nhiều vì đã giúp đỡ!

* EDIT ***

Chức năng read_six_numbers disassembles như sau:

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

Nếu người lắp ráp ... không phải mọi người sẽ cần biết kiến ​​trúc không? Giống như x86? – FoolishSeth

+0

@FoolishSeth chắc chắn x86 –

+0

Đã thêm ghi chú trong câu hỏi - đó là x86, cú pháp AT & T. – rosalindwills

Trả lời

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

Các hướng dẫn trên được truy cập vào một phần tử của một mảng. Điều này được gọi là SIB giải quyết trong x86, cho Quy mô, Chỉ mục, Cơ sở. Ngoài ra còn có một thành phần bù đắp. Mảng được đặt tại một địa chỉ được xác định bởi thanh ghi Base (EBP ở đây) cộng với một offset (khi sử dụng một con trỏ khung, các biến cục bộ, bao gồm các mảng, được giải quyết như là một offset từ con trỏ khung). Số phần tử có tại thanh ghi chỉ mục (EAX tại đây). Kích thước của mỗi phần tử được xác định bởi Thang đo (4 tại đây).

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 

Đây chỉ là strlen(0x805a6d8). ES:EDI trỏ đến chuỗi để quét (so sánh lại một byte tham chiếu) tại 0x804a6d8. AL chứa ký tự cần quét: 0 - ASCII NUL. cld đặt hướng quét: tăng dần (std sẽ làm cho quá trình quét giảm dần). ECX được khởi tạo là ~0 = -1: tất cả các bit 1. repnz lặp lại lệnh scas (SCAN STRING) giảm ECX trong khi ECX không bằng 0 (điều này sẽ không xảy ra vì ECX đủ lớn để ngăn điều đó) và quá trình quét không thành công (NZ) quét (so sánh giữa chuỗi và tham chiếu AL) đã không đặt cờ số không). Sau đó, ECX chứa -1-(steps in the scan). NOT làm cho rằng (steps in the scan). SUB làm cho rằng (steps in the scan) - 1 = (length of string not including the terminating NUL). Cũng được giải thích tại http://www.int80h.org/strlen/.

+0

Wow, cảm ơn. Điều này rất hữu ích. Cảm ơn nhiều! – rosalindwills

Các vấn đề liên quan