攻防世界 Reverse进阶区 BABYRE WP
IDA下得到反匯編代碼
顯然,對于judge這個常量先與或處理,而后讀取字符串s,判斷s長度是否為14;
接下來這個judge(s)讓我看不懂了,judge不是個數組嗎,怎么可以這么使用?
<關鍵點>看了其他大佬的WP才知道,原來還有將data轉為code執行的騷操作,所以這里其實是將judge數組的內容當成一個函數來執行,可以使用熱鍵C將data轉化為code,也可以用U恢復。
調試程序,先讓其運行完字符串的初始處理,在if處下斷點,觀察judge函數的匯編代碼
1.
push rbp 和mov rbp,rsp是棧指針操作
鼠標移動到rdi上,可以知道rdi存儲著我們輸入的字符串s的內容,mov [rbp-28h],rdi 則是將其拷貝到[rbp-28h]上;接下來將一堆字符入棧,數了一下,剛好14個,對應flag的長度,接下來必有用處; 然后給[rbp-4]賦值0,跳轉到loc_600B71。
loc_600B71的匯編代碼如下
比較[rbp-4]與14的大小 ,小于等于則進入loc_600B49,顯然是個14次的循環,[rbp-4]即為i。
其大意如下:
rdx=eax=i ;rax=&s[i] //rax拿到s[i]的地址
edx=i;??????? rdx=&s[i] //rdx拿到s[i]的地址
edx=s[i];????????????????????? //edx拿到s[i]的內容
xor edx,ecx????????????? //將s[i]與i進行異或,結果存到edx中
mov [rax],dl??????????????? //由于字符ascii值較小,dl中即為edx的值,將其存到rax的地址上,也就是原s[i]被替換了
然后不斷循環,直至處理完所有字符s[i];之后[rbp-4]置0,進入loc_600BA9
?顯然,這也是個循環,大概解讀思路同上一致,需要注意的點在 movzx eax,byte ptr [rbp+rax-20h]和cmp dl,al這兩句
前一句的地址實際上就是前面提到的14個字符常量;后一句則是將dl和al比較,也即edx和eax比較,edx存儲著上一個循環中經過異或處理后的字符,eax中存儲著前文的14個字符常量,當兩者相等時才會繼續循環,故這就是尋找flag的關鍵。
<尋找flag代碼>
#include <iostream> using namespace std; int main(){//14個字符常量char sstring[14] = {0x66,0x6D,0x63,0x64,0x7F,0x6B,0x37,0x64,0x3B,0x56,0x60,0x3B,0x6E,0x70};//flag字符串char flag[14];for(int i = 0; i < 14; i++){flag[i] = sstring[i] ^ i;cout << flag[i];} }運行得到flag{n1c3_j0b}
總結
以上是生活随笔為你收集整理的攻防世界 Reverse进阶区 BABYRE WP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git篇
- 下一篇: JAVA电子竞技赛事管理系统计算机毕业设