埠偵探(PortSpy)V3.8.28.06

看雪資料發表於2015-11-15

埠偵探(PortSpy)V3.8.28.06


軟體介紹:

軟體名稱:埠偵探(PortSpy)

軟體版本:V3.8.28.06 增強版

執行平臺:Win98、WinME、Win2000、WinXP、Win2003

軟體性質:共享軟體

軟體作者:黃金龍(KimLon Huang)

作者聯絡方法:QQ:80215521 kimlon@163.com


【軟體簡介】:  本程式主要是針對電腦串列埠(COM)和並口(LPT)的除錯與監測.是一款綜合型除錯軟體。串列埠除錯:跟市面上大多數軟體一樣,可以對串列埠的波特率,資料位,停止位,校驗位等,可對串列埠進行讀寫資料。串列埠監試:可以不佔用串列埠資源對串列埠的資料(傳送和接收)進行捕獲。並口操作:可以對並口進行讀寫資料,捕獲資料。


【軟體限制】:未註冊只能使用30次

【作者宣告】:初學Crack,只是感興趣,沒有其它目的。失誤之處敬請諸位大俠賜教!

【破解工具】:Ollydbg1.09、IDA、PEiD、DeDe、pe-scan 3.31


一、脫殼
用PEiD偵察得知殼為PEtite 2.1,殼雖然沒怎麼聽說過,用pe-scan 3.31倒是很輕鬆的脫調了殼,再一看
Delphi程式。
  
二、自校驗

雙擊執行無反映,估計有自校驗存在,於是下斷CreateFileA停在KIMLMON.dll中,清除斷點,按Ctrl+F9回到PortSpy程式空間,停在0048C2AC,到IDA中看一下,還是比較清楚的阿,呵呵。主要驗證函式都在KIMLON.DLL中,而且其倒出函式作用都一目瞭然。


FormCreate事件

