Delphi逆向工程筆記[6]――關於String區域性變數
Delphi逆向工程筆記[6]
先廢話一會。本來這篇東西昨天晚上寫好的,但是打算發時發現論壇上不去了。一直到剛才才開啟。不知道是不是被dos了,還是檢修什麼的……
==================================================================
下面處理MainProc。規矩照舊。
0000:00404A44 sub_404A44 proc near
0000:00404A44
0000:00404A44 Paint = PAINTSTRUCT ptr -4Ch
0000:00404A44 wParam = dword ptr -0Ch
//這裡看起來是個callback的引數,但實際上是一個HFONT。這從下面對
//WM_INITDIALOG的分析可以看到。
0000:00404A44 pt = POINT ptr -8
0000:00404A44 hWnd = dword ptr 8
0000:00404A44 arg_4 = dword ptr 0Ch
0000:00404A44 arg_8 = dword ptr 10h
0000:00404A44 arg_C = word ptr 14h
0000:00404A44
0000:00404A44 push ebp
0000:00404A45 mov ebp, esp
0000:00404A47 add esp, 0FFFFFFB4h
0000:00404A4A push ebx
0000:00404A4B push esi
0000:00404A4C push edi
0000:00404A4D mov esi, [ebp+hWnd]
0000:00404A50 xor ebx, ebx
0000:00404A52 mov eax, [ebp+arg_4]
0000:00404A55 cmp eax, 133h ; WM_CTLCOLOREDIT
0000:00404A5A jg short loc_404A87
0000:00404A5C jz loc_404CB3
0000:00404A62 sub eax, 0Fh ; WM_PAINT
0000:00404A65 jz loc_404BD6
0000:00404A6B sub eax, 1Ch ; WM_DRAWITEM
0000:00404A6E jz loc_404C86
0000:00404A74 sub eax, 0E5h ; WM_INITDIALOG
0000:00404A79 jz short loc_404AAB
0000:00404A7B dec eax ; WM_COMMAND
0000:00404A7C jz loc_404C0B
0000:00404A82 jmp loc_404CF5
0000:00404A87 loc_404A87:
0000:00404A87 sub eax, 136h ; WM_CTLCOLORDLG
0000:00404A8C jz loc_404C92
0000:00404A92 sub eax, 2 ; WM_CTLCOLORSTATIC
0000:00404A95 jz loc_404CD4
0000:00404A9B sub eax, 0C9h ; WM_LBUTTONDOWN
0000:00404AA0 jz loc_404B95
0000:00404AA6 jmp loc_404CF5
0000:00404CF5 loc_404CF5:
0000:00404CF5 xor ebx, ebx
0000:00404CF7 loc_404CF7:
0000:00404CF7 mov eax, ebx
0000:00404CF9 pop edi
0000:00404CFA pop esi
0000:00404CFB pop ebx
0000:00404CFC mov esp, ebp
0000:00404CFE pop ebp
0000:00404CFF retn 10h
0000:00404CFF sub_404A44 endp
於是有:
Function MainProc(hDlg:HWND;Msg,wParam,lParam:DWORD):LRESULT;stdcall;
Var
sPaint:PAINTSTRUCT;
sPoint:TPoint;
LFont:HFONT;
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;
WM_CTLCOLOREDIT:
Begin
End;
End;
End;
由於這裡和LicenseProc總體差別不大,所以就把大致相同或比較簡單的部分直
接給出,不一一分析了。
WM_CTLCOLOREDIT:
Begin
SetTextColor(wParam,$A0A0A0);
SetBkMode(wParam,TRANSPARENT);
Result:=h_Brush;
End;
WM_PAINT:
Begin
Paint(BeginPaint(hDlg,sPaint),h_Icon,szMainCaption,$767676,0,sRECTM);
EndPaint(hDlg,sPaint);
End;
WM_DRAWITEM:
Begin
ItemDraw(PDrawItemStruct(lParam));
Result:=0;
End;
WM_CTLCOLORDLG:
Begin
SetTextColor(wParam,$A0A0A0);
SetBkMode(wParam,TRANSPARENT);
Result:=h_Brush;
End;
WM_CTLCOLORSTATIC:
Begin
SetTextColor(wParam,$A0A0A0);
SetBkMode(wParam,TRANSPARENT);
Result:=h_Brush;
End;
WM_LBUTTONDOWN:
Begin
sPoint.x:=lParam AND $FFFF;
sPoint.y:=lParam SHR 16;
If PtInRect(sRectM,sPoint) Then
Begin
PostMessage(hDlg,WM_NCLBUTTONDOWN,2,0);
End;
End;
WM_COMMAND:
Begin
Case wParam of
MAIN_CALC:
Begin
GetDlgItemText(hDlg,$7DA,@RegName,255);
GetRegCode;
SetDlgItemText(hDlg,$7D9,@RegCode);
End;
MAIN_EXIT:
Begin
EndDialog(hDlg,0);
End;
MAIN_about :
Begin
MessageBeep(0);
DialogBox(h_Inst,LPCTSTR(IDD_ABOUTDLG),0,@AboutProc);
End;
MAIN_CLOSE:
Begin
EndDialog(hDlg,0);
End;
End;
End;
注意,MAIN_CALC的處理,特別是GetRegCode,肯定和原文不同(個人愛好)。原
文是帶一個PChar引數的。
餘下的部分就是WM_INITDIALOG和關於對話方塊部分了。
先反WM_INITDIALOG:
000:00404AAB loc_404AAB:
0000:00404AAB push offset stru_4060DC ; lpRect
//這裡和LicenseProc一樣,都用了全域性的Rect。當時沒有反到這裡,所以名字取得
//不是很好。
0000:00404AB0 push esi ; hWnd
0000:00404AB1 call GetClientRect
0000:00404AB6 mov eax, ds:stru_4060DC.top
0000:00404ABB add eax, 14h
0000:00404ABE mov ds:stru_4060DC.bottom, eax
0000:00404AC3 push offset dword_404D04 ; lpString
0000:00404AC8 push 7DBh ; nIDDlgItem
0000:00404ACD push esi ; hDlg
0000:00404ACE call SetDlgItemTextA
//主頁連線
0000:00404AD3 push offset loc_404D1C ; lpString
0000:00404AD8 push 7D8h ; nIDDlgItem
0000:00404ADD push esi ; hDlg
0000:00404ADE call SetDlgItemTextA
//時間
0000:00404AE3 push (offset loc_404D25+3) ; lpString
//這裡的話,其實是IDA在發飈。因為所謂的loc_404D25根本不是什麼程式碼,而是常
//量。誤判。
0000:00404AE8 push 7D5h ; nIDDlgItem
0000:00404AED push esi ; hDlg
0000:00404AEE call SetDlgItemTextA
//軟體名
0000:00404AF3 push offset dword_404D38 ; lpString
0000:00404AF8 push 7D6h ; nIDDlgItem
0000:00404AFD push esi ; hDlg
0000:00404AFE call SetDlgItemTextA
//開發者
0000:00404B03 push offset dword_404D4C ; lpString
0000:00404B08 push 7D7h ; nIDDlgItem
0000:00404B0D push esi ; hDlg
0000:00404B0E call SetDlgItemTextA
//解密者
0000:00404B13 push offset dword_404D5C ; lpString
0000:00404B18 push 7DCh ; nIDDlgItem
0000:00404B1D push esi ; hDlg
0000:00404B1E call SetDlgItemTextA
//KeyGen的版權所有者
0000:00404B23 push offset dword_404D84 ; lpString
0000:00404B28 push esi ; hWnd
0000:00404B29 call SetWindowTextA
//視窗的標題
0000:00404B2E push offset nullsub_4 ; LPCSTR
//發飈
0000:00404B33 push 0 ; DWORD
0000:00404B35 push 0 ; DWORD
0000:00404B37 push 0 ; DWORD
0000:00404B39 push 0 ; DWORD
0000:00404B3B push 1 ; DWORD
0000:00404B3D push 0 ; DWORD
0000:00404B3F push 1 ; DWORD
0000:00404B41 push 0 ; DWORD
0000:00404B43 push 2BCh ; int
0000:00404B48 push 0 ; int
0000:00404B4A push 0 ; int
0000:00404B4C push 0 ; int
0000:00404B4E push 0FFFFFFF4h ; int
0000:00404B50 call CreateFontA
0000:00404B55 mov [ebp+wParam], eax
//沒什麼說的
0000:00404B58 push 7DBh ; nIDDlgItem
0000:00404B5D push esi ; hDlg
0000:00404B5E call GetDlgItem
//這裡是從ID得到HWND
0000:00404B63 mov edi, eax
0000:00404B65 push 0 ; lParam
0000:00404B67 mov eax, [ebp+wParam]
0000:00404B6A push eax ; wParam
0000:00404B6B push 30h ; Msg
0000:00404B6D push edi ; hWnd
0000:00404B6E call SendMessageA
//設定字型
0000:00404B73 push offset sub_4043FC ; dwNewLong
0000:00404B78 push 0FFFFFFFCh ; nIndex
0000:00404B7A push edi ; hWnd
0000:00404B7B call SetWindowLongA
0000:00404B80 push eax ; dwNewLong
0000:00404B81 push 0FFFFFFEBh ; nIndex
0000:00404B83 push edi ; hWnd
0000:00404B84 call SetWindowLongA
//設定超連線效果callback
0000:00404B89 mov eax, esi ; hWnd
0000:00404B8B call sub_404358
//其實就是LicenseProc最後的那個call
0000:00404B90 jmp loc_404CF7
超連線的callback:
0000:004043FC sub_4043FC proc near
0000:004043FC
0000:004043FC hWnd = dword ptr 8
0000:004043FC arg_4 = dword ptr 0Ch
0000:004043FC wParam = dword ptr 10h
0000:004043FC lParam = dword ptr 14h
0000:004043FC
0000:004043FC push ebp
0000:004043FD mov ebp, esp
0000:004043FF push ebx
0000:00404400 push esi
0000:00404401 mov ebx, [ebp+arg_4]
0000:00404404 mov esi, 1
//現在esi是返回值,下面可以看到
0000:00404409 mov eax, ebx
0000:0040440B sub eax, 20h
//WM_SETCURSOR
0000:0040440E jz short loc_404439
0000:00404410 sub eax, 64h
//WM_NCHITTEST
0000:00404413 jz short loc_404432
0000:00404415 sub eax, 17Eh
//WM_LBUTTONUP
0000:0040441A jnz short loc_404446
//還不是就去預設處理
0000:0040441C push 0 ; nShowCmd
0000:0040441E push 0 ; lpDirectory
0000:00404420 push 0 ; lpParameters
0000:00404422 push offset dword_40446C ; lpFile
0000:00404427 push 0 ; lpOperation
0000:00404429 push 0 ; hwnd
0000:0040442B call ShellExecuteA
0000:00404430 jmp short loc_404464
0000:00404432
0000:00404432 loc_404432:
0000:00404432 mov esi, 1
0000:00404437 jmp short loc_404464
0000:00404439
0000:00404439 loc_404439:
0000:00404439 mov eax, ds:hCursor
0000:0040443E push eax ; hCursor
0000:0040443F call SetCursor
0000:00404444 jmp short loc_404464
0000:00404446
0000:00404446 loc_404446:
0000:00404446 push 0FFFFFFEBh ; nIndex
0000:00404448 mov eax, [ebp+hWnd]
0000:0040444B push eax ; hWnd
0000:0040444C call GetWindowLongA
0000:00404451 mov edx, [ebp+lParam]
0000:00404454 push edx ; lParam
0000:00404455 mov edx, [ebp+wParam]
0000:00404458 push edx ; wParam
0000:00404459 push ebx ; Msg
0000:0040445A mov edx, [ebp+hWnd]
0000:0040445D push edx ; hWnd
0000:0040445E push eax ; lpPrevWndFunc
0000:0040445F call CallWindowProcA
0000:00404464
0000:00404464 loc_404464:
0000:00404464 mov eax, esi
0000:00404466 pop esi
0000:00404467 pop ebx
0000:00404468 pop ebp
0000:00404469 retn 10h
0000:00404469 sub_4043FC endp
PS:其實這個函式在laoqian的文章裡有,是他寫的。不過這裡還是逆一下。那
麼,下面就給出WM_INITDIALOG和LinkProc:
WM_INITDIALOG:
Begin
GetClientRect(hDlg,sRectM);
sRectM.Bottom:=sRectM.Top+$14;
SetDlgItemText(hDlg,2011,szLink);
SetDlgItemText(hDlg,2008,szTime);
SetDlgItemText(hDlg,2005,szName);
SetDlgItemText(hDlg,2006,szBy);
SetDlgItemText(hDlg,2007,szCracker);
SetDlgItemText(hDlg,2012,szCopyright);
SetWindowText(hDlg,szMainCaption);
LFont:=CreateFont(-$C,0,0,0,$2BC,0,1,0,1,0,0,0,0,'宋體');
LinkHWND:=GetDlgItem(hDlg,2011);
SendMessage(LinkHWND,WM_SETFONT,LFont,0);//設定字型
SetLongRet:=SetWindowLong(LinkHWND,GWL_WNDPROC,LongWord(@LinkProc));
SetWindowLong(LinkHWND,GWL_USERDATA,SetLongRet);
DialogInit(hDlg);
End;
Function LinkProc(hDlg:HWND;Msg,wParam,lParam:DWORD):LRESULT;stdcall;
Begin
Result:=1;
Case Msg of
WM_SETCURSOR:
Begin
SetCursor(h_Cur);
End;
WM_NCHITTEST:
Begin
Result:=1;
End;
WM_LBUTTONUP:
Begin
ShellExecute(0,nil,szLink,nil,nil,0);//偷了點懶
End;
Else
Begin
CallWindowProc(Pointer(GetWindowLong(hDlg,GWL_USERDATA)),hDlg,Msg,wParam,lParam);
End;
End;
End;
還好有IDA,要不對照xRef肯定累死。
OK,還剩下最後的About對話方塊。請耐心等待,最遲不超過2周!
補充:
1、如果AboutProc為空,那麼整個MainDLG都顯示不正常的。
2、laoqian說沒有逆出實時顯示註冊碼部分。這是因為我分析的版本是老的,不
是那個2in1。所以裡面沒有實時顯示的部分。新版一時找不到。不過恰好我以前寫過
一個SDK程式,裡面用到了Notification。所以,我還是自己寫吧:
要實時顯示註冊碼,就必須監測Edit內容的改變。這是被稱為Notification的。
寫過相關程式的人都知道,當選單的某項被選中,一個子控制元件向父視窗傳送一個
Notification,或者快捷鍵被按時,事件處理程式就會接到WM_COMMAND訊息。這時,
wParam的低16位指明瞭選單/子控制元件/快捷鍵的ID,而高16位則在wParam的低16位指明
了子控制元件的時候,存放Notification。就是說,判斷ID時應該使用wParam的低位。但
是一般我們見到的KeyGen模板都是直接用wParam的。那麼高位呢?原因是:一般情況
下,我們只用到了Button和Label。但是在Button的Notification裡有以下一條定義:
{ Button Notification Codes }
const
{$EXTERNALSYM BN_CLICKED}
BN_CLICKED = 0;
這樣,如果只是簡單地按個按鈕,Notification為BN_CLICKED,wParam就肯定等
於ID了。
下面就是修改的程式碼:
Case wParam AND $FFFF of
$7DA://就是RegName的ID,感覺越來越懶了……
Begin
Case wParam SHR 16 of
EN_CHANGE:
Begin
GetDlgItemText(hDlg,$7DA,@RegName,255);
GetRegCode;
SetDlgItemText(hDlg,$7D9,@RegCode);
End;
End;
End;
End;
=========================================================================非
相關文章
- Delphi逆向工程筆記[1]2004-10-27筆記
- Delphi逆向工程筆記[2]2004-10-27筆記
- Delphi逆向工程筆記[3]2004-10-27筆記
- Delphi逆向工程筆記[4]2004-10-28筆記
- Delphi逆向工程筆記[5]2004-11-11筆記
- Delphi逆向工程筆記[7](終結篇)2004-11-21筆記
- 全域性變數與區域性變數2019-10-21變數
- C語言區域性變數、全域性變數、靜態區域性變數、靜態全域性變數2017-11-21C語言變數
- Java區域性變數與全域性變數2018-12-21Java變數
- java 全域性變數和區域性變數2018-07-27Java變數
- JavaScript —— 區域性變數和全域性變數2013-07-20JavaScript變數
- jmeter全域性變數和區域性變數2024-04-02JMeter變數
- 【c】全域性變數與區域性變數2024-08-20變數
- 記一個全域性變數"冒充"區域性變數引起的bug2013-07-18變數
- javascript中的作用域(全域性變數和區域性變數)2018-05-22JavaScript變數
- python全域性變數與區域性變數2013-03-22Python變數
- 成員變數和區域性變數2024-03-16變數
- JavaScript五:全域性變數&區域性變數;運算子2020-12-27JavaScript變數
- python全域性變數和區域性變數, global2017-03-07Python變數
- 成員變數和區域性變數的區別2017-03-23變數
- iOS 靜變數static、全域性變數extern、區域性變數、例項變數2016-05-13iOS變數
- Python中的全域性變數和區域性變數2018-10-05Python變數
- js-js的全域性變數和區域性變數2018-11-01JS變數
- Python全域性變數與區域性變數詳解2013-07-22Python變數
- 詳解python 區域性變數與全域性變數2012-12-20Python變數
- 記憶體分配知識(全域性,區域性,靜態變數)2013-03-07記憶體變數
- 成員變數、全域性變數、例項變數、類變數、靜態變數和區域性變數的區別2018-03-03變數
- Python的區域性變數和全域性變數使用解惑2017-08-16Python變數
- Python中類變數、成員變數、區域性變數的區別2020-10-10Python變數
- 區域性變數和全域性變數(靜態和非靜態)區別2020-10-27變數
- Python的全域性和區域性變數2018-01-03Python變數
- 【Java貓說】例項變數與區域性變數2019-01-19Java變數
- 筆記:MyBatis逆向工程 - Win/Mac2018-09-28筆記MyBatisMac
- Java基礎-成員變數和區域性變數的區別2017-03-07Java變數
- 程式程式碼,常量,區域性變數,全域性變數在記憶體中的儲存位置2011-12-17變數記憶體
- python學習筆記 區域性和全域性作用域2019-03-20Python筆記
- 十二、變數作用域:區域性變數、全域性變數,函式版名片管理系統—新增函式文件2018-07-23變數函式
- Android中全域性變數與區域性變數的使用總結2015-01-07Android變數