快速增长你的逆向编程能力=--学会反汇编角度编写程序

http://bbs.fishc.com/forum.php?mod=viewthread&tid=18337&extra=page%3D1%26filter%3Dtypeid%26typeid%3D287%26typeid%3D287

该系列案例解析按级别类别排列,如:


  • [基础知识]: 类别为基础知识
  • 1.2: 级别,第一个1表示属于最简单级别,后边的2仅为案例的序数(不代表难度增加(⊙o⊙)哦)


小甲鱼用了一个通宵的时间来编写和调试程序,大家有可能不理解的地方也做了详细注释,谨以此献给喜欢鱼C,热爱编程的朋友们!

仅希望不喜的朋友勿喷,喜欢的朋友耐心学习,回复的朋友注意论坛环境,不要回复一堆毫无意义标点符号!

用这种方法写程序,将其编译链接后的可执行文件用IDA等工具将其反汇编后,两者基本保持一致。掌握这种写法,可以加深对逆向的反应和思考能力,适合平时锻炼提高逆向能力!

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; by 小甲鱼, http://www.fishc.com
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 功能:实现与反汇编同样语法的汇编编程,有点纠结,但非常有利于锻炼逆向思维!
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .386
        .model flat,stdcall
        option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib

    .data    
hIcon       dd  0
hWnd        dd  0
hDc         dd  0
winX        dd  0
winY        dd  0
wWidth      dd  0
wHeight     dd  0    
stPs        PAINTSTRUCT <0>
stRect      RECT <0>
wc          WNDCLASSEX  <0>                 ; wc定义为WNDCALSSEX结构,并用零填充
msg         MSG <0>                         ; 用于存放消息
szClassName db  'MyClass', 0
szCaption   db  '欢迎来到鱼C工作室', 0   
szMessage   db  '学习编程最好的地方 -- 鱼C工作室: www.fishc.com', 0

    .code
main:
    push ebp                    ; 保存上一个程序的ebp
    mov ebp, esp                ; ebp == esp,ebp主要用于后边的参数和变量的索引

;------------------------------------------------------------------
;......................... 初始化程序 .............................
;------------------------------------------------------------------
    push 1000                   ; 图标的ID
    push DWORD PTR [ebp+8]      ; 就是在调用main函数前压入的参数,为本模块的句柄
    call LoadIcon
    mov hIcon, eax  
    
    mov wc.cbSize, sizeof WNDCLASSEX
    mov wc.style, CS_BYTEALIGNWINDOW
    mov wc.lpfnWndProc, offset WndProc  
    mov wc.cbClsExtra, NULL
    mov wc.cbWndExtra, NULL
    mov eax, [ebp+8]            ; 就是在调用main函数前压入的参数,为本模块的句柄
    mov wc.hInstance, eax
    mov wc.hbrBackground, COLOR_WINDOW+1
    mov wc.lpszMenuName, NULL
    mov wc.lpszClassName, offset szClassName
    
    push hIcon
    pop eax                     ; 经典做法,相当于mov eax, hIcon
    mov wc.hIcon, eax
    
    push IDC_ARROW
    push NULL
    call LoadCursor
    mov wc.hCursor, eax
    
    push hIcon
    pop eax
    mov wc.hIconSm, eax
    
    push offset wc
    call RegisterClassEx        ; 注册窗口
    
    mov wWidth, 600             ; 窗口宽度
    mov wHeight, 450            ; 窗口高度
    mov winX, 50
    mov winY, 50
    
;------------------------------------------------------------------
;........................... 创建窗口 .............................
;------------------------------------------------------------------      
    push NULL
    push DWORD PTR [ebp+8]      ; 还记得吧,本模块句柄
    push NULL                   ; 菜单句柄,这里不需要,所以木有
    push NULL                   ; 父窗口句柄,这里木有,所以没有
    push wHeight                ; 高度
    push wWidth                 ; 宽度
    push winY                   ; 左上角y值
    push winX                   ; 左上角x值
    push WS_OVERLAPPEDWINDOW    ; 窗口风格
    push offset szCaption       ; 标题
    push offset szClassName     ; 类名
    push WS_EX_LEFT             ; 扩展窗口风格
    call CreateWindowEx         ; 上边的都是这个函数的参数,注意入栈是从右到左
    mov hWnd, eax
    
    push SW_SHOWNORMAL
    push hWnd
    call ShowWindow             ; 显示窗口
    
    push hWnd
    call UpdateWindow           ; 更新窗口
    
