昨天有說過在組合語言當中stack是怎麼運作的,只要掌握好這個關鍵今天的題目應該是很容易可以拿到Flag的,那今天就繼續看看其他的題目吧
這題一樣問說asm1(0xc8)回傳值是多少,那我們就一樣 cat eq_asm_rev.S
看看組合語言吧
這邊用行號做說明會比較好說明
asm1:
push ebp
mov ebp,esp
cmp DWORD PTR [ebp+0x8],0x9a
jg part_a
cmp DWORD PTR [ebp+0x8],0x8
jne part_b
mov eax,DWORD PTR [ebp+0x8]
add eax,0x3
jmp part_d
part_a:
cmp DWORD PTR [ebp+0x8],0x2c
jne part_c
mov eax,DWORD PTR [ebp+0x8]
sub eax,0x3
jmp part_d
part_b:
mov eax,DWORD PTR [ebp+0x8]
sub eax,0x3
jmp part_d
cmp DWORD PTR [ebp+0x8],0xc8
jne part_c
mov eax,DWORD PTR [ebp+0x8]
sub eax,0x3
jmp part_d
part_c:
mov eax,DWORD PTR [ebp+0x8]
add eax,0x3
part_d:
pop ebp
ret
還記得昨天的stack嗎,這邊就直接將stack貼出來讓大家複習一次
那首先從最上面看下來,第4,5行的意思是說0xc8跟0x9a比較,如果比較大就跳至part_a
那這邊顯然是成立的就直接跳到part_a,12,13行的意思是0xc8與0x2c比較,若不相等跳至part_c
這邊也是成立的就直接跳到part_c的部份,這邊用eax=0x38再來又對eax做eax+=3
所以這時eax的值是0xcb
那因為組合語言是由上到下執行的,所以執行完part_c之後是直接執行part_d
這邊就結束這個函數了,所以最終傳回的值就是0xcb
Flag是 picoCTF{0xcb}
這邊也列出一些常見的跳躍指令,當然不只這些,若有興趣可以自己Google
指令 | 功能 |
---|---|
je | 相等則跳 == |
jne | 不相等則跳 != |
jg | 大於則跳 > |
jge | 大於等於則跳 >= |
jl | 小於則跳 < |
jle | 小於等於則跳 <= |
jmp | 無條件跳 goto |
jz | 等於零則跳 ==0 |
jnz | 不等於零則跳 !=0 |
這一題給了一個連結和一個檔案,第一個可以不用理他沒關係,我們可以直接來看題目吧
那這邊他給了一個執行檔,我們先執行看看
他說我們需要換快一點的電腦,好吧那今天就到這啦,換了電腦這題就解的出來囉
當然不是!這邊我們可以使用琳瑯滿目的工具對他進行反組譯,像是有名的IDA pro,gdb,objdump等等都可以,這邊我使用objdump
一開始先看看main在做什麼吧
這邊有可以看到整個程式的流程他呼叫了四次function,可以透過函式名稱大概可以知道他在做什麼,那這邊我看了一下關鍵應該會在set_timer和get_key這兩個函式,那點進去看後我決定從get_key中下手
那這邊可以看到他又呼叫了一個函式calculate_key
這段不長也不難理解,可以看到中間有三行
400711: 83 45 fc 01 add DWORD PTR [rbp-0x4],0x1
400715: 81 7d fc 7a 96 ea df cmp DWORD PTR [rbp-0x4],0xdfea967a
40071c: 75 f3 jne 400711 <calculate_key+0xb>
他將這個變數每次+1,然後比對是否等於0xdfea967a,那如果不等於就跳回去再加一,這邊的概念就是迴圈,可以把他想像成
for(i=0x6ff54b3d;i<0xdfea967a;i++);
不過這個迴圈相當於從1878346557加到3756693114,難怪他說我們需要快一點的電腦,不過沒關係我們這邊知道問題點在哪裡,我們可以將原本0x6ff54b3d改成0xdfea9670就只需要運算10次
可以透過hexeditor
修改他裡面的內容
輸入$ hexeditor ./be-quick-or-be-dead-1
就可以打開一個藍色密密麻麻的視窗
那這邊下面可以看到一些功能表,這裡主要用到的就是搜尋,那我們剛剛看到有問題的地方大約是在40070a這個位子然後machine code 是 c7 45 fc 3d 4b f5 6f,那我們就直接搜尋看看吧
點Ctrl+w
就可以搜尋,要搜尋16進位時記得選這個
這邊也告訴大家一個重要的觀念,一定會覺得奇怪明明是0x6ff54b3d,為什麼他的machine code 是3d 4b f5 6f反過來,因為x86都是採用 little endian
的方式
這邊給大家看他們之間的差異
旁邊的a往下代表下面是高位址,上面是低位址,所以因為little endian
的方式才會看起來像是顛倒的,所以要記得以後看到這類的位址不要搞混!
回到hexeditor,這邊就可以直接將上面的值做更改,更改完後就Ctrl+x
儲存離開
這時再執行一次就會發現找到Flag了~
其實這一題還有很多種方法可以拿到Flag,可以用一樣的方法做更改,那至於其他的方法我這邊就不說了,可以試試看往set_timer這個函式去看看
這邊在教大家一個組合語言指令,他叫做nop
那他的machine code是90,他的功用就是沒有功用XD
他叫做No op 也就是這個指令他不會做任何事情,那在很多時候是非常好用的,就請大家自行發掘他的用途吧!