首页
社区
课程
招聘
Delphi逆向工程笔记[5]
2004-11-11 22:24 15140

Delphi逆向工程笔记[5]

2004-11-11 22:24
15140
第5篇终于出来了……wuwu

今天是个特别的日子,先乱弹一番。

巴勒斯坦的英雄――亚西尔・阿拉法特去世了。在这里,谨向他致以最高敬意!

另外,今天也是中国人民解放军空军部队成立55周年纪念日!缅怀一下!想当年,新生的中国空军在朝鲜大展神威……

最后,今天和好友联系时偶尔得知她还是单身,呵呵……于是心情大好,决定今天把这篇东西赶出来。

好,废话少说,开讲!

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

抱歉,最近一直很忙,所以拖了很长时间。

这部分超长,自我感觉也是最难的部分。和这部分相比,前面的分析基本就是大路货了。请
有点耐心,否则还是请赶快离开的好。

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

  OK,LicenseProc的最后一部分――WM_PAINT。应该有却还没有的效果应该就在里
面。

0000:00404EBD loc_404EBD:
0000:00404EBD                 lea     eax, [ebp+Paint]
0000:00404EC0                 push    eax             ; lpPaint
0000:00404EC1                 mov     eax, [ebp+hWnd]
0000:00404EC4                 push    eax             ; hWnd
0000:00404EC5                 call    BeginPaint
0000:00404ECA                 push    offset sRect
0000:00404ECF                 push    0
0000:00404ED1                 push    767676h
0000:00404ED6                 mov     ecx, offset dword_4052F0
0000:00404EDB                 mov     edx, ds:dword_4076E8
//结合下面可以看到,这是一个hIcon,但奇怪的是,IDA显示没有其它的
//ref。然而我翻了一下前面的代码,发现这就是主程序的h_Icon!
//看来IDA的确有问题。

0000:00404EE1                 call    near ptr sub_403FF8
//好吧,又来一个公共call。
//记得以前专门研究过TP/Delphi的传值问题,但当时写的东西不知道丢
//哪里了。不过幸好D5的HLP已经很详细了。
//从这里看应该有5个参数,但是考虑到Register方式的特点,我怀疑还
//有第6个参数eax。从逻辑上看也应该是这样。查看sub_403FF8发现,
//需要在eax里放一个hdc,而BeginPaint的返回值就是hdc。
//那么dword_4052F0是什么呢?查看Hex可知,就是窗口标题。这样,我
//以前的一个分析就被证明是错误的,不过不影响已经得到的代码。

0000:00404EE6                 lea     eax, [ebp+Paint]
0000:00404EE9                 push    eax             ; lpPaint
0000:00404EEA                 mov     eax, [ebp+hWnd]
0000:00404EED                 push    eax             ; hWnd
0000:00404EEE                 call    EndPaint
0000:00404EF3                 jmp     loc_404F8F

  公共call:

0000:00403FF8 sub_403FF8      proc far
0000:00403FF8
0000:00403FF8 rc              = RECT ptr -50h
0000:00403FF8 var_40          = LOGBRUSH ptr -40h
0000:00403FF8 Rect            = tagRECT ptr -34h
0000:00403FF8 var_24          = word ptr -24h
//这个是循环变量
0000:00403FF8 var_22          = word ptr -22h
0000:00403FF8 var_20          = word ptr -20h
0000:00403FF8 var_1E          = word ptr -1Eh
0000:00403FF8 var_1C          = word ptr -1Ch
0000:00403FF8 var_1A          = word ptr -1Ah
0000:00403FF8 var_18          = word ptr -18h
//从var_18到var_22都用了一次
0000:00403FF8 var_16          = word ptr -16h
0000:00403FF8 var_14          = word ptr -14h
0000:00403FF8 var_12          = word ptr -12h
//上面3个有点象rgb,范围都是字节,变量
0000:00403FF8 hbr             = dword ptr -10h
//必须说明变量
0000:00403FF8 var_C           = dword ptr -0Ch
//仅用一次
0000:00403FF8 hIcon           = dword ptr -8
//内部没有改变
0000:00403FF8 hDC             = dword ptr -4
//内部没有改变
0000:00403FF8 arg_4           = dword ptr  10h
0000:00403FF8
0000:00403FF8                 push    ebp
0000:00403FF9                 mov     ebp, esp
0000:00403FFB                 add     esp, 0FFFFFFB0h
0000:00403FFE                 push    ebx
0000:00403FFF                 push    esi
0000:00404000                 push    edi
0000:00404001                 mov     esi, [ebp+arg_4]
//公共的Rect变量
0000:00404004                 lea     edi, [ebp+Rect]
//局部Rect变量
0000:00404007                 push    ecx
0000:00404008                 mov     ecx, 4
0000:0040400D                 rep movsd
0000:0040400F                 pop     ecx
//把公共变量复制过来
0000:00404010                 mov     [ebp+var_C], ecx
0000:00404013                 mov     [ebp+hIcon], edx
0000:00404016                 mov     [ebp+hDC], eax
//三个通过reg传递的参数
0000:00404019                 xor     eax, eax
0000:0040401B                 call    nullsub_1
//空过程,为什么?延时?还是Align?
0000:00404020                 and     eax, 0FFh
0000:00404025                 mov     [ebp+var_18], ax
//置0
0000:00404029                 xor     eax, eax
0000:0040402B                 call    sub_403C90
//右移8位
0000:00404030                 and     eax, 0FFh
0000:00404035                 mov     [ebp+var_1A], ax
0000:00404039                 xor     eax, eax
0000:0040403B                 call    sub_403C94
//右移16位,就是取高位
0000:00404040                 and     eax, 0FFh
0000:00404045                 mov     [ebp+var_1C], ax
//置0
//很多废代码

0000:00404049                 mov     eax, 767676h
//这里很奇特,不知道和那个废参数有什么关系。怀疑原来就是
//那个参数,因为调试的需要临时注释掉了,或者相反。

0000:0040404E                 call    nullsub_1
0000:00404053                 and     eax, 0FFh
0000:00404058                 mov     [ebp+var_1E], ax
0000:0040405C                 mov     eax, 767676h
0000:00404061                 call    sub_403C90
0000:00404066                 and     eax, 0FFh
0000:0040406B                 mov     [ebp+var_20], ax
0000:0040406F                 mov     eax, 767676h
0000:00404074                 call    sub_403C94
0000:00404079                 and     eax, 0FFh
0000:0040407E                 mov     [ebp+var_22], ax
//字节分离,太象RGB了!
0000:00404082                 mov     ebx, [ebp+Rect.right]
0000:00404085                 sub     ebx, [ebp+Rect.left]
0000:00404088                 sar     ebx, 1
0000:0040408A                 jns     short loc_40408F
0000:0040408C                 adc     ebx, 0
//取水平中点,或者说水平长度的一半
0000:0040408F
0000:0040408F loc_40408F:
0000:0040408F                 xor     eax, eax
0000:00404091                 mov     [ebp+rc.top], eax
//清0
0000:00404094                 mov     eax, [ebp+Rect.bottom]
0000:00404097                 sub     eax, [ebp+Rect.top]
0000:0040409A                 mov     [ebp+rc.bottom], eax
//这里应该是求高
0000:0040409D                 xor     eax, eax
0000:0040409F                 mov     [ebp+var_40.lbStyle], eax
//清0
0000:004040A2                 xor     eax, eax
0000:004040A4                 mov     [ebp+var_40.lbHatch], eax
//同上
0000:004040A7                 test    bx, bx
0000:004040AA                 jl      loc_4041C8
0000:004040B0                 mov     eax, ebx
0000:004040B2                 inc     eax
0000:004040B3                 mov     [ebp+var_24], ax
//sar以后最高位是保留的
0000:004040B7                 xor     edi, edi
//从下面可以看到,edi是个计数器,而var_24是循环变量
//一般说循环变量会用reg以加快速度的,但是这里例外
//看循环变量就看循环末尾的dec什么的

0000:004040B9
0000:004040B9 loc_4040B9:
//一个Damn循环,很长,到004041C2
0000:004040B9                 movsx   esi, bx
//注意movsx,这说明ebx不会很大
//但是ebx>$7f=127可以说明什么呢?