snyped:0048C264                 push    ebp
snyped:0048C265                 mov     ebpesp
snyped:0048C267                 mov     ecx, 1Eh
snyped:0048C26C 
snyped:0048C26C loc_48C26C:                             ; CODE XREF: snyped:0048C271j
snyped:0048C26C                 push    0
snyped:0048C26E                 push    0
snyped:0048C270                 dec     ecx
snyped:0048C271                 jnz     short loc_48C26C
snyped:0048C273                 push    ebx
snyped:0048C274                 push    esi
snyped:0048C275                 mov     ebxeax
snyped:0048C277                 xor     eaxeax
snyped:0048C279                 push    ebp
snyped:0048C27A                 push    offset loc_48CB3F
snyped:0048C27F                 push    dword ptr fs:[eax]
snyped:0048C282                 mov     fs:[eax], esp
snyped:0048C285                 lea     eax, [ebp-30h]
snyped:0048C288                 push    eax
snyped:0048C289                 lea     edx, [ebp-7Ch]
snyped:0048C28C                 mov     eaxds:dword_493020
snyped:0048C291                 mov     eax, [eax]
snyped:0048C293                 call    unknown_libname_311
snyped:0048C298                 mov     edx, [ebp-7Ch]
snyped:0048C29B                 lea     eax, [ebp-78h]
snyped:0048C29E                 call    unknown_libname_21
snyped:0048C2A3                 mov     eax, [ebp-78h]
snyped:0048C2A6                 push    eax
snyped:0048C2A7                 call    GetCheckSum    ; 呼叫KIMLON.DLL! GetCheckSum 函式,計算檔案校驗碼
snyped:0048C2AC                 lea     edx, [ebp-84h] ; <======= 停到此處
snyped:0048C2B2                 mov     eaxds:dword_493020
snyped:0048C2B7                 mov     eax, [eax]
snyped:0048C2B9                 call    unknown_libname_311
snyped:0048C2BE                 mov     edx, [ebp-84h]
snyped:0048C2C4                 lea     eax, [ebp-80h]
snyped:0048C2C7                 call    unknown_libname_21
snyped:0048C2CC                 mov     eax, [ebp-80h]
snyped:0048C2CF                 push    eax
snyped:0048C2D0                 lea     eax, [ebp-10h]
snyped:0048C2D3                 push    eax
snyped:0048C2D4                 call    FileDateTime ;呼叫KIMLON.DLL! FileDateTime 函式,獲取檔案日期
snyped:0048C2D9                 lea     edx, [ebp-8Ch]
snyped:0048C2DF                 mov     eaxds:dword_493020
snyped:0048C2E4                 mov     eax, [eax]
snyped:0048C2E6                 call    unknown_libname_311
snyped:0048C2EB                 mov     edx, [ebp-8Ch]
snyped:0048C2F1                 lea     eax, [ebp-88h]
snyped:0048C2F7                 call    unknown_libname_21
snyped:0048C2FC                 mov     eax, [ebp-88h]
snyped:0048C302                 push    eax
snyped:0048C303                 call    FileSizeX  ;呼叫KIMLON.DLL! FileSizeX 函式,獲取檔案大小
snyped:0048C308                 mov     esieax
snyped:0048C30A                 call    SumText  ;呼叫KIMLON.DLL! SumText 函式,獲取儲存在KIMLON.DLL內的PortSpy.exe的校驗碼
snyped:0048C30F                 cmp     eax, [ebp-30h]
snyped:0048C312                 jnz     short loc_48C36F
snyped:0048C314                 lea     eax, [ebp-90h]
snyped:0048C31A                 push    eax
snyped:0048C31B                 call    FileDTText  ;呼叫KIMLON.DLL! FileDTText 函式,獲取儲存在KIMLON.DLL內的PortSpy.exe檔案建立
snyped:0048C320                 mov     edx, [ebp-90h]
snyped:0048C326                 mov     eax, [ebp-10h]
snyped:0048C329                 call    @System@@WStrCmp$qqrv ; System::__linkproc__ WStrCmp(void) 比較檔案日期是否相同
snyped:0048C32E                 jnz     short loc_48C36F
snyped:0048C330                 call    FileSizeText  ;呼叫KIMLON.DLL! FileSizeText 函式,獲取儲存在KIMLON.DLL內的PortSpy.exe的檔案大小
snyped:0048C335                 cmp     esieax      ;比較檔案大小是否相同
snyped:0048C337                 jnz     short loc_48C36F
snyped:0048C339                 call    FILEVXD       ;呼叫KIMLON.DLL! FILEVXD用CreateFileA()來判斷是否有偵錯程式,下同
snyped:0048C33E                 test    alal
snyped:0048C340                 jnz     short loc_48C36F
snyped:0048C342                 call    portmvxd
snyped:0048C347                 test    alal
snyped:0048C349                 jnz     short loc_48C36F
snyped:0048C34B                 call    REGVXD
snyped:0048C350                 test    alal
snyped:0048C352                 jnz     short loc_48C36F
snyped:0048C354                 call    checkoutsoft  ;呼叫KIMLON.DLL! checkoutsoft透過FindWindow()來判斷是否有softice,ida等在後臺,留待待會處理
snyped:0048C359                 test    alal
snyped:0048C35B                 jnz     short loc_48C36F
snyped:0048C35D                 call    SoftIceNT
snyped:0048C362                 test    alal
snyped:0048C364                 jnz     short loc_48C36F
snyped:0048C366                 call    SoftIce95
snyped:0048C36B                 test    alal
snyped:0048C36D                 jz      short loc_48C38B
snyped:0048C36F 
snyped:0048C36F loc_48C36F:                             ; CODE XREF: snyped:0048C312j
snyped:0048C36F                                         ; snyped:0048C32Ej ...
snyped:0048C36F                 call    @Sysutils@Beep$qqrv ; Sysutils::Beep(void)
snyped:0048C374                 mov     eaxds:dword_493020 snyped:0048C379                 mov     eax, [eax]
snyped:0048C37B                 mov     byte ptr [eax+5Bh], 0
snyped:0048C37F                 mov     eaxds:dword_493020
snyped:0048C384                 mov     eax, [eax]
snyped:0048C386                 call    @Forms@TApplication@Terminate$qqrv ; Forms::TApplication::Terminate(void)
snyped:0048C38B 
snyped:0048C38B 
snyped:0048C38B loc_48C38B:                             ; CODE XREF: snyped:0048C36Dj
snyped:0048C38B                 push    ebx
snyped:0048C38C                 push    offset loc_48F474 ; ; 定時器觸發函式呼叫KIMLON.DLL! closeout關閉黑名單中軟體事件
snyped:0048C391                 mov     eax, [ebx+450h]
snyped:0048C397                 call    @Extctrls@TTimer@SetOnTimer$qqrynpqqrp14System@TObject$v ; Extctrls::TTimer::SetOnTimer(void (*)(System::TObject *))
snyped:0048C39C                 mov     edx, 0C8h  ; 間隔200毫秒
snyped:0048C3A1                 mov     eax, [ebx+450h]
snyped:0048C3A7                 call    @Extctrls@TTimer@SetInterval$qqrui ; Extctrls::TTimer::SetInterval(uint)


