ReverseMe 不完美分析过程

ReverseMe 不完美分析过程
lnn1123/2006.3

为了响应老大的号召http://bbs.pediy.com//showthread.php?s=&threadid=22990去下了个ReverseMe玩玩
下玩东西,先看说明
You must insert a MenuItem called "Detour" into the menu of the
ReverseMe. When clicking this MenuItem, it should call a function inside
a Dll that you will have to code yourself. This function should show the
RunDialog-box (like the one in the Windows "Start"-menu.... Hint: call by
Ordinal in Shell32.dll). When executed, the RunDialog should show the Icon
of the ReverseMe. You MUST do this by pushing the handle of the Icon to the
call of your function inside your DLL. The OK-button of the RunDialog must
be disabled when the RunDialog opens (and enabled when entering something in
the editbox of the dialog). Afterwards the code-execution will have to 
return
to the ReverseMe without exiting the program.
要你添加一个菜单,完成一点功能.那我就不客气了用ResHacker添加一个菜单
CAPTRESREMEMENU MENU
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
POPUP "&CaptREsMenu"
{
  MENUITEM "&About",  1
  MENUITEM SEPARATOR
  MENUITEM "Detour",  3     //自己添加的,注意后面的资源ID不能重复
  MENUITEM "E&xit",  2
}
}
保存运行看看,出来就是给你一个下马威,异常,OD调试跟踪到下面代码处异常

 
00401070  |. 68 70454000    PUSH CaptRERe.00404570                   ; /FileName = ""
00401075  |. E8 8C010000    CALL <JMP.&KERNEL32.LoadLibraryA>        ; /LoadLibraryA
0040107A  |. 68 78454000    PUSH CaptRERe.00404578                   ; /ProcNameOrOrdinal = ""
0040107F  |. 50             PUSH EAX                                 ; |hModule
00401080  |. E8 7B010000    CALL <JMP.&KERNEL32.GetProcAddress>      ; /GetProcAddress
00401085  |. 6A 00          PUSH 0
00401087  |. 68 1E454000    PUSH CaptRERe.0040451E
0040108C  |. 6A 00          PUSH 0
0040108E  |. FFD0           CALL EAX                                 //就是这个竟然call 0了,肯定异常了
看代码00401070处加载dll时就出错拉,push CaptRERe.00404570这句应该指向dll名字符,这里竟然是0,后面看看代码
加载dll后作者也没有检测是否加载成功就直接用函数名(函数名竟然也指向空字符)得到函数地址了,分析一下估计是
ResHacker在添加资源菜单的时候把原来文件某些地方的东西给弄没有了,并且很可能是00404570(offset:1170),00404578(offset:1178)处的字

符被清0了,对比原文件用Hex Workshop 到1170处发现果然被ResHacker修改后的文件1170初是00,而原文件是有字符的,这个好办,把原文件1104

处大小为80字节的内容复制到目标文件相同地址处(记得是覆盖),这样保存后运行正常.

看说明用写一个dll 执行菜单Detour功能,还要弄一个运行框的东西出来.
思路是这样的:

利用窗口子类化处理Detour的执行,在Detour执行的时候用dll弄一个对话框出来,并且完成相应功能

看说明要你点Detour的时候出来一个运行框,可以选择一个文件并且运行它,这些都是在dll里面来完成的,这个先放一放,要用dll中的函数先要

把原程序来改一改,因为dll中的输出函数有一个参数是调用dll的进程的窗口句饼,所以定位CreateWindowExA到这里


004010E6  |. 8945 B0        MOV DWORD PTR SS:[EBP-50],EAX
004010E9  |. 6A 01          PUSH 1                                   ; /ShowState = SW_SHOWNORMAL//就修改这里跳到我的代码处
004010EB  |. FF75 B0        PUSH DWORD PTR SS:[EBP-50]               ; |hWnd
004010EE  |. E8 EF000000    CALL <JMP.&USER32.ShowWindow>            ; /ShowWindow
004010F3  |. FF75 B0        PUSH DWORD PTR SS:[EBP-50]               ; /hWnd
004010F6  |. E8 ED000000    CALL <JMP.&USER32.UpdateWindow>          ; /UpdateWindow
004010FB  |> 6A 00          PUSH 0                                   ; /MsgFilterMax = 0