;------------------------------------------------------------------
;........................... 消息循环 .............................
;------------------------------------------------------------------  
msgLoop:
    push 0
    push 0
    push NULL
    push offset msg
    call GetMessage             ; 获取消息
    
    cmp eax, 0                  
    je exitLoop                 ; 如果返回值为0,则退出循环,准备结束程序
    
    push offset msg
    call TranslateMessage       ; 转发消息
    
    push offset msg
    call DispatchMessage        ; 分派消息
    
    jmp msgLoop
 
exitLoop:
    mov esp, ebp                ; 恢复堆栈
    pop ebp                     ; 恢复上一个程序的ebp
    ret                         ; 返回
    
;------------------------------------------------------------------
;........................... 窗口过程 .............................
;------------------------------------------------------------------      
WndProc:
    push ebp
    mov ebp, esp
    
; 小甲鱼再啰嗦下!WndProc proc hWin, uMsg, wPrarm, lParam
;                                |     |      |       |
; 他们分别用ebp的索引值是:    ebp+8 ebp+12 ebp+16  ebp+20
    cmp DWORD PTR [ebp+12], WM_PAINT    ; 判断是否绘制窗口消息
    jne @F
    
    push offset stPs
    push [ebp+8]               ; hWin入栈
    call BeginPaint
    mov hDc, eax
    
    push offset stRect
    push [ebp+8]
    call GetClientRect
    
    push DT_SINGLELINE or DT_CENTER or DT_VCENTER
    push offset stRect
    push -1
    push offset szMessage
    push hDc
    call DrawText
    
    push offset stPs
    push [ebp+8]
    call EndPaint             ; 擦屁股,释放资源
    
@@:
    cmp DWORD PTR [ebp+12], WM_CLOSE    ; 判断是不是获得关闭的消息
    jne @F
    
    push NULL
    call PostQuitMessage
    
@@:
    push DWORD PTR[ebp+20]     ; lParam
    push DWORD PTR[ebp+16]     ; wParam
    push DWORD PTR[ebp+12]     ; uMsg
    push DWORD PTR[ebp+8]      ; hWin
    call DefWindowProc         ; 把我们不关注的消息都让默认函数来处理
 
    mov esp, ebp
    pop ebp
    ret    

start:      
    push NULL
    call GetModuleHandle        ; 获取本模块句柄,注意现在我们不用invoke,我们时刻要保持反汇编写法
    
    push eax                    ; eax保存着拿到的模块句柄,并作为main函数的参数入栈
    call main   
    
    push 0
    call ExitProcess            ; 退出程序
        
    end start         

以下是用IDA逆向后的反汇编程序,请鱼油们注意比较,两者基本保持一致。


