S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
失业的娱乐-IDA逆向工程入门(一)(二)(三)(四)
layper 当前离线 添加 layper 的声望 反映此帖

标 题: 失业的娱乐-IDA逆向工程入门(一)(二)(三)(四)
作 者: layper
时 间: 2007-03-08,23:49
链 接: http://bbs.pediy.com/showthread.php?t=40765

【文章标题】: 失业的娱乐-IDA逆向工程入门(一)
【文章作者】: layper
【作者邮箱】: layper@yahoo.com.cn
【作者主页】: http://blog.csdn.net/layper/
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
    牢骚一堆,对不起大家了.我是从2004年底开始玩crack的.曾经得到很多朋友的帮助.如hyd009,拉登徒弟,天边涯等以前poje论坛兄弟们帮助(可惜已经很
  少碰见他们了).之间学习脱壳又到看雪论坛学习提问,得到很多高手的回答帮助尤其是fly大侠最为热心,我之所以来这个论坛,全是因为fly大侠.看了很
  多他的文章,从中受益非浅.在此向你们说声谢谢了.
  
  IDA是一个非常强大的反汇编工具,在reverse engineerings中首选的工具.看这篇文章首先明确一个目的,我不是破解,如果你要看破解某某软件的文章
  你可略过,这也不是什么高深的文章,因为,我刚开始学习逆向工程,高深的理论知识我不懂!!!由于本人知识所限错漏难免,请多包含.
  
  在我看来,逆向工程是学习别人软件编程的一种好方法.当你手头上没什么资料可以利用时,或者想了解或者模仿别人的软件时,逆向工程不失为一种好办法.
  (这就是为什么那么多公司在安装协议要用户同意不能逆向的原因:)).
  
  好多的逆向工程的文章一开始就跟你讲什么虚函数,析构函数,库等等,这些确实是经典,理论性很强,适合专业或高手看的.我是一开始就学破解,然后接触汇编
  语言,之后又看了一些乱七八糟的书.编程菜鸟都算不上!!!一开始就来分析这么仔细,这么精益求精,对我来说----蚊子叮猪屁股---太肥了!:)
  
  对我来说,能够把软件逆向后的出源码,并重新编译能够通过是我现阶段最容易得到满足的.依照这个思路,我开始就想把IDA里面反汇编的代码修改后运行.但实践
  证明这个不是一个有效好的方法.要修改IDA反编译出来的代码也比较困难.因为IDA中很多高级语言的结构,高级语言的库,关键字在汇编中不支持或者冲突,就算能
  也很复杂,所以说,
  layper逆向工程第一要点:
  
  (一)从那里来,回到那里去.
  比如汇编语言写的软件,你就把它逆回汇编语言.
  用工具VC++写的软件,你就把他逆回VC++中.
  DELPHI的逆回DELPHI中(这个用DEDE逆向配合应该更好).
  当然,这个不是硬性规定,有些软件他虽然用高级语言写的,但反汇编代码利用价值已经非常高了.
  
  根据这一点要求,我们不得不对逆向工程分析的研究分类,即分为asm,vc++,delphi这三大类,其他的如.net技术等不是我涉及的内容.
  
  下一篇开始,我分别用最简单的win32程序开始分类讲述.
  
  
  (注:虽然逆向工程这个想法在心里已经很久了,但实际学习就是这几天的事,本人水平有限,做法可能不可取,或者可笑请多包涵.下篇
  心情好再写了.)
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年03月02日 11:49:08

返回顶端
layper
级别:7 | 在线时长:78小时 | 升级还需:18小时 级别:7 | 在线时长:78小时 | 升级还需:18小时 级别:7 | 在线时长:78小时 | 升级还需:18小时 级别:7 | 在线时长:78小时 | 升级还需:18小时

普通会员
普通会员

资 料:
注册日期: Aug 2004
帖子: 122layper 品行端正
精华: 9
现金: 202 Kx
2 旧 2007-03-08, 23:50 默认失业的娱乐-IDA逆向工程入门(二)-汇编程序(1)
layper 当前离线 添加 layper 的声望 反映此帖