修改后的代码:

004010E6   . 8945 B0        MOV DWORD PTR SS:[EBP-50],EAX            ;保存窗口句饼
004010E9   . E9 3D010000    JMP 4.0040122B                           ;跳到我的代码处
004010EE     90             NOP
004010EF     90             NOP
004010F0     90             NOP
004010F1     90             NOP
004010F2     90             NOP
004010F3   > FF75 B0        PUSH DWORD PTR SS:[EBP-50]               ; /hWnd
004010F6   . E8 ED000000    CALL <JMP.&USER32.UpdateWindow>          ; /UpdateWindow
004010FB   > 6A 00          PUSH 0                                   ; /MsgFilterMax = 0
004010FD   . 6A 00          PUSH 0                                   ; |MsgFilterMin = 0
004010FF   . 6A 00          PUSH 0                                   ; |hWnd = NULL
00401101   . 8D45 B4        LEA EAX,DWORD PTR SS:[EBP-4C]            ; |
00401104   . 50             PUSH EAX                                 ; |pMsg
00401105   . E8 BA000000    CALL <JMP.&USER32.GetMessageA>           ; /GetMessageA
0040110A   . 0BC0           OR EAX,EAX
0040110C   . 74 0B          JE SHORT 4.00401119
0040110E   . 8D45 B4        LEA EAX,DWORD PTR SS:[EBP-4C]
00401111   . 50             PUSH EAX                                 ; /pMsg
00401112   . E8 A7000000    CALL <JMP.&USER32.DispatchMessageA>      ; /DispatchMessageA
00401117   .^EB E2          JMP SHORT 4.004010FB
00401119   > 8B45 BC        MOV EAX,DWORD PTR SS:[EBP-44]
0040111C   . C9             LEAVE
0040111D   . C2 1000        RETN 10
00401120  /. 55             PUSH EBP
00401121  |. 8BEC           MOV EBP,ESP
00401123  |. 837D 0C 02     CMP DWORD PTR SS:[EBP+C],2
00401127  |. 75 09          JNZ SHORT 4.00401132
00401129  |. 6A 00          PUSH 0                                   ; /ExitCode = 0
0040112B  |. E8 A6000000    CALL <JMP.&USER32.PostQuitMessage>       ; /PostQuitMessage
00401130  |. EB 79          JMP SHORT 4.004011AB
00401132  |> 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],111
00401139  |. 75 5B          JNZ SHORT 4.00401196
0040113B  |. 8B45 10        MOV EAX,DWORD PTR SS:[EBP+10]
0040113E  |. 66:83F8 01     CMP AX,1
00401142  |. 75 2B          JNZ SHORT 4.0040116F
00401144  |. 68 70454000    PUSH 4.00404570                          ; /FileName = "Shell32"
00401149  |. E8 B8000000    CALL <JMP.&KERNEL32.LoadLibraryA>        ; /LoadLibraryA
0040114E  |. 68 64454000    PUSH 4.00404564                          ; /ProcNameOrOrdinal = "ShellAboutA"
00401153  |. 50             PUSH EAX                                 ; |hModule
00401154  |. E8 A7000000    CALL <JMP.&KERNEL32.GetProcAddress>      ; /GetProcAddress
00401159  |. FF35 90304000  PUSH DWORD PTR DS:[403090]
0040115F  |. 68 5A454000    PUSH 4.0040455A                          ;  ASCII "By CaptRE"
00401164  |. 68 11454000    PUSH 4.00404511                          ;  ASCII "CaptREsReMe1"
00401169  |. 6A 00          PUSH 0
0040116B  |. FFD0           CALL EAX
0040116D  |. EB 3C          JMP SHORT 4.004011AB
0040116F  |> 66:83F8 02     CMP AX,2
00401173  |. 75 36          JNZ SHORT 4.004011AB
00401175  |. 6A 24          PUSH 24                                  ; /Style = MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL
00401177  |. 68 11454000    PUSH 4.00404511                          ; |Title = "CaptREsReMe1"
0040117C  |. 68 3E454000    PUSH 4.0040453E                          ; |Text = "Do you really want to exit?"
00401181  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
00401183  |. E8 48000000    CALL <JMP.&USER32.MessageBoxA>           ; /MessageBoxA
00401188  |. 83F8 06        CMP EAX,6
0040118B  |. 75 07          JNZ SHORT 4.00401194
0040118D  |. 6A 00          PUSH 0                                   ; /ExitCode = 0
0040118F  |. E8 5A000000    CALL <JMP.&KERNEL32.ExitProcess>         ; /ExitProcess
00401194  |> EB 15          JMP SHORT 4.004011AB
00401196  |> FF75 14        PUSH DWORD PTR SS:[EBP+14]               ; /lParam
00401199  |. FF75 10        PUSH DWORD PTR SS:[EBP+10]               ; |wParam
0040119C  |. FF75 0C        PUSH DWORD PTR SS:[EBP+C]                ; |Message
0040119F  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004011A2  |. E8 11000000    CALL <JMP.&USER32.DefWindowProcA>        ; /DefWindowProcA
004011A7  |. C9             LEAVE
004011A8  |. C2 1000        RETN 10
004011AB  |> 33C0           XOR EAX,EAX
004011AD  |. C9             LEAVE
004011AE  /. C2 1000        RETN 10
004011B1     CC             INT3
004011B2   $-FF25 38204000  JMP DWORD PTR DS:[<&USER32.CreateWindowE>;  USER32.CreateWindowExA
004011B8   $-FF25 28204000  JMP DWORD PTR DS:[<&USER32.DefWindowProc>;  USER32.DefWindowProcA
004011BE   $-FF25 30204000  JMP DWORD PTR DS:[<&USER32.DispatchMessa>;  USER32.DispatchMessageA
004011C4   $-FF25 2C204000  JMP DWORD PTR DS:[<&USER32.GetMessageA>] ;  USER32.GetMessageA
004011CA   $-FF25 24204000  JMP DWORD PTR DS:[<&USER32.LoadCursorA>] ;  USER32.LoadCursorA
004011D0   $-FF25 1C204000  JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ;  USER32.MessageBoxA
004011D6   $-FF25 18204000  JMP DWORD PTR DS:[<&USER32.PostQuitMessa>;  USER32.PostQuitMessage
004011DC   $-FF25 34204000  JMP DWORD PTR DS:[<&USER32.RegisterClass>;  USER32.RegisterClassExA
004011E2   .-FF25 3C204000  JMP DWORD PTR DS:[<&USER32.ShowWindow>]  ;  USER32.ShowWindow
004011E8   $-FF25 20204000  JMP DWORD PTR DS:[<&USER32.UpdateWindow>>;  USER32.UpdateWindow
004011EE   .-FF25 10204000  JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>;  kernel32.ExitProcess
004011F4   $-FF25 0C204000  JMP DWORD PTR DS:[<&KERNEL32.GetCommandL>;  kernel32.GetCommandLineA
004011FA   $-FF25 08204000  JMP DWORD PTR DS:[<&KERNEL32.GetModuleHa>;  kernel32.GetModuleHandleA
00401200   $-FF25 04204000  JMP DWORD PTR DS:[<&KERNEL32.GetProcAddr>;  kernel32.GetProcAddress
00401206   $-FF25 00204000  JMP DWORD PTR DS:[<&KERNEL32.LoadLibrary>;  kernel32.LoadLibraryA
0040120C     00             DB 00
0040120D     00             DB 00
0040120E     00             DB 00
0040120F     00             DB 00
00401210     00             DB 00
00401211     00             DB 00
00401212     00             DB 00
00401213     00             DB 00
00401214     00             DB 00
00401215     00             DB 00
00401216     00             DB 00
00401217   . 6C 6F 61 64 2E>ASCII "load.dll",0                       ; dll名
00401220     00             DB 00
00401221   . 62 62 62 00    ASCII "bbb",0                            ; 要调用的函数名
00401225     00             DB 00
00401226     00             DB 00
00401227     00             DB 00
00401228     00             DB 00
00401229     00             DB 00
0040122A     00             DB 00
0040122B   > 60             PUSHAD                                   ; 保护环境
0040122C   . 68 17124000    PUSH 4.00401217                          ; /FileName = "load.dll"
00401231   . FF15 00204000  CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; /LoadLibraryA
00401237   . 85C0           TEST EAX,EAX                             ; 加载是否成功
00401239   . 74 15          JE SHORT 4.00401250
0040123B   . 68 21124000    PUSH 4.00401221                          ; /ProcNameOrOrdinal = "bbb"
00401240   . 50             PUSH EAX                                 ; |hModule
00401241   . FF15 04204000  CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; /GetProcAddress
00401247   . 85C0           TEST EAX,EAX                             ; 得到了函数地址?
00401249   . 74 05          JE SHORT 4.00401250                      ; 没得到跳
0040124B   . FF75 B0        PUSH DWORD PTR SS:[EBP-50]               ; 窗口句饼
0040124E   . FFD0           CALL EAX                                 ; 子类化函数
00401250   > 61             POPAD
00401251   . 6A 01          PUSH 1                                   ; /ShowState = SW_SHOWNORMAL
00401253   . FF75 B0        PUSH DWORD PTR SS:[EBP-50]               ; |hWnd
00401256   . FF15 3C204000  CALL DWORD PTR DS:[<&USER32.ShowWindow>] ; /ShowWindow ;这里是修补原来被NOP了的函数
0040125C   . 68 F3104000    PUSH 4.004010F3
00401261   . C3             RETN                                     ;  RET used as a jump to 004010F3

下面就是写dll了,代码如下:
; code:lnn1123
; Date:2006.3
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.586
Option CaseMap: None
.Model Flat, StdCall
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      include /masm32/include/windows.inc
      include /masm32/include/user32.inc
      include /masm32/include/kernel32.inc
      include /masm32/include/gdi32.inc
      include /masm32/include/masm32.inc
      include /masm32/include/comdlg32.inc
      include /masm32/include/Comctl32.inc
      include /masm32/include/shell32.inc
; lib  
      includelib /masm32/lib/user32.lib
      includelib /masm32/lib/kernel32.lib
      includelib /masm32/lib/gdi32.lib
      includelib /masm32/lib/masm32.lib
      includelib /masm32/lib/comdlg32.lib
      includelib /masm32/lib/Comctl32.lib
      includelib /masm32/lib/shell32.lib

IDD_DLG1    equ 1000
IDC_EDT1    equ 1002
IDC_Open    equ 1001
IDC_oK      equ 1003
IDC_eXit    equ 1004
Detour      equ 3
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    .data?
szFileName                  db  MAX_PATH dup (?)
hInstance            DWORD  ?
Old_Window_Main_Proc    DWORD  ?  
EIDC_oK                         DWORD  ?
hWinMain                  dd  ?
.const
open                            db "open",0
szExtPe                          db  'PE Files',0,'*.exe;*.dll;*.scr;*.fon;*.drv',0
                    db  'All Files(*.*)',0,'*.*',0,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    .code
DialogProc        proto :DWORD,:DWORD,:DWORD,:DWORD
Window_Main_Proc  proto :DWORD,:DWORD,:DWORD,:DWORD
bbb               proto :DWORD
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; dll 的入口函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DllEntry  proc  _hInstance,_dwReason,_dwReserved

    mov  eax,TRUE
    ret

DllEntry  Endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 对话框消息处理过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DialogProc  proc hDlg :HWND, uMsg :UINT, wParam :WPARAM, lParam :LPARAM
    mov  eax,uMsg
    .if  eax == WM_CLOSE
      invoke  EndDialog,hDlg,NULL
    .elseif  eax == WM_INITDIALOG
                  push hDlg
                  pop  hWinMain
                  invoke GetDlgItem, hDlg, IDC_oK
                  mov EIDC_oK,eax
    .elseif  eax == WM_COMMAND
      mov  eax,wParam
      .if  ax ==  IDC_Open
        call _OpenFile
                        invoke EnableWindow,EIDC_oK,TRUE

      .elseif  ax ==  IDC_oK
                       invoke ShellExecute,hDlg,offset open,offset szFileName,NULL,NULL,SW_SHOW ;运行打开的程序               

                  .elseif ax==IDC_eXit
                           invoke  EndDialog,hDlg,NULL         
              .endif
    .else
      mov  eax,FALSE
      ret
    .endif
    mov  eax,TRUE
    ret

DialogProc  endp
_OpenFile  proc
    local  @stOF:OPENFILENAME
    local  @hFile,@dwFileSize,@hMapFile,@lpMemory

    invoke  RtlZeroMemory,addr @stOF,sizeof @stOF
    mov  @stOF.lStructSize,sizeof @stOF
    push  hWinMain
    pop  @stOF.hwndOwner
    mov  @stOF.lpstrFilter,offset szExtPe   ;填写结构体字段
    mov  @stOF.lpstrFile,offset szFileName  ;TOO
    mov  @stOF.nMaxFile,MAX_PATH            ;TOO
    mov  @stOF.Flags,OFN_PATHMUSTEXIST or OFN_FILEMUSTEXIST ;TOO
    invoke  GetOpenFileName,addr @stOF         ;打开文件
    .if  ! eax
      jmp  @F
    .endif
               invoke  SetDlgItemText,hWinMain,IDC_EDT1,OFFSET szFileName ;设置 edit编辑框文本为打开的文件名
               invoke  CreateFile,addr szFileName,GENERIC_READ,FILE_SHARE_READ or /
      FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
               .if  eax !=  INVALID_HANDLE_VALUE   ;文件打开错误?
                  mov  @hFile,eax
                  invoke  CloseHandle,@hFile
               .endif            
                               
                  
@@:
    ret

_OpenFile  endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 下面的这个子程序还是用dummy的
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Window_Main_Proc proc hWnd :HWND, uMsg :UINT, wParam :WPARAM, lParam :LPARAM
        mov    ecx, [uMsg]
        cmp    ecx, WM_COMMAND
        jne    @F
        mov    ebx, [wParam]
        shr    ebx, 16
        cmp    bx, BN_CLICKED
        je    _MAIN_bn_clicked
        cmp    bx, EN_CHANGE
        jne    @F
;        invoke  InvalidateRect, lParam, NULL, TRUE
        jmp    @F
  _MAIN_bn_clicked:
        cmp    [wParam], Detour
        je    NewDlg    ;按的是 Detour?
                                jmp         @F            ;不是就给原来窗口处理过程处理

NewDlg:
        invoke  DialogBoxParam, 10000000h, IDD_DLG1,hWnd, addr DialogProc, 0;创建一个对话框
        xor    eax, eax
        ret


  @@:
        invoke  CallWindowProc, Old_Window_Main_Proc, hWnd, uMsg, wParam, lParam
        ret
Window_Main_Proc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; dll 的导出函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bbb    proc         aa :HWND
        
        invoke  SetWindowLong, aa, GWL_WNDPROC, Window_Main_Proc ;子类化窗口
        mov    Old_Window_Main_Proc, eax                ;保存原来窗口函数入口
        ret
bbb ENDP
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
End  DllEntry看一下修改后的样子
 
这样就实现了窗口子类化,完成了相应功能,但是还有一个问题没有弄好
When executed, the RunDialog should show the Icon
of the ReverseMe. You MUST do this by pushing the handle of the Icon to the
call of your function inside your DLL
这个不知道怎么实现,当我把dll 和目标文件放在一起的时候.exe文件的图标也没有了,不知道为什么.
END
                                                                                     lnn1123 2006.3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值