前言
之前的實(shí)驗(yàn)部分,也出現(xiàn)過(guò)加殼對(duì)抗,文中也說(shuō)了幾種工具脫殼和手動(dòng)脫殼的方法,但是之前主要還是針對(duì)功能點(diǎn)的分析。從這里開始,主要涉及到的就是逆向?qū)沽恕?/p>
Lab15:花指令
花指令是企圖隱藏掉不想被逆向工程的代碼塊(或其它功能)的一種方法,在真實(shí)代碼中插入一些垃圾代碼的同時(shí)還保證原有程序的正確執(zhí)行,而程序無(wú)法很好地反編譯, 難以理解程序內(nèi)容,達(dá)到混淆視聽(tīng)的效果。
__asm { }內(nèi)聯(lián)嵌入__emit 0e8h;
當(dāng)出現(xiàn)這樣的語(yǔ)句時(shí),ida會(huì)把E8當(dāng)作call,然后后面的部分當(dāng)作調(diào)用函數(shù),導(dǎo)致出現(xiàn)混淆。
所以此時(shí)一般可以用xor配合跳轉(zhuǎn)語(yǔ)句,保證程序的正常運(yùn)行。
除此之外,也可以加入0E9h等混淆IDA.
call $+5
add [esp],5
retn
當(dāng)內(nèi)聯(lián)嵌入這樣的語(yǔ)句時(shí),會(huì)混淆IDA的流程圖,這個(gè)語(yǔ)句最后的效果相當(dāng)于一個(gè)jmp,等于沒(méi)有。
Lab15-1
放入IDA中查看。
可以看到這里有一個(gè)永假跳轉(zhuǎn)。
這邊因?yàn)樽址_頭是E8,會(huì)讓反編譯誤認(rèn)為是Call,這時(shí)候把它先轉(zhuǎn)為數(shù)據(jù),然后把E8排除,就出現(xiàn)了原來(lái)的代碼了。
接著可以看到下面還有好幾處地方一樣
用之前的方法修復(fù)
可以看到先是判斷了參數(shù)的個(gè)數(shù)
之后第一個(gè)參數(shù)和p比,第二個(gè)參數(shù)和d比,第三個(gè)參數(shù)和q比,進(jìn)行對(duì)比,最后可以得出當(dāng)參數(shù)是pdq的時(shí)候成功。
Lab15-2
放到IDA中查看。
可以看到第一個(gè)出現(xiàn)返匯編的地方。
將40115E這一行,先變成data,然后把115F變成code,最后E9轉(zhuǎn)為nop.
之后來(lái)到第二處
進(jìn)行相似的修補(bǔ)。
繼續(xù)一樣的修補(bǔ)。
這里面的修補(bǔ)都差不多,最后的結(jié)果圖
接著分析修復(fù)好后的程序。
先獲取了主機(jī)名,然后這里經(jīng)過(guò)+1和替換變成了agent頭。
這里可以看到訪問(wèn)的網(wǎng)站。
從網(wǎng)站中取出Bamboo::和::之間的內(nèi)容,作為下載的網(wǎng)址
下載并運(yùn)行。
Lab15-3
放到IDA中查看。
看到了異常處
修復(fù)
繼續(xù)修復(fù)。
繼續(xù)修復(fù)
修補(bǔ)后
分析修補(bǔ)后的網(wǎng)站
看到傳入url函數(shù)的進(jìn)行了異或
寫個(gè)idc腳本進(jìn)行解密
之后下載運(yùn)行。
Lab16:反調(diào)試
進(jìn)程運(yùn)行時(shí),位置fs:[30h]指向PEB的基地址。為了實(shí)現(xiàn)反調(diào)試技術(shù),惡意代碼通過(guò)這個(gè)位置的BeingDebugged標(biāo)志檢測(cè),這個(gè)標(biāo)志標(biāo)識(shí)進(jìn)程是否正在被調(diào)試
Reserved4數(shù)組中一個(gè)未公開的位置叫做ProcessHeap,它被設(shè)置為加載器為進(jìn)程分配的第一個(gè)堆的位置。ProcessHeap位于PEB結(jié)構(gòu)的0x18處。第一個(gè)堆頭部有一個(gè)屬性字段,它告訴內(nèi)核這個(gè)堆是否在調(diào)試器中創(chuàng)建。這些屬性叫做ForceFlags和Flags
windows XP系統(tǒng)中,F(xiàn)orceFlags屬性位于堆頭部偏移量0x10處;但是在Windows7系統(tǒng)中,對(duì)于32位應(yīng)用程序來(lái)說(shuō)它位于偏移量0x44處
由于調(diào)試器中啟動(dòng)進(jìn)程與正常模式下啟動(dòng)進(jìn)程有些不同,所以它們創(chuàng)建內(nèi)存堆的方式也不同。系統(tǒng)使用PEB結(jié)構(gòu)偏移量0x68處的一個(gè)未公開設(shè)置,來(lái)決定如何創(chuàng)建堆結(jié)構(gòu)。如果這個(gè)位置的值為0x70,我們就知道進(jìn)程正在調(diào)試器中
系統(tǒng)痕跡檢測(cè)
HKEY_LOCAL_macHINESOFTWAREMicrosoftWindows NTCurrentVersionAeDebug
該注冊(cè)表項(xiàng)指定當(dāng)應(yīng)用程序發(fā)生錯(cuò)誤時(shí),觸發(fā)哪一個(gè)調(diào)試器。默認(rèn)情況下,它被設(shè)置為Dr.Watson.如果該注冊(cè)表的鍵值被修改為OllyDbg,則惡意代碼可能確定它正在被調(diào)試
1
掃描代碼的斷點(diǎn)
call $+5
pop edi
sub edi,5
mov ecx,400h
mov eax,0CCh
repne scasb
jz DebuggerDeteced
對(duì)抗這種反調(diào)試技術(shù)的方法是使用硬件斷點(diǎn)而不是使用軟件斷點(diǎn)
時(shí)鐘檢測(cè)
被調(diào)試時(shí),進(jìn)程的運(yùn)行速度大大降低,例如,單步調(diào)試大幅度降低惡意代碼的運(yùn)行速度,所以時(shí)鐘檢測(cè)是惡意代碼探測(cè)調(diào)試器存在的最常用方式之一。
記錄執(zhí)行一段操作前后的時(shí)間戳,然后比較這兩個(gè)時(shí)間戳,如果存在滯后,則可以認(rèn)為存在調(diào)試器
Lab16-1
放入IDA中查看,這個(gè)跟lab9的一個(gè)樣本是一樣的,除了增加反調(diào)試。
可以看到先是檢查了BeingDebugged是否為0
之后檢查processheap的forceflag是否為0
再檢查NTGlobalFlag是否為70h
如果檢測(cè)到任何一個(gè)有反調(diào)試的行為就刪除自身。
對(duì)于這幾個(gè)反調(diào)試方法都可以使用填充0的方法進(jìn)行繞過(guò)
dump ds:[fs:[30] +0x18] + 0x10
dump fs:[30]
dump fs:[30]+0x68
也可以手動(dòng)修改寄存器的值,讓其跳轉(zhuǎn)產(chǎn)生改變。
剩下的功能點(diǎn)前面都分析過(guò)了,就不繼續(xù)分析了。
Lab16-2
這里用PEView查看
放入IDA中查看。
arg_4與1比較,說(shuō)明只在程序剛開始的時(shí)候有用。
查看有無(wú)OllyDbg.
BeingDebugged,之后通過(guò)檢查這個(gè)值,進(jìn)行調(diào)試判斷。
之后發(fā)現(xiàn)通過(guò)OutDebugStringA檢測(cè)調(diào)試器
這里針對(duì)PEB,還是之前的方法
針對(duì)tls,把exit換成nop
針對(duì)OutputDebugStringA,也是用nop填充add.
但是不知道為啥我這里的密碼得到是bzrr,書上是byrr.
Lab16-3
運(yùn)行,會(huì)直接退出。跟之前分析過(guò)的一個(gè)樣本是一樣的
用od動(dòng)態(tài)調(diào)試,我這邊直接就出了最后的答案。
找到比較名字的地方。
但還是跟著步驟走一遍,找到4011E0
進(jìn)入查看,可以看到QueryPerformanceCounter,通過(guò)兩次時(shí)間差,判斷有無(wú)調(diào)試。
通過(guò)設(shè)置2來(lái)作為有調(diào)試的標(biāo)準(zhǔn),因此這里設(shè)置為nop
查看其中的異常處理
因?yàn)榍懊娴膞or語(yǔ)句,這里ecx被設(shè)置為0,所以這里會(huì)產(chǎn)生異常。
接著看下面,這里通過(guò)GetTickCount,對(duì)時(shí)間進(jìn)行判斷。
這里的401000也是異常處理。
繼續(xù)往下看,可以看到rdstc,也是通過(guò)異常處理。
Lab17:反虛擬化
當(dāng)鏡像安裝了vmware Tools,進(jìn)程中就會(huì)出現(xiàn)VMwareService.exe、VMwareTray.exe和VMware.exe
通過(guò)搜索注冊(cè)表中安裝的服務(wù)
或者.NET stat | findstr Vmware
“航天課堂”第一課內(nèi)容非常精彩。接下來(lái)我們會(huì)以更簡(jiǎn)單明了的方式向小朋友講解相關(guān)知識(shí)。敬請(qǐng)期待第二節(jié)航天課堂。
以00:0C:29開始的MAC地址與VMware相對(duì)應(yīng)
Red Pill反虛擬機(jī)技術(shù)
通過(guò)運(yùn)行sidt指令獲取IDTR寄存器的值。虛擬機(jī)監(jiān)視器必須重新定位Guest系統(tǒng)的IDTR,來(lái)避免與host系統(tǒng)的IDTR沖突。因?yàn)樵谔摂M機(jī)中運(yùn)行sidt指令時(shí),虛擬機(jī)監(jiān)視器不會(huì)得到通知,所以會(huì)返回虛擬機(jī)的IDTR,Red Pill通過(guò)測(cè)試這種差異來(lái)探測(cè)VMware的使用
查詢I/O通信端口
VMware使用虛擬化I/O端口完成宿主系統(tǒng)與虛擬機(jī)之間的通信,以便支持諸如復(fù)制和粘貼功能。這個(gè)端口可以被查詢
這種技術(shù)成功的關(guān)鍵在于x86體系結(jié)構(gòu)中的in指令,它從一個(gè)源操作數(shù)指定的端口復(fù)制數(shù)據(jù)到目的操作數(shù)指導(dǎo)的內(nèi)存地址
str指令用來(lái)從任務(wù)寄存器中檢索段選擇子,段選擇子指向當(dāng)前運(yùn)行任務(wù)的任務(wù)狀態(tài)段(TSS)
惡意代碼編寫者可以利用str指令探測(cè)虛擬機(jī)的存在,因?yàn)檫@條指令返回的值,在虛擬機(jī)系統(tǒng)與宿主系統(tǒng)可能不同(這種技術(shù)對(duì)于多處理器的硬件無(wú)效)
Lab17-1
這里先寫一個(gè)idc腳本,在程序中搜索相關(guān)反虛擬的指令,然后輸出對(duì)應(yīng)的地址。
這里可以看到有三個(gè)地址,三個(gè)地方存在反虛擬的指令401121,4011b5,401204
先去401121,可以看到是sldt
之后對(duì)sldt之后值進(jìn)行了一個(gè)比較,應(yīng)對(duì)方法,nop掉
再去4011b5,可以看到這里是sidt.
這里是對(duì)結(jié)果的一個(gè)檢測(cè),也可以通過(guò)nop的方式解決。
接下來(lái)是str.
之后是檢測(cè),也是nop
Lab17-2
這次只關(guān)注反虛擬化的操作。
這里用之前寫好的idc腳本,找到了一個(gè)地址。
可以看到是in
這里也可以用nop處理
Lab17-3
放入ida中查看。
用之前的idc腳本查找
可以查到一個(gè)地址
是I/O查找
這里看一下交叉引用
這里可以用Olldydbg將test該為xor
這里查看strings
查看交叉引用
然后到這里
再查看交叉引用,
看到是SYSTEMCurrentControlSetControlDevicesClasses傳入。
可以得知這里是查詢與vmware對(duì)比,探測(cè)虛擬化
利用之前的test修改為xor即可
Lab18:脫殼
前面提到過(guò)幾個(gè)手動(dòng)脫殼的方法,這里再來(lái)深入一下。
脫殼存根指向了以下三步操作
將原始程序脫殼到內(nèi)存中
解析原始可執(zhí)行文件的所有導(dǎo)入函數(shù)
將可執(zhí)行程序轉(zhuǎn)移到原始的程序入口點(diǎn)(OEP)
單步跟蹤法
宗旨:向上的跳轉(zhuǎn)不讓實(shí)現(xiàn),向下的跳轉(zhuǎn)實(shí)現(xiàn),當(dāng)發(fā)現(xiàn)大跨度跳轉(zhuǎn)時(shí),即會(huì)到OEP
ESP定律法
遵循堆棧平衡原理,在殼對(duì)程序進(jìn)行操作加密或者壓縮時(shí),會(huì)把程序的OEP壓入棧中,當(dāng)殼執(zhí)行完成后,進(jìn)行解密或者解壓縮,會(huì)把真正的OEP從棧中彈出
2次內(nèi)存鏡像法
在殼進(jìn)行解密或解壓縮時(shí),最后釋放的是資源區(qū)段:.rsrc,這個(gè)區(qū)段被釋放完全后,說(shuō)明整個(gè)程序已經(jīng)被全部解密
Lab18-1
放入od,直接Ollydump插件即可,然后修復(fù)即可
Lab18-2
放入od,也是插件即可
Lab18-3
放入od,設(shè)置硬件斷點(diǎn),利用ESP定律
Lab18-4
放入od,設(shè)置硬件斷點(diǎn),利用ESP定律
這里單步調(diào)試到OEP
Lab18-5
跟之前一樣,放入od,設(shè)置硬件斷點(diǎn),利用ESP定律