【文章标题】: 失业的娱乐-IDA逆向工程入门(二)-汇编程序(1)
【文章作者】: layper
【作者邮箱】: layper@yahoo.com.cn
【作者主页】: http://blog.csdn.net/layper/
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  这个是第二篇,入门就要从最简单的开始!!!!!!!!
  
  为什么选汇编程序,因为在IDA逆向出来的就是汇编语言.所以选这个是最好入门的.在这之前你先准备好几样工具,IDA,masm32汇编工具包并安装好,
  在radasm设置好你的路径.
  
  (一)最简单的win32汇编程序源码
  hellow.asm
  
  .386
  .model flat,stdcall
  option casemap:none
  include WINDOWS.INC
  include user32.inc
  include kernel32.inc
  includelib user32.lib
  includelib kernel32.lib
  .data
  sztitle db "你好",0
  sztext db "你好!祝你有个好的开始!!!",0
  .code
  start:
  invoke MessageBox,NULL,offset sztext,offset sztitle,MB_OK
  invoke ExitProcess,NULL
  end start
  
  
  radasm默认编译.无资源段
  
  
  
  (二)IDA自动识别的反汇编代码(未优化直接保存)
  
  
  
  ;
  ; 赏屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?
; ?This file is generated by The Interactive Disassembler (IDA)      ?
; ?Copyright (c) 2006 by DataRescue sa/nv,  <ida@datarescue.com>      ?
; ?Licensed to: Paul Ashton - Blue Lane Technologies (1-user Advanced 03/2006)  ?s
  ; 韧屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?