上面還有一些程式碼是呼叫KPSDisk.dll! DiskID32得到硬碟序列號




三、判斷是否註冊

下面是讀取登錄檔儲存的註冊碼。

snyped:0048C4F2                 mov     dl, 1
snyped:0048C4F4                 mov     eaxds:dword_4621A0
snyped:0048C4F9                 call    @Registry@TRegistry@$bctr$qqrv ; Registry::TRegistry::TRegistry(void)
snyped:0048C4FE                 mov     esieax
snyped:0048C500                 mov     edx, 80000002h
snyped:0048C505                 mov     eaxesi
snyped:0048C507                 call    @Registry@TRegistry@SetRootKey$qqrui ; Registry::TRegistry::SetRootKey(uint)
snyped:0048C50C                 mov     cl, 1
snyped:0048C50E                 mov     edx, offset aSoftwareMicr_0 ; "Software\Microsoft\Windows\PortReg"
snyped:0048C513                 mov     eaxesi
snyped:0048C515                 call    @Registry@TRegistry@OpenKey$qqrx17System@AnsiStringo ; Registry::TRegistry::OpenKey(System::AnsiString,bool)
snyped:0048C51A                 test    alal
snyped:0048C51C                 jz      loc_48C6E8
snyped:0048C522                 lea     ecx, [ebp-14h]
snyped:0048C525                 mov     edx, offset dword_48CBE4  ; "tag"
snyped:0048C52A                 mov     eaxesi
snyped:0048C52C                 call    @TRegistry@ReadString$qqrx10AnsiString ; TRegistry::ReadString(AnsiString)
snyped:0048C531                 lea     ecx, [ebp-1Ch]
snyped:0048C534                 mov     edx, offset dword_48CBF0  ; "XX"
snyped:0048C539                 mov     eax, [ebp-14h]
snyped:0048C53C                 call    sub_4767F4  ; sub_4767F4([tag],"XX",返回值) 對註冊tag項中儲存值進行解碼,對註冊碼多一層保護,解出值應為"TRY"
snyped:0048C541                 lea     ecx, [ebp-18h]
snyped:0048C544                 mov     edx, offset dword_48CBFC  ; "!!!!" 該註冊項儲存著註冊碼
snyped:0048C549                 mov     eaxesi
snyped:0048C54B                 call    @TRegistry@ReadString$qqrx10AnsiString ; TRegistry::ReadString(AnsiString)
snyped:0048C550                 lea     edx, [ebp-0BCh]
snyped:0048C556                 mov     eax, [ebx+494h]
snyped:0048C55C                 call    @TControl@GetText$qqrv ; TControl::GetText(void)
snyped:0048C561                 mov     eax, [ebp-0BCh]
snyped:0048C567                 lea     ecx, [ebp-0B8h]
snyped:0048C56D                 mov     edx, offset dword_48CC0C  ; "3!a@c"
snyped:0048C572                 call    sub_476548    ; 註冊碼=sub_4767F4("CP"+硬碟卷標,"3!a@c",返回值)"3!a@c"
snyped:0048C577                 mov     ecx, [ebp-0B8h]
snyped:0048C57D                 lea     eax, [ebp-20h]
snyped:0048C580                 mov     edx, offset dword_48CC1C ;  "KC" 註冊碼以"KC"開頭 
snyped:0048C585                 call    @System@@LStrCat3$qqrv ;  註冊碼="KC" + 註冊碼
snyped:0048C58A                 mov     eax, [ebp-1Ch]
snyped:0048C58D                 mov     edx, offset dword_48CC28  ; "TRY"
snyped:0048C592                 call    @System@@LStrCmp$qqrv  ; [tag]項解出是否為"TRY"
snyped:0048C597                 jnz     short loc_48C5D5
snyped:0048C599                 mov     eax, [ebp-18h]
snyped:0048C59C                 mov     edx, [ebp-20h]
snyped:0048C59F                 call    @System@@LStrCmp$qqrv ;   *****關鍵! 註冊碼明碼比較*****
snyped:0048C5A4                 jnz     short loc_48C5D5
snyped:0048C5A6                 mov     edx, offset dword_48CC34 ;  ->"感謝您的註冊! (^_^)"
snyped:0048C5AB                 mov     eax, [ebx+4A0h]
snyped:0048C5B1                 call    @Controls@TControl@SetText$qqrx17System@AnsiString ; Controls::TControl::SetText(System::AnsiString)
snyped:0048C5B6                 mov     dl, 1
snyped:0048C5B8                 mov     eax, [ebx+4A0h]
snyped:0048C5BE                 call    @Stdctrls@TCustomEdit@SetReadOnly$qqro ; Stdctrls::TCustomEdit::SetReadOnly(bool)
snyped:0048C5C3                 xor     edxedx
snyped:0048C5C5                 mov     eax, [ebx+498h]
snyped:0048C5CB                 mov     ecx, [eax]
snyped:0048C5CD                 call    dword ptr [ecx+64h]
snyped:0048C5D0                 jmp     loc_48C6E8
snyped:0048C5D5 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
snyped:0048C5D5 
snyped:0048C5D5 loc_48C5D5:                             ; CODE XREF: snyped:0048C597j
snyped:0048C5D5                                         ; snyped:0048C5A4j
snyped:0048C5D5                 mov     edx, 80000001h
snyped:0048C5DA                 mov     eaxesi
snyped:0048C5DC                 call    @Registry@TRegistry@SetRootKey$qqrui ; Registry::TRegistry::SetRootKey(uint)
snyped:0048C5E1                 mov     cl, 1
snyped:0048C5E3                 mov     edx, offset aSoftwareMicr_1 ; "Software\Microsoft"
snyped:0048C5E8                 mov     eaxesi
snyped:0048C5EA                 call    @Registry@TRegistry@OpenKey$qqrx17System@AnsiStringo ; Registry::TRegistry::OpenKey(System::AnsiString,bool)
snyped:0048C5EF                 test    alal
snyped:0048C5F1                 jz      loc_48C6E8
snyped:0048C5F7                 mov     edx, offset dword_48CC6C
snyped:0048C5FC                 mov     eaxesi
snyped:0048C5FE                 call    @Registry@TRegistry@ValueExists$qqrx17System@AnsiString ; Registry::TRegistry::ValueExists(System::AnsiString)
snyped:0048C603                 test    alal
snyped:0048C605                 jz      loc_48C6C1
snyped:0048C60B                 lea     ecx, [ebp-24h]
snyped:0048C60E                 mov     edx, offset dword_48CC6C
snyped:0048C613                 mov     eaxesi
snyped:0048C615                 call    @TRegistry@ReadString$qqrx10AnsiString ; TRegistry::ReadString(AnsiString)
snyped:0048C61A                 lea     ecx, [ebp-2Ch]
snyped:0048C61D                 mov     edx, offset aKimlon_0 ; "kimlon"
snyped:0048C622                 mov     eax, [ebp-24h]
snyped:0048C625                 call    sub_4767F4            ; 使用資訊儲存在Software\Microsoft下,kao(??!!!, faint)項中,
                                                              ; 過期後如果刪除此項,即可重新使用。sub_4767F4為解碼函式,解出使用者使用次數
