小默

[zz]失业的娱乐-IDA逆向工程入门(四)-汇编程序实战

【文章标题】: 失业的娱乐-IDA逆向工程入门(四)-汇编程序实战
【文章作者】: layper
【作者邮箱】: layper@yahoo.com.cn
【作者主页】: http://blog.csdn.net/layper/
【软件名称】: biatch
【下载地址】: 自己搜索下载
【使用工具】: IDA,Radasm,Resource Hacker
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  这段时间忙着学习网页制作,刚刚初学,N多问题要学习,搞得我头晕脑涨.现在放松一下,继续逆向玩玩.:)
  
  汇编程序在逆向工程中是比较简单的一种语言,反汇编得到的代码基本上与源码差不多,只是稍微作点修改就可以了.前面的
  几篇都是有源码对照的例子,这篇我们进行实战,没有源码.:)
  
  这是老外的一个工具biatch,今天拿他开刀.
  
  IDA载入完成后,文件-创建文件-创建asm文件保存为1.asm。接着用Resource Hacker载入biatch,保存对话框资源为1.rc。
  
  用RadASM载入1.asm,好了初步工作完成了,接下来先按照上次我写的第三篇步骤来修改.
  
  (一)增加模式定义\options语句\还原include\lib语句
  
  在IDA中Shift+F7打开区段窗口接着双击.idata来到.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
  
  从这里知道了用到四个dll,即comdlg32.dll、gdi32.dll、kernel32.dll、user32.dll,所以我们还原的include和includelib就要包含
  这几个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段.
  
  (二)删除结构
  在RadASM中Ctrl+F5试着构建并运行,有错误提示.
  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导致出错,删除LOGFONTA结构(在开头处).把tagOFNA结构移动到includelib user32.lib后面.
  
  (三)修改移动_data段
  在_text段前增加
  .data
  
  把_data全部移到.data之后
  删除_data段开头的
  _data    segment  para public 'DATA' use32
      assume cs:_data
  和_data末尾的
  _data    ends
  
  注意:中间的代码不要删除!!!
  
  (四)修改_text段
  加上.code
  _text    segment  para public 'CODE' use32   ;在这之前加上.code 
  
  删除_text开头的
  _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
  
  注意:中间的代码不要删除!!!
  
  (五)修改hWnd错误
  在RadASM中Ctrl+F5试着构建并运行,有错误提示.
  
  D:\crack\国外工具\tf10\1.asm(834) : error A2005:  : hWnd
  D:\crack\国外工具\tf10\1.asm(1286) : error A2005:  : hWnd
  D:\crack\国外工具\tf10\1.asm(1499) : error A2005:  : hWnd
  D:\crack\国外工具\tf10\1.asm(1640) : error A2005:  : hWnd
  D:\crack\国外工具\tf10\1.asm(2609) : error A2189:  : 128
  D:\crack\国外工具\tf10\1.asm(821) : error A2005:  : hWnd
  D:\crack\国外工具\tf10\1.asm(1277) : error A2005:  : hWnd
  D:\crack\国外工具\tf10\1.asm(1489) : error A2005:  : hWnd
  D:\crack\国外工具\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 ...
  这个提示两个函数DialogFunc和sub_401500用到这个全局变量hWnd,其他函数的hWnd错误的地方。我们
逐条寻找出错位置
1.asm(834) : error A2005:  : hWnd
这条错误在
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    ;这里出错,这里的局部变量hWnd与全局变量hWnd冲突,修改为hWnd1
lpMem    = dword  ptr -4
hDlg    = dword  ptr  8
在IDA中打开Functions窗口,找到sub_401500,
sub_401500                  .text 00401500 00000291 R . . . B T . 
双击来到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,经过修改后IDA自动识别全局变量hWnd和hWnd1比手动快,而且正确率高.

继续查找
1.asm(1286) : error A2005:  : hWnd
错误在
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    ;这个不是局部变量了
Msg    = dword  ptr  0Ch
wParam    = dword  ptr  10h
lParam    = dword  ptr  14h

因为这里不是局部变量了,我们先修改前面三个函数(或者子程序),sub_401500,sub_401810,sub_401A10.
保存修改后的代码为2.asm,接着把1.asm里的sub_401500,sub_401810,sub_401A10这三个函数全部用2.asm
里的sub_401500,sub_401810,sub_401A10替换掉.

接着在RadASM中Ctrl+F5构建并运行,
D:\crack\国外工具\tf10\1.asm(1640) : error A2005:  : hWnd
D:\crack\国外工具\tf10\1.asm(2609) : error A2189:  : 128
D:\crack\国外工具\tf10\1.asm(1629) : error A2005:  : hWnd