;
  ; Input  MD5   :  10721E858F8E4DA3413D6FBFAE63E7B3
  
  ; File Name   :  D:\lyp\hellow\hellow.exe
  ; Format      :  Portable executable for  80386 (PE)
  ; Imagebase   :  400000
  ; Section 1. (virtual address 00001000)
  ; Virtual size      : 00000026 (   38.)
  ; Section size in file    : 00000200 (  512.)
  ; Offset to raw  data for section: 00000400
  ; Flags  60000020: Text Executable Readable
  ; Alignment  : default
  
      .686p
      .mmx
      .model flat
  
  ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?

  ; Segment type:  Pure code
  ; Segment permissions: Read/Execute
  _text    segment  para public 'CODE' use32
      assume cs:_text
      ;org 401000h
      assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing
  
  ; *************** S U B  R O U T  I N E ***************************************
  
  
      public start
  start    proc near
      push  0    ; uType
      push  offset Caption  ; "你好"
      push  offset Text  ; "你好!祝你有个好的开始!!!"
      push  0    ; hWnd
      call  MessageBoxA
  
      push  0    ; uExitCode
      call  ExitProcess
  
  start    endp
  
  ; [00000006 BYTES: COLLAPSED FUNCTION MessageBoxA. PRESS KEYPAD  "+" TO EXPAND]
  ; [00000006 BYTES: COLLAPSED FUNCTION ExitProcess. PRESS KEYPAD  "+" TO EXPAND]
      align 200h
  _text    ends
  
  ; Section 2. (virtual address 00002000)
  ; Virtual size      : 00000092 (  146.)
  ; Section size in file    : 00000200 (  512.)
  ; Offset to raw  data for section: 00000600
  ; Flags  40000040: Data Readable
  ; Alignment  : default
  ;
  ; Imports from kernel32.dll
  ;
  ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?

  ; Segment type:  Externs
  ; _idata
  ; void __stdcall ExitProcess(UINT uExitCode)
      extrn __imp_ExitProcess:dword ;  DATA XREF: ExitProcessr
  
  ;
  ; Imports from user32.dll
  ;
  ; int __stdcall  MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
      extrn __imp_MessageBoxA:dword ;  DATA XREF: MessageBoxAr
  
  
  ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?

  ; Segment type:  Pure data
  ; Segment permissions: Read
  _rdata    segment  para public 'DATA' use32
      assume cs:_rdata
      ;org 402010h
      db  54h  ; T
      db  20h
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db  6Ah  ; j
      db  20h
      db    0
      db    0
      db    8
      db  20h
      db    0
      db    0
      db  4Ch  ; L
      db  20h
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db  84h  ; ?
    db  20h
      db    0
      db    0
      db    0
      db  20h
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db  76h  ; v
      db  20h
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db  5Ch  ; \
      db  20h
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db  9Dh  ; ?
    db    1
      db  4Dh  ; M
      db  65h  ; e
      db  73h  ; s
      db  73h  ; s
      db  61h  ; a
      db  67h  ; g
      db  65h  ; e
      db  42h  ; B
      db  6Fh  ; o
      db  78h  ; x
      db  41h  ; A
      db    0
      db  75h  ; u
      db  73h  ; s
      db  65h  ; e
      db  72h  ; r
      db  33h  ; 3
      db  32h  ; 2
      db  2Eh  ; .
      db  64h  ; d
      db  6Ch  ; l
      db  6Ch  ; l
      db    0
      db    0
      db  80h  ; ?
      db    0
      db  45h  ; E
      db  78h  ; x
      db  69h  ; i
      db  74h  ; t
      db  50h  ; P
      db  72h  ; r
      db  6Fh  ; o
      db  63h  ; c
      db  65h  ; e
      db  73h  ; s
      db  73h  ; s
      db    0
      db  6Bh  ; k
      db  65h  ; e
      db  72h  ; r
      db  6Eh  ; n
      db  65h  ; e
      db  6Ch  ; l
      db  33h  ; 3
      db  32h  ; 2
      db  2Eh  ; .
      db  64h  ; d
      db  6Ch  ; l
      db  6Ch  ; l
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
      db    0
  _rdata    ends
  
  ; Section 3. (virtual address 00003000)
  ; Virtual size      : 0000001E (   30.)
  ; Section size in file    : 00000200 (  512.)
  ; Offset to raw  data for section: 00000800
  ; Flags  C0000040: Data Readable  Writable
  ; Alignment  : default
  ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?

  ; Segment type:  Pure data
  ; Segment permissions: Read/Write
  _data    segment  para public 'DATA' use32
      assume cs:_data
      ;org 403000h
  ; char Caption[]
  Caption    db '你好',0             ; DATA XREF: start+2o
  ; char Text[]
  Text    db '你好!祝你有个好的开始!!!',0 ; DATA XREF: start+7o
      align 200h
  _data    ends
  
  
      end start
  用radasm编译成功,不用修改!!!
  
  (三)比对文件
  
  (1)模式定义
  相同度:
  
  .386                                                .686p                      ;不同
  无                                                  .mmx
  .model flat,stdcall                                 .model flat        
  option casemap:none                                 无                         ;不同
  
  我的IDA默认的为686p模式,model语句无语言模式,无option语句.
  
  (2)inc文件,lib文件去向
  
  源文件中的
  include WINDOWS.INC
  include user32.inc
  include kernel32.inc
  includelib user32.lib
  includelib kernel32.lib
  消失在代码中,要寻找回他们!!
  这几个语句其实就是连接系统的dll文件的,在反汇编代码中寻找user32.dll,kernel32.dll,找到这里
  ; Imports from kernel32.dll
  ;
  ; 屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯?
  
  ; Segment type:  Externs
  ; _idata
  ; void __stdcall ExitProcess(UINT uExitCode)
      extrn __imp_ExitProcess:dword ;  DATA XREF: ExitProcessr
  
  ;
  ; Imports from user32.dll
  ;
  ; int __stdcall  MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
      extrn __imp_MessageBoxA:dword ;  DATA XREF: MessageBoxAr
  
  注释很明白了,输入表有两个dll在_idata段,include语句的在_idata段找寻.
  
  (3)段定义的变化
  源代码中段定义是这样
  .段名
  而反汇编中的段定义
  段名    segment  para public 'DATA' use32
      assume cs:_data
  段名    ends
  传统的dos汇编写法.
  
  (4)段的增减
  我们通过比对,发现段的数量跟我们原本的不一致
  原本我们只有两个段
  .data和.code段,而反汇编后变成
  .text和.idata和.rdata和.data段
  经过仔细辨认你就可以发现
  反汇编的text段就是源代码中的.code段,data段是代码段,.idata和.rdata是编译器生成的,而idata是寻找include语句的地方,
  .idata基本没什么用处,可以删掉.
  
  (5)数据段
  通过比对发现基本上一致无什么增加,增加了一个    align 200h
  删掉即可.
  
  (6)代码段变化
  入口函数变化
                  public start
  start    proc near
      push  0    ; uType
      push  offset Caption  ; "你好"
      push  offset Text  ; "你好!祝你有个好的开始!!!"
      push  0    ; hWnd
      call  MessageBoxA
  
      push  0    ; uExitCode
      call  ExitProcess
  
  start    endp
  
  。。。。。。
  
  。。。。。。。
  
      end start
  
  注意end start放在了所有段后面
  
  到这里我们大体上看完这个程序反汇编的大体轮廓。
  
