內存地址 | 內存地址中的數 | 注釋 | 指向這塊內存的寄存器 |
0xffffd0e8 | 函數phase_2的棧幀 | ||
0xffffd0e4 | 0xffffd0f4 | 函數phase_2的棧幀 | |
0xffffd0e0 | 0x5655b7b0 | 函數phase_2的棧幀 | |
0xffffd0dc | 0x565566ca | 函數read_six_numbers的返回地址,函數phase_2的棧幀 | |
0xffffd0d8 | 0x5655af64 | 舊%ebx的值 | |
0xffffd0d4 | |||
0xffffd0d0 | |||
0xffffd0cc | 0xffffd108 | 第<read_six_numbers+26>行 push %edx | |
0xffffd0c8 | 0xffffd104 | 第<read_six_numbers+30>行 push %edx | |
0xffffd0c4 | 0xffffd100 | 第<read_six_numbers+34>行 push %edx | |
0xffffd0c0 | 0xffffd0fc | 第<read_six_numbers+38>行 push %edx | |
0xffffd0bc | 0xffffd0f8 | 第<read_six_numbers+42>行 push %edx | |
0xffffd0b8 | 0xffffd0f4 | 第<read_six_numbers+43>行 push %eax | |
0xffffd0b4 | 0x565583c1 | 0x565583c1是字符串'%d %d %d %d %d %d'的地址 | %esp |
(圖1:實際運行與紙上分析——使用"ni"命令執行第<read_six_numbers+50>行匯編代碼之后各寄存器與棧幀的情況)
是不是有點小激動了呀哈哈哈,耐住性子千萬不要著急,一步一步慢慢來哦!
內存地址 | 內存地址中的數 | 注釋 | 指向這塊內存的寄存器 |
0xffffd0e8 | 函數phase_2的棧幀 | ||
0xffffd0e4 | 0xffffd0f4 | 函數phase_2的棧幀 | |
0xffffd0e0 | 0x5655b7b0 | 函數read_six_numbers的第一個入口參數,函數phase_2的棧幀 | |
0xffffd0dc | 0x565566ca | 函數read_six_numbers的返回地址,函數phase_2的棧幀 | |
0xffffd0d8 | 0x5655af64 | 舊%ebx的值 | |
0xffffd0d4 | |||
0xffffd0d0 | |||
0xffffd0cc | 0xffffd108 | 第<read_six_numbers+26>行 push %edx | |
0xffffd0c8 | 0xffffd104 | 第<read_six_numbers+30>行 push %edx | |
0xffffd0c4 | 0xffffd100 | 第<read_six_numbers+34>行 push %edx | |
0xffffd0c0 | 0xffffd0fc | 第<read_six_numbers+38>行 push %edx | |
0xffffd0bc | 0xffffd0f8 | 第<read_six_numbers+42>行 push %edx | |
0xffffd0b8 | 0xffffd0f4 | 第<read_six_numbers+43>行 push %eax | |
0xffffd0b4 | 0x565583c1 | 0x565583c1是字符串'%d %d %d %d %d %d'的地址 | |
0xffffd0b0 | 0x5655b7b0 | 0x5655b7b0是你輸入的針對'phase_2'的字符串的地址 | %esp |
(圖2:實際運行與紙上分析——使用"ni"命令執行第<read_six_numbers+51>行匯編代碼之后各寄存器與棧幀的情況)
內存地址 | 內存地址中的數 | 注釋 | 指向這塊內存的寄存器 |
0xffffd0e8 | 函數phase_2的棧幀 | ||
0xffffd0e4 | 0xffffd0f4 | 函數phase_2的棧幀 | |
0xffffd0e0 | 0x5655b7b0 | 函數read_six_numbers的第一個入口參數,函數phase_2的棧幀 | |
0xffffd0dc | 0x565566ca | 函數read_six_numbers的返回地址,函數phase_2的棧幀 | |
0xffffd0d8 | 0x5655af64 | 舊%ebx的值 | |
0xffffd0d4 | |||
0xffffd0d0 | |||
0xffffd0cc | 0xffffd108 | 0x6 | |
0xffffd0c8 | 0xffffd104 | 0x5 | |
0xffffd0c4 | 0xffffd100 | 0x4 | |
0xffffd0c0 | 0xffffd0fc | 0x3 | |
0xffffd0bc | 0xffffd0f8 | 0x2 | |
0xffffd0b8 | 0xffffd0f4 | 0x1 | |
0xffffd0b4 | 0x565583c1 | 0x565583c1是字符串'%d %d %d %d %d %d'的地址 | |
0xffffd0b0 | 0x5655b7b0 | 0x5655b7b0是你輸入的針對'phase_2'的字符串的地址 | %esp |
(圖3:實際運行與紙上分析——使用"ni"命令執行第<read_six_numbers+55>行匯編代碼之后各寄存器與棧幀的情。這時是不是覺得<__isoc99_sscanf@plt>非常神奇!!!在這一步過后,我們的思路便豁然開朗了起來)
內存地址 | 內存地址中的數 | 注釋 | 指向這塊內存的寄存器 |
0xffffd0e8 | 函數phase_2的棧幀 | ||
0xffffd0e4 | 0xffffd0f4 | 函數phase_2的棧幀 | |
0xffffd0e0 | 0x5655b7b0 | 函數read_six_numbers的第一個入口參數,函數phase_2的棧幀 | |
0xffffd0dc | 0x565566ca | 函數read_six_numbers的返回地址,函數phase_2的棧幀 | |
0xffffd0d8 | 0x5655af64 | 舊%ebx的值 | |
0xffffd0d4 | |||
0xffffd0d0 | %esp | ||
0xffffd0cc | 0xffffd108 | 0x6 | |
0xffffd0c8 | 0xffffd104 | 0x5 | |
0xffffd0c4 | 0xffffd100 | 0x4 | |
0xffffd0c0 | 0xffffd0fc | 0x3 | |
0xffffd0bc | 0xffffd0f8 | 0x2 | |
0xffffd0b8 | 0xffffd0f4 | 0x1 | |
0xffffd0b4 | 0x565583c1 | 0x565583c1是字符串'%d %d %d %d %d %d'的地址 | |
0xffffd0b0 | 0x5655b7b0 | 0x5655b7b0是你輸入的針對'phase_2'的字符串的地址 |
(圖4:實際運行與紙上分析——使用"ni"命令執行第<read_six_numbers+60>行匯編代碼之后各寄存器與棧幀的情。)
內存地址 | 內存地址中的數 | 注釋 | 指向這塊內存的寄存器 |
0xffffd0e8 | 函數phase_2的棧幀 | ||
0xffffd0e4 | 0xffffd0f4 | 函數phase_2的棧幀 | |
0xffffd0e0 | 0x5655b7b0 | 函數read_six_numbers的第一個入口參數,函數phase_2的棧幀 | |
0xffffd0dc | 0x565566ca | 函數read_six_numbers的返回地址,函數phase_2的棧幀 | |
0xffffd0d8 | 0x5655af64 | 舊%ebx的值 | |
0xffffd0d4 | |||
0xffffd0d0 | %esp | ||
0xffffd0cc | 0xffffd108 | 0x6 | |
0xffffd0c8 | 0xffffd104 | 0x5 | |
0xffffd0c4 | 0xffffd100 | 0x4 | |
0xffffd0c0 | 0xffffd0fc | 0x3 | |
0xffffd0bc | 0xffffd0f8 | 0x2 | |
0xffffd0b8 | 0xffffd0f4 | 0x1 | |
0xffffd0b4 | 0x565583c1 | 0x565583c1是字符串'%d %d %d %d %d %d'的地址 | |
0xffffd0b0 | 0x5655b7b0 | 0x5655b7b0是你輸入的針對'phase_2'的字符串的地址 |
寄存器名稱 | 寄存器中的值 |
%eax | 0x6 |
(圖5:實際運行與紙上分析——使用"ni"命令執行第<read_six_numbers+63>行匯編代碼之后各寄存器與棧幀的情。因為此時我們的%eax寄存器中的值為0x6,大于0x5,所以不會跳轉到<read_six_numbers+73>這個沒有任何內容的空地址上,進而不會引爆炸彈。)
……………………
(圖6:實際運行與紙上分析——使用"ni"命令執行第<phase_2+47>行匯編代碼之后各寄存器與棧幀的情。接著,第<phase_2+50>行判斷(%esp+4)和0的大小,如果不相等就會跳到第<phase_2+64>行,可是第<phase_2+64>行就是引爆炸彈,所以不能不相等,所以%esp+4應該是0,而我們輸入的卻是1,所以萬萬不能繼續執行了)
按quit退出,接著再重復一遍,先輸入phase_1的正確字符串,接著輸入"0 1 2 3 4 5"作為我們假設的phase_2的答案,然后一路按"ni",一直到我們剛剛的那個地方,如 圖7:又來到了同樣的<phase_2+50>這個地方 所示。
(圖7:又來到了同樣的<phase_2+50>這個地方。接著,第<phase_2+50>行判斷(%esp+4)和0的大小,如果不相等就會跳到第<phase_2+64>行。但是我們此時的函數棧幀中(%esp+4)的值就是0,相等,不會跳到<phase_2+64>,所以我們輸入的6個數中對了第1個數,是"0"。)
(圖8:實際運行與紙上分析——使用"ni"命令執行第<phase_2+55>行匯編代碼之后各寄存器與棧幀的情況)
接著使用同樣的方法,我們分別得到了剩下的幾個數為:"1 1 2 3 5",也就是說,這其實是一個以0,1開頭的斐波那契數列,所以我們針對phase_2的答案字符串即為"0 1 1 2 3 5"。
I turned the moon into something I call a Death Star.
0 1 1 2 3 5