snyped:0048C62A                 cmp     dword ptr [ebp-2Ch], 0
snyped:0048C62E                 jnz     short loc_48C647
snyped:0048C630                 mov     eaxds:dword_493020
snyped:0048C635                 mov     eax, [eax]
snyped:0048C637                 mov     byte ptr [eax+5Bh], 0
snyped:0048C63B                 mov     eaxds:dword_493020
snyped:0048C640                 mov     eax, [eax]
snyped:0048C642                 call    @Forms@TApplication@Terminate$qqrv ; Forms::TApplication::Terminate(void)
snyped:0048C647 
snyped:0048C647 loc_48C647:                             ; CODE XREF: snyped:0048C62Ej
snyped:0048C647                 mov     eax, [ebp-2Ch]
snyped:0048C64A                 mov     edx, offset dword_48CC88
snyped:0048C64F                 call    @System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void)
snyped:0048C654                 jz      short loc_48C663
snyped:0048C656                 mov     eax, [ebp-2Ch]
snyped:0048C659                 call    @Sysutils@StrToInt$qqrx17System@AnsiString ; Sysutils::StrToInt(System::AnsiString)
snyped:0048C65E                 cmp     eax, 5Ah     ; 關鍵! *******每次使用值+3,編碼後儲存在登錄檔中,故為30×3=90******
snyped:0048C661                 jle     short loc_48C67C ; 如果使用次數<30則跳
snyped:0048C663 
snyped:0048C663 loc_48C663:                             ; CODE XREF: snyped:0048C654j
snyped:0048C663                 mov     eaxds:dword_493020
snyped:0048C668                 mov     eax, [eax]
snyped:0048C66A                 mov     byte ptr [eax+5Bh], 0
snyped:0048C66E                 mov     eaxds:dword_493020
snyped:0048C673                 mov     eax, [eax]
snyped:0048C675                 call    @Forms@TApplication@Terminate$qqrv ; Forms::TApplication::Terminate(void)
snyped:0048C67A                 jmp     short loc_48C6E8
snyped:0048C67C ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
snyped:0048C67C 
snyped:0048C67C loc_48C67C:                             ; CODE XREF: snyped:0048C661j
snyped:0048C67C                 mov     eax, [ebp-2Ch]
snyped:0048C67F                 call    @Sysutils@StrToInt$qqrx17System@AnsiString ; Sysutils::StrToInt(System::AnsiString)
snyped:0048C684                 add     eax, 3         ; 每次使用值+3,編碼後儲存在登錄檔中
snyped:0048C687                 lea     edx, [ebp-0C0h]
snyped:0048C68D                 call    @Sysutils@IntToStr$qqri ; Sysutils::IntToStr(int)
snyped:0048C692                 mov     edx, [ebp-0C0h]
snyped:0048C698                 lea     eax, [ebp-2Ch]
snyped:0048C69B                 call    @System@@LStrLAsg$qqrv ; System::__linkproc__ LStrLAsg(void)
snyped:0048C6A0                 lea     ecx, [ebp-28h]
snyped:0048C6A3                 mov     edx, offset aKimlon_0 ; "kimlon"
snyped:0048C6A8                 mov     eax, [ebp-2Ch]
snyped:0048C6AB                 call    sub_476548  ; 編碼函式,編碼後儲存在登錄檔中
snyped:0048C6B0                 mov     ecx, [ebp-28h]
snyped:0048C6B3                 mov     edx, offset dword_48CC6C
snyped:0048C6B8                 mov     eaxesi
snyped:0048C6BA                 call    @TRegistry@WriteString ; TRegistry::WriteString
snyped:0048C6BF                 jmp     short loc_48C6E8
...