--------------------------------------------------------------------------------
【经验总结】
  (1)模式定义少了语言模式和opention语句,我们要看情况是否加回上去。
  (2)include语句寻找_idata中的dll名,得到常用包含库文件.
  (3).rdate段不用看,可以删掉
  (4)入口开始处寻找start.
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年03月02日 13:56:14

返回顶端
layper
级别:7 | 在线时长:78小时 | 升级还需:18小时 级别:7 | 在线时长:78小时 | 升级还需:18小时 级别:7 | 在线时长:78小时 | 升级还需:18小时 级别:7 | 在线时长:78小时 | 升级还需:18小时

普通会员
普通会员

资 料:
注册日期: Aug 2004
帖子: 122layper 品行端正
精华: 9
现金: 202 Kx
3 旧 2007-03-08, 23:53 默认失业的娱乐-IDA逆向工程入门(三)-汇编程序(2)
layper 当前离线 添加 layper 的声望 反映此帖

【文章标题】: 失业的娱乐-IDA逆向工程入门(三)-汇编程序(2)
【文章作者】: layper
【作者邮箱】: layper@yahoo.comcn
【作者主页】: http://blog.csdn.net/layper/
【下载地址】: 自己搜索下载
【编写语言】: asm
【使用工具】: IDA\reshack\radasm\
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  多谢大家的支持,特别是fly还关心我的工作问题,无已回报,只能继续写些小文供大家批评了!!!
  
  上一篇我们所逆的是非常简单的win32汇编,总共才两个api函数,一个消息框和ExitProcess函数,这篇我们就涉及一个真正的窗口
  程序firstwindows,我学汇编是看了罗云彬的《windows环境下汇编语言程序设计》才入门的,我直接拿里面的例子来讲吧,如果作
  者觉得不合适,我会删去的!!!!!
  
  顺便讲一下学习逆向工程的方法,这个跟学脱壳方法类似,你先用一种语言写一个程序(刚开始比较简单的),编译后用IDA或者
  其他工具反汇编,观察源代码和反汇编代码有什么异同,想办法在逆向代码中逐渐靠近源代码,最后再把他整理到编译工具中不
  断编译,在编译器中看那里出错,逐步修改,直至成功,最后总结经验,这样就会逐步提高了.
  
  限于篇幅,我只把完整源码贴出来,未修改的反汇编在压缩包内的1.asm,请自行查看
  firstwindows源码
  
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  ; Sample code for < Win32ASM Programming >
  ; by 罗云彬, http://asm.yeah.net
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  ; FirstWindow.asm
  ; 窗口程序的模板代码
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  ; 使用 nmake 或下列命令进行编译和链接:
  ; ml /c /coff FirstWindow.asm
  ; Link /subsystem:windows FirstWindow.obj
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      .386
      .model flat,stdcall
      option casemap:none
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  ; Include 文件定义
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  include    windows.inc
  include    gdi32.inc
  includelib  gdi32.lib
  include    user32.inc
  includelib  user32.lib
  include    kernel32.inc
  includelib  kernel32.lib
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  ; 数据段
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      .data?
  
  hInstance  dd    ?
  hWinMain  dd    ?
  
      .const
  
  szClassName  db  'MyClass',0
  szCaptionMain  db  'My first Window !',0
  szText    db  'Win32 Assembly, Simple and powerful !',0
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  ; 代码段
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      .code
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  ; 窗口过程
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  _ProcWinMain  proc  uses ebx edi esi,hWnd,uMsg,wParam,lParam
      local  @stPs:PAINTSTRUCT
      local  @stRect:RECT
      local  @hDc
  
      mov  eax,uMsg
  ;********************************************************************
      .if  eax ==  WM_PAINT
        invoke  BeginPaint,hWnd,addr @stPs
        mov  @hDc,eax
  
        invoke  GetClientRect,hWnd,addr @stRect
        invoke  DrawText,@hDc,addr szText,-1,\
          addr @stRect,\
          DT_SINGLELINE or DT_CENTER or DT_VCENTER
  
        invoke  EndPaint,hWnd,addr @stPs
  ;********************************************************************
      .elseif  eax ==  WM_CLOSE
        invoke  DestroyWindow,hWinMain
        invoke  PostQuitMessage,NULL
  ;********************************************************************
      .else
        invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
      .endif
  ;********************************************************************
      xor  eax,eax
      ret
  
  _ProcWinMain  endp
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  _WinMain  proc
      local  @stWndClass:WNDCLASSEX
      local  @stMsg:MSG
  
      invoke  GetModuleHandle,NULL
      mov  hInstance,eax
      invoke  RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
  ;********************************************************************
  ; 注册窗口类
  ;********************************************************************
      invoke  LoadCursor,0,IDC_ARROW
      mov  @stWndClass.hCursor,eax
      push  hInstance
      pop  @stWndClass.hInstance
      mov  @stWndClass.cbSize,sizeof WNDCLASSEX
      mov  @stWndClass.style,CS_HREDRAW or CS_VREDRAW
      mov  @stWndClass.lpfnWndProc,offset _ProcWinMain
      mov  @stWndClass.hbrBackground,COLOR_WINDOW + 1
      mov  @stWndClass.lpszClassName,offset szClassName
      invoke  RegisterClassEx,addr @stWndClass
  ;********************************************************************
  ; 建立并显示窗口
  ;********************************************************************
      invoke  CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
        WS_OVERLAPPEDWINDOW,\
        100,100,600,400,\
        NULL,NULL,hInstance,NULL
      mov  hWinMain,eax
      invoke  ShowWindow,hWinMain,SW_SHOWNORMAL
      invoke  UpdateWindow,hWinMain
  ;********************************************************************
  ; 消息循环
  ;********************************************************************
      .while  TRUE
        invoke  GetMessage,addr @stMsg,NULL,0,0
        .break  .if eax  == 0
        invoke  TranslateMessage,addr @stMsg
        invoke  DispatchMessage,addr @stMsg
      .endw
      ret
  
  _WinMain  endp
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  start:
      call  _WinMain
      invoke  ExitProcess,NULL
  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      end  start
  
  在radasm编译通过.
  
  用IAD反汇编载入完成后,点击文件-创建文件-创建asm文件就得到未经修改的反汇编后得到的1.asm文件(有点绕口:)),直接用
  radasm打开,在radasm中ctrl+f5构建并运行看看结果怎样,呵呵,出错了.

