抱歉,刚才把没有整理完全的发了。
=================================================================================
下面处理WM_INITDIALOG。
0000:00404E2B loc_404E2B:
0000:00404E2B push offset sRect ; lpRect
//注意,这里是我手动改名的结果。
//sRect是一个全局变量,这从下面对它的引用也可以看出来。
0000:00404E30 mov eax, [ebp+hWnd]
0000:00404E33 push eax ; hWnd
0000:00404E34 call GetClientRect
//这里没有什么好说的。
0000:00404E39 mov eax, ds:sRect.top
0000:00404E3E add eax, 14h
0000:00404E41 mov ds:sRect.bottom, eax
//这里好象是得到一个新的RECT,高度是14。估计是一个标题栏。
因为程序没有用系统的标题栏,而是自己画了一个。
0000:00404E46 push offset word_404F98 ; lpString
0000:00404E4B mov eax, [ebp+hWnd]
0000:00404E4E push eax ; hWnd
0000:00404E4F call SetWindowTextA
0000:00404E54 push offset aBbbbA ; lpString
0000:00404E59 push 3EDh ; nIDDlgItem
0000:00404E5E mov eax, [ebp+hWnd]
0000:00404E61 push eax ; hDlg
0000:00404E62 call SetDlgItemTextA
//授权协议。但奇怪的是协议本身可以看到,那个标题看不到。
//怀疑是目前rip出的代码不完整,缺了WM_PAINT和WM_DRAWITEM。
0000:00404E67 mov eax, [ebp+hWnd] ; hWnd
0000:00404E6A call sub_404358
//这是一个奇怪的call,从其代码可以看到,eax是入口参数。
//而且它是一个公用子程序。
0000:00404E6F mov ebx, 1
//这里就必须返回1说明消息已经处理了。
0000:00404E74 jmp loc_404F8F
OK,下面就是WM_INITDIALOG了:
WM_INITDIALOG:
Begin
GetClientRect(hDlg,sRect);
sRect.Bottom:=sRect.Top+$14;
SetWindowText(hDlg,szLicenseCaption);
SetDlgItemText(hDlg,1005,szLicenseText);
DialogInit(hDlg);
//暂且叫这个名字吧。
Result:=1;
End;
好,来看看那个奇怪的call:
0000:00404358 ; int __fastcall sub_404358(HWND hWnd)
0000:00404358 sub_404358 proc near
0000:00404358
0000:00404358
0000:00404358 X = word ptr -14h
0000:00404358 Y = word ptr -12h
0000:00404358 Rect = tagRECT ptr -10h
//这些局部变量也被改名了,目的是便于阅读分析。
0000:00404358
0000:00404358 push ebx
0000:00404359 push esi
0000:0040435A push edi
0000:0040435B push ebp
0000:0040435C add esp, 0FFFFFFECh
//这里相当于sub esp,14h。真不知道Borland那帮人是怎么想的。
//实际上,如果后面没有push,这句就是多余的。这是编译器优化的结果。
//PS:记得TP里是用bp做Local指针的。
0000:0040435F mov edi, eax
0000:00404361 push 0 ; nCmdShow
0000:00404363 push edi ; hWnd
0000:00404364 call ShowWindow
0000:00404369 lea eax, [esp+14h+Rect]
//esp+14h,明白了?
0000:0040436D push eax ; lpRect
0000:0040436E push edi ; hWnd
0000:0040436F call GetWindowRect
0000:00404374 mov eax, [esp+14h+Rect.right]
//因为API是自己处理esp,所以这里依然是+14h
0000:00404378 mov edx, eax
0000:0040437A sub edx, [esp+14h+Rect.left]
0000:0040437E sar edx, 1
0000:00404380 jns short loc_404385
0000:00404382 adc edx, 0
//OK,这里其实就是取Rect的X轴方向中点。
//sar移过以后,最高位是保持原来的,所以要判断一下,如果<0就
//加回来。这个组合比较巧妙。
//Borland那帮人确实与众不同!
0000:00404385
0000:00404385 loc_404385:
0000:00404385 mov [esp+14h+X], dx
0000:00404389 mov edx, [esp+14h+Rect.bottom]
0000:0040438D sub edx, [esp+14h+Rect.top]
0000:00404391 sar edx, 1
0000:00404393 jns short loc_404398
0000:00404395 adc edx, 0
0000:00404398
0000:00404398 loc_404398:
0000:00404398 mov [esp+14h+Y], dx
0000:0040439D mov ebp, eax
//这里eax等于Rect.right
0000:0040439F sar ebp, 1
0000:004043A1 jns short loc_4043A6
0000:004043A3 adc ebp, 0
0000:004043A6
0000:004043A6 loc_4043A6:
0000:004043A6 test bp, bp
//应该是进一步保证bp>0,结合下面可以看到,bp是循环变量
0000:004043A9 jl short loc_4043F2
0000:004043AB inc ebp
0000:004043AC xor ebx, ebx
//因为ebp在循环体内没有用到,所以可以和ebx合并处理
0000:004043AE
0000:004043AE loc_4043AE:
//循环体就没有什么值得注意的地方了,顶多是注意寄存器的变化
0000:004043AE movsx ecx, [esp+14h+Y]
0000:004043B3 movsx eax, bx
0000:004043B6 add ecx, eax
0000:004043B8 push ecx ; int
0000:004043B9 movsx edx, [esp+18h+X]
//因为上面push了一下。所以偏移要修改。当时分析时一时没看出来
0000:004043BE mov ecx, edx
0000:004043C0 add ecx, eax
0000:004043C2 push ecx ; int
0000:004043C3 movsx ecx, [esp+1Ch+Y]
//这里也是
0000:004043C8 sub ecx, eax
0000:004043CA push ecx ; int
0000:004043CB sub edx, eax
0000:004043CD push edx ; int
0000:004043CE call CreateRectRgn
0000:004043D3 mov esi, eax
0000:004043D5 push 0FFFFFFFFh ; bRedraw
0000:004043D7 push esi ; hRgn
0000:004043D8 push edi ; hWnd
0000:004043D9 call SetWindowRgn
0000:004043DE push 5 ; nCmdShow
0000:004043E0 push edi ; hWnd
0000:004043E1 call ShowWindow
0000:004043E6 push esi ; HGDIOBJ
0000:004043E7 call DeleteObject
0000:004043EC inc ebx
0000:004043ED dec bp
0000:004043F0 jnz short loc_4043AE
0000:004043F2
0000:004043F2 loc_4043F2:
0000:004043F2 add esp, 14h
0000:004043F5 pop ebp
0000:004043F6 pop edi
0000:004043F7 pop esi
0000:004043F8 pop ebx
0000:004043F9 retn
0000:004043F9 sub_404358 endp
这样,我们就得到了那个奇怪的call。
Procedure DialogInit(hDlg:HWND);
Var
RECT:TRect;
X,Y:Word;
i:Word;
Rgn:HRGN;
Begin
ShowWindow(hDlg,SW_HIDE);
GetWindowRect(hDlg,RECT);
X:=(RECT.Right-RECT.Left) DIV 2;
Y:=(RECT.Bottom-RECT.Top) DIV 2;
For i:=1 to RECT.Right DIV 2 do
Begin
Rgn:=CreateRectRgn(X-i,Y-i,X+i,Y+i);
SetWindowRgn(hDlg,Rgn,True);
ShowWindow(hDlg,SW_SHOW);
DeleteObject(Rgn);
End;
End;
需要说明的是,这里在循环变量的处理上和原程序不一样,但是效果应该没有什么
差别(起码我的眼睛没有好到那样的程度)。
这样,我们已经可以知道那个call是干什么的了——窗口的RoomIn特效!(实际
上我是运行了才知道的,呵呵)
==================================================================
这样,我目前RE出来的部分就发完了。以后再发可能就没有这么完整的结构了,而且间隔也会加长。
抱歉,因为我不是专职做这个。