snyped:0048C354                 call    checkoutsoft  ;呼叫KIMLON.DLL! checkoutsoft透過FindWindow()來判斷是否有softice,ida等
這個函式透過使用FindWindowA來查詢是否有黑名單上的軟體在執行,這技法不怎麼新鮮阿,黑名單中都是些耳熟能詳的軟體了呵呵,用HexWorkShop看看有
^[.OWL_Window..TIdaWindow..OLLYDBG.NuMega SoftICE Symbol Loader....TMainForm...TRW2000.#32770..TRW2000 for Windows 9x..-=CHiNA CrACKiNG GrOUp=-....TDeDeMainForm...18467-41....RegmonClass.FileMonClass....PortmonClass....Registry Shot for Win9X,WinNT...TSpyWindow..APIMonitor By Rohitab...WFS_Frame

.WFS_Frame...OWL_Window..TIdaWindow..OLLYDBG.TRW2000.TRW2000 for Windows 9x..#32770..TDeDeMainForm...FileMonClass....RegmonClass.PortmonClass....18467-41

不過程式並不立即進行比較,只是將這些找到的列表儲存下來,待會會向這些程式挨個發退出訊息,還好沒讓你重起,^_^
可以將這些名字胡改一下,或者在更改主程式中判斷語句。



四、輸入註冊碼

當你在0048C59F看到了註冊碼,可是當想用這個註冊碼在註冊頁面輸入時卻發現點選註冊按鈕沒有反映,why??難道註冊碼不正確嗎?開始讓我很疑惑,以為這是個試用版不能註冊。
用DEDE載入,看看註冊按鈕響應事件指向0048EF50,看了看這個事件判斷大致判斷即為註冊事件。設定斷點,卻沒能斷下來。

這就是此軟體有意思的地方---- 註冊按鈕響應事件指向並不正確,指向一個垃圾事件,非真正的響應.
等一下,整理思路,首先我們找到的註冊碼應該是正確的,輸入不正確代表裡面有判斷事件

還是在FormCreate事件
...
snyped:0048CA6B                 mov     eax, [ebx+498h] ;獲取"註冊"按鈕 指標
snyped:0048CA71                 mov     [eax+124h], ebx
snyped:0048CA77                 mov     dword ptr [eax+120h], offset sub_48DE70  ; 設定註冊按鈕事件(垃圾事件,非真正的響應)
...

這是Delphi獲取控制元件指標的慣用手法mov     eax, [ebx+498h]
處498h為"註冊"按鈕控制元件offset值,可在dede中檢視到,
所以可以透過在IDA中查詢[ebx+498h] or [eax+498h]來找到使用"註冊"按鈕指標的引用之處


找到了這裡,在DEDE中一看是"g" lable(即"註冊碼"label)的雙擊事件,
當雙擊"註冊碼"Label後才掛接正確註冊按鈕響應事件,作者還真用心良苦阿,:)