因为一步一步来讲比较长,我先把操作过程写下来,在慢慢解释,1.asm修改如下:
(一)增加模式定义\options语句\还原include语句
      .686p
      .mmx
      .model flat,stdcall
      option casemap:none
  include WINDOWS.INC
  include kernel32.inc
  includelib kernel32.lib
  include user32.inc
  includelib user32.lib
(二)删除结构MSG\POINT\PAINTSTRUCT\RECT,并把余下的结构移动到  includelib user32.lib之后,即第一步之后,
然后做如下修改:
tagMSG    struc ;  (sizeof=0x1C, standard type)
hwnd    dd ?      ; offset
message    dd ?
wParam    dd ?
lParam    dd ?
time    dd ?
pt    POINT ?    ;这里修改为pt    POINT <>
tagMSG    ends

tagPAINTSTRUCT  struc ;  (sizeof=0x40, standard type)
hdc    dd ?      ; offset
fErase    dd ?
rcPaint    RECT ?      ;这里修改为rcPaint    RECT <>
fRestore  dd ?
fIncUpdate  dd ?
rgbReserved  db 32 dup(?)
tagPAINTSTRUCT  ends
(三)对函数的局部变量进行修改
一共三个函数start\sub_401000和sub_401089,修改如下
sub_401089:
sub_401089  proc near    ; CODE XREF: startp

