Delphi逆向工程筆記[2]

看雪資料發表於2004-10-27

自己寫的破爛居然被加精了……這裡做個說明,由於這個KeyGen的RE有點難度,目前
手上完成了的也就一點點,夠寫3篇。以後的要等我慢慢分析了。不過我保證,一定
會全部RE出來的,而且在PEDIY發全。

PS:本來是要發到CSDN的Blog上的,不過那個Blog有點爛,發不上去。於是就扔到
PEDIY來了。以為不會有人注意,結果居然被最想躲開的人看見了……實際上某人的
猜想是對的。他寫了某篇文章給我看到了,於是我就拿了某個程式開刀,幸運的是
那個程式沒有用某些軟體處理過,要不就沒有這篇破爛了。莫怪莫怪。

=================================================================================

  下面處理LicenseProc,就是sub_404DD4。為了便於檢視,這裡先把主框架rip出
來。

0000:00404DD4 sub_404DD4      proc near
0000:00404DD4
0000:00404DD4 Paint           = PAINTSTRUCT ptr -48h
0000:00404DD4 pt              = POINT ptr -8
0000:00404DD4 hWnd            = dword ptr  8
0000:00404DD4 Msg             = dword ptr  0Ch
0000:00404DD4 wParam          = dword ptr  10h
0000:00404DD4 lParam          = word ptr  14h
//4個引數,2個區域性變數
0000:00404DD4
0000:00404DD4                 push    ebp
0000:00404DD5                 mov     ebpesp
//標準的Delphi呼叫框架
0000:00404DD7                 add     esp, 0FFFFFFB8h
//這裡相當於sub esp,48h。注意上面的Paint=PAINTSTRUCT ptr -48h
//相當有趣。
0000:00404DDA                 push    ebx
0000:00404DDB                 xor     ebxebx
0000:00404DDD                 mov     eax, [ebp+Msg]
0000:00404DE0                 cmp     eax, 111h       ; WM_COMMAND
0000:00404DE5                 jg      short loc_404E0B
0000:00404DE7                 jz      loc_404EF8
//我沒有反過VC,但這裡顯然和通常的思維不大一樣。
//WM_COMMAND被當作分界線以減少判斷。
0000:00404DED                 sub     eax, 0Fh        ; WM_PAINT
//sub!居然不是cmp!
0000:00404DF0                 jz      loc_404EBD
0000:00404DF6                 sub     eax, 1Ch        ; WM_DRAWITEM
0000:00404DF9                 jz      loc_404F3F
0000:00404DFF                 sub     eax, 0E5h       ; WM_INITDIALOG
0000:00404E04                 jz      short loc_404E2B
0000:00404E06                 jmp     loc_404F8D
//這裡就退出了
0000:00404E0B loc_404E0B:
0000:00404E0B                 sub     eax, 136h       ; WM_CTLCOLORDLG
0000:00404E10                 jz      loc_404F4B
0000:00404E16                 sub     eax, 2          ; WM_CTLCOLORSTATIC
0000:00404E19                 jz      loc_404F6C
0000:00404E1F                 sub     eax, 0C9h       ; WM_LBUTTONDOWN
0000:00404E24                 jz      short loc_404E79
0000:00404E26                 jmp     loc_404F8D
//退出
...
0000:00404F8D loc_404F8D:
0000:00404F8D
0000:00404F8D                 xor     ebxebx
//下面要把ebx作為返回值的。
0000:00404F8F loc_404F8F:
0000:00404F8F
0000:00404F8F                 mov     eaxebx
0000:00404F91                 pop     ebx
0000:00404F92                 mov     espebp
0000:00404F94                 pop     ebp
0000:00404F95                 retn    10h

  結合SDK程式的寫法,得到主訊息迴圈。

Function LicenseProc(hDlg:HWND;Msg,wParam,lParam:DWORD):LRESULT;stdcall;
Var
  sPaint:PAINTSTRUCT;
Begin
  Result:=0;
  
  Case Msg of
    WM_COMMAND:
      Begin
      End;
    WM_PAINT:
      Begin
      End;
    WM_DRAWITEM:
      Begin
      End;
    WM_INITDIALOG:
      Begin
      End;
    WM_CTLCOLORDLG:
      Begin
      End;
    WM_CTLCOLORSTATIC:
      Begin
      End;
    WM_LBUTTONDOWN:
      Begin
      End;
  End;