...
snyped:0048FED8                 mov     edx, [eax+498h]
snyped:0048FEDE                 mov     [edx+124h], eax
snyped:0048FEE4                 mov     dword ptr [edx+120h], offset sub_48EF50 ; 掛接"註冊"按鈕正確得響應事件
snyped:0048FEEE                 mov     eaxedx
snyped:0048FEF0                 mov     edx, offset dword_48FF04
snyped:0048FEF5                 call    @Controls@TControl@SetText$qqrx17System@AnsiString ; Controls::TControl::SetText(System::AnsiString)
snyped:0048FEFA                 retn
...

再試一次,輸入註冊碼還是不管用,暈~~~,不過不要氣餒,cracker最需要的就是耐心了 :)
於是ollydbg載入設斷0048EF50,果然停在這裡了,:)
單步走來到這裡

0048F009   .  8B45 E0       MOV     EAXDWORD PTR SS:[EBP-20]
0048F00C   .  8D4D F4       LEA     ECXDWORD PTR SS:[EBP-C]
0048F00F   .  BA 74F14800   MOV     EDX, <PortSpy3.dword_48F174>    ;  ASCII "3!a@c"
0048F014   .  E8 2F75FEFF   CALL    <PortSpy3.sub_476548>  ; 計算註冊碼,若要得到演算法,可研究一下此call,我粗略看了一下,好像不怎麼複雜,可是吾彙編太差了,還是不懂,:(。有一點奇怪的就是此函式在dede中顯示為TRichEditStrings類的一個函式??
0048F019   .  8BB3 A0040000 MOV     ESIDWORD PTR DS:[EBX+4A0] ; 獲取"註冊碼"Label 指標 
0048F01F   .  837E 0C 01    CMP     DWORD PTR DS:[ESI+C], 1  ; 判斷是否註冊使能,TEdit.Tag=1?
0048F023   .  0F85 CC000000 JNZ     <PortSpy3.loc_48F0F5>

這裡一跳走就沒戲了,看來這是"註冊碼"Label的一個屬性,標誌註冊使能。看來還沒有完,繼續IDA中查詢[ebx+4A0h] or [eax+4A0h]
找到這裡:
註冊碼輸入框okeditKeyDown事件

snyped:0048F820 sub_48F820      proc near               ; DATA XREF: snyped:0048CA3Ao
snyped:0048F820 
snyped:0048F820 arg_0           = byte ptr  8
snyped:0048F820 
snyped:0048F820                 push    ebp
snyped:0048F821                 mov     ebpesp
snyped:0048F823                 test    [ebp+arg_0], 4       ;按下Ctrl,可以從
snyped:0048F827                 jz      short loc_48F853
snyped:0048F829                 mov     dx, [ecx]
snyped:0048F82C                 sub     dl, 41h              ;鍵盤掃描碼 'a'
snyped:0048F82F                 jz      short loc_48F836
snyped:0048F831                 sub     dl, 20h              ; or 'A'
snyped:0048F834                 jnz     short loc_48F853
snyped:0048F836 
snyped:0048F836 loc_48F836:                             ; CODE XREF: sub_48F820+Fj
snyped:0048F836                 mov     edx, [eax+4A0h] ; 指向註冊碼輸入框okedit
snyped:0048F83C                 mov     dword ptr [edx+0Ch], 1  ; <==== 註冊使能,TEdit.Tag=1,Tag屬性是程式設計師自己定義意義得屬性
snyped:0048F843                 mov     edx, offset dword_48F860
snyped:0048F848                 mov     eax, [eax+498h]
snyped:0048F84E                 call    @Controls@TControl@SetText$qqrx17System@AnsiString ; Controls::TControl::SetText(System::AnsiString)
snyped:0048F853 
snyped:0048F853 loc_48F853:                             ; CODE XREF: sub_48F820+7j
snyped:0048F853                                         ; sub_48F820+14j
snyped:0048F853                 pop     ebp
snyped:0048F854                 retn    4
snyped:0048F854 sub_48F820      endp


也就是在註冊碼輸入框輸入Ctrl+A(a)方能開啟,再次輸入註冊碼,註冊碼輸入框變為 "感謝您的註冊! (^_^)"
怎麼看這小臉笑得這麼甜,:)


總結一下注冊過程,首先雙擊"註冊碼" Label,然後在註冊碼輸入框按Ctrl+A,使能註冊事件。Delphi中獲取控制元件指標好像有固定模式,

snyped:0048CA6B                 mov     eax, [ebx+498h] ; 獲取控制元件指標,498h為控制元件偏移,有時是[eax+498h]
snyped:0048CA71                 mov     [eax+124h], ebx
snyped:0048CA77                 mov     dword ptr [eax+120h], offset sub_48DE70  ;  寫控制元件屬性

再透過IDA強大查詢功能可以找到一些隱含屬性或事件讀寫之處,方便破解。

初學破解,破文寫的有些混亂,見諒。

相關文章