2012-02-08 52 views
19

Vì vậy, một nền tảng nhỏ. Tôi là người mới bắt đầu với mã c và lắp ráp, chúng tôi có một nhiệm vụ "bom" (viết bằng c) gọi các phương thức yêu cầu mật khẩu nhất định, nhưng mã không hiển thị và tôi cần xác định mật khẩu chính xác bằng cách xem mã lắp ráp .Giải mã và hiểu mã lắp ráp

Mã cho biết mật khẩu cho phương pháp này là 6 số, được chuyển thành "đầu vào" cho phương thức giai đoạn 2 (Tôi đang cố gắng tránh kích hoạt).

Phần tôi đang bối rối đang nhảy từ +64 đến +42. Nó có vẻ là một vòng lặp nhưng tôi không chắc chắn làm thế nào ngăn xếp bị ảnh hưởng với mỗi vượt qua. Dường như vòng lặp thoát ra nếu hai số cuối cùng giống nhau và nó có liên quan đến việc cộng và trừ 4 nhưng tôi không chắc chắn cách các địa chỉ được duyệt qua. Nếu bất cứ ai có thể dịch chính xác những gì đang xảy ra, hoặc nếu tôi cần phải tìm trong bất kỳ sổ đăng ký/địa điểm cụ thể nó sẽ giúp rất nhiều. Có thêm 4 giai đoạn được cho là phức tạp hơn vì vậy tôi muốn hiểu rõ hơn về cách tiếp cận đọc những giai đoạn này.

Ngoài ra nếu có tài nguyên tốt (như bảng có thể in) với từ khóa mã lắp ráp cũng hữu ích, và cũng có thể có sự khác biệt giữa đăng ký 32 bit và 64 bit. tên đăng ký ..

82   phase_2(input); 
(gdb) disas phase_2 
Dump of assembler code for function phase_2: 
0x000000000040106b <phase_2+0>: push %rbp 
0x000000000040106c <phase_2+1>: push %rbx 
0x000000000040106d <phase_2+2>: sub $0x28,%rsp 
0x0000000000401071 <phase_2+6>: mov %rsp,%rsi 
0x0000000000401074 <phase_2+9>: callq 0x401457 <read_six_numbers> 
0x0000000000401079 <phase_2+14>:  cmpl $0x0,(%rsp) 
0x000000000040107d <phase_2+18>:  jne 0x401086  <phase_2+27> 
0x000000000040107f <phase_2+20>:  cmpl $0x1,0x4(%rsp) 
0x0000000000401084 <phase_2+25>:  je  0x40108b <phase_2+32> 
0x0000000000401086 <phase_2+27>:  callq 0x401421 <explode_bomb> 
0x000000000040108b <phase_2+32>:  lea 0x8(%rsp),%rbx 
0x0000000000401090 <phase_2+37>:  lea 0x18(%rsp),%rbp 
0x0000000000401095 <phase_2+42>:  mov -0x8(%rbx),%eax 
0x0000000000401098 <phase_2+45>:  add -0x4(%rbx),%eax 
0x000000000040109b <phase_2+48>:  cmp %eax,(%rbx) 
0x000000000040109d <phase_2+50>:  je  0x4010a4 <phase_2+57> 
0x000000000040109f <phase_2+52>:  callq 0x401421 <explode_bomb> 
0x00000000004010a4 <phase_2+57>:  add $0x4,%rbx 
0x00000000004010a8 <phase_2+61>:  cmp %rbp,%rbx 
0x00000000004010ab <phase_2+64>:  jne 0x401095 <phase_2+42> 
0x00000000004010ad <phase_2+66>:  add $0x28,%rsp 
0x00000000004010b1 <phase_2+70>:  pop %rbx 
0x00000000004010b2 <phase_2+71>:  pop %rbp 
0x00000000004010b3 <phase_2+72>:  retq 
+0

Nếu bạn đang sử dụng cửa sổ, tôi khuyên bạn nên sử dụng: http://www.ollydbg.de/ với gdb (Tôi chỉ tìm hiểu) sử dụng TUI, http://stackoverflow.com/a/2422063/1149736 và hơn : 'layout asm'' start' 'layout regs'' ni' 'ni'' ni' :) và theo dõi cẩn thận http://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_7 .html – Vyktor

+9

Bạn đã có một giáo viên khá thú vị :) –

Trả lời

45

đây là một C tương đương với Phase2:

int t[6]; 
read_six_numbers (t); 
if ((t[0] != 0) || (t[1] != 1)) { 
    explode_bomb(); 
} 

for (int i = 2; i < 6; i++) { 
     if (t[i] != t[i - 2] + t[i - 1]) { 
      explode_bomb(); 
    } 
} 

Vì vậy, mật khẩu là 0, 1, 1, 2, 3, 5.

Làm thế nào d Tôi làm điều này? Bằng cách dần thay thế lắp ráp bằng C.

Bạn sẽ lưu ý rằng ngăn xếp ngăn xếp (rsp) không bao giờ thay đổi. Bạn có thể thấy stack như là một mảng của các số 32 bit. Đó là mỗi lần bạn di chuyển 4 byte, bạn chuyển sang phần tử tiếp theo. tức là 0 (% rsp), 4 (% rsp), ... tương đương với t [0], t [1], ...

Tôi sẽ cho bạn thấy sự chuyển đổi dần dần của bit mà bạn có rắc rối với:

   lea 0x8(%rsp),%rbx 
       lea 0x18(%rsp),%rbp 
<phase_2+42>: mov -0x8(%rbx),%eax 
       add -0x4(%rbx),%eax 
       cmp %eax,(%rbx) 
       je  <phase_2+57> 
       callq explode_bomb 
<phase_2+57>: add $0x4,%rbx 
       cmp %rbp,%rbx 
       jne phase_2+42 
------------------------------------------------------ 
        rbx = rsp + 8; 
        rbp = rsp + 24; 
<phase_2+42>:  eax = [rbx - 8]; 
        eax += [rbx - 4]; 
        if (eax == [rbx]) goto <phase_2+57>; 
        explode_bomb(); 
<phase_2+57>:  rbx += 4; 
        if (rbx != rbp) goto phase_2+42; 
------------------------------------------------------ 
rbx = rsp + 8; 
rbp = rsp + 24; 
do { 
    eax = [rbx - 8] + [rbx - 4]; 
     if (eax != [rbx]) { 
     explode_bomb(); 
    } 
     rbx += 4; 
} while (rbx != rbp); 
------------------------------------------------------ 
rbx = 8; 
do { 
    eax = [rsp + rbx - 8] + [rsp + rbx - 4]; 
     if (eax != [rsp + rbx]) { 
     explode_bomb(); 
    } 
     rbx += 4; 
} while (rbx < 24); 
------------------------------------------------------ 
i = 2; 
do { 
    eax = t[i - 2] + t[i - 1]; 
     if (eax != t[i]) { 
     explode_bomb(); 
    } 
     i += 1; 
} while (i < 6); 
------------------------------------------------------ 
for (int i = 2; i < 6; i++) { 
    if (t[i] != t[i - 2] + t[i - 1]) { 
      explode_bomb(); 
     } 
} 

Nếu bạn dành thời gian để hiểu những chuyển đổi này, bạn sẽ có thể biến đổi và hiểu bất kỳ phần lắp ráp nào.

+1

Cũng được viết, +1. –

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