【文章標(biāo)題】: 失業(yè)的娛樂(lè)-IDA逆向工程入門(四)-匯編程序?qū)崙?zhàn)
【文章作者】: layper
【作者郵箱】:
layper@yahoo.com.cn【作者主頁(yè)】:
http://blog.csdn.net/layper/【軟件名稱】: biatch
【下載地址】: 自己搜索下載
【使用工具】: IDA,Radasm,Resource Hacker
【作者聲明】: 只是感興趣,沒(méi)有其他目的。失誤之處敬請(qǐng)諸位大俠賜教!
--------------------------------------------------------------------------------
【詳細(xì)過(guò)程】
這段時(shí)間忙著學(xué)習(xí)網(wǎng)頁(yè)制作,剛剛初學(xué),N多問(wèn)題要學(xué)習(xí),搞得我頭暈?zāi)X漲.現(xiàn)在放松一下,繼續(xù)逆向玩玩.:)
匯編程序在逆向工程中是比較簡(jiǎn)單的一種語(yǔ)言,反匯編得到的代碼基本上與源碼差不多,只是稍微作點(diǎn)修改就可以了.前面的
幾篇都是有源碼對(duì)照的例子,這篇我們進(jìn)行實(shí)戰(zhàn),沒(méi)有源碼.:)
這是老外的一個(gè)工具biatch,今天拿他開(kāi)刀.
IDA載入完成后,文件-創(chuàng)建文件-創(chuàng)建asm文件保存為1.asm。接著用Resource Hacker載入biatch,保存對(duì)話框資源為1.rc。
用RadASM載入1.asm,好了初步工作完成了,接下來(lái)先按照上次我寫(xiě)的第三篇步驟來(lái)修改.
(一)增加模式定義\options語(yǔ)句\還原include\lib語(yǔ)句
在IDA中Shift+F7打開(kāi)區(qū)段窗口接著雙擊.idata來(lái)到.idata段,
.idata:00403000 ;
.idata:00403000 ; Imports from comdlg32.dll注意這里,使用comdig32.dll
.idata:00403000 ;
.idata:00403000 ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?
.idata:00403000
.idata:00403000 ; Segment type: Externs
.idata:00403000 ; _idata
.idata:00403000 ; BOOL __stdcall GetOpenFileNameA(LPOPENFILENAMEA)
.idata:00403000 extrn __imp_GetOpenFileNameA:dword
.idata:00403000 ; DATA XREF: GetOpenFileNameAr
.idata:00403000 ; Create an Open common dialog box
.idata:00403004
.idata:00403008 ;
.idata:00403008 ; Imports from gdi32.dll注意這里,使用gdi32.dll
.idata:00403008 ;
.idata:00403008 ; HFONT __stdcall CreateFontIndirectA(const LOGFONTA *)
.idata:00403008 extrn __imp_CreateFontIndirectA:dword
.idata:00403008 ; DATA XREF: CreateFontIndirectAr
.idata:0040300C ; BOOL __stdcall DeleteObject(HGDIOBJ)
.idata:0040300C extrn __imp_DeleteObject:dword ; DATA XREF: DeleteObjectr
.idata:00403010
.idata:00403014 ;
.idata:00403014 ; Imports from kernel32.dll注意這里,使用kernel32.dll
.idata:00403014 ;
.idata:00403014 ; LPTOP_LEVEL_EXCEPTION_FILTER __stdcall SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
.idata:00403014 extrn __imp_SetUnhandledExceptionFilter:dword
.idata:00403014 ; DATA XREF: SetUnhandledExceptionFilterr
.idata:00403018 ; HANDLE GetProcessHeap(void)
.idata:00403018 extrn __imp_GetProcessHeap:dword
.idata:00403018 ; DATA XREF: GetProcessHeapr
.idata:0040301C ; BOOL __stdcall CloseHandle(HANDLE hObject)
.idata:0040301C extrn __imp_CloseHandle:dword ; DATA XREF: CloseHandler
.idata:00403020 ; HANDLE __stdcall CreateFileA(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
.idata:00403020 extrn __imp_CreateFileA:dword ; DATA XREF: CreateFileAr
.......................
........................
.idata:00403040 ; HMODULE __stdcall GetModuleHandleA(LPCSTR lpModuleName)
.idata:00403040 extrn __imp_GetModuleHandleA:dword
.idata:00403040 ; DATA XREF: GetModuleHandleAr
.idata:00403044 ; void __stdcall ExitProcess(UINT uExitCode)
.idata:00403044 extrn __imp_ExitProcess:dword ; DATA XREF: ExitProcessr
.idata:00403048 ; LPVOID __stdcall HeapAlloc(HANDLE hHeap,DWORD dwFlags,DWORD dwBytes)
.idata:00403048 extrn __imp_HeapAlloc:dword ; DATA XREF: HeapAllocr
.idata:0040304C
.idata:00403050 ;
.idata:00403050 ; Imports from user32.dll注意這里,使用user32.dll
.idata:00403050 ;
.idata:00403050 ; LONG __stdcall SetWindowLongA(HWND hWnd,int nIndex,LONG dwNewLong)
.idata:00403050 extrn __imp_SetWindowLongA:dword
.idata:00403050 ; DATA XREF: SetWindowLongAr
.................................
.idata:00403098 extrn __imp_CheckDlgButton:dword
.idata:00403098 ; DATA XREF: CheckDlgButtonr
.idata:00403098 ; Change the check state of a button control
.idata:0040309C ; LRESULT __stdcall CallWindowProcA(WNDPROC lpPrevWndFunc,HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
.idata:0040309C extrn __imp_CallWindowProcA:dword
.idata:0040309C ; DATA XREF: CallWindowProcAr
.idata:004030A0 ; BOOL __stdcall ShowWindow(HWND hWnd,int nCmdShow)
.idata:004030A0 extrn __imp_ShowWindow:dword ; DATA XREF: ShowWindowr
.idata:004030A4 ; int wsprintfA(LPSTR,LPCSTR,...)
.idata:004030A4 extrn __imp_wsprintfA:dword ; DATA XREF: wsprintfAr
.idata:004030A8
從這里知道了用到四個(gè)dll,即comdlg32.dll、gdi32.dll、kernel32.dll、user32.dll,所以我們還原的include和includelib就要包含
這幾個(gè)dll。
所以把
.686p
.mmx
.model flat
還原成:
.686p
.mmx
.model flat,stdcall
option casemap:none
include WINDOWS.INC
include comdlg32.inc
includelib comdlg32.lib
include gdi32.inc
includelib gdi32.lib
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
刪除前面的.idata段.
(二)刪除結(jié)構(gòu)
在RadASM中Ctrl+F5試著構(gòu)建并運(yùn)行,有錯(cuò)誤提示.
D:\masm32\Include\WINDOWS.INC(9666) : error A2163: : LOGFONTA
D:\masm32\Include\WINDOWS.INC(9667) : error A2163: : LOGFONTA
D:\masm32\Include\WINDOWS.INC(9668) : error A2163: : LOGFONTA
D:\masm32\Include\WINDOWS.INC(9669) : error A2163: : LOGFONTA
D:\masm32\Include\WINDOWS.INC(9670) : error A2163: : LOGFONTA
從這里可以判斷1.asm的LOGFONTA導(dǎo)致出錯(cuò),刪除LOGFONTA結(jié)構(gòu)(在開(kāi)頭處).把tagOFNA結(jié)構(gòu)移動(dòng)到includelib user32.lib后面.
(三)修改移動(dòng)_data段
在_text段前增加
.data
把_data全部移到.data之后
刪除_data段開(kāi)頭的
_data segment para public 'DATA' use32
assume cs:_data
和_data末尾的
_data ends
注意:中間的代碼不要?jiǎng)h除!!!
(四)修改_text段
加上.code
_text segment para public 'CODE' use32 ;在這之前加上.code
刪除_text開(kāi)頭的
_text segment para public 'CODE' use32
assume cs:_text
;org 401000h
assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
和_text末尾的
_text ends
注意:中間的代碼不要?jiǎng)h除!!!
(五)修改hWnd錯(cuò)誤
在RadASM中Ctrl+F5試著構(gòu)建并運(yùn)行,有錯(cuò)誤提示.
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(834) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1286) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1499) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1640) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2609) : error A2189: : 128
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(821) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1277) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1489) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1629) : error A2005: : hWnd
在.data段尋找hWnd
; HWND hWnd
hWnd dd 0 ; DATA XREF: DialogFunc+241r
; DialogFunc+264w DialogFunc+26Dr
; DialogFunc+28Br DialogFunc+29Dr
; sub_401500+9r ...
這個(gè)提示兩個(gè)函數(shù)DialogFunc和sub_401500用到這個(gè)全局變量hWnd,其他函數(shù)的hWnd錯(cuò)誤的地方。我們
逐條尋找出錯(cuò)位置
1.asm(834) : error A2005: : hWnd
這條錯(cuò)誤在
sub_401500 proc near ; CODE XREF: DialogFunc+21Fp
var_18 = dword ptr -18h
var_14 = dword ptr -14h
var_10 = dword ptr -10h
var_C = dword ptr -0Ch
hWnd = dword ptr -8 ;這里出錯(cuò),這里的局部變量hWnd與全局變量hWnd沖突,修改為hWnd1
lpMem = dword ptr -4
hDlg = dword ptr 8
在IDA中打開(kāi)Functions窗口,找到sub_401500,
sub_401500 .text 00401500 00000291 R . . . B T .
雙擊來(lái)到sub_401500處
.text:00401500 sub_401500 proc near ; CODE XREF: DialogFunc+21Fp
.text:00401500
.text:00401500 var_18 = dword ptr -18h
.text:00401500 var_14 = dword ptr -14h
.text:00401500 var_10 = dword ptr -10h
.text:00401500 var_C = dword ptr -0Ch
.text:00401500 hWnd = dword ptr -8 ;修改這里為hWnd1
.text:00401500 lpMem = dword ptr -4
.text:00401500 hDlg = dword ptr 8
在hWnd上右鍵-重命名把hWnd為hWnd1.
注意:推薦在IDA里面重命名hWnd,經(jīng)過(guò)修改后IDA自動(dòng)識(shí)別全局變量hWnd和hWnd1比手動(dòng)快,而且正確率高.
繼續(xù)查找
1.asm(1286) : error A2005: : hWnd
錯(cuò)誤在
sub_401810 proc near ; CODE XREF: sub_401380+130p
hWnd = dword ptr -8 ;在IDA中修改為hWnd1
lpMem = dword ptr -4
hDlg = dword ptr 8
1.asm(1499) : error A2005: : hWnd
找到
sub_401A10 proc near ; CODE XREF: DialogFunc+233p
var_8 = dword ptr -8
hWnd = dword ptr -4 ;在IDA中修改為hWnd1
hDlg = dword ptr 8
1.asm(1640) : error A2005: : hWnd
找到
sub_401B6C proc near ; DATA XREF: DialogFunc+9Eo
; DialogFunc+CBo sub_401380+57o
hWnd = dword ptr 8 ;這個(gè)不是局部變量了
Msg = dword ptr 0Ch
wParam = dword ptr 10h
lParam = dword ptr 14h
因?yàn)檫@里不是局部變量了,我們先修改前面三個(gè)函數(shù)(或者子程序),sub_401500,sub_401810,sub_401A10.
保存修改后的代碼為2.asm,接著把1.asm里的sub_401500,sub_401810,sub_401A10這三個(gè)函數(shù)全部用2.asm
里的sub_401500,sub_401810,sub_401A10替換掉.
接著在RadASM中Ctrl+F5構(gòu)建并運(yùn)行,
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1640) : error A2005: : hWnd
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2609) : error A2189: : 128
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1629) : error A2005: : hWnd
看來(lái)sub_401B6C的hWnd也要改掉,在IDA中修改后覆蓋到1.asm里,
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2609) : error A2189: : 128
hWnd沒(méi)有出現(xiàn)錯(cuò)誤了.
(五)刪除align
1.asm(2609) : error A2189: : 128 ;這里就是align,直接刪除了
(六)修改fs[0]
前面幾篇都沒(méi)有涉及到這個(gè)內(nèi)容,這里就出現(xiàn)關(guān)于fs[0]的出錯(cuò)代碼的修改.
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1950) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1951) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1971) : error A2206:
這幾行在1.asm對(duì)應(yīng)的代碼是sub_401D80中
push large dword ptr fs:0
mov large fs:0, esp
pop large dword ptr fs:0
這幾行代碼都在
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2010) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2011) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2054) : error A2206:
這幾行在1.asm對(duì)應(yīng)的代碼是sub_401DE0中
push large dword ptr fs:0
mov large fs:0, esp
pop large dword ptr fs:0
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2422) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2423) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2478) : error A2206:
這幾行在1.asm對(duì)應(yīng)的代碼是sub_402050中
push large dword ptr fs:0
mov large fs:0, esp
pop large dword ptr fs:0
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2536) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2537) : error A2206:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2581) : error A2206:
這幾行在1.asm對(duì)應(yīng)的代碼是sub_4020F0中
push large dword ptr fs:0
mov large fs:0, esp
pop large dword ptr fs:0
這幾句代碼的寫(xiě)法不正確,我們把他們改為
push fs:[0]
mov fs:[0], esp
pop fs:[0]
試構(gòu)建運(yùn)行看看
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1950) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1951) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(1971) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2010) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2011) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2054) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2422) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2423) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2478) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2536) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2537) : error A2108:
D:\crack\國(guó)外工具\(yùn)tf10\1.asm(2581) : error A2108:
還是提示出錯(cuò),經(jīng)過(guò)認(rèn)真觀察,參考了其他代碼,我在函數(shù)sub_401D80,sub_401DE0,sub_4020F0,sub_4020F0開(kāi)頭處加上一句
代碼:
assume fs:nothing
查一下資料,因?yàn)镸ASM編譯器默認(rèn)是把FS定義為error,所以在程序中要使用FS寄存器就要用
assume fs:nothing 來(lái)聲明,否則就會(huì)報(bào)錯(cuò)。
構(gòu)建運(yùn)行
D:\masm32\BIN\ML.EXE /c /coff /Cp /nologo /I"D:\masm32\Include" "D:\crack\國(guó)外工具\(yùn)tf10\1.asm"
Assembling: D:\crack\國(guó)外工具\(yùn)tf10\1.asm
D:\masm32\BIN\LINK.EXE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"D:\masm32\LIB" "D:\crack\國(guó)外工具\(yùn)tf10\1.obj"
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
執(zhí)行:
"D:\crack\國(guó)外工具\(yùn)tf10\1.exe"
構(gòu)建完成.
總共編譯時(shí)間 781 毫秒
無(wú)錯(cuò)誤提示,呵呵,我們逆向的代碼初步成功了.
(七)加入資源
我們?cè)囘\(yùn)行1.exe發(fā)現(xiàn)沒(méi)有出現(xiàn)界面,這個(gè)就是沒(méi)有把資源加回去才出現(xiàn)這種錯(cuò)誤的.
利用Resource Hacker生成的1.rc修改后用makefile文件把資源文件編譯進(jìn)去.
1.rc所做的修改如下:
增加
#include <resource.h>
刪除掉
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
makefile文件:
NAME = 1
OBJS = $(NAME).obj
RES = $(NAME).res
LINK_FLAG = /subsystem:windows
ML_FLAG = /c /coff
$(NAME).exe: $(OBJS) $(RES)
Link $(LINK_FLAG) $(OBJS) $(RES)
.asm.obj:
ml $(ML_FLAG) $<
.rc.res:
rc $<
clean:
del *.obj
del *.res
注意:這里編譯我直接用命令行形式編譯,不用RadASM.
呵呵,現(xiàn)在你已經(jīng)擁有一份不太完善的biatch的源碼了.
匯編程序的逆向工程就告一段落了.我這里演示的只是一部分還原方法或注意事項(xiàng),在實(shí)際應(yīng)用當(dāng)中
并不是僅僅這幾步內(nèi)容(比如優(yōu)化就是非常重要),這個(gè)就要多多進(jìn)行練習(xí)來(lái)提高水平了。
--------------------------------------------------------------------------------
【版權(quán)聲明】: 轉(zhuǎn)載請(qǐng)注明作者并保持文章的完整, 謝謝!
2007年03月30日 0:46:41