0000:004040BC                 push    esi             ; nDenominator
0000:004040BD                 push    esi             ; nNumerator
0000:004040BE                 movsx   eax, di
0000:004040C1                 push    eax             ; nNumber
0000:004040C2                 call    MulDiv
//这个地方虽然调用了MulDiv,但是由于不知道它是不是由Delphi自动调用的,
//所以必须写段程序实验一下。用两个Longword相乘,再除以另外一个Longword。
//可以看到,Delphi用了浮点指令。所以结论是,MulDiv是源程序调用的。
//另外,注意到MulDiv的参数意义,可以看出这个调用实际是没有实际作用的。
//这样的例子下面还有。

0000:004040C7                 mov     [ebp+rc.left], eax
0000:004040CA                 push    esi             ; nDenominator
0000:004040CB                 push    esi             ; nNumerator
0000:004040CC                 movsx   eax, di
0000:004040CF                 inc     eax
0000:004040D0                 push    eax             ; nNumber
0000:004040D1                 call    MulDiv
0000:004040D6                 mov     [ebp+rc.right], eax
0000:004040D9                 push    esi             ; nDenominator
0000:004040DA                 movsx   eax, [ebp+var_1E]
0000:004040DE                 push    eax             ; nNumerator
0000:004040DF                 movsx   eax, di
0000:004040E2                 push    eax             ; nNumber
0000:004040E3                 call    MulDiv
0000:004040E8                 add     ax, [ebp+var_18]
0000:004040EC                 mov     [ebp+var_12], ax
0000:004040F0                 push    esi             ; nDenominator
0000:004040F1                 movsx   eax, [ebp+var_20]
0000:004040F5                 push    eax             ; nNumerator
0000:004040F6                 movsx   eax, di
0000:004040F9                 push    eax             ; nNumber
0000:004040FA                 call    MulDiv
0000:004040FF                 add     ax, [ebp+var_1A]
0000:00404103                 mov     [ebp+var_14], ax
0000:00404107                 push    esi             ; nDenominator
0000:00404108                 movsx   eax, [ebp+var_22]
0000:0040410C                 push    eax             ; nNumerator
0000:0040410D                 movsx   eax, di
0000:00404110                 push    eax             ; nNumber
0000:00404111                 call    MulDiv
0000:00404116                 add     ax, [ebp+var_1C]
0000:0040411A                 mov     [ebp+var_16], ax
0000:0040411E                 cmp     [ebp+var_12], 0FFh
0000:00404124                 jle     short loc_40412C
0000:00404126                 mov     [ebp+var_12], 0FFh
//最大变化到255
0000:0040412C
0000:0040412C loc_40412C:
0000:0040412C                 cmp     [ebp+var_14], 0FFh
0000:00404132                 jle     short loc_40413A
0000:00404134                 mov     [ebp+var_14], 0FFh
0000:0040413A
0000:0040413A loc_40413A:
0000:0040413A                 cmp     [ebp+var_16], 0FFh
0000:00404140                 jle     short loc_404148
0000:00404142                 mov     [ebp+var_16], 0FFh
0000:00404148
0000:00404148 loc_404148:
0000:00404148                 mov     cl, byte ptr [ebp+var_16]
0000:0040414B                 mov     dl, byte ptr [ebp+var_14]
0000:0040414E                 mov     al, byte ptr [ebp+var_12]
0000:00404151                 call    unknown_libname_15 ; Borland Visual Component Library & Packages
//来,拼一下RGB分量
0000:00404156                 mov     [ebp+var_40.lbColor], eax
//返回的分量
0000:00404159                 lea     eax, [ebp+var_40]
0000:0040415C                 push    eax             ; LOGBRUSH *
0000:0040415D                 call    CreateBrushIndirect
0000:00404162                 mov     [ebp+hbr], eax
0000:00404165                 mov     eax, [ebp+hbr]
0000:00404168                 push    eax             ; hbr
0000:00404169                 lea     eax, [ebp+rc]
0000:0040416C                 push    eax             ; lprc
0000:0040416D                 mov     eax, [ebp+hDC]
0000:00404170                 push    eax             ; hDC
0000:00404171                 call    FillRect
0000:00404176                 push    esi             ; nDenominator
0000:00404177                 push    esi             ; nNumerator
0000:00404178                 movsx   eax, di
0000:0040417B                 push    eax             ; nNumber
0000:0040417C                 call    MulDiv
0000:00404181                 mov     edx, [ebp+Rect.right]
0000:00404184                 sub     edx, [ebp+Rect.left]
0000:00404187                 sub     edx, eax
0000:00404189                 mov     [ebp+rc.left], edx
0000:0040418C                 push    esi             ; nDenominator
0000:0040418D                 push    esi             ; nNumerator
0000:0040418E                 movsx   eax, di
0000:00404191                 inc     eax
0000:00404192                 push    eax             ; nNumber
0000:00404193                 call    MulDiv
0000:00404198                 mov     edx, [ebp+Rect.right]
0000:0040419B                 sub     edx, [ebp+Rect.left]
0000:0040419E                 sub     edx, eax
0000:004041A0                 mov     [ebp+rc.right], edx
0000:004041A3                 mov     eax, [ebp+hbr]
0000:004041A6                 push    eax             ; hbr
0000:004041A7                 lea     eax, [ebp+rc]
0000:004041AA                 push    eax             ; lprc
0000:004041AB                 mov     eax, [ebp+hDC]
0000:004041AE                 push    eax             ; hDC
0000:004041AF                 call    FillRect
0000:004041B4                 mov     eax, [ebp+hbr]
0000:004041B7                 push    eax             ; HGDIOBJ
0000:004041B8                 call    DeleteObject
0000:004041BD                 inc     edi
0000:004041BE                 dec     [ebp+var_24]
0000:004041C2                 jnz     loc_4040B9
//循环末尾
0000:004041C8
0000:004041C8 loc_4041C8:
0000:004041C8                 mov     [ebp+var_40.lbColor], 9E6A54h
0000:004041CF                 lea     eax, [ebp+var_40]
0000:004041D2                 push    eax             ; LOGBRUSH *
0000:004041D3                 call    CreateBrushIndirect
0000:004041D8                 mov     [ebp+hbr], eax
0000:004041DB                 mov     eax, [ebp+hbr]
0000:004041DE                 push    eax             ; hbr
0000:004041DF                 lea     eax, [ebp+Rect]
0000:004041E2                 push    eax             ; lprc
0000:004041E3                 mov     eax, [ebp+hDC]
0000:004041E6                 push    eax             ; hDC
0000:004041E7                 call    FrameRect
0000:004041EC                 mov     eax, [ebp+hbr]
0000:004041EF                 push    eax             ; HGDIOBJ
0000:004041F0                 call    DeleteObject
0000:004041F5                 push    0DCDCDCh        ; COLORREF
0000:004041FA                 mov     eax, [ebp+hDC]
0000:004041FD                 push    eax             ; HDC
0000:004041FE                 call    SetTextColor
0000:00404203                 push    1               ; int
0000:00404205                 mov     eax, [ebp+hDC]
0000:00404208                 push    eax             ; HDC
0000:00404209                 call    SetBkMode
0000:0040420E                 mov     [ebp+Rect.left], 2
0000:00404215                 mov     [ebp+Rect.top], 2
0000:0040421C                 sub     [ebp+Rect.bottom], 2
0000:00404220                 push    offset locret_4042A4 ; LPCSTR
0000:00404225                 push    0               ; DWORD
0000:00404227                 push    0               ; DWORD
0000:00404229                 push    0               ; DWORD
0000:0040422B                 push    0               ; DWORD
0000:0040422D                 push    1               ; DWORD
0000:0040422F                 push    0               ; DWORD
0000:00404231                 push    0               ; DWORD
0000:00404233                 push    0               ; DWORD
0000:00404235                 push    2BCh            ; int
0000:0040423A                 push    0               ; int
0000:0040423C                 push    0               ; int
0000:0040423E                 push    0               ; int
0000:00404240                 push    0FFFFFFF4h      ; int
0000:00404242                 call    CreateFontA
0000:00404247                 mov     ebx, eax
0000:00404249                 push    ebx             ; HGDIOBJ
0000:0040424A                 mov     eax, [ebp+hDC]
0000:0040424D                 push    eax             ; HDC
0000:0040424E                 call    SelectObject
0000:00404253                 cmp     [ebp+hIcon], 0
0000:00404257                 jz      short loc_40427B
0000:00404259                 push    3               ; diFlags
0000:0040425B                 push    0               ; hbrFlickerFreeDraw
0000:0040425D                 push    0               ; istepIfAniCur
0000:0040425F                 push    10h             ; cyWidth
0000:00404261                 push    10h             ; cxWidth
0000:00404263                 mov     eax, [ebp+hIcon]
0000:00404266                 push    eax             ; hIcon
0000:00404267                 push    2               ; yTop
0000:00404269                 push    2               ; xLeft
0000:0040426B                 mov     eax, [ebp+hDC]
0000:0040426E                 push    eax             ; hdc
0000:0040426F                 call    DrawIconEx
0000:00404274                 mov     [ebp+Rect.left], 14h
0000:0040427B
0000:0040427B loc_40427B:
0000:0040427B                 push    24h             ; uFormat
0000:0040427D                 lea     eax, [ebp+Rect]
0000:00404280                 push    eax             ; lpRect
0000:00404281                 push    0FFFFFFFFh      ; nCount
0000:00404283                 mov     eax, [ebp+var_C]
0000:00404286                 call    @System@@LStrToPChar$qqrv ; System::__linkproc__ LStrToPChar(void)
0000:0040428B                 push    eax             ; lpString
0000:0040428C                 mov     eax, [ebp+hDC]
0000:0040428F                 push    eax             ; hDC
0000:00404290                 call    DrawTextA
0000:00404295                 push    ebx             ; HGDIOBJ
0000:00404296                 call    DeleteObject
0000:0040429B                 pop     edi
0000:0040429C                 pop     esi
0000:0040429D                 pop     ebx
0000:0040429E                 mov     esp, ebp
0000:004042A0                 pop     ebp
0000:004042A1                 retn    0Ch
0000:004042A4
0000:004042A4 ; const CHAR locret_4042A4
0000:004042A4 locret_4042A4:
0000:004042A4                 retf
0000:004042A4 sub_403FF8      endp ; sp = -60h