Msg    = MSG ptr -4Ch
var_30    = WNDCLASSEXA ptr -30h
修改为:
sub_401089  proc near    ; CODE XREF: startp

    LOCAL Msg:MSG 
    LOCAL var_30:WNDCLASSEXA 



sub_401000:

sub_401000  proc near    ; DATA XREF: sub_401089+43o

hDC    = dword  ptr -54h
Rect    = tagRECT ptr -50h
Paint    = PAINTSTRUCT ptr -40h
hWnd    = dword  ptr  8
Msg    = dword  ptr  0Ch
wParam    = dword  ptr  10h
lParam    = dword  ptr  14h

修改为:
sub_401000  proc uses ebx edi esi ,hWnd,Msg,wParam,lParam    ; DATA XREF: sub_401089+43o

    LOCAL hDC
    LOCAL Rect:tagRECT
    LOCAL Paint:PAINTSTRUCT


(四)_text段修改
删除
在_text段前增加.code
_text    segment  para public 'CODE' use32
    assume cs:_text
    ;org 401000h
    assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing

_text    ends
注意:中间的代码不要删除!!!

(五)删除align 40h

(六)移动修改_data段
在.code前增加.data,并且把_data段移动到这里

_data    segment  para public 'DATA' use32
    assume cs:_data
    ;org 403000h
和          ; sub_401089+A6r
_data    ends
删除
注意:中间的代码不要删除!!!

(七)修改sub_401000的hWnd,只要出现有的都修改为hWnd1.

(八)删除_idata段

(九)
把函数含有[ebp+变量]的代码全部修改为变量
sub_401089的代码
[ebp+var_30] 改为  var_30
[ebp+var_30.hCursor]  改为  var_30.hCursor
[ebp+var_30.hInstance]  改为  var_30.hInstance
[ebp+var_30.cbSize]  改为  var_30.cbSize
[ebp+var_30.style]  改为  var_30.style
[ebp+var_30.lpfnWndProc]  改为  var_30.lpfnWndProc
[ebp+var_30.hbrBackground]  改为  var_30.hbrBackground
[ebp+var_30.lpszClassName]  改为  var_30.lpszClassName
[ebp+Msg]    改为  Msg

sub_401000的代码
[ebp+hDC]    改为  hDC
[ebp+Rect]    改为  Rect
[ebp+Paint]    改为  Paint
[ebp+hWnd1]    改为  hWnd1
[ebp+Msg]    改为  Msg
[ebp+wParam]    改为  wParam
[ebp+lParam]    改为  lParam

(十)删掉函数多余的开头
sub_401089处:
sub_401089  proc near    ; CODE XREF: startp

    LOCAL Msg:MSG 
    LOCAL var_30:WNDCLASSEXA 

    push  ebp    ;删掉
    mov  ebp, esp  删掉
    add  esp, 0FFFFFFB4h  ;删掉

