這是過後才作出來的,網上沒有找到現成的writeup,因此在這裏記錄一下linux
UPX加殼,並且linux下upx -d沒法解,也沒法gdb/ida attach 算法
由於是64位,因此沒有pushad,只能挨個函數進入,退出,看看程序是否恢復。 api
當運行到一0x400dd0,發現此時已經能夠看見字符串了 ide
用dumphex的腳原本dump出內存,見hide_dump 函數
static main(void) oop
{ this
auto fp, begin, end, dexbyte; 3d
fp = fopen("C:\\dump.dex", "wb"); 調試
begin = 0x400000; blog
end = 0xADC000;
for ( dexbyte = begin; dexbyte < end; dexbyte ++ )
fputc(Byte(dexbyte), fp);
}
此時dump出的內容已經有程序運行的字符串了,經過字符串反查,這裏
0x400890纔是真正的啓動地址
之後運行程序,在ida裏面輸入一下內容,便可直接運行到0x4009ef
from idaapi import *
from idc import *
run_to(0x4009ef)
qwb{this_is_wrong_flag}
check到一個假flag,若是此時繞過ptrace且用ctrl+d做爲結束,能夠輸出right。
可是輸入到正常程序是報wrong的,說明還有地方反調試以及修改了邏輯
根據ptrace.h,ptrace這裏是PTRACE_TRACEME,自我調試
忽然發現「Enter the flag:」字符串有2處引用
在4C8EA0也有相似的輸出,懷疑正式運行時是這裏。恢復函數失敗,只能動態調試
上面這裏判斷是否是qwb{}格式,構造payload
而後調用3次如下2個函數,輸入內容爲qwb{0123456789abcdef}中間部分的0123456789abcdef
sub_4C8CC0(__int64 a1)
這部分算法恢復見test2.py中的loop_j
sub_4C8E50——按位異或
目標:rdi(qwb{}中間內容通過上面的屢次變換後) == rsi(以下),
通過test2.py的逆向,獲得一個有意義的輸入串f1Nd_TH3HldeC0dE
因此認爲flag是qwb{f1Nd_TH3HldeC0dE}
實際運行,輸入完qwb{f1Nd_TH3HldeC0dE}後,用ctrl+d能夠看到成功(回車不行,由於用sys_read會連回車也認爲是字符?)
可是實際爲什麼會運行到hide腳本,就沒有分析了,由於ptrace本身後發生什麼事情,很難搞。
如下是經過IDA運行並跳過反調試的腳本
from idaapi import *
from idc import *
run_to(0x4009ef)
GetDebuggerEvent(WFNE_SUSP, -1)
SetRegValue(0x4C8EA0,"RIP")
GetDebuggerEvent(WFNE_SUSP, -1)
run_to(0x4C8EB3)
GetDebuggerEvent(WFNE_SUSP, -1)
SetRegValue(0,"RAX")
run_to(0x4C8CC0)
腳本含義