調出phase_5函數:
0000000000401062 <phase_5>: 401062: 53 push %rbx 401063: 48 83 ec 20 sub $0x20,%rsp 401067: 48 89 fb mov %rdi,%rbx 40106a: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax ;此處搞不懂 401071: 00 00 401073: 48 89 44 24 18 mov %rax,0x18(%rsp) 401078: 31 c0 xor %eax,%eax 40107a: e8 9c 02 00 00 callq 40131b <string_length> ;檢測字符串長度 40107f: 83 f8 06 cmp $0x6,%eax 401082: 74 4e je 4010d2 <phase_5+0x70> ;如果字符串長度不為6,bomb。 401084: e8 b1 03 00 00 callq 40143a <explode_bomb> 401089: eb 47 jmp 4010d2 <phase_5+0x70> 40108b: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx ;%ecx=%eax+%ebx。 40108f: 88 0c 24 mov %cl,(%rsp) ;取%ecx得低8位,相當於%ecx & 0xff,並將值放入內存地址(%rsp)中 401092: 48 8b 14 24 mov (%rsp),%rdx 401096: 83 e2 0f and $0xf,%edx ;聯系上幾行,相當於 %ecx & 0xf,並將運算值放入寄存器%edx。 401099: 0f b6 92 b0 24 40 00 movzbl 0x4024b0(%rdx),%edx ;根據%edx的值,從內存地址0x4024b0中將數據讀入%edx中 4010a0: 88 54 04 10 mov %dl,0x10(%rsp,%rax,1);再將讀入的數據轉移轉移到內存地址(%rsp+0x10+%rax)中 4010a4: 48 83 c0 01 add $0x1,%rax ;%rax+=1 4010a8: 48 83 f8 06 cmp $0x6,%rax ;當rax=6跳出循環,這里注意到6等於所需輸入的字符串長度 4010ac: 75 dd jne 40108b <phase_5+0x29> 4010ae: c6 44 24 16 00 movb $0x0,0x16(%rsp) ;由之前關卡可知strings_not_equal函數的運行機制 4010b3: be 5e 24 40 00 mov $0x40245e,%esi ;%esi存儲答案字符串首地址 4010b8: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi ;%rdi存儲被檢測字符串首地址。 4010bd: e8 76 02 00 00 callq 401338 <strings_not_equal> 4010c2: 85 c0 test %eax,%eax ;字符串一一符合則完成破解。 4010c4: 74 13 je 4010d9 <phase_5+0x77> ;這一關重點是在0x4024b0與0x40245e兩個字符串之間的關系。 4010c6: e8 6f 03 00 00 callq 40143a <explode_bomb> 4010cb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 4010d0: eb 07 jmp 4010d9 <phase_5+0x77> 4010d2: b8 00 00 00 00 mov $0x0,%eax 4010d7: eb b2 jmp 40108b <phase_5+0x29> 4010d9: 48 8b 44 24 18 mov 0x18(%rsp),%rax 4010de: 64 48 33 04 25 28 00 xor %fs:0x28,%rax 4010e5: 00 00 4010e7: 74 05 je 4010ee <phase_5+0x8c> 4010e9: e8 42 fa ff ff callq 400b30 <__stack_chk_fail@plt> 4010ee: 48 83 c4 20 add $0x20,%rsp 4010f2: 5b pop %rbx 4010f3: c3 retq
主要內容在注釋中貼出來了,解讀如下:
這一關要求輸入一個長度為6的字符串,但是字符串的內容與strings_not_equal函數中%esi存儲的地址的字符串不一樣,可以看到在這個函數之前有一個轉換過程,而且%edi存儲的地址是%rsp數據段的地址,這是要點。
轉換過程是取得字符的最低4位,值在0-15之間,通過這個值來調取地址0x4024b0 中的字符,並存入%rsp數據段中,需要%rsp數據段中的字符串與%rsi總的字符串相同,才可以通過這一關。
地址0x4024b0中的字符串:m a d u i e r s n f o t v b y l (空格分開只是為了便於查看)
地址%esi=0x40245e中的字符串:"flyers"
觀察這兩個字符串的兩兩對應關系,要從混亂字符串中選出字符組成"flyers",需要選出的字符序號(從0開始)為 “9,15,4,5,6,7”,十六進制則是"9,f,e,5,6,7"
所以只要輸入字符串中對應位的字符的最低4位的數值等於"9,f,e,5,6,7",即可通過這一關。
比如:通過查看ASCII值,可以得到
字符最低位值:9 f e 5 6 7
對應可選字符:i o n e f g
y u v w
所以字符串"ionefg"是正確答案。(也可以是"yonefg"或者"yonuvw"都可以,只要字符串滿足最低位序號的要求均可以。)