sub_401000处:
sub_401000  proc near uses ebx edi esi ,hWnd1,Msg,wParam,lParam    ; DATA XREF: sub_401089+43o

    LOCAL hDC
    LOCAL Rect:tagRECT
    LOCAL Paint:PAINTSTRUCT


    push  ebp  ;删掉
    mov  ebp, esp  ;删掉
    add  esp, 0FFFFFFACh  ;删掉
    push  ebx    ;删掉
    push  edi    ;删掉
    push  esi    ;删掉


--------------------------------------------------------------------------------
【经验总结】
 其实只要你把反编译的代码按照radasm的提示一步一步修改就可以了.
解释:
(一)
这一步我在上篇已经解释的比较明白了.因为我们汇编开头就是那么几句代码.
include语句加回去这个是因为我们编译的是汇编程序,这样肯定要用到库.如果IDA使用生成的_data段
就非常容易出错.毕竟它只是"识别"而不是源码!!!!!!!

(二)
 (1)删除结构体MSG\POINT\PAINTSTRUCT\RECT
我们进行了第一步操作后,用radasm进行构建,就会提示我们
D:\masm32\Include\WINDOWS.INC(7873) : error A2163:  : POINT
D:\masm32\Include\WINDOWS.INC(7874) : error A2163:  : POINT
D:\masm32\Include\WINDOWS.INC(8841) : error A2163:  : MSG
D:\masm32\Include\WINDOWS.INC(8842) : error A2163:  : MSG
D:\masm32\Include\WINDOWS.INC(8843) : error A2163:  : MSG
D:\masm32\Include\WINDOWS.INC(8844) : error A2163:  : MSG
D:\masm32\Include\WINDOWS.INC(8845) : error A2163:  : MSG
D:\masm32\Include\WINDOWS.INC(8846) : error A2163:  : MSG
D:\masm32\Include\WINDOWS.INC(8846) : fatal error A1016: 

构建时发生错误.
总共编译时间 271 毫秒

这个这个意思说我们的库文件出错,这个可能吗?当然也有可能,但我想你首先应该想到是你的反汇编代码错.
先查询一下windows.inc"出错"的到底是什么
POINT STRUCT
  x  DWORD ?  ;7873行
  y  DWORD ?  ;7874行
POINT ENDS

MSG STRUCT
  hwnd      DWORD      ?  ;8841
  message   DWORD      ?  ;8842
  wParam    DWORD      ?  ;8843
  lParam    DWORD      ?  ;8844
  time      DWORD      ?  ;8845
  pt        POINT      <>  ;8846
MSG ENDS

呵呵,你再看看反汇编代码开头
MSG    struc ;  (sizeof=0x1C, standard type)
hwnd    dd ?      ; offset
message    dd ?
wParam    dd ?
lParam    dd ?
time    dd ?
pt    POINT ?
MSG    ends

; ---------------------------------------------------------------------------

POINT    struc ;  (sizeof=0x8, standard type)
x    dd ?
y    dd ?
POINT    ends
明白怎么是这样了吧?我们反汇编代码重复定义了结构msg,point所以要把他们删除.同理PAINTSTRUCT\RECT也删除了.
(2)移动剩余结构到include语句后.
这一步我是为了省事,剩余三个结构
tagMSG    struc ;  (sizeof=0x1C, standard type)
hwnd    dd ?      ; offset
message    dd ?
wParam    dd ?
lParam    dd ?
time    dd ?
pt    POINT ?
tagMSG    ends
; ---------------------------------------------------------------------------
WNDCLASSEXA  struc ;  (sizeof=0x30, standard type)
cbSize    dd ?
style    dd ?
lpfnWndProc  dd ?      ; offset
cbClsExtra  dd ?
cbWndExtra  dd ?
hInstance  dd ?      ; offset
hIcon    dd ?      ; offset
hCursor    dd ?      ; offset
hbrBackground  dd ?      ; offset
lpszMenuName  dd ?      ; offset
lpszClassName  dd ?      ; offset
hIconSm    dd ?      ; offset
WNDCLASSEXA  ends
; ---------------------------------------------------------------------------
tagRECT    struc ;  (sizeof=0x10, standard type)
left    dd ?
top    dd ?
right    dd ?
bottom    dd ?
tagRECT    ends
; ---------------------------------------------------------------------------
tagPAINTSTRUCT  struc ;  (sizeof=0x40, standard type)
hdc    dd ?      ; offset
fErase    dd ?
rcPaint    RECT ?
fRestore  dd ?
fIncUpdate  dd ?
rgbReserved  db 32 dup(?)
tagPAINTSTRUCT  ends
其中tagMSG和tagPAINTSTRUCT结构分别用到了POINT结构和RECT结构,刚才我们删了,只有windows.inc中有
所以直接把他们剪切到这里省去出错的机会.
(3)修改结构
tagMSG结构和tagPAINTSTRUCT结构修改,我是参照windows.inc结构定义方法.结构中用结构<> :)
这个不一定完全正确,想研究这方面多阅读.inc文件