.text:00401000 ; int __cdecl sub_401000(HINSTANCE hInstance)
.text:00401000 sub_401000      proc near               ; CODE XREF: start+8p
.text:00401000
.text:00401000 hInstance       = dword ptr  8
.text:00401000
.text:00401000                 push    ebp
.text:00401001                 mov     ebp, esp
.text:00401003                 push    3E8h            ; lpIconName
.text:00401008                 push    [ebp+hInstance] ; hInstance
.text:0040100B                 call    LoadIconA
.text:00401010                 mov     dword_403000, eax
.text:00401015                 mov     stru_40306C.cbSize, 30h
.text:0040101F                 mov     stru_40306C.style, 2000h
.text:00401029                 mov     stru_40306C.lpfnWndProc, offset sub_40114B
.text:00401033                 mov     stru_40306C.cbClsExtra, 0
.text:0040103D                 mov     stru_40306C.cbWndExtra, 0
.text:00401047                 mov     eax, [ebp+hInstance]
.text:0040104A                 mov     stru_40306C.hInstance, eax
.text:0040104F                 mov     stru_40306C.hbrBackground, 6
.text:00401059                 mov     stru_40306C.lpszMenuName, 0
.text:00401063                 mov     stru_40306C.lpszClassName, offset ClassName ; "MyClass"
.text:0040106D                 push    dword_403000
.text:00401073                 pop     eax
.text:00401074                 mov     stru_40306C.hIcon, eax
.text:00401079                 push    7F00h           ; lpCursorName
.text:0040107E                 push    0               ; hInstance
.text:00401080                 call    LoadCursorA
.text:00401085                 mov     stru_40306C.hCursor, eax
.text:0040108A                 push    dword_403000
.text:00401090                 pop     eax
.text:00401091                 mov     stru_40306C.hIconSm, eax
.text:00401096                 push    offset stru_40306C ; WNDCLASSEXA *
.text:0040109B                 call    RegisterClassExA
.text:004010A0                 mov     nWidth, 258h
.text:004010AA                 mov     nHeight, 1C2h
.text:004010B4                 mov     X, 32h
.text:004010BE                 mov     Y, 32h
.text:004010C8                 push    0               ; lpParam
.text:004010CA                 push    [ebp+hInstance] ; hInstance
.text:004010CD                 push    0               ; hMenu
.text:004010CF                 push    0               ; hWndParent
.text:004010D1                 push    nHeight         ; nHeight
.text:004010D7                 push    nWidth          ; nWidth
.text:004010DD                 push    Y               ; Y
.text:004010E3                 push    X               ; X
.text:004010E9                 push    0CF0000h        ; dwStyle
.text:004010EE                 push    offset WindowName ; "欢迎来到鱼C工?
.text:004010F3                 push    offset ClassName ; "MyClass"
.text:004010F8                 push    0               ; dwExStyle
.text:004010FA                 call    CreateWindowExA
.text:004010FF                 mov     hWnd, eax
.text:00401104                 push    1               ; nCmdShow
.text:00401106                 push    hWnd            ; hWnd
.text:0040110C                 call    ShowWindow
.text:00401111                 push    hWnd            ; hWnd
.text:00401117                 call    UpdateWindow
.text:0040111C
.text:0040111C loc_40111C:                             ; CODE XREF: sub_401000+145j
.text:0040111C                 push    0               ; wMsgFilterMax
.text:0040111E                 push    0               ; wMsgFilterMin
.text:00401120                 push    0               ; hWnd
.text:00401122                 push    offset Msg      ; lpMsg
.text:00401127                 call    GetMessageA
.text:0040112C                 cmp     eax, 0
.text:0040112F                 jz      short loc_401147
.text:00401131                 push    offset Msg      ; lpMsg
.text:00401136                 call    TranslateMessage
.text:0040113B                 push    offset Msg      ; lpMsg
.text:00401140                 call    DispatchMessageA
.text:00401145                 jmp     short loc_40111C
.text:00401147 ; ---------------------------------------------------------------------------
.text:00401147
.text:00401147 loc_401147:                             ; CODE XREF: sub_401000+12Fj
.text:00401147                 mov     esp, ebp
.text:00401149                 pop     ebp
.text:0040114A                 retn
.text:0040114A sub_401000      endp
.text:0040114A
.text:0040114B
.text:0040114B ; =============== S U B R O U T I N E =======================================
.text:0040114B
.text:0040114B ; Attributes: bp-based frame
.text:0040114B
.text:0040114B ; int __cdecl sub_40114B(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
.text:0040114B sub_40114B      proc near               ; DATA XREF: sub_401000+29o
.text:0040114B
.text:0040114B hWnd            = dword ptr  8
.text:0040114B Msg             = dword ptr  0Ch
.text:0040114B wParam          = dword ptr  10h
.text:0040114B lParam          = dword ptr  14h
.text:0040114B
.text:0040114B                 push    ebp
.text:0040114C                 mov     ebp, esp
.text:0040114E                 cmp     [ebp+Msg], 0Fh
.text:00401152                 jnz     short loc_401199
.text:00401154                 push    offset Paint    ; lpPaint
.text:00401159                 push    [ebp+hWnd]      ; hWnd
.text:0040115C                 call    BeginPaint
.text:00401161                 mov     hdc, eax
.text:00401166                 push    offset Rect     ; lpRect
.text:0040116B                 push    [ebp+hWnd]      ; hWnd
.text:0040116E                 call    GetClientRect
.text:00401173                 push    25h             ; format
.text:00401175                 push    offset Rect     ; lprc
.text:0040117A                 push    0FFFFFFFFh      ; cchText
.text:0040117C                 push    offset chText   ; "学习编程最好的地方 -- 鱼C工?
.text:00401181                 push    hdc             ; hdc
.text:00401187                 call    DrawTextA
.text:0040118C                 push    offset Paint    ; lpPaint
.text:00401191                 push    [ebp+hWnd]      ; hWnd
.text:00401194                 call    EndPaint
.text:00401199
.text:00401199 loc_401199:                             ; CODE XREF: sub_40114B+7j
.text:00401199                 cmp     [ebp+Msg], 10h
.text:0040119D                 jnz     short loc_4011A6
.text:0040119F                 push    0               ; nExitCode
.text:004011A1                 call    PostQuitMessage
.text:004011A6
.text:004011A6 loc_4011A6:                             ; CODE XREF: sub_40114B+52j
.text:004011A6                 push    [ebp+lParam]    ; lParam
.text:004011A9                 push    [ebp+wParam]    ; wParam
.text:004011AC                 push    [ebp+Msg]       ; Msg
.text:004011AF                 push    [ebp+hWnd]      ; hWnd
.text:004011B2                 call    DefWindowProcA
.text:004011B7                 mov     esp, ebp
.text:004011B9                 pop     ebp
.text:004011BA                 retn
.text:004011BA sub_40114B      endp
.text:004011BA


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值