0000:00403C8C nullsub_1       proc near
0000:00403C8C                 retn
0000:00403C8C nullsub_1       endp

0000:00403C90 sub_403C90      proc near
0000:00403C90                 shr     eax, 8
0000:00403C93                 retn
0000:00403C93 sub_403C90      endp

0000:00403C94 sub_403C94      proc near
0000:00403C94                 shr     eax, 10h
0000:00403C97                 retn
0000:00403C97 sub_403C94      endp

0000:00403C70 ; Borland Visual Component Library & Packages
0000:00403C70 ; Attributes: library function
0000:00403C70
0000:00403C70 unknown_libname_15 proc near
0000:00403C70                 and     eax, 0FFh
0000:00403C75                 and     edx, 0FFh
//取al和dl
0000:00403C7B                 shl     edx, 8
0000:00403C7E                 or      eax, edx
0000:00403C80                 xor     edx, edx
0000:00403C82                 mov     dl, cl
0000:00403C84                 shl     edx, 10h
0000:00403C87                 or      eax, edx
//非常象是RGB的拼装,字节顺序是
//CL:DL:AL

0000:00403C89                 retn
0000:00403C89 unknown_libname_15 endp

  首先看看参数。这个公共的call从形式上有6个参数,前3个依次用eax,edx,ecx传,