看来sub_401B6C的hWnd也要改掉,在IDA中修改后覆盖到1.asm里,
D:\crack\国外工具\tf10\1.asm(2609) : error A2189:  : 128

hWnd没有出现错误了.

(五)删除align

1.asm(2609) : error A2189:  : 128  ;这里就是align,直接删除了

(六)修改fs[0]
前面几篇都没有涉及到这个内容,这里就出现关于fs[0]的出错代码的修改.
D:\crack\国外工具\tf10\1.asm(1950) : error A2206: 
D:\crack\国外工具\tf10\1.asm(1951) : error A2206: 
D:\crack\国外工具\tf10\1.asm(1971) : error A2206:


这几行在1.asm对应的代码是sub_401D80中
    push  large dword ptr  fs:0
    mov  large fs:0, esp
    pop  large dword ptr  fs:0
这几行代码都在

D:\crack\国外工具\tf10\1.asm(2010) : error A2206: 
D:\crack\国外工具\tf10\1.asm(2011) : error A2206: 
D:\crack\国外工具\tf10\1.asm(2054) : error A2206: 

这几行在1.asm对应的代码是sub_401DE0中
    push  large dword ptr  fs:0
    mov  large fs:0, esp
    pop  large dword ptr  fs:0


D:\crack\国外工具\tf10\1.asm(2422) : error A2206: 
D:\crack\国外工具\tf10\1.asm(2423) : error A2206: 
D:\crack\国外工具\tf10\1.asm(2478) : error A2206: 
这几行在1.asm对应的代码是sub_402050中
    push  large dword ptr  fs:0
    mov  large fs:0, esp
    pop  large dword ptr  fs:0


D:\crack\国外工具\tf10\1.asm(2536) : error A2206: 
D:\crack\国外工具\tf10\1.asm(2537) : error A2206: 
D:\crack\国外工具\tf10\1.asm(2581) : error A2206: 
这几行在1.asm对应的代码是sub_4020F0中
    push  large dword ptr  fs:0
    mov  large fs:0, esp
    pop  large dword ptr  fs:0
这几句代码的写法不正确,我们把他们改为
    push  fs:[0]
    mov  fs:[0], esp
    pop  fs:[0]
试构建运行看看
D:\crack\国外工具\tf10\1.asm(1950) : error A2108: 
D:\crack\国外工具\tf10\1.asm(1951) : error A2108: 
D:\crack\国外工具\tf10\1.asm(1971) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2010) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2011) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2054) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2422) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2423) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2478) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2536) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2537) : error A2108: 
D:\crack\国外工具\tf10\1.asm(2581) : error A2108: 

还是提示出错,经过认真观察,参考了其他代码,我在函数sub_401D80,sub_401DE0,sub_4020F0,sub_4020F0开头处加上一句
代码:
    assume fs:nothing

查一下资料,因为MASM编译器默认是把FS定义为error,所以在程序中要使用FS寄存器就要用   
  assume   fs:nothing   来声明,否则就会报错。
构建运行
D:\masm32\BIN\ML.EXE /c /coff /Cp /nologo /I"D:\masm32\Include" "D:\crack\国外工具\tf10\1.asm"
 Assembling: D:\crack\国外工具\tf10\1.asm
D:\masm32\BIN\LINK.EXE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /LIBPATH:"D:\masm32\LIB" "D:\crack\国外工具\tf10\1.obj" 
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

执行:
 "D:\crack\国外工具\tf10\1.exe"

构建完成.
总共编译时间 781 毫秒

无错误提示,呵呵,我们逆向的代码初步成功了.

(七)加入资源
我们试运行1.exe发现没有出现界面,这个就是没有把资源加回去才出现这种错误的.

利用Resource Hacker生成的1.rc修改后用makefile文件把资源文件编译进去.

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.

呵呵,现在你已经拥有一份不太完善的biatch的源码了.

汇编程序的逆向工程就告一段落了.我这里演示的只是一部分还原方法或注意事项,在实际应用当中
并不是仅仅这几步内容(比如优化就是非常重要),这个就要多多进行练习来提高水平了。


--------------------------------------------------------------------------------
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年03月30日 0:46:41

posted on 2009-12-25 12:12 小默 阅读(1611) 评论(0)  编辑 收藏 引用 所属分类: Tools


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

留言簿(13)

随笔分类(287)

随笔档案(289)

漏洞

搜索

积分与排名

最新评论

阅读排行榜