End;

  不尋常的事發生了。它用了兩個不常見的訊息:WM_CTLCOLORDLG和
WM_CTLCOLORSTATIC。

  先看WM_COMMAND:

0000:00404EF8 loc_404EF8:
0000:00404EF8                 mov     eax, [ebp+wParam]
0000:00404EFB                 sub     eax, 3E9h
//照例是sub的把戲,反正引數是傳值的
//結合dump出的RC可以看到這是一個按鈕的ID
0000:00404F00                 jz      short loc_404F0C
0000:00404F02                 dec     eax
0000:00404F03                 jz      short loc_404F23
0000:00404F05                 sub     eax, 2
0000:00404F08                 jz      short loc_404F30
0000:00404F0A                 jmp     short loc_404F3B
0000:00404F0C loc_404F0C:
0000:00404F0C                 mov     ds:dword_4060B0, 0FFFFFFFFh
//注意這裡,這就是那個返回的Flag!因為程式開頭先把它清0了
//所以這裡只需要賦個值就可以了。注意,Delphi裡True是非0的!
0000:00404F16                 push    0               ; nResult
0000:00404F18                 mov     eax, [ebp+hWnd]
0000:00404F1B                 push    eax             ; hDlg
0000:00404F1C                 call    EndDialog
0000:00404F21                 jmp     short loc_404F3B
0000:00404F23 loc_404F23:
0000:00404F23                 push    0               ; nResult
0000:00404F25                 mov     eax, [ebp+hWnd]
0000:00404F28                 push    eax             ; hDlg
0000:00404F29                 call    EndDialog
0000:00404F2E                 jmp     short loc_404F3B
0000:00404F30 loc_404F30:
0000:00404F30                 push    0               ; nResult
0000:00404F32                 mov     eax, [ebp+hWnd]
0000:00404F35                 push    eax             ; hDlg
0000:00404F36                 call    EndDialog
0000:00404F3B
0000:00404F3B loc_404F3B:
0000:00404F3B
0000:00404F3B                 xor     ebxebx
0000:00404F3D                 jmp     short loc_404F8F

  好的,現在WM_COMMAND的處理有了。

        Case wParam of
          LICENSE_YES:
            Begin
              Flag:=True;
              EndDialog(hDlg,0);
            End;
          LICENSE_NO:
            Begin
              EndDialog(hDlg,0);
            End;
          LICENSE_CLOSE:
            Begin
              EndDialog(hDlg,0);
            End;
        End;
        
  很清楚,不是嗎?下面是WM_CTLCOLORDLG和WM_CTLCOLORSTATIC。

0000:00404F4B loc_404F4B:
0000:00404F50                 mov     eax, [ebp+wParam]
0000:00404F53                 push    eax             ; HDC
0000:00404F54                 call    SetTextColor
0000:00404F59                 push    1               ; int
0000:00404F5B                 mov     eax, [ebp+wParam]
0000:00404F5E                 push    eax             ; HDC
0000:00404F5F                 call    SetBkMode
0000:00404F64                 mov     ebxds:hbr
//這裡有點費解,從CreateSolidBrush的說明可以知道,如果函式
//失敗,返回的是null,就是false。這裡估計是利用了這點。
//一旦CreateSolidBrush失敗,這裡就可以退出了。有點意思。
0000:00404F6A                 jmp     short loc_404F8F
0000:00404F6C loc_404F6C:
0000:00404F6C                 push    0A0A0A0h        ; COLORREF
0000:00404F71                 mov     eax, [ebp+wParam]
0000:00404F74                 push    eax             ; HDC
0000:00404F75                 call    SetTextColor
0000:00404F7A                 push    1               ; int
0000:00404F7C                 mov     eax, [ebp+wParam]
0000:00404F7F                 push    eax             ; HDC
0000:00404F80                 call    SetBkMode
0000:00404F85                 mov     ebxds:hbr
0000:00404F8B                 jmp     short loc_404F8F

  給出相應的SRC:

    WM_CTLCOLORDLG:
      Begin
        SetTextColor(wParam,$A0A0A0);
        SetBkMode(wParam,TRANSPARENT);
        Result:=h_Brush;
        //如果要清楚一點可以改為Result:=h_Brush<>nil;
        //當然函式返回型別要改。
      End;
    WM_CTLCOLORSTATIC:
      Begin
        SetTextColor(wParam,$A0A0A0);
        SetBkMode(wParam,TRANSPARENT);
        Result:=h_Brush;
      End;

相關文章