后3个通过stack传。从代码看,call前push了12个字节,ret时也pop了12个,堆栈是平
衡的。如果有谁怀疑,不妨自己数数整个call的push和pop,可以锻炼一下。我自己没
有数,但不反对别人数。
  这个call有很多局部变量和3个堆栈参数,至少形式是这样,但是IDA只分析出一个
堆栈参数。我一开始以为IDA发飚了,于是画了一下堆栈,结果发现程序没有用到第4和
第5个参数,调的时候直接传了个数的。但是看上去第4个参数好象是个RGB数。对不对,
请laoqian指正。
  分析这个call不能象前面几个call一样可以直接写出框架。只有逐步来。首先写出
过程首部。

Procedure Paint(dc:HDC;Icon:hIcon;Caption:PChar;dummy:DWORD;dummyRGB:DWORD;Rect:TRect);

  然后直接把ASM改成Pas,但是寄存器名和形如var_18的名称依然作为变量保留。下
面是精简变量。简单的说,就是只赋值和使用一次的变量可以去掉,其他的作为局部变
量保留。最后根据变量使用的情况,分别改用适当的名称,这样便于阅读理解。
  下面就是得到的代码了:

Procedure Paint(dc:HDC;Icon:hIcon;Caption:PChar;dummy:DWORD;dummyRGB:DWORD;Rect:TRect);

  然后直接把ASM改成Pas,但是寄存器名和形如var_18的名称依然作为变量保留。下
