(gdb)info reg
查看所有寄存器的信息(gdb)info frame
查看棧的信息(gdb)b * 0x
在0x處設(shè)置斷點(diǎn)(gdb)b phase_1
在函數(shù)phase_1處設(shè)置斷點(diǎn)(gdb)x/2s 0x
輸出0x開(kāi)始的兩個(gè)字符串(gdb)stepi
執(zhí)行一條指令(gdb)nexti
類(lèi)似于stepi,但以函數(shù)調(diào)用為單位(gdb)c
繼續(xù)(遇到斷點(diǎn)后)(gdb)run ans.txt
命令行參數(shù)運(yùn)行(gdb)q
退出(gdb)finish
運(yùn)行到當(dāng)前函數(shù)返回(gdb)delete
刪除所有斷點(diǎn)(gdb)delete 5
刪除斷點(diǎn) 5(gdb)layout asm
展示當(dāng)前的匯編語(yǔ)言(非常的好用,ctrl + L 刷新)(gdb)p *(int *) 0x
輸出位于地址0x的整數(shù)(gdb)p $rax
輸出%rax的值(gdb)p /x $rax
以十六進(jìn)制輸出%rax的值(gdb)p *(int *)($rbp + 0x8)
輸出地址%rbp + 0x8的整數(shù)(gdb)disas phase_1
反匯編phase_1函數(shù)objdump -d bomb > asm.txt
。然后把asm.txt的內(nèi)容復(fù)制粘貼到word。用word來(lái)看匯編語(yǔ)言,方便涂色標(biāo)注創(chuàng)新互聯(lián)建站于2013年開(kāi)始,先為沂源等服務(wù)建站,沂源等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為沂源企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。
在phase_1函數(shù)處設(shè)置斷點(diǎn)。
隨便輸出一個(gè)答案,如 abcdef。
觀察斷點(diǎn)信息,input_strings可知,答案確實(shí)是一個(gè)字符串。
反匯編觀察到 strings_not_equal,推測(cè)是在判斷字符串是否相等。然后,test命令測(cè)試返回值,如果非0,則爆炸。
0為真,1為假,那么非0對(duì)于strings_not_equal,應(yīng)該是字符串不等,所以現(xiàn)在要找到那個(gè)與輸出的字符串匹配的字符串。
觀察到,傳遞給寄存器%esi的值0x
打印此處的字符串: x/2s 0x
得到答案
00000000004013f9 <phase_1>:
4013f9: 55 push %rbp
4013fa: 48 89 e5 mov %rsp,%rbp
4013fd: be 50 31 40 00 mov $0x,%esi
: e8 3d 04 00 00 callq <strings_not_equal>
: 85 c0 test %eax,%eax
: 75 02 jne d <phase_1+0x14>
b: 5d pop %rbp
c: c3 retq
d: e8 2e 05 00 00 callq <explode_bomb>
: eb f7 jmp b <phase_1+0x12>****
在phase_2設(shè)置斷點(diǎn)。
運(yùn)行,參數(shù)為ans.txt,其中寫(xiě)有剛剛得到的第一個(gè)的答案。
先隨便輸入,這里輸入一個(gè)數(shù) 5。
反匯編觀察,一開(kāi)始調(diào)用了<read_six_numbers>函數(shù),那么可以先把輸入改為6個(gè)數(shù)
繼續(xù)觀察下面的匯編語(yǔ)言,發(fā)現(xiàn) -30(%rbp)不就是存放第一個(gè)數(shù)的位置嗎?這里判斷第一個(gè)數(shù)必須為0,否則炸彈爆炸
在后面,%ebx先賦值為1,然后判斷是否大于5,是一個(gè)循環(huán),然后根據(jù)輸入的6個(gè)數(shù),每輪打印發(fā)現(xiàn)規(guī)律。
得出代碼:for(int i = 1; i <= 5; i ++) a[i] = a[i - 1] + i;
。
則得出答案。
0000000000 <phase_2>:
: 55 push %rbp
: 48 89 e5 mov %rsp,%rbp
: 53 push %rbx
: 48 83 ec 28 sub $0x28,%rsp
d: 48 8d 75 d0 lea -0x30(%rbp),%rsi
: e8 3c 05 00 00 callq <read_six_numbers>
: 83 7d d0 00 cmpl $0x0,-0x30(%rbp)
a: 78 07 js <phase_2+0x1f>
c: bb 01 00 00 00 mov $0x1,%ebx
: eb 0f jmp <phase_2+0x2e>
: e8 08 05 00 00 callq <explode_bomb>
: eb f2 jmp c <phase_2+0x18>
a: e8 01 05 00 00 callq <explode_bomb>
f: 83 c3 01 add $0x1,%ebx
: 83 fb 05 cmp $0x5,%ebx
: 7f 17 jg e <phase_2+0x4a>
: 48 63 c3 movslq %ebx,%rax
a: 8d 53 ff lea -0x1(%rbx),%edx
d: 48 63 d2 movslq %edx,%rdx
: 89 d9 mov %ebx,%ecx
: 03 4c 95 d0 add -0x30(%rbp,%rdx,4),%ecx
: 39 4c 85 d0 cmp %ecx,-0x30(%rbp,%rax,4)
a: 74 e3 je f <phase_2+0x2b>
c: eb dc jmp a <phase_2+0x26>
e: 48 83 c4 28 add $0x28,%rsp
: 5b pop %rbx
: 5d pop %rbp
: c3 retq
設(shè)置斷點(diǎn),運(yùn)行,反匯編。
發(fā)現(xiàn)線索: :be 1f 33 40 00 mov $0xf,%esi
。
打印0xf處的字符串,得到:
結(jié)合后邊的f:e88cfcff ff callq <__isoc99_sscanf@plt>
可知,本題答案為兩個(gè)整型變量
: 8b 45 fc mov -0x4(%rbp),%eax
c: 83 f8 07 cmp $0x7,%eax
f: 77 7b ja c <phase_3+0xa7>
第一個(gè)輸入的數(shù)不能大于7
結(jié)合后面的可猜測(cè),是一個(gè)根據(jù)第一個(gè)輸入的數(shù)的switch語(yǔ)句
那就輸入 1 2 進(jìn)行調(diào)試測(cè)試
觀察到
4014cf: 39 45 f8 cmp %eax,-0x8(%rbp)
4014d2: 74 05 je 4014d9 <phase_3+0x74>
4014d4: e8 67 04 00 00 callq <explode_bomb>
4014d9: c9 leaveq
? 是函數(shù)不爆炸的出口
? 在這里設(shè)置斷點(diǎn),打印出%eax,得到-1199。
0000000000 <phase_3>:
: 55 push %rbp
: 48 89 e5 mov %rsp,%rbp
: 48 83 ec 10 sub $0x10,%rsp
d: 48 8d 4d f8 lea -0x8(%rbp),%rcx
: 48 8d 55 fc lea -0x4(%rbp),%rdx
: be 1f 33 40 00 mov $0xf,%esi
a: b8 00 00 00 00 mov $0x0,%eax
f: e8 8c fc ff ff callq <__isoc99_sscanf@plt>
: 83 f8 01 cmp $0x1,%eax
: 7e 11 jle a <phase_3+0x35>
: 8b 45 fc mov -0x4(%rbp),%eax
c: 83 f8 07 cmp $0x7,%eax
f: 77 7b ja c <phase_3+0xa7>
: 89 c0 mov %eax,%eax
: ff 24 c5 c0 31 40 00 jmpq *0x4031c0(,%rax,8)
a: e8 a1 04 00 00 callq <explode_bomb>
f: eb e8 jmp <phase_3+0x24>
4014a1: b8 00 00 00 00 mov $0x0,%eax
4014a6: 2d 7b 02 00 00 sub $0x27b,%eax
4014ab: 05 2c 01 00 00 add $0x12c,%eax
4014b0: 2d 60 03 00 00 sub $0x360,%eax
4014b5: 05 60 03 00 00 add $0x360,%eax
4014ba: 2d 60 03 00 00 sub $0x360,%eax
4014bf: 05 60 03 00 00 add $0x360,%eax
4014c4: 2d 60 03 00 00 sub $0x360,%eax
4014c9: 83 7d fc 05 cmpl $0x5,-0x4(%rbp)
4014cd: 7f 05 jg 4014d4 <phase_3+0x6f>
4014cf: 39 45 f8 cmp %eax,-0x8(%rbp)
4014d2: 74 05 je 4014d9 <phase_3+0x74>
4014d4: e8 67 04 00 00 callq <explode_bomb>
4014d9: c9 leaveq
4014da: c3 retq
4014db: b8 95 02 00 00 mov $0x295,%eax
4014e0: eb c4 jmp 4014a6 <phase_3+0x41>
4014e2: b8 00 00 00 00 mov $0x0,%eax
4014e7: eb c2 jmp 4014ab <phase_3+0x46>
4014e9: b8 00 00 00 00 mov $0x0,%eax
4014ee: eb c0 jmp 4014b0 <phase_3+0x4b>
4014f0: b8 00 00 00 00 mov $0x0,%eax
4014f5: eb be jmp 4014b5 <phase_3+0x50>
4014f7: b8 00 00 00 00 mov $0x0,%eax
4014fc: eb bc jmp 4014ba <phase_3+0x55>
4014fe: b8 00 00 00 00 mov $0x0,%eax
: eb ba jmp 4014bf <phase_3+0x5a>
: b8 00 00 00 00 mov $0x0,%eax
a: eb b8 jmp 4014c4 <phase_3+0x5f>
c: e8 2f 04 00 00 callq <explode_bomb>
: b8 00 00 00 00 mov $0x0,%eax
: eb b1 jmp 4014c9 <phase_3+0x64>
設(shè)置斷點(diǎn),運(yùn)行,反匯編
觀察到
: be 1f 33 40 00 mov $0xf,%esi
: b8 00 00 00 00 mov $0x0,%eax
c: e8 9f fb ff ff callq <__isoc99_sscanf@plt>
? 調(diào)用scanf讀入,那么先打印下0xf是什么
? 答案是兩個(gè)整型變量
:8b 45 fc mov -0x4(%rbp),%eax
:85 c0 test %eax,%eax
b:78 05 js <phase_4+0x30>
d:83 f8 0e cmp $0xe,%eax
:7e 05 jle <phase_4+0x35>
:e8 b9 03 00 00 callq <explode_bomb>
:ba 0e 00 00 00 mov $0xe,%edx
得出,輸入的第一個(gè)數(shù)范圍:[0, 14]
: e8 7f ff ff ff callq <func4>
: 83 f8 05 cmp $0x5,%eax
c: 75 06 jne 4015a4 <phase_4+0x52>
? 可知func4的返回值必須為5
e: 83 7d f8 05 cmpl $0x5,-0x8(%rbp)
4015a2: 74 05 je 4015a9 <phase_4+0x57>
4015a4: e8 97 03 00 00 callq <explode_bomb>
? 可知,輸入的第二個(gè)數(shù)必須為5
下面分析遞歸函數(shù)func4。
func4里每次都用到 %edi, %esi,%edx,%eax。
而我們輸入的第一個(gè)數(shù)在一開(kāi)始便是%edi 的值,%esi 一開(kāi)始為0,%edx一開(kāi)始為0xe,即為14。
不妨,將這四個(gè)寄存器, 記為 a,b,c,res
看看這幾段
c: 89 d1 mov %edx,%ecx
e: 29 f1 sub %esi,%ecx
: 89 c8 mov %ecx,%eax
: c1 e8 1f shr $0x1f,%eax// 邏輯右移31
:01c8 add %ecx,%eax : d1 f8 sar %eax //算術(shù)右移
: 01 f0 add %esi,%eax
寫(xiě)為公式:\(res = [(c - b) >> 31 + (c - b)] / 2 + b\).
化簡(jiǎn)一下,\(res = (c - b) / 2 + b\).
再看后面的分支,和分支的執(zhí)行:
if(a < res) func4(a, b, res – 1, res), res *= 2, return res
else if(a > res) func(a, res + 1, c, res), res = res * 2 + 1; return res
else return 0
\(5 = 2 * 2 + 1\) , \(res = (14 - 0) / 2 + 0 = 7\) 當(dāng)前func4(a, 0, 14, 7) 則遞歸func4(a, 8, 14, 7)
\(2 = 2 * 1\) , \(res = (14 - 8) / 2 + 8 = 11\) 當(dāng)前func4(a, 8, 14, 11) 則遞歸func4(a, 8, 10, 11)
\(1 = 2 * 0 + 1\) , \(res = (10 - 8) / 2 + 8 = 9\) 當(dāng)前func4(a, 8, 10, 9) 則遞歸func4(a, 10, 10, 9)
\(0 = 0\) ,遞歸終止條件,此時(shí)$ res = (10 - 10) / 2 + 10 = 10$
好,那么可以得出 a = 10
0000000000 <func4>:
: 55 push %rbp
: 48 89 e5 mov %rsp,%rbp
c: 89 d1 mov %edx,%ecx
e: 29 f1 sub %esi,%ecx
: 89 c8 mov %ecx,%eax
: c1 e8 1f shr $0x1f,%eax
: 01 c8 add %ecx,%eax
: d1 f8 sar %eax
: 01 f0 add %esi,%eax
b: 39 f8 cmp %edi,%eax
d: 7f 09 jg <func4+0x20>
f: 7c 13 jl <func4+0x2c>
: b8 00 00 00 00 mov $0x0,%eax
: 5d pop %rbp
: c3 retq
: 8d 50 ff lea -0x1(%rax),%edx
b: e8 d8 ff ff ff callq <func4>
: 01 c0 add %eax,%eax
: eb f2 jmp <func4+0x1e>
: 8d 70 01 lea 0x1(%rax),%esi
: e8 cc ff ff ff callq <func4>
c: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
: eb e4 jmp <func4+0x1e>
0000000000 <phase_4>:
: 55 push %rbp
: 48 89 e5 mov %rsp,%rbp
: 48 83 ec 10 sub $0x10,%rsp
a: 48 8d 4d f8 lea -0x8(%rbp),%rcx
e: 48 8d 55 fc lea -0x4(%rbp),%rdx
: be 1f 33 40 00 mov $0xf,%esi
: b8 00 00 00 00 mov $0x0,%eax
c: e8 9f fb ff ff callq <__isoc99_sscanf@plt>
: 83 f8 02 cmp $0x2,%eax
: 75 0c jne <phase_4+0x30>
: 8b 45 fc mov -0x4(%rbp),%eax
: 85 c0 test %eax,%eax
b: 78 05 js <phase_4+0x30>
d: 83 f8 0e cmp $0xe,%eax
: 7e 05 jle <phase_4+0x35>
: e8 b9 03 00 00 callq <explode_bomb>
: ba 0e 00 00 00 mov $0xe,%edx
c: be 00 00 00 00 mov $0x0,%esi
: 8b 7d fc mov -0x4(%rbp),%edi
: e8 7f ff ff ff callq <func4>
: 83 f8 05 cmp $0x5,%eax
c: 75 06 jne 4015a4 <phase_4+0x52>
e: 83 7d f8 05 cmpl $0x5,-0x8(%rbp)
4015a2: 74 05 je 4015a9 <phase_4+0x57>
4015a4: e8 97 03 00 00 callq <explode_bomb>
4015a9: c9 leaveq
4015aa: c3 retq
設(shè)置斷點(diǎn),運(yùn)行,反匯編
觀察到
4015b7: e8 74 02 00 00 callq <string_length>
4015bc: 83 f8 06 cmp $0x6,%eax
4015bf: 75 24 jne 4015e5 <phase_5+0x3a>
? 推測(cè)輸入為字符串,且長(zhǎng)度為6
4015c1: b8 00 00 00 00 mov $0x0,%eax
4015c6: 83 f8 05 cmp $0x5,%eax//循環(huán)了6次
4015c9: 7f 21 jg 4015ec <phase_5+0x41>
4015cb: 48 63 c8 movslq %eax,%rcx
4015ce: 0f b6 14 0b movzbl (%rbx,%rcx,1),%edx
// 逐個(gè)取你輸?shù)淖址?4015d2: 83 e2 0f and $0xf,%edx // 轉(zhuǎn)為[0,15]
4015d5: 0f b6 92 00 32 40 00 movzbl 0x(%rdx),%edx
4015dc: 88 54 0d e9 mov %dl,-0x17(%rbp,%rcx,1)
4015e0: 83 c0 01 add $0x1,%eax
可以看出,它取出字符串中每一個(gè)字符,然后轉(zhuǎn)為[0, 15]的一個(gè)數(shù),然后從地址0x 加這個(gè)數(shù)的偏移量,然后取出一個(gè)東西,再把它放入棧的內(nèi)存中,注意!這里的%dl說(shuō)明是一個(gè)字節(jié),那不還是字符嘛
好,先打印下0x處的字符串
? 發(fā)現(xiàn)打印出的一段奇怪的字符串。
? 但是,根據(jù)剛剛分析出的[0,15]的偏移量,我們?nèi)〕銮?6個(gè)字符
? 得到:maduiersnfotvbyl
再將斷點(diǎn)設(shè)在循環(huán)內(nèi),每次打印出%dl , 發(fā)現(xiàn)對(duì)于輸入的abcdef,得到了aduier的ASCII碼,再聯(lián)系一下ASCII碼的十六進(jìn)制,a 為0x61。和0xf做與運(yùn)算得到 0x1 。
發(fā)現(xiàn),輸出的字符串中的字符的ASCII碼對(duì)0x60的偏移量 與 原字符串的字符的下標(biāo)是相等的。
繼續(xù)向下看
4015f0: be ae 31 40 00 mov $0x4031ae,%esi
4015f5: 48 8d 7d e9 lea -0x17(%rbp),%rdi
4015f9: e8 46 02 00 00 callq <strings_not_equal>
4015fe: 85 c0 test %eax,%eax
: 75 07 jne <phase_5+0x5e>
? 發(fā)現(xiàn)又是字符串匹配,先看看0x4031ae處的字符串
? 根據(jù)前面得到的結(jié)論。先取出這些字符,看在原字符串中的下標(biāo)。
? 得到:9 15 14 5 6 7,然后加上0x60, 查閱ASCII碼
? 得到:ionefg
00000000004015ab <phase_5>:
4015ab: 55 push %rbp
4015ac: 48 89 e5 mov %rsp,%rbp
4015af: 53 push %rbx
4015b0: 48 83 ec 18 sub $0x18,%rsp
4015b4: 48 89 fb mov %rdi,%rbx
4015b7: e8 74 02 00 00 callq <string_length>
4015bc: 83 f8 06 cmp $0x6,%eax
4015bf: 75 24 jne 4015e5 <phase_5+0x3a>
4015c1: b8 00 00 00 00 mov $0x0,%eax
// 循環(huán)6次 0~5
4015c6: 83 f8 05 cmp $0x5,%eax
4015c9: 7f 21 jg 4015ec <phase_5+0x41>
4015cb: 48 63 c8 movslq %eax,%rcx
4015ce: 0f b6 14 0b movzbl (%rbx,%rcx,1),%edx // 逐個(gè)取你輸?shù)淖址? 4015d2: 83 e2 0f and $0xf,%edx // 轉(zhuǎn)為[0,15]
4015d5: 0f b6 92 00 32 40 00 movzbl 0x(%rdx),%edx
4015dc: 88 54 0d e9 mov %dl,-0x17(%rbp,%rcx,1)
4015e0: 83 c0 01 add $0x1,%eax
4015e3: eb e1 jmp 4015c6 <phase_5+0x1b>
4015e5: e8 56 03 00 00 callq <explode_bomb>
4015ea: eb d5 jmp 4015c1 <phase_5+0x16>
4015ec: c6 45 ef 00 movb $0x0,-0x11(%rbp)
4015f0: be ae 31 40 00 mov $0x4031ae,%esi
4015f5: 48 8d 7d e9 lea -0x17(%rbp),%rdi
4015f9: e8 46 02 00 00 callq <strings_not_equal>
4015fe: 85 c0 test %eax,%eax
: 75 07 jne <phase_5+0x5e>
: 48 83 c4 18 add $0x18,%rsp
: 5b pop %rbx
: 5d pop %rbp
: c3 retq
: e8 32 03 00 00 callq <explode_bomb>
e: eb f2 jmp <phase_5+0x57>
設(shè)置斷點(diǎn),運(yùn)行,反匯編
解讀匯編代碼知:
鏈表的發(fā)現(xiàn):
4016be: ba d0 52 40 00 mov $0x4052d0,%edx // 鏈表頭
4016c9: 48 89 d9 mov %rbx,%rcx
4016db: 48 89 51 08 mov %rdx,0x8(%rcx) //next指針
發(fā)現(xiàn)是鏈?zhǔn)浇Y(jié)構(gòu),設(shè)置斷點(diǎn),打印出:
發(fā)現(xiàn)nodej也是在提示
第一個(gè)為鏈表值,第二個(gè)為鏈表游標(biāo),第三個(gè)為next指針
那么,將鏈表值按降序排序,得到游標(biāo)為5 1 3 4 6 2
再,由 \(j = 7 – i\), 得到答案 2 6 4 3 1 5
0000000000 <phase_6>:
: 55 push %rbp
: 48 89 e5 mov %rsp,%rbp
: 41 55 push %r13
: 41 54 push %r12
: 53 push %rbx
: 48 83 ec 58 sub $0x58,%rsp
d: 48 8d 75 c0 lea -0x40(%rbp),%rsi
: e8 3c 03 00 00 callq <read_six_numbers>
: 41 bc 00 00 00 00 mov $0x0,%r12d // %r12d = 0
c: eb 29 jmp <phase_6+0x47>
e: e8 0d 03 00 00 callq <explode_bomb>
: eb 37 jmp c <phase_6+0x5c>
: e8 06 03 00 00 callq <explode_bomb>
a: 83 c3 01 add $0x1,%ebx
===============================================================
------------------------------------------------------------
d: 83 fb 05 cmp $0x5,%ebx // if(%ebx > 5)
: 7f 12 jg <phase_6+0x44>
: 49 63 c4 movslq %r12d,%rax // %rax = %r12d
: 48 63 d3 movslq %ebx,%rdx // %rdx = %ebx
: 8b 7c 95 c0 mov -0x40(%rbp,%rdx,4),%edi
c: 39 7c 85 c0 cmp %edi,-0x40(%rbp,%rax,4)
: 75 e8 jne a <phase_6+0x2a>
-----------------------------------------------------------
: eb e1 jmp <phase_6+0x25>
: 45 89 ec mov %r13d,%r12d
: 41 83 fc 05 cmp $0x5,%r12d // cmp %r12d 5
b: 7f 19 jg <phase_6+0x66> // >
d: 49 63 c4 movslq %r12d,%rax // %rax = %r12d
: 8b 44 85 c0 mov -0x40(%rbp,%rax,4),%eax
: 83 e8 01 sub $0x1,%eax // %rax -= 1
: 83 f8 05 cmp $0x5,%eax // if rax > 5
a: 77 c2 ja e <phase_6+0x1e>
c: 45 8d 6c 24 01 lea 0x1(%r12),%r13d
// %r13d=(%r12d+1)
: 44 89 eb mov %r13d,%ebx // %ebx = %r13d
: eb c7 jmp d <phase_6+0x2d>
================================================================
: b8 00 00 00 00 mov $0x0,%eax // %eax = 0
b: eb 13 jmp <phase_6+0x80>
// j = 7 - i
==========================================================
d: 48 63 c8 movslq %eax,%rcx
: ba 07 00 00 00 mov $0x7,%edx
: 2b 54 8d c0 sub -0x40(%rbp,%rcx,4),%edx
從第一個(gè)數(shù)開(kāi)始
: 89 54 8d c0 mov %edx,-0x40(%rbp,%rcx,4)
d: 83 c0 01 add $0x1,%eax
: 83 f8 05 cmp $0x5,%eax
: 7e e8 jle d <phase_6+0x6d>
==========================================================
: be 00 00 00 00 mov $0x0,%esi
a: eb 18 jmp 4016b4 <phase_6+0xa4>
c: 48 8b 52 08 mov 0x8(%rdx),%rdx
4016a0: 83 c0 01 add $0x1,%eax
//二重循環(huán),尋找第j個(gè)鏈表元素
==============================================================
4016a3: 48 63 ce movslq %esi,%rcx
4016a6: 39 44 8d c0 cmp %eax,-0x40(%rbp,%rcx,4)
4016aa: 7f f0 jg c <phase_6+0x8c>
4016ac: 48 89 54 cd 90 mov %rdx,-0x70(%rbp,%rcx,8)
4016b1: 83 c6 01 add $0x1,%esi
4016b4: 83 fe 05 cmp $0x5,%esi
4016b7: 7f 0c jg 4016c5 <phase_6+0xb5>
4016b9: b8 01 00 00 00 mov $0x1,%eax
4016be: ba d0 52 40 00 mov $0x4052d0,%edx // 鏈表頭
4016c3: eb de jmp 4016a3 <phase_6+0x93>
4016c5: 48 8b 5d 90 mov -0x70(%rbp)
4016c9: 48 89 d9 mov %rbx,%rcx //%rcx = %rbx
4016cc: b8 01 00 00 00 mov $0x1,%eax // eax = 1
4016d1: eb 12 jmp 4016e5 <phase_6+0xd5>
4016d3: 48 63 d0 movslq %eax,%rdx // rdx = eax
4016d6: 48 8b 54 d5 90 mov -0x70(%rbp,%rdx,8),%rdx
4016db: 48 89 51 08 mov %rdx,0x8(%rcx)
4016df: 83 c0 01 add $0x1,%eax
4016e2: 48 89 d1 mov %rdx,%rcx // rcx = rdx
4016e5: 83 f8 05 cmp $0x5,%eax // while 循環(huán)
4016e8: 7e e9 jle 4016d3 <phase_6+0xc3>
=========================================================
4016ea: 48 c7 41 08 00 00 00 movq $0x0,0x8(%rcx)
4016f1: 00
4016f2: 41 bc 00 00 00 00 mov $0x0,%r12d
4016f8: eb 08 jmp <phase_6+0xf2>
4016fa: 48 8b 5b 08 mov 0x8(%rbx),%rbx
4016fe: 41 83 c4 01 add $0x1,%r12d
: 41 83 fc 04 cmp $0x4,%r12d
: 7f 11 jg <phase_6+0x109>
: 48 8b 43 08 mov 0x8(%rbx),%rax
c: 8b 00 mov (%rax),%eax
e: 39 03 cmp %eax,(%rbx)
: 7d e8 jge 4016fa <phase_6+0xea>
// 這里是一重循環(huán),判斷是否前個(gè)元素大于等于后一個(gè)元素,即降序
// 否則爆炸
: e8 29 02 00 00 callq <explode_bomb>
: eb e1 jmp 4016fa <phase_6+0xea>
: 48 83 c4 58 add $0x58,%rsp
d: 5b pop %rbx
e: 41 5c pop %r12
: 41 5d pop %r13
: 5d pop %rbp
: c3 retq
0000000000401ac9 <phase_defused>:
401ac9: 83 3d 9c 3c 00 00 06 cmpl $0x6,0x3c9c(%rip) \#c <num_input_strings>
401ad0: 74 01 je 401ad3 <phase_defused+0xa>
? 在0x401ad0處設(shè)置斷點(diǎn),然后打印出0x3c9c(%rip)
? 發(fā)現(xiàn)分別為 1 2 3 4 5 6
? 則可以推斷出,要在6個(gè)炸彈都拆后才可以進(jìn)入后邊。
401ae7: be 69 33 40 00 mov $0x,%esi
401aec: bf 70 58 40 00 mov $0x,%edi
----
401b0c: be 72 33 40 00 mov $0x,%esi
401b11: 48 8d 7d b0 lea -0x50(%rbp),%rdi
401b15: e8 2a fd ff ff callq <strings_not_equal>
先打印出這三個(gè)地址的字符串:
可以推斷出,輸入為兩個(gè)整型變量和一個(gè)字符串。
且這個(gè)字符串必須為DrEvil。但是,phase_4和phase_3的輸入都是兩個(gè)整數(shù)
那么我們?cè)谂袛嘧址嗟忍?,設(shè)置斷點(diǎn),打印出值觀察:
10 和 5!
那么就確定為phase_4的答案后加上DrEvil
成功進(jìn)入隱藏關(guān)。
看secret_phase函數(shù)
0000000000e <secret_phase>:
: e8 32 02 00 00 callq e <read_line>
f: e8 cc f9 ff ff callq <atoi@plt
發(fā)現(xiàn)了readline函數(shù)和atoi函數(shù),說(shuō)明是輸一個(gè)數(shù)字。(atoi函數(shù)作用為將字符串轉(zhuǎn)為整型)
: 8d 40 ff lea -0x1(%rax),c%eax
: 3d e8 03 00 00 cmp $0x3e8,%eax //1000
e: 77 27 ja 4017a7 <secret_phase+0x49>
: 89 de mov %ebx,%esi
: bf f0 50 40 00 mov $0x4050f0,%edi//此處地址的值為36
: e8 98 ff ff ff callq <fun7>
c: 83 f8 05 cmp $0x5,%eax //返回值得為5
則輸出值不超1001
? 輸入進(jìn)func7后,返回值必須為5
再看func7函數(shù)又是一個(gè)分支+遞歸。
直接寫(xiě)出偽代碼:
? 記%rdi 為 p,%rax 為 res, %esi為 x,
? 則func7(* p, int res, int x) 。
? 一開(kāi)始,\(*p = 36\), x為你輸入的數(shù)。
if(x < *p)
p = *(p + 8),func7(p, res, x), res *= 2,return res;
else if(x > *p)
p = *(p + 10),func7(p, res, x), res = res * 2 + 1,return res;
else
return 0;
那么現(xiàn)在由返回值5逆推
5 = 2 * 2 + 1 p = *p + 10
2 = 2 * 1 p = *p + 8
1 = 2 * 0 + 1 p = *p + 10
0 = 0 *p == x
則可以調(diào)試打印出:
0000000000 <fun7>:
: 48 85 ff test %rdi,%rdi
: 74 2f je <fun7+0x34>
: 55 push %rbp
a: 48 89 e5 mov %rsp,%rbp
d: 8b 07 mov (%rdi),%eax
f: 39 f0 cmp %esi,%eax
: 7f 09 jg c <fun7+0x18>
: 75 14 jne <fun7+0x25>
: b8 00 00 00 00 mov $0x0,%eax
a: 5d pop %rbp
b: c3 retq
c: 48 8b 7f 08 mov 0x8(%rdi),%rdi
: e8 df ff ff ff callq <fun7>
: 01 c0 add %eax,%eax
: eb f1 jmp a <fun7+0x16>
: 48 8b 7f 10 mov 0x10(%rdi),%rdi
d: e8 d2 ff ff ff callq <fun7>
: 8d 44 00 01 lea 0x1(%rax,%rax,1),%eax
: eb e2 jmp a <fun7+0x16>
: b8 ff ff ff ff mov $0xffffffff,%eax
d: c3 retq
0000000000e <secret_phase>:
e: 55 push %rbp
f: 48 89 e5 mov %rsp,%rbp
: 53 push %rbx
: 48 83 ec 08 sub $0x8,%rsp
: e8 32 02 00 00 callq e <read_line>
c: 48 89 c7 mov %rax,%rdi
f: e8 cc f9 ff ff callq <atoi@plt>
: 89 c3 mov %eax,%ebx
: 8d 40 ff lea -0x1(%rax),%eax
: 3d e8 03 00 00 cmp $0x3e8,%eax
e: 77 27 ja 4017a7 <secret_phase+0x49>
: 89 de mov %ebx,%esi
: bf f0 50 40 00 mov $0x4050f0,%edi
: e8 98 ff ff ff callq <fun7>
c: 83 f8 05 cmp $0x5,%eax
f: 75 1d jne 4017ae <secret_phase+0x50>
: bf 88 31 40 00 mov $0x,%edi
: e8 c5 f8 ff ff callq <puts@plt>
b: e8 29 03 00 00 callq 401ac9 <phase_defused>
4017a0: 48 83 c4 08 add $0x8,%rsp
4017a4: 5b pop %rbx
4017a5: 5d pop %rbp
4017a6: c3 retq
4017a7: e8 94 01 00 00 callq <explode_bomb>
4017ac: eb d2 jmp <secret_phase+0x22>
4017ae: e8 8d 01 00 00 callq <explode_bomb>
4017b3: eb dc jmp <secret_phase+0x33>
0000000000401ac9 <phase_defused>:
401ac9: 83 3d 9c 3c 00 00 06 cmpl $0x6,0x3c9c(%rip) # c <num_input_strings>
401ad0: 74 01 je 401ad3 <phase_defused+0xa>
401ad2: c3 retq
401ad3: 55 push %rbp
401ad4: 48 89 e5 mov %rsp,%rbp
401ad7: 48 83 ec 60 sub $0x60,%rsp
401adb: 4c 8d 45 b0 lea -0x50(%rbp),%r8
401adf: 48 8d 4d a8 lea -0x58(%rbp),%rcx
401ae3: 48 8d 55 ac lea -0x54(%rbp),%rdx
401ae7: be 69 33 40 00 mov $0x,%esi
401aec: bf 70 58 40 00 mov $0x,%edi
401af1: b8 00 00 00 00 mov $0x0,%eax
401af6: e8 15 f6 ff ff callq <__isoc99_sscanf@plt>
401afb: 83 f8 03 cmp $0x3,%eax
401afe: 74 0c je 401b0c <phase_defused+0x43>
401b00: bf a8 32 40 00 mov $0x4032a8,%edi
401b05: e8 56 f5 ff ff callq <puts@plt>
401b0a: c9 leaveq
401b0b: c3 retq
401b0c: be 72 33 40 00 mov $0x,%esi
401b11: 48 8d 7d b0 lea -0x50(%rbp),%rdi
401b15: e8 2a fd ff ff callq <strings_not_equal>
401b1a: 85 c0 test %eax,%eax
401b1c: 75 e2 jne 401b00 <phase_defused+0x37>
401b1e: bf 48 32 40 00 mov $0x,%edi
401b23: e8 38 f5 ff ff callq <puts@plt>
401b28: bf 70 32 40 00 mov $0x,%edi
401b2d: e8 2e f5 ff ff callq <puts@plt>
401b32: b8 00 00 00 00 mov $0x0,%eax
401b37: e8 22 fc ff ff callq e <secret_phase>
401b3c: eb c2 jmp 401b00 <phase_defused+0x37>
做了一遍挺痛苦,然后寫(xiě)實(shí)驗(yàn)報(bào)告梳理了一遍思路,還是挺有收獲的。
文章標(biāo)題:BinaryBombs(二進(jìn)制炸彈實(shí)驗(yàn))
標(biāo)題路徑:http://chinadenli.net/article16/dsoiegg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站收錄、品牌網(wǎng)站設(shè)計(jì)、搜索引擎優(yōu)化、App設(shè)計(jì)、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)