(三)函数修改
在反汇编代码中只要出现proc的,到现在为止我都看成是函数!!!
IDA反汇编都它的函数都变成这个样子
sub_401000  proc near    ; DATA XREF: sub_401089+43o

hDC    = dword  ptr -54h  ;注意这里是减(-)
Rect    = tagRECT ptr -50h
Paint    = PAINTSTRUCT ptr -40h
hWnd    = dword  ptr  8    ;这里其实是加(+)
Msg    = dword  ptr  0Ch
wParam    = dword  ptr  10h
lParam    = dword  ptr  14h

    push  ebp
    mov  ebp, esp
    add  esp, 0FFFFFFACh
    push  ebx
    push  edi
    push  esi
    mov  eax, [ebp+Msg]
这里就会出现一个问题.我们先前又删结构又改结构,而这里又用到结构,不修改编译也会出错的.
我们改成比较正规的win32汇编程序格式.
刚才我提示加减的地方,总结一条规律给大家:
函数开头 xx = 结构 - xxh 这个就是函数的局部变量,可用local xx:结构替换.
函数开头 xx = dword  ptr xxh 这个是函数的参数,函数可改为
函数名 proc xx

(四)_text段修改
代码段
_text    segment  para public 'CODE' use32
    assume cs:_text
    ;org 401000h
    assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing

_text    ends
IDA这种段写法有很大的弊端,也是引起我们修改后的代码编译不通过的一个很重要原因.(具体我还说不上来,我还很菜)

(五)删除align 40h
align是反汇编代码不通过编译的一种常见错误.

(六)移动修改_data段
一般来说_data段是我们的数据段,一般我们放在前面.(呵呵,代码顺序也很重要)

(七)在数据段中
hWnd    dd ?      ; DATA XREF: sub_401000+54r
          ; sub_401089+94w sub_401089+9Br
          ; sub_401089+A6r
提示hWnd是函数sub_401089的,并不是sub_401000,所以要重命名他们.

(八)删除_idata段
include语句已经有了函数定义,再保留这里就会出错.

(九)
把函数含有[ebp+变量]的代码全部修改为变量
[ebp+]这个是编译器加上去的,我们直接用的话,编译后会变成[ebp+ebp+变量],容易出错.

(十)删掉函数多余的开头
反汇编代码中,编译器为你加上象这样的代码
    push  ebp
    mov  ebp, esp
    add  esp, 0FFFFFFB4h
如果你直接编译的话代码就变成了:
    push  ebp
    mov  ebp, esp
    add  esp, 0FFFFFFB4h
    push  ebp
    mov  ebp, esp
    add  esp, 0FFFFFFB4h
重新编译也容易出错,所以要删去.

同理,要注意函数结束地方看看是否要删去.

(十一)
这里说一点跟上一篇不同的是没有删除_rdata,因为这里有我们程序要的数据,所以没删除.如
果你还想优化自己弄了!!!

呵呵,终于弄完这篇了,把它整理好花了好大工夫.错误难免,请多包涵!!!!

--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年03月04日 12:21:20

上传的附件
文件类型: rar firstwindow.rar (0, 574 次下载) [谁下载?]

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