面是精简变量。简单的说,就是只赋值和使用一次的变量可以去掉,其他的作为局部变
量保留。最后根据变量使用的情况,分别改用适当的名称,这样便于阅读理解。
  下面就是得到的代码了:

Procedure Paint(dc:HDC;Icon:hIcon;Caption:PChar;BeginRGB:DWORD;EndRGB:DWORD;Rect:TRect);
Var
  LogBrush:TLogBrush;
  LRect,rc:TRect;
  LhBR:HBRUSH;
  R,G,B,Ri,Gi,Bi,Rt,Gt,Bt:Word;
  LFont:HFONT;
  Width:Word;
  i:Word;
Begin
  LRect:=Rect;
  
  B:=EndRGB AND $FF;
  G:=(EndRGB SHR 8) AND $FF;
  R:=(EndRGB SHR 16) AND $FF;

  Bi:=BeginRGB AND $FF;
  Gi:=(BeginRGB SHR 8) AND $FF;
  Ri:=(BeginRGB SHR 16) AND $FF;

  Width:=(LRect.right-LRect.left) DIV 2;

  rc.top:=0;
  rc.bottom:=LRect.bottom-LRect.top;

  LogBrush.lbStyle:=0;
  LogBrush.lbHatch:=0;

  If Width>=0 Then
    Begin
      For i:=0 To (Width AND $FF) Do
        Begin
            rc.left:=i;
            rc.right:=i+1;

            Bt:=MulDiv(i,Bi,Width)+B;
            Gt:=MulDiv(i,Gi,Width)+G;
            Rt:=MulDiv(i,Ri,Width)+R;

            If Bt>$FF Then Bt:=$FF;
            If Gt>$FF Then Gt:=$FF;
            If Rt>$FF Then Rt:=$FF;

            LogBrush.lbColor:=(Rt SHL 16) OR (Gt SHL 8) OR (Bt);
            LhBR:=CreateBrushIndirect(LogBrush);
            FillRect(dc,rc,LhBR);

            rc.left:=Rect.right-Rect.left-i;
            rc.right:=Rect.right-Rect.left-i-1;

            FillRect(dc,rc,LhBR);
            DeleteObject(LhBR);
        End;
    End;

  LogBrush.lbColor:=$9E6A54;
  LhBR:=CreateBrushIndirect(LogBrush);
  FrameRect(dc,Rect,LhBR);
  DeleteObject(LhBR);
  SetTextColor(dc,$DCDCDC);
  SetBkMode(dc,1);

  Rect.left:=2;
  Rect.top:=2;
  Dec(Rect.bottom,2);

  LFont:=CreateFont(-$C,0,0,0,$2BC,0,0,0,1,0,0,0,0,'宋体');
  SelectObject(dc,LFont);

  If Icon<>0 Then
    Begin
      DrawIconEx(dc,2,2,Icon,$10,$10,0,0,3);
      Rect.left:=$14;
    End;

  DrawText(dc,Caption,-1,Rect,$24);
  DeleteObject(LFont);
