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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章