CSAPP LAB————二進位制炸彈(bomblab)
阿新 • • 發佈:2019-02-14
<span style="font-size:14px;">(gdb) disassemble phase_6 Dump of assembler code for functionphase_6: 0x08048c89 <+0>: push %ebp 0x08048c8a <+1>: mov %esp,%ebp 0x08048c8c <+3>: push %edi 0x08048c8d <+4>: push %esi 0x08048c8e <+5>: push %ebx 0x08048c8f <+6>: sub $0x5c,%esp 0x08048c92 <+9>: lea -0x30(%ebp),%eax 0x08048c95 <+12>: mov %eax,0x4(%esp) 0x08048c99 <+16>: mov 0x8(%ebp),%eax 0x08048c9c <+19>: mov %eax,(%esp) 棧初始化 0x08048c9f <+22>: call 0x804910b <read_six_numbers> 讀取6個數 0x08048ca4 <+27>: mov $0x0,%esi esi=0 0x08048ca9 <+32>: lea -0x30(%ebp),%edi edi是索引地址 0x08048cac <+35>: mov (%edi,%esi,4),%eax 0x08048caf <+38>: sub $0x1,%eax eax小於等於6 0x08048cb2 <+41>: cmp $0x5,%eax 0x08048cb5 <+44>: jbe 0x8048cbc <phase_6+51> jbe 小於等於跳轉 0x08048cb7 <+46>: call 0x80490d1 <explode_bomb> 第一個數小於等於6 0x08048cbc <+51>: add $0x1,%esi esi+1=1 0x08048cbf<+54>: cmp $0x6,%esi 6 1 0x08048cc2 <+57>: je 0x8048ce6 <phase_6+93> 不跳 最後從這裡跳出到93 0x08048cc4 <+59>: lea (%edi,%esi,4),%ebx 第二個數 ---Type <return> to continue, or q<return> to quit--- 0x08048cc7 <+62>: mov %esi,-0x4c(%ebp) 0x08048cca <+65>: mov -0x4(%edi,%esi,4),%eax 0x08048cce <+69>: cmp (%ebx),%eax 第二個數不等於第一個數 這裡說明兩個數不能相等 0x08048cd0 <+71>: jne 0x8048cd7 <phase_6+78> 0x08048cd2 <+73>: call 0x80490d1 <explode_bomb> 0x08048cd7 <+78>: addl $0x1,-0x4c(%ebp) 0x08048cdb <+82>: add $0x4,%ebx 0x08048cde <+85>: cmpl $0x5,-0x4c(%ebp) 0x08048ce2 <+89>: jle 0x8048cca <phase_6+65> 小於等於5 ////這裡前面的句子就是一個迴圈驗證,說明共六個數,每個數各不相同均小於等於6 0x08048ce4 <+91>: jmp 0x8048cac <phase_6+35> 0x08048ce6 <+93>: mov $0x0,%ebx ebx=0 0x08048ceb <+98>: lea -0x30(%ebp),%edi edi為索引地址 0x08048cee <+101>:jmp 0x8048d06<phase_6+125> 0x08048cf0 <+103>: mov 0x8(%edx),%edx 連結串列地址賦值這裡8應該表示連結串列中有兩個數,後面驗證正確 0x08048cf3 <+106>: add $0x1,%eax eax+1 0x08048cf6 <+109>: cmp %ecx,%eax 0x08048cf8 <+111>: jne 0x8048cf0 <phase_6+103> 不等於就跳 0x08048cfa <+113>: mov %edx,-0x48(%ebp,%esi,4) 0x08048cfe <+117>: add $0x1,%ebx 0x08048d01 <+120>: cmp $0x6,%ebx 0x08048d04 <+123>: je 0x8048d1c <phase_6+147> 這裡說明也要迴圈六次 0x08048d06 <+125>: mov %ebx,%esi 0x08048d08 <+127>: mov (%edi,%ebx,4),%ecx ---Type <return> to continue, or q<return> to quit--- 0x08048d0b <+130>: mov $0x804c0c4,%edx 一開始以為這裡是一個序列,後來驗證錯誤 最後想到這裡存在一個連結串列 0x08048d10 <+135>: mov $0x1,%eax 0x08048d15 <+140>: cmp $0x1,%ecx 0x08048d18 <+143>: jg 0x8048cf0 <phase_6+103> 0x08048d1a <+145>: jmp 0x8048cfa <phase_6+113> 這一塊的C語言 for(int i = 0; i < 6; i++) { addr = 0x0x804c0c4; for(int j = 0; j < data[i]; j++) addr = *(addr + 0x8); -0x30(%ebp) + 4 * i = addr; } 這裡的意思就是按輸入序列排序 0x08048d1c <+147>: mov -0x48(%ebp),%ebx ebx儲存連結串列初始地址 0x08048d1f <+150>: mov -0x44(%ebp),%eax 0x08048d22 <+153>: mov %eax,0x8(%ebx) -0x44(%ebp)放入了*(-0x48(%ebp)) + 0x8 下面同理 0x08048d25 <+156>: mov -0x40(%ebp),%edx 0x08048d28 <+159>: mov %edx,0x8(%eax) 0x08048d2b <+162>: mov -0x3c(%ebp),%eax 0x08048d2e <+165>: mov %eax,0x8(%edx) 0x08048d31 <+168>: mov -0x38(%ebp),%edx 0x08048d34 <+171>: mov %edx,0x8(%eax) 0x08048d37 <+174>: mov -0x34(%ebp),%eax 0x08048d3a <+177>: mov %eax,0x8(%edx) 0x08048d3d <+180>: movl $0x0,0x8(%eax) 前面這些語句,明顯可以看出構造了一個連結串列 0x08048d44<+187>: mov $0x0,%esi 0x08048d49 <+192>: mov 0x8(%ebx),%eax 第二個連結串列的值 a[n+1] 0x08048d4c <+195>: mov (%ebx),%edx 第一個連結串列中的值 a[n] 0x08048d4e <+197>: cmp (%eax),%edx a[n]>=a[n+1] 0x08048d50 <+199>: jge 0x8048d57 <phase_6+206> 0x08048d52 <+201>: call 0x80490d1 <explode_bomb> ---Type <return> to continue, or q<return> to quit--- 0x08048d57 <+206>: mov 0x8(%ebx),%ebx 0x08048d5a <+209>: add $0x1,%esi 0x08048d5d <+212>: cmp $0x5,%esi 這裡迴圈5次,比較5次 0x08048d60 <+215>: jne 0x8048d49 <phase_6+192> C語言程式碼 struct node { int x, y; node *next; }; node a = firstNode; for(int i = 0; i < 5; i++) { node b = a->next; if (a->x >= b->x) a = b; else explode_bomb(); } 0x08048d62 <+217>: add $0x5c,%esp 退出函式 0x08048d65 <+220>: pop %ebx 0x08048d66 <+221>: pop %esi 0x08048d67 <+222>: pop %edi 0x08048d68 <+223>: pop %ebp 0x08048d69 <+224>: ret End of assembler dump.</span>