End;

  Shit!效果是:按钮上的字没有,标题栏的颜色有问题。标题颜色估计是对signed
int处理不当,但按钮的字就有点头痛。只能说,应该是WM_DRAWITEM的问题,但是我传
的参数肯定是对的,否则是没有那个三维按钮效果的!
  按钮的问题,要么是SetColor出了问题,要么就是Get/Set文本出问题。
  好,调试一下。发现问题!GetWindowText得到的Str是空的!看来还是String的
转换存在问题。把Str定义为Array of Byte,成功!
  下面就是改正的ItemDraw:

Procedure ItemDraw(lpDIS:PDrawItemStruct);
Var
  Str:Array[1..11] of Byte;
Begin
  FillRect(lpDIS^.hDC,lpDIS^.rcItem,h_Brush);
  SetTextColor(lpDIS^.hDC,$A0A0A0);
  SetBkMode(lpDIS^.hDC,TRANSPARENT);
  DrawEdge(lpDIS^.hDC,lpDIS^.rcItem,BDR_RAISEDOUTER,BF_RECT);
  GetWindowText(lpDIS^.hwndItem,@Str,10);
  DrawText(lpDIS^.hDC,@Str,-1,lpDIS^.rcItem,DT_SINGLELINE OR DT_VCENTER OR DT_CENTER);
  
  If lpDIS^.itemState MOD 2=1 Then
    Begin
      SetTextColor(lpDIS^.hDC,$DDFF);
      DrawText(lpDIS^.hDC,@Str,-1,lpDIS^.rcItem,DT_SINGLELINE OR DT_VCENTER OR DT_CENTER);
      DrawEdge(lpDIS^.hDC,lpDIS^.rcItem,BDR_SUNKENOUTER,BF_RECT);
    End;
End;

  那么余下的问题就是颜色了。这个,负数的处理恰好是我头痛的问题。下次再说
吧……另外,为什么必须用Array of Byte(上面刚刚提到的嘛),这个也下次分析
了……

  当然,不要指望上面的代码和原始代码一样(哪怕是99%的相似),因为我是做了
点优化的,去掉了从逻辑上无用的代码。

  OK,我很想知道这么一大篇东西有没有人会真的有耐心看完,特别是对dump出的代
码的分析,而不仅仅是Delphi的代码。我在上面的分析里提到以前的一个判断被证明是
错误的。知道我在说什么的人有兴趣的话请在FCG论坛发短信告诉我,ID嘛,一样的。

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

补充:
      For i:=0 To (Width AND $FF) Do
        Begin
---->       rc.left:=1;
            rc.right:=i+1;
            
箭头指的地方,1应该改为i。这实际是我的笔误。改了就对了。

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
点赞7
打赏
分享
最新回复 (15)
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
firstrose 16 2004-11-11 22:25
2
0
en……

兴奋过头,居然忘了,这次可以给出sample了。

附件:KeyGen.rar

没加壳。有兴趣的可以看看disasm和原文件有何不同。
雪    币: 85496
活跃值: (198820)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 2004-11-11 23:15
3
0
支持!!!
雪    币: 208
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
mYeXcKsN 2004-11-12 08:34
4
0
很好!
雪    币: 414
活跃值: (531)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
nig 4 2004-11-12 09:21
5
0
我喜欢.呵呵!
雪    币: 332
活跃值: (479)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
laoqian 8 2004-11-12 09:24
6
0
最初由 firstrose 发布
最后,今天和好友联系时偶尔得知她还是单身,呵呵……于是心情大好


我对这最感兴趣,抓紧啊,老弟!这比什么都重要,哈哈。

不是没用那2个参数,而是“标题栏渐变起始颜色和结束颜色”调入后分别分解为RGB,然后...
除了这段你其余都分析得差不多!
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
firstrose 16 2004-11-12 12:01
7
0
最初由 laoqian 发布

不是没用那2个参数,而是“标题栏渐变起始颜色和结束颜色”调入后分别分解为RGB,然后...
........


问题是delphi是直接用了常数。所以我虽然怀疑,但无法得到证实。不过既然你这么说了,那就很明显是那里了。OK,我不客气了。多谢。

faint,第一次贴的没有排版效果,改过以后贴就好了。因为效果没有实质区别,附件就不更新了。

哪天把一些变量名处理一下,和那两个问题合写个5-续
雪    币: 332
活跃值: (479)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
laoqian 8 2004-11-12 15:43
8
0
为什么直接用了常数?是在主程序里定义的,是为了改颜色方便而以!因为不同人的喜欢不同的颜色,方便他改模班
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mhsong 2004-11-12 16:57
9
0
欢迎这么人性化的好文!
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DoorKey 2004-11-12 20:15
10
0
to 楼主,“为什么必须用Array of Byte(上面刚刚提到的嘛),这个也下次分析了……” -----------其实这个道理很简单,因为str变量是用在API函数,GetWindowText里,这个API的第二个参数是pchar类型的(Delphi的数据类型)在C++里等价于字符数组,其实这个定义应该改为:

var
  Str:Array[1..11] of char;

才是最准确的。其它的我也没什么时间再看了!!先到此为止了!!
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
firstrose 16 2004-11-12 22:33
11
0
最初由 laoqian 发布
为什么直接用了常数?是在主程序里定义的,是为了改颜色方便而以!因为不同人的喜欢不同的颜色,方便他改模班


NO,NO。我是指你那常量参数传了以后,Delphi编译时就直接用了xor eax,eax和mov eax,767676h,而没有mov eax,[ebp+xxh]。

所以我没有看出来。
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
firstrose 16 2004-11-12 22:40
12
0
最初由 DoorKey 发布
to 楼主,“为什么必须用Array of Byte(上面刚刚提到的嘛),这个也下次分析了……” -----------其实这个道理很简单,因为str变量是用在API函数,GetWindowText里,这个API的第二个参数是pchar类型的(Delphi的数据类型)在C++里等价于字符数组,其实这个定义应该改为:

var
Str:Array[1..11] of char;

........


这个……你完全误解了。str定义成array还是string,是byte还是char,完全无关紧要。用什么完全是个人爱好。反正我喜欢用arr of byte,最直接。

我的意思是,做PChar(String)的转换时,String到底被转换成了什么。而这个转换其实就决定了GetWindowText的调用是否成功。

反正,等续篇出来你就知道了。
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DoorKey 2004-11-13 11:05
13
0
哈哈,你要是定义str: string,而传给GetWindowText时用
pchar(string)永远都是调用不成功的。因为在调用之前str没有被分配内存。当然你可以先给它分配上内存再调用了。但是,这样是不是让自己更麻烦呢?能简单我们没有理由不简单嘛!!
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DoorKey 2004-11-13 11:08
14
0
还有在Delphi只要是常量,编译出来的绝对是直接用这个常量的值的。你可以用Delphi编些程序,然后调试一下就知道了。如果觉得我这样说没有依据,可以参见 刘艺 著的一本书:《Delphi源代码分析》!!
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
firstrose 16 2004-11-13 11:42
15
0
最初由 DoorKey 发布
哈哈,你要是定义str: string,而传给GetWindowText时用
pchar(string)永远都是调用不成功的。因为在调用之前str没有被分配内存。当然你可以先给它分配上内存再调用了。但是,这样是不是让自己更麻烦呢?能简单我们没有理由不简单嘛!!


我的目的是学习,而不仅仅是得到模板的src。

通过RE,学习研究String背后的秘密。
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
firstrose 16 2004-11-13 11:50
16
0
最初由 DoorKey 发布
还有在Delphi只要是常量,编译出来的绝对是直接用这个常量的值的。你可以用Delphi编些程序,然后调试一下就知道了。如果觉得我这样说没有依据,可以参见 刘艺 著的一本书:《Delphi源代码分析》!!


我不是要问为什么。对那种书也没有什么兴趣。直接使用常量,从TP就开始了。

我只是当时没有把参数和函数内容这两者联系起来看。

但还是多谢你的指教,顺便说一句,我是从tp,debug,sourcer用上来的。
游客
登录 | 注册 方可回帖
返回