轉貼一篇文章 作者的功力絕對不亞於任何高手 (37千字)

看雪資料發表於2001-11-19

SpyWindows監測軟體ME全系列完全破解--以ExeSpyME為例


  SpyWindows監測軟體ME系列包括以下工具:ComSpyME、ModemWatchME、ExeSpyME、HeapExplorer SE、ProcessExplorer SE、MemoryMonitorME、ODBCSpyME、HeapExplorerME、PhysicalMemoryExplorerME、ProcessMemoryExplorerME和SystemMemoryExplorerME,見名知義,從名字我們就可以知道其用途,這裡我就不細講了。以前我們曾經討論過SpyWindows監測軟體98系列三款工具的破解方法:SetupMonitor98、RegistryMonitor98及ResSpy98,ME系列在98系列的“.DAT” KEY FILE的基礎上又多出一個“.DLL”動態連結庫KEY FILE,其加密強度比單純的“.DAT” KEY FILE型要高出許多,所以要破解ME系列的軟體需要具有WIN32下DLL的彙編程式設計知識,而前面我們已經領教過98系列“.DAT” KEY FILE的厲害,那麼現在你可以想想要破解ME系列監測軟體的難度有多大了!同樣,ME系列所有軟體的加密方法跟98系列產品之間一樣,其同系列的產品加密方法一樣,只需要在某個軟體KEY FILE的基礎上簡單的替換一些相關資訊即可應用於其它軟體,這裡我們以ExeSpyME為例進行講解,其它ME系列的產品看完破解過程後你自然就明白怎麼改了。

程式名 :ExeSpyME
版本   :V5.0
大小   :689KB
執行平臺:Windows 95/98/ME
保護方式:KEY FILE(“.DAT”和“.DLL”)
破解方式:KEY FILE產生
破解難度:非常難

作者   :ddcrack (2001/11/05)

破解步驟:

1. 首先把98系列的破解搞懂:“SetupMonitor98/RegistryMonitor98/ResSpy98完全破解”,如果沒有徹底看明白,那麼下面的東西對你來說毫無用處,因為我是在98系列破解教程的基礎上展開的(為什麼不從頭開始寫?難到你真想讓我吐血啊!!!即便是我寫了,相信也沒有人看得懂,太複雜了!!!);

2. 用softice載入windows(透過CTRL+D來檢查softice是否已經準備好,按F5退出softice);

3. 在“開始”選單中點選“Spy Suite”下“ExeSpyME”的“ExeSpy”,此時我們可以從彈出的註冊對話方塊中看到KEY FILE的名字分別叫“EXEMEUE.DAT”和“ExeMEKey.DLL”;

4. 對於“EXEMEUE.DAT”,因為前面我們已經攻破了98系列的工具,所以我們這裡乾脆用98系列的“.DAT”KEY FILE來代替;而對於“ExeMEKey.DLL”就要多一些心眼了,我們可以想想這個“.DLL”的KEY FILE是不是隻是為了迷惑我們而故意用了DLL的字尾,其實暗地裡仍然是個“.DAT”KEY FILE呢?如果它真的是個動態連結庫檔案,那麼顯然我們就要面臨很大的困難了;先把SetupMonitor98的KEY FILE“SET98UR.DAT”改名換成“EXEMEUE.DAT”放在C盤根目錄下(注意:98系列的KEY FILE都有“SPYS”和“SPY1”兩種型別,那麼這裡究竟用哪一個呢?回答是用“SPY1”型,因為“SPY1”型的KEY FILE比“SPYS”型的複雜,我想在這種情況下複雜總比簡單的好吧!就象WINDOWS ME比WINDOWS 98要好一樣,新東西通常都比舊東西要複雜一點,而功能會更好一些),因為現在我們還不知道這個“.DLL”的KEY FILE究竟是何方神聖?所以暫時我們先構造一個名為“ExeMEKey.DLL”的文字檔案,假設這裡為“0123456789ABCDEFFEDCBA9876543210”,內容可以隨意(也許你有點糊塗:如何建立一個文字型別的“ExeMEKey.DLL”檔案呢?哈哈,這很簡單,先建個“.TXT”的檔案,將上面的文字內容輸進去,然後將檔名改掉就行了^_^);

5. 因為剛才把假的“EXEMEUE.DAT”和“ExeMEKey.DLL”放在了C盤根目錄,所以我們在ExeSpyME的註冊視窗中輸入驅動器號“C”;

6. 用CTRL+D撥出softice,下萬能斷點:bpx hmemcpy,按F5返回到ExeSpyME(是不是覺得有點浪費筆墨啊^_^,請多多包涵,我的破解文章總是這樣老土的,哈哈。。。);

7. 同樣地,在ExeSpyME註冊框中點選“LOAD”,程式立馬被softice攔截住(希望順利一些,不要太複雜了呀^_^);

8. 用 bd * 暫停斷點 bpx hmemcpy ;

9. 按F12鍵返回到ExeSpyME的領空(跟98系列一樣,應該還是9次啦!),程式停留在下面的地方:

。。。
0167:00411A30  MOV      BYTE PTR [EBP-50],00
0167:00411A34  PUSH      50
0167:00411A36  LEA      ECX,[EBP-50]
0167:00411A39  PUSH      ECX
0167:00411A3A  PUSH      000000BF
0167:00411A3F  MOV      EDX,[EBP+08]
0167:00411A42  PUSH      EDX
0167:00411A43  CALL      [USER32!GetDlgItemTextA]  <-- 獲取輸入的驅動器號
0167:00411A49  MOVSX    EAX,BYTE PTR [EBP-50]   <-- 我們來到這裡,將驅動器號送入EAX
0167:00411A4D  CMP      EAX,41
0167:00411A50  JL        00411A5B
0167:00411A52  MOVSX    ECX,BYTE PTR [EBP-50]
0167:00411A56  CMP      ECX,5A
0167:00411A59  JLE      00411A75
0167:00411A5B  MOVSX    EDX,BYTE PTR [EBP-50]
0167:00411A5F  CMP      EDX,61
0167:00411A62  JL        00411DD7
0167:00411A68  MOVSX    EAX,BYTE PTR [EBP-50]
0167:00411A6C  CMP      EAX,7A
0167:00411A6F  JG        00411DD7
0167:00411A75  MOV      DWORD PTR [EBP-00A4],00000001 <-- [EBP-00A4]置1
0167:00411A7F  MOVSX    ECX,BYTE PTR [004200AC]  <-- 004200AC指向字串“.\EXEMEKEY.DLL”
0167:00411A86  TEST      ECX,ECX
0167:00411A88  JZ        00411BF7
0167:00411A8E  LEA      EDX,[EBP-50]
0167:00411A91  PUSH      EDX
0167:00411A92  LEA      EAX,[EBP+FFFFEF54]
0167:00411A98  PUSH      EAX
0167:00411A99  CALL      [KERNEL32!lstrcpy]
0167:00411A9F  PUSH      00425154
0167:00411AA4  LEA      ECX,[EBP+FFFFEF54]
0167:00411AAA  PUSH      ECX
0167:00411AAB  CALL      [KERNEL32!lstrcat]
0167:00411AB1  PUSH      004200AE
0167:00411AB6  LEA      EDX,[EBP+FFFFEF54]
0167:00411ABC  PUSH      EDX
0167:00411ABD  CALL      [KERNEL32!lstrcat]
0167:00411AC3  PUSH      004200AC
0167:00411AC8  LEA      EAX,[EBP+FFFFDF54]
0167:00411ACE  PUSH      EAX
0167:00411ACF  CALL      [KERNEL32!lstrcpy]
0167:00411AD5  PUSH      00
0167:00411AD7  LEA      ECX,[EBP+FFFFEF54]
0167:00411ADD  PUSH      ECX            <-- ECX指向字串“C:\EXEMEKEY.DLL”
0167:00411ADE  CALL      [KERNEL32!_lopen]     <-- 開啟KEY FILE“C:\EXEMEKEY.DLL”
0167:00411AE4  MOV      [EBP-00A8],EAX
0167:00411AEA  CMP      DWORD PTR [EBP-00A8],-01
0167:00411AF1  JNZ      00411B36
0167:00411AF3  LEA      EDX,[EBP+FFFFEF54]
0167:00411AF9  PUSH      EDX
0167:00411AFA  PUSH      00425158
0167:00411AFF  LEA      EAX,[EBP-00A0]
0167:00411B05  PUSH      EAX
0167:00411B06  CALL      [USER32!wsprintfA]
0167:00411B0C  ADD      ESP,0C
0167:00411B0F  PUSH      10
0167:00411B11  PUSH      0042516C
0167:00411B16  LEA      ECX,[EBP-00A0]
0167:00411B1C  PUSH      ECX
0167:00411B1D  MOV      EDX,[EBP+08]
0167:00411B20  PUSH      EDX
0167:00411B21  CALL      [USER32!MessageBoxA]
0167:00411B27  MOV      DWORD PTR [EBP-00A4],00000000
0167:00411B31  JMP      00411BF7
0167:00411B36  PUSH      00
0167:00411B38  LEA      EAX,[EBP+FFFFDF54]
0167:00411B3E  PUSH      EAX            <-- EAX指向字串“.\EXEMEKEY.DLL”
0167:00411B3F  CALL      [KERNEL32!_lcreat]     <-- 在EXESPYME的當前目錄建立檔案“EXEMEKEY.DLL”
0167:00411B45  MOV      [EBP-00AC],EAX
0167:00411B4B  CMP      DWORD PTR [EBP-00AC],-01
0167:00411B52  JNZ      00411B9B
0167:00411B54  LEA      ECX,[EBP+FFFFDF54]
0167:00411B5A  PUSH      ECX
0167:00411B5B  LEA      EDX,[EBP+FFFFEF54]
0167:00411B61  PUSH      EDX
0167:00411B62  PUSH      00425174
0167:00411B67  LEA      EAX,[EBP-00A0]
0167:00411B6D  PUSH      EAX
0167:00411B6E  CALL      [USER32!wsprintfA]
0167:00411B74  ADD      ESP,10
0167:00411B77  PUSH      10
0167:00411B79  PUSH      00425194
0167:00411B7E  LEA      ECX,[EBP-00A0]
0167:00411B84  PUSH      ECX
0167:00411B85  MOV      EDX,[EBP+08]
0167:00411B88  PUSH      EDX
0167:00411B89  CALL      [USER32!MessageBoxA]
0167:00411B8F  MOV      DWORD PTR [EBP-00A4],00000000
0167:00411B99  JMP      00411BEA
0167:00411B9B  PUSH      50
0167:00411B9D  LEA      EAX,[EBP-00A0]
0167:00411BA3  PUSH      EAX
0167:00411BA4  MOV      ECX,[EBP-00A8]
0167:00411BAA  PUSH      ECX
0167:00411BAB  CALL      [KERNEL32!_hread]     <-- 讀檔案“C:\EXEMEKEY.DLL”
0167:00411BB1  MOV      [EBP+FFFFDF50],EAX
0167:00411BB7  CMP      DWORD PTR [EBP+FFFFDF50],00
0167:00411BBE  JLE      00411BDD
0167:00411BC0  MOV      EDX,[EBP+FFFFDF50]
0167:00411BC6  PUSH      EDX
0167:00411BC7  LEA      EAX,[EBP-00A0]
0167:00411BCD  PUSH      EAX
0167:00411BCE  MOV      ECX,[EBP-00AC]
0167:00411BD4  PUSH      ECX
0167:00411BD5  CALL      [KERNEL32!_hwrite]     <-- 寫檔案“.\EXEMEKEY.DLL”
0167:00411BDB  JMP      00411B9B
0167:00411BDD  MOV      EDX,[EBP-00AC]
0167:00411BE3  PUSH      EDX
0167:00411BE4  CALL      [KERNEL32!_lclose]     <-- 關閉檔案“.\EXEMEKEY.DLL”
0167:00411BEA  MOV      EAX,[EBP-00A8]
0167:00411BF0  PUSH      EAX
0167:00411BF1  CALL      [KERNEL32!_lclose]     <-- 關閉檔案“C:\EXEMEKEY.DLL”
0167:00411BF7  CMP      DWORD PTR [EBP-00A4],00
0167:00411BFE  JZ        00411DD5          <-- 不會跳
0167:00411C04  PUSH      0042519C
0167:00411C09  LEA      ECX,[EBP-50]
0167:00411C0C  PUSH      ECX
0167:00411C0D  CALL      [KERNEL32!lstrcat]
0167:00411C13  PUSH      0042009E
0167:00411C18  LEA      EDX,[EBP-50]
0167:00411C1B  PUSH      EDX
0167:00411C1C  CALL      [KERNEL32!lstrcat]
0167:00411C22  PUSH      00
0167:00411C24  LEA      EAX,[EBP-50]
0167:00411C27  PUSH      EAX            <-- EAX指向字串“C:\EXEMEUE.DAT”
0167:00411C28  CALL      [KERNEL32!_lopen]     <-- 開啟KEY FILE“C:\EXEMEUE.DAT”
0167:00411C2E  MOV      [EBP-00A8],EAX
0167:00411C34  CMP      DWORD PTR [EBP-00A8],-01
0167:00411C3B  JNZ      00411C73
0167:00411C3D  LEA      ECX,[EBP-50]
0167:00411C40  PUSH      ECX
0167:00411C41  PUSH      004251A0
0167:00411C46  LEA      EDX,[EBP-00A0]
0167:00411C4C  PUSH      EDX
0167:00411C4D  CALL      [USER32!wsprintfA]
0167:00411C53  ADD      ESP,0C
0167:00411C56  PUSH      10
0167:00411C58  PUSH      004251B4
0167:00411C5D  LEA      EAX,[EBP-00A0]
0167:00411C63  PUSH      EAX
0167:00411C64  MOV      ECX,[EBP+08]
0167:00411C67  PUSH      ECX
0167:00411C68  CALL      [USER32!MessageBoxA]
0167:00411C6E  JMP      00411DD5
0167:00411C73  MOV      EDX,[EBP-00A8]
0167:00411C79  PUSH      EDX
0167:00411C7A  CALL      [KERNEL32!_lclose]     <-- 關閉檔案“C:\EXEMEUE.DAT”
0167:00411C80  LEA      EAX,[EBP+FFFFDC9C]
0167:00411C86  PUSH      EAX            <-- 記憶體地址壓棧
0167:00411C87  LEA      ECX,[EBP+FFFFDCA4]
0167:00411C8D  PUSH      ECX            <-- 記憶體地址壓棧
0167:00411C8E  PUSH      0042006C          <-- 記憶體地址0042006C中是字串“ExeSpy Millennium Edition for Windows ME/98/95”
0167:00411C93  LEA      EDX,[EBP-50]
0167:00411C96  PUSH      EDX            <-- EDX指向字串“C:\EXEMEUE.DAT”
0167:00411C97  CALL      00419455          <-- 初步驗證KEY FILE“C:\EXEMEUE.DAT”
0167:00411C9C  MOV      [EBP+FFFFDCA0],EAX
0167:00411CA2  CMP      DWORD PTR [EBP+FFFFDCA0],00
0167:00411CA9  JNZ      00411CC6          <-- 驗證成功,則跳到00411CC6去
。。。

10. 這篇文章我不想再像前次那般詳細,因為經過98系列的破解後我們對程式已經有了足夠的瞭解,所以這裡“話不多說,點到即止”!在跟蹤的時候也沒有必要一步的走了,我們可以加快腳步,只是到了關鍵處才停下來看看,但是因為還不知道ME系列到底和98系列是否有多大的不同,所以我們還必須要從頭開始跟蹤程式一直到最後(針對“.DAT”KEY FILE而言)!

11. 上面的程式段作用比較簡單,主要是試著分別開啟KEY FILE“EXEMEKEY.DLL”和“EXEMEUE.DAT”,如果有一個檔案不存在則顯示出錯資訊,否則將KEY FILE“EXEMEKEY.DLL”複製到EXESPYME的當前目錄下;最後有個子程式CALL 00419455,看看其入口引數我們就知道是要初步驗證“EXEMEUE.DAT”的有效性,那麼這個CALL是否跟98系列的那個CALL一模一樣呢?當然不能保證了,但是至少應該不會差太多吧,還楞在這裡幹什麼,趕緊進去啊:
。。。
0167:00419455  PUSH      EBP
0167:00419456  MOV      EBP,ESP
0167:00419458  SUB      ESP,24
0167:0041945B  MOV      DWORD PTR [00426E00],00000000
0167:00419465  MOV      DWORD PTR [00426E04],00000000
0167:0041946F  MOV      DWORD PTR [00429F84],00429FA0
0167:00419479  PUSH      00008003
0167:0041947E  CALL      [KERNEL32!SetErrorMode]
0167:00419484  MOV      [EBP-1C],EAX
0167:00419487  PUSH      00
0167:00419489  MOV      EAX,[EBP+08]
0167:0041948C  PUSH      EAX
0167:0041948D  CALL      [KERNEL32!_lopen]     <-- 開啟KEY FILE“C:\EXEMEUE.DAT”
0167:00419493  MOV      [EBP-18],EAX
0167:00419496  MOV      ECX,[EBP-1C]
0167:00419499  PUSH      ECX
0167:0041949A  CALL      [KERNEL32!SetErrorMode]
0167:004194A0  CMP      DWORD PTR [EBP-18],-01
0167:004194A4  JZ        004194B9
0167:004194A6  PUSH      04
0167:004194A8  PUSH      00429FA0          <-- 將KEY FILE內容讀到記憶體地址00429FA0處
0167:004194AD  MOV      EDX,[EBP-18]
0167:004194B0  PUSH      EDX
0167:004194B1  CALL      [KERNEL32!_hread]
0167:004194B7  JMP      004194D2
0167:004194B9  PUSH      00425BD4
0167:004194BE  MOV      EAX,[EBP+10]
0167:004194C1  ADD      EAX,18
0167:004194C4  PUSH      EAX
0167:004194C5  CALL      [KERNEL32!lstrcpy]
0167:004194CB  XOR      EAX,EAX
0167:004194CD  JMP      00419579
0167:004194D2  MOV      ECX,[EBP-18]
0167:004194D5  PUSH      ECX
0167:004194D6  CALL      [KERNEL32!_lclose]
0167:004194DC  CMP      DWORD PTR [00429FA0],53595053  <-- 53595053即字串“SPYS”
0167:004194E6  JNZ      004194EF
0167:004194E8  XOR      EAX,EAX
0167:004194EA  JMP      00419579            <-- 完蛋了,GAME OVER!
0167:004194EF  CMP      DWORD PTR [00429FA0],31595053  <-- 31595053即字串“SPY1”
0167:004194F9  JNZ      0041952A
0167:004194FB  CMP      DWORD PTR [004256F4],02     <-- [004256F4] = 03
0167:00419502  JG        0041951E
0167:00419504  MOV      EDX,[EBP+14]
0167:00419507  PUSH      EDX
0167:00419508  MOV      EAX,[EBP+10]
0167:0041950B  PUSH      EAX
0167:0041950C  MOV      ECX,[EBP+0C]
0167:0041950F  PUSH      ECX
0167:00419510  MOV      EDX,[EBP+08]
0167:00419513  PUSH      EDX
0167:00419514  CALL      004197FC
0167:00419519  MOV      [EBP-20],EAX
0167:0041951C  JMP      00419525
0167:0041951E  MOV      DWORD PTR [EBP-20],00000000
0167:00419525  MOV      EAX,[EBP-20]
0167:00419528  JMP      00419579            <-- 完蛋了,GAME OVER!
0167:0041952A  CMP      DWORD PTR [00429FA0],32595053  <-- 32595053即字串“SPY2”
0167:00419534  JNZ      00419565
0167:00419536  CMP      DWORD PTR [004256F4],03     <-- [004256F4] = 03
0167:0041953D  JG        00419559
0167:0041953F  MOV      EAX,[EBP+14]
0167:00419542  PUSH      EAX            <-- 記憶體地址壓棧
0167:00419543  MOV      ECX,[EBP+10]
0167:00419546  PUSH      ECX            <-- 記憶體地址壓棧
0167:00419547  MOV      EDX,[EBP+0C]
0167:0041954A  PUSH      EDX            <-- EDX指向字串“ExeSpy Millennium Edition for Windows ME/98/95”
0167:0041954B  MOV      EAX,[EBP+08]
0167:0041954E  PUSH      EAX            <-- EAX指向字串“C:\EXEMEUE.DAT”
0167:0041954F  CALL      0041A0CC          <-- 驗證KEY FILE“C:\EXEMEUE.DAT”
0167:00419554  MOV      [EBP-24],EAX
0167:00419557  JMP      00419560
0167:00419559  MOV      DWORD PTR [EBP-24],00000000
0167:00419560  MOV      EAX,[EBP-24]
0167:00419563  JMP      00419579
0167:00419565  PUSH      00425BE0
0167:0041956A  MOV      ECX,[EBP+10]
0167:0041956D  ADD      ECX,18
0167:00419570  PUSH      ECX
0167:00419571  CALL      [KERNEL32!lstrcpy]
0167:00419577  XOR      EAX,EAX
0167:00419579  MOV      ESP,EBP
0167:0041957B  POP      EBP
0167:0041957C  RET      0010
。。。

12. 是不是跟98系列不一樣了呀?“半路殺出個程咬金”,程式中多了一個值為03的常量[004256F4]摻和進來,為什麼我說是常量呢?因為這個值不是KEY FILE驗證部分程式設定的,而且你可以試著多執行程式幾次,它的值都固定為03,在這段程式中,我們可以發現以前98系列採用的兩種KEY FILE型“SPYS”和“SPY1”在這裡都已經失效,只有當KEY FILE資料的頭4個字元是“SPY2”才能繼續下面的驗證;因此現在要麼回頭修改那個假的KEY FILE,要麼用 RFL Z 命令騙過程式,總之要走到0167:0041954F處的CALL 0041A0CC並跟蹤進去(其它地方都是死路一條啊!另外,關於[004256F4],用W32DASM反彙編EXESPYME之後查詢“004256F4”,你會發現這個值其實是程式初始化時設定的一個跟版本有關的東西,所以它是不會變的):
。。。
0167:0041A0CC  PUSH      EBP
0167:0041A0CD  MOV      EBP,ESP
0167:0041A0CF  SUB      ESP,24
0167:0041A0D2  MOV      DWORD PTR [EBP-08],00000000 <-- [EBP-08]置00
0167:0041A0D9  MOV      DWORD PTR [EBP-04],00000000 <-- [EBP-04]置00
0167:0041A0E0  MOVSX    EAX,BYTE PTR [004200AC]
0167:0041A0E7  TEST      EAX,EAX
0167:0041A0E9  JZ        0041A15A
0167:0041A0EB  PUSH      004200AC          <-- 004200AC指向字串“.\EXEMEKEY.DLL”
0167:0041A0F0  CALL      [KERNEL32!LoadLibraryA]  <-- 載入EXESPYME當前目錄中的動態連結庫“EXEMEKEY.DLL”
0167:0041A0F6  MOV      [EBP-1C],EAX        <-- 儲存返回結果,成功則EAX為動態連結庫控制程式碼,否則EAX=NULL
0167:0041A0F9  CMP      DWORD PTR [EBP-1C],00   <-- 載入成功嗎?
0167:0041A0FD  JZ        0041A15A          <-- 不成功
0167:0041A0FF  PUSH      65             <-- 引出函式索引值為65
0167:0041A101  MOV      ECX,[EBP-1C]
0167:0041A104  PUSH      ECX            <-- 動態連結庫控制程式碼壓棧
0167:0041A105  CALL      [KERNEL32!GetProcAddress] <-- 得到引出索引值為65的函式在記憶體中的地址值
0167:0041A10B  MOV      [EBP-20],EAX        <-- 儲存返回結果,成功則EAX為函式地址,否則EAX=NULL
0167:0041A10E  CMP      DWORD PTR [EBP-20],00   <-- 動態連結庫“EXEMEKEY.DLL”中是否存在索引值為65的函式?
0167:0041A112  JZ        0041A150          <-- 不成功
0167:0041A114  LEA      EDX,[EBP-18]
0167:0041A117  PUSH      EDX            <-- 記憶體地址EBP-18壓棧
0167:0041A118  PUSH      000002AC          <-- 常數000002AC壓棧
0167:0041A11D  PUSH      00429380          <-- 記憶體地址00429380壓棧
0167:0041A122  CALL      [EBP-20]          <-- 呼叫動態連結庫中引出索引值為65的函式(搞什麼鬼呀!不明白!)
0167:0041A125  MOV      [EBP-04],EAX        <-- 儲存函式返回結果EAX到[EBP-04]
0167:0041A128  CMP      DWORD PTR [EBP-04],00   <-- 返回結果為00嗎?
0167:0041A12C  JZ        0041A150          <-- 是則跳到0041A150去,想想。。。哇噻!跳過去就死蹺蹺了!
0167:0041A12E  MOV      EAX,[EBP-18]        <-- EBP-18是函式的入口引數之一
0167:0041A131  MOV      [004256E0],EAX       <-- [EBP-18]存入[004256E0]
0167:0041A136  MOV      ECX,[EBP-14]
0167:0041A139  MOV      [004256E4],ECX       <-- [EBP-14]存入[004256E4]
0167:0041A13F  MOV      EDX,[EBP-10]
0167:0041A142  MOV      [004256E8],EDX       <-- [EBP-10]存入[004256E8]
0167:0041A148  MOV      EAX,[EBP-0C]
0167:0041A14B  MOV      [004256EC],EAX       <-- [EBP-0C]存入[004256EC]
0167:0041A150  MOV      ECX,[EBP-1C]
0167:0041A153  PUSH      ECX            <-- 動態連結庫控制程式碼壓棧
0167:0041A154  CALL      [KERNEL32!FreeLibrary]   <-- 釋放動態連結庫“.\EXEMEKEY.DLL”
0167:0041A15A  CMP      DWORD PTR [EBP-04],00   <-- [EBP-04]仍然是00嗎?
0167:0041A15E  JZ        0041A178          <-- 是則跳到0041A178去
0167:0041A160  MOV      EDX,[EBP+14]
0167:0041A163  PUSH      EDX            <-- 記憶體地址壓棧
0167:0041A164  MOV      EAX,[EBP+10]
0167:0041A167  PUSH      EAX            <-- 記憶體地址壓棧
0167:0041A168  MOV      ECX,[EBP+0C]
0167:0041A16B  PUSH      ECX            <-- ECX指向字串“ExeSpy Millennium Edition for Windows ME/98/95”
0167:0041A16C  MOV      EDX,[EBP+08]
0167:0041A16F  PUSH      EDX            <-- EAX指向字串“C:\EXEMEUE.DAT”
0167:0041A170  CALL      00419C0B          <-- 繼續驗證KEY FILE“C:\EXEMEUE.DAT”(煩不煩啊,不知道還會出什麼花招?!)
0167:0041A175  MOV      [EBP-08],EAX        <-- 驗證結果存在[EBP-08]中
0167:0041A178  PUSH      00000298          <-- 常數000002AC壓棧
0167:0041A17D  PUSH      00429394          <-- 記憶體地址00429380+14壓棧(為什麼這樣寫,因為地址00429394在00429380的偏移14處
0167:0041A182  MOV      EAX,[EBP+10]        <-- EBP+10是前面CALL 00419C0B的入口引數之一
0167:0041A185  ADD      EAX,14           <-- 偏移14處的地址給EAX
0167:0041A188  PUSH      EAX            <-- EAX中的地址壓棧
0167:0041A189  CALL      0041A085          <-- 不知道里面有什麼機關?
0167:0041A18E  MOV      [EBP-04],EAX        <-- 返回值存在[EBP-04]中
0167:0041A191  MOV      EAX,[EBP-04]
0167:0041A194  NEG      EAX            <-- [EBP-04]取反
0167:0041A196  SBB      EAX,EAX          <-- 帶進位自減,如果CY=1,則EAX=FFFFFFFF,否則EAX=0
0167:0041A198  AND      EAX,[EBP-08]        <-- 減法結果和[EBP-08]相與作為子程式返回值
0167:0041A19B  MOV      ESP,EBP
0167:0041A19D  POP      EBP
0167:0041A19E  RET      0010
。。。

13. 上面的程式跟98系列就完全不一樣了,因為這裡是“EXEMEKEY.DLL”在唱主角:0167:0041A0F0處的CALL [KERNEL32!LoadLibraryA]載入動態連結庫“EXEMEKEY.DLL”,接著0167:0041A105處的CALL [KERNEL32!GetProcAddress]試圖取得動態連結庫中索引值為65的函式在記憶體中的地址,然後在0167:0041A122 CALL [EBP-20]處程式呼叫這個函式;現在看來這個“EXEMEKEY.DLL”KEY FILE可不是省油的燈,因為我們構造的假“EXEMEKEY.DLL”只是個文字檔案,所以當我們走到0167:0041A0F0 CALL [KERNEL32!LoadLibraryA]時就已經被斃掉了;繼續往下看,從0167:0041A12E到0167:0041A14B,緊接著剛才的函式呼叫之後程式開始設定[004256E0]、[004256E4]、[004256E8]和[004256EC]的值,這幾個值肯定跟那個函式有關,隨後程式在0167:0041A154 CALL [KERNEL32!FreeLibrary]釋放已經載入的動態連線庫“EXEMEKEY.DLL”;

14. 到這裡就不要急著往下走了(可以將滑鼠移到0167:0041A0F0處並按F9設定一個斷點,下次就不用重複前面已經搞清楚的跟蹤了),因為程式在檢測“EXEMEKEY.DLL”這個動態連結庫KEY FILE,雖然可以繼續用 RFL Z 來騙過去,但是我們要想破解它就必須寫出真正的“EXEMEKEY.DLL”來,雖然現在還不知道“EXEMEKEY.DLL”的內部應該是什麼樣的程式結構,但是至少我們已經知道這個DLL至少包含一個索引值為65的引出函式,如果具備這個條件,那麼程式就可以順利的走到0167:0041A154 CALL [KERNEL32!FreeLibrary]處,至於其它的奧妙要等後面的進一步跟蹤才能明白;

15. 開頭我就已經講過破解EXESPYME需要懂得WIN32下的DLL彙編程式設計,所以這裡我直接給出程式,至於為什麼就不要問我了,如果你不懂DLL的知識,可以去主頁的“組合語言”中看看“Iczelion's Win32 彙編教學”,以下是源程式(用MASM32編譯透過,MASM32可以在“組合語言”中下載,其實程式再簡單不過了^_^!):
-------------------------------------------------------------------------------------------------------------------------
;Exemekey.asm

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data

.code
DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
      mov  eax,TRUE
      ret
DllEntry Endp

Call_ebp_20 proc
      mov  eax,00000001      <-- 注意:EAX是程式返回值,不能為0,所以將其設為1
      ret  0ch                <-- 為什麼是“ret 0ch”,因為函式有3個入口引數嘛!,所以要讓ESP加3*4=12,否則程式會出問題的
Call_ebp_20 Endp

End DllEntry

-----------------------------------------------------------------------------------------------------------------------
;Exemekey.def

LIBRARY Exemekey
EXPORTS Call_ebp_20 @101      <-- 101即為16進位制數65H

-----------------------------------------------------------------------------------------------------------------------

;build.bat

@echo off
\masm32\bin\ml /c /coff /Cp Exemekey.asm
\masm32\bin\link /DLL /DEF:Exemekey.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib Exemekey.obj
pause

-----------------------------------------------------------------------------------------------------------------------

16. 用上面給出的批處理檔案“build.bat”建立動態連結庫KEY FILE“EXEMEKEY.DLL”,然後將其替換掉C盤根目錄下原來那個假的文字DLL KEY FILE,重新來到步驟12的地方(記得剛才用F9設定的斷點嗎?),因為現在我們的“EXEMEKEY.DLL”是個真正的DLL程式,並且具有索引值為65的函式,所以我們按F10可以一直來到0167:0041A170 CALL 00419C0B,接著按F8進入CALL 00419C0B裡去:
。。。
0167:00419C0B  PUSH      EBP
0167:00419C0C  MOV      EBP,ESP
0167:00419C0E  SUB      ESP,60
0167:00419C11  PUSH      ESI
0167:00419C12  MOV      DWORD PTR [00426E00],00000000
0167:00419C1C  MOV      DWORD PTR [00426E04],00000002
0167:00419C26  MOV      DWORD PTR [00429F84],00429FA0
0167:00419C30  PUSH      00008003
0167:00419C35  CALL      [KERNEL32!SetErrorMode]
0167:00419C3B  MOV      [EBP-38],EAX
0167:00419C3E  PUSH      00
0167:00419C40  MOV      EAX,[EBP+08]
0167:00419C43  PUSH      EAX
0167:00419C44  CALL      [KERNEL32!_lopen]
0167:00419C4A  MOV      [EBP-34],EAX
0167:00419C4D  MOV      ECX,[EBP-38]
0167:00419C50  PUSH      ECX
0167:00419C51  CALL      [KERNEL32!SetErrorMode]
0167:00419C57  CMP      DWORD PTR [EBP-34],-01
0167:00419C5B  JZ        00419C73
0167:00419C5D  PUSH      0001E000
0167:00419C62  PUSH      00429FA0
0167:00419C67  MOV      EDX,[EBP-34]
0167:00419C6A  PUSH      EDX
0167:00419C6B  CALL      [KERNEL32!_hread]
0167:00419C71  JMP      00419C8C
0167:00419C73  PUSH      00425C64
0167:00419C78  MOV      EAX,[EBP+10]
0167:00419C7B  ADD      EAX,18
0167:00419C7E  PUSH      EAX
0167:00419C7F  CALL      [KERNEL32!lstrcpy]
0167:00419C85  XOR      EAX,EAX
0167:00419C87  JMP      0041A07E
0167:00419C8C  MOV      ECX,[EBP-34]
0167:00419C8F  PUSH      ECX
0167:00419C90  CALL      [KERNEL32!_lclose]
0167:00419C96  MOV      EDX,[00429FAC]
0167:00419C9C  XOR      EDX,[004256E8]
0167:00419CA2  MOV      [EBP-20],EDX       <-- [EBP-20]=[00429FA0+0C] XOR [004256E8]
0167:00419CA5  MOV      EAX,[00429FB0]
0167:00419CAA  XOR      EAX,[004256E4]
0167:00419CB0  MOV      [EBP-1C],EAX       <-- [EBP-1C]=[00429FA0+10] XOR [004256E4]
0167:00419CB3  MOV      ECX,[00429FB4]
0167:00419CB9  XOR      ECX,[004256E0]
0167:00419CBF  MOV      [EBP-14],ECX       <-- [EBP-14]=[00429FA0+14] XOR [004256E0]
0167:00419CC2  MOV      EDX,[EBP-14]
0167:00419CC5  XOR      EDX,[EBP-1C]
0167:00419CC8  XOR      EDX,[EBP-20]
0167:00419CCB  MOV      [EBP-0C],EDX       <-- [EBP-0C]=[EBP-20] XOR [EBP-1C] XOR [EBP-14]
0167:00419CCE  MOV      EAX,[00429FB8]
0167:00419CD3  MOV      [EBP-28],EAX
0167:00419CD6  MOV      EAX,[00429FA4]
0167:00419CDB  XOR      EAX,[00429FA8]
0167:00419CE1  CDQ
0167:00419CE2  AND      EDX,03
0167:00419CE5  ADD      EAX,EDX
0167:00419CE7  SAR      EAX,02
0167:00419CEA  ADD      EAX,06
0167:00419CED  MOV      [EBP-10],EAX
0167:00419CF0  CMP      DWORD PTR [EBP-10],00002800
0167:00419CF7  JL        00419D12
0167:00419CF9  PUSH      00425C70
0167:00419CFE  MOV      ECX,[EBP+10]
0167:00419D01  ADD      ECX,18
0167:00419D04  PUSH      ECX
0167:00419D05  CALL      [KERNEL32!lstrcpy]
0167:00419D0B  XOR      EAX,EAX
0167:00419D0D  JMP      0041A07E
0167:00419D12  MOV      EDX,[EBP-10]
0167:00419D15  MOV      EAX,[EDX*4+00429FA0]
0167:00419D1C  MOV      [EBP-28],EAX
0167:00419D1F  MOV      EAX,[EBP-28]
0167:00419D22  CDQ
0167:00419D23  AND      EDX,03
0167:00419D26  ADD      EAX,EDX
0167:00419D28  SAR      EAX,02
0167:00419D2B  MOV      ECX,[EBP-10]
0167:00419D2E  LEA      EDX,[EAX+ECX+01]
0167:00419D32  MOV      [EBP-10],EDX
0167:00419D35  CMP      DWORD PTR [EBP-10],00002800
0167:00419D3C  JGE      00419D44
0167:00419D3E  CMP      DWORD PTR [EBP-10],00
0167:00419D42  JG        00419D5D
0167:00419D44  PUSH      00425C7C
0167:00419D49  MOV      EAX,[EBP+10]
0167:00419D4C  ADD      EAX,18
0167:00419D4F  PUSH      EAX
0167:00419D50  CALL      [KERNEL32!lstrcpy]
0167:00419D56  XOR      EAX,EAX
0167:00419D58  JMP      0041A07E
0167:00419D5D  MOV      ECX,[EBP-10]
0167:00419D60  MOV      EDX,[ECX*4+00429FA0]
0167:00419D67  MOV      [EBP-28],EDX
0167:00419D6A  MOV      EAX,[EBP-28]
0167:00419D6D  MOV      ECX,[EBP-10]
0167:00419D70  LEA      EDX,[EAX+ECX+01]
0167:00419D74  CMP      EDX,00002800
0167:00419D7A  JGE      00419D8A
0167:00419D7C  MOV      EAX,[EBP-28]
0167:00419D7F  MOV      ECX,[EBP-10]
0167:00419D82  LEA      EDX,[EAX+ECX+01]
0167:00419D86  TEST      EDX,EDX
0167:00419D88  JG        00419DA3
0167:00419D8A  PUSH      00425C88
0167:00419D8F  MOV      EAX,[EBP+10]
0167:00419D92  ADD      EAX,18
0167:00419D95  PUSH      EAX
0167:00419D96  CALL      [KERNEL32!lstrcpy]
0167:00419D9C  XOR      EAX,EAX
0167:00419D9E  JMP      0041A07E
0167:00419DA3  MOV      ECX,[EBP-10]
0167:00419DA6  LEA      EDX,[ECX*4+00429FA4]
0167:00419DAD  MOV      [EBP-18],EDX       <-- [EBP-18]=ECX*4+00429FA4
0167:00419DB0  MOV      EAX,[EBP-18]
0167:00419DB3  ADD      EAX,14
0167:00419DB6  MOV      [00429F80],EAX
0167:00419DBB  MOV      DWORD PTR [EBP-24],000000A5
0167:00419DC2  JMP      00419DCD
0167:00419DC4  MOV      ECX,[EBP-24]
0167:00419DC7  SUB      ECX,01
0167:00419DCA  MOV      [EBP-24],ECX
0167:00419DCD  CMP      DWORD PTR [EBP-24],00
0167:00419DD1  JL        00419E03
0167:00419DD3  MOV      EDX,[EBP-0C]
0167:00419DD6  XOR      EDX,[EBP-24]
0167:00419DD9  MOV      EAX,[EBP-24]
0167:00419DDC  MOV      ECX,[00429F80]
0167:00419DE2  MOV      EAX,[EAX*4+ECX-04]
0167:00419DE6  XOR      EAX,EDX
0167:00419DE8  MOV      ECX,[EBP-24]
0167:00419DEB  MOV      EDX,[00429F80]
0167:00419DF1  MOV      ECX,[ECX*4+EDX]
0167:00419DF4  XOR      ECX,EAX
0167:00419DF6  MOV      EDX,[EBP-24]
0167:00419DF9  MOV      EAX,[00429F80]
0167:00419DFE  MOV      [EDX*4+EAX],ECX
0167:00419E01  JMP      00419DC4
0167:00419E03  MOV      ECX,[00429F80]
0167:00419E09  MOV      EDX,[ECX]
0167:00419E0B  XOR      EDX,[EBP-0C]
0167:00419E0E  MOV      EAX,[00429F80]
0167:00419E13  MOV      [EAX],EDX
0167:00419E15  CMP      DWORD PTR [EBP-0C],00
0167:00419E19  JZ        00419E23
0167:00419E1B  MOV      ECX,[EBP-0C]
0167:00419E1E  MOV      [EBP-60],ECX
0167:00419E21  JMP      00419E2A
0167:00419E23  MOV      DWORD PTR [EBP-60],00000001
0167:00419E2A  MOV      EDX,[EBP+14]
0167:00419E2D  MOV      EAX,[EBP-60]
0167:00419E30  MOV      [EDX],EAX
0167:00419E32  MOV      ECX,[EBP+0C]
0167:00419E35  PUSH      ECX
0167:00419E36  MOV      EDX,[EBP-18]
0167:00419E39  ADD      EDX,18
0167:00419E3C  PUSH      EDX
0167:00419E3D  CALL      [KERNEL32!lstrcmp]
0167:00419E43  TEST      EAX,EAX
0167:00419E45  JZ        00419E60
0167:00419E47  PUSH      00425C94
0167:00419E4C  MOV      EAX,[EBP+10]
0167:00419E4F  ADD      EAX,18
0167:00419E52  PUSH      EAX
0167:00419E53  CALL      [KERNEL32!lstrcpy]
0167:00419E59  XOR      EAX,EAX
0167:00419E5B  JMP      0041A07E
0167:00419E60  MOV      ECX,[EBP+10]
0167:00419E63  MOV      [EBP-2C],ECX
0167:00419E66  MOV      EDX,[EBP-18]
0167:00419E69  MOV      [EBP-30],EDX
0167:00419E6C  MOV      DWORD PTR [EBP-24],00000000
0167:00419E73  JMP      00419E7E
0167:00419E75  MOV      EAX,[EBP-24]
0167:00419E78  ADD      EAX,01
0167:00419E7B  MOV      [EBP-24],EAX
0167:00419E7E  CMP      DWORD PTR [EBP-24],000002AC
0167:00419E85  JAE      00419E99
0167:00419E87  MOV      ECX,[EBP-2C]
0167:00419E8A  ADD      ECX,[EBP-24]
0167:00419E8D  MOV      EDX,[EBP-30]
0167:00419E90  ADD      EDX,[EBP-24]
0167:00419E93  MOV      AL,[EDX]
0167:00419E95  MOV      [ECX],AL
0167:00419E97  JMP      00419E75
0167:00419E99  MOV      ECX,[EBP-18]       <-- [EBP-18]=ECX*4+00429FA4(這個ECX是上面的ECX)
0167:00419E9C  ADD      ECX,000002AC
0167:00419EA2  MOV      [EBP-50],ECX
0167:00419EA5  MOV      EDX,[EBP-50]       <-- [EBP-18]=ECX*4+00429FA4+000002AC
0167:00419EA8  MOV      EAX,[EDX]
0167:00419EAA  XOR      EAX,[004256E8]
0167:00419EB0  MOV      [EBP-48],EAX       <-- [EBP-48]=[ECX*4+00429FA4+000002AC+00] XOR [004256E8]
0167:00419EB3  MOV      ECX,[EBP-50]
0167:00419EB6  MOV      EDX,[ECX+04]
0167:00419EB9  XOR      EDX,[004256E4]
0167:00419EBF  MOV      [EBP-44],EDX       <-- [EBP-44]=[ECX*4+00429FA4+000002AC+04] XOR [004256E4]
0167:00419EC2  MOV      EAX,[EBP-50]
0167:00419EC5  MOV      ECX,[EAX+08]
0167:00419EC8  XOR      ECX,[004256E0]
0167:00419ECE  MOV      [EBP-40],ECX       <-- [EBP-40]=[ECX*4+00429FA4+000002AC+08] XOR [004256E0]
0167:00419ED1  MOV      EDX,[EBP-40]
0167:00419ED4  ADD      EDX,[EBP-44]
0167:00419ED7  ADD      EDX,[EBP-48]
0167:00419EDA  MOV      [EBP-3C],EDX       <-- [EBP-3C]=[EBP-40] ADD [EBP-44] ADD [EBP-48]
0167:00419EDD  MOV      EAX,[EBP-18]
0167:00419EE0  ADD      EAX,000002B8
0167:00419EE5  MOV      [EBP-04],EAX       <-- [EBP-04]=ECX*4+00429FA4+000002B8
0167:00419EE8  MOV      ECX,[EBP-04]
0167:00419EEB  ADD      ECX,14
0167:00419EEE  MOV      [00429F80],ECX
0167:00419EF4  MOV      DWORD PTR [EBP-24],000000A5
0167:00419EFB  JMP      00419F06
0167:00419EFD  MOV      EDX,[EBP-24]
0167:00419F00  SUB      EDX,01
0167:00419F03  MOV      [EBP-24],EDX
0167:00419F06  CMP      DWORD PTR [EBP-24],00
0167:00419F0A  JL        00419F3C
0167:00419F0C  MOV      EAX,[EBP-3C]
0167:00419F0F  XOR      EAX,[EBP-24]
0167:00419F12  MOV      ECX,[EBP-24]
0167:00419F15  MOV      EDX,[00429F80]
0167:00419F1B  MOV      ECX,[ECX*4+EDX-04]
0167:00419F1F  XOR      ECX,EAX
0167:00419F21  MOV      EDX,[EBP-24]
0167:00419F24  MOV      EAX,[00429F80]
0167:00419F29  MOV      EDX,[EDX*4+EAX]
0167:00419F2C  XOR      EDX,ECX
0167:00419F2E  MOV      EAX,[EBP-24]
0167:00419F31  MOV      ECX,[00429F80]
0167:00419F37  MOV      [EAX*4+ECX],EDX
0167:00419F3A  JMP      00419EFD
0167:00419F3C  MOV      EDX,[00429F80]
0167:00419F42  MOV      EAX,[EDX]
0167:00419F44  XOR      EAX,[EBP-3C]
0167:00419F47  MOV      ECX,[00429F80]
0167:00419F4D  MOV      [ECX],EAX
0167:00419F4F  MOV      EDX,[EBP-04]       <-- [EBP-04]=ECX*4+00429FA4+000002B8
0167:00419F52  ADD      EDX,000002AC
0167:00419F58  MOV      [EBP-50],EDX       <-- [EBP-50]=ECX*4+00429FA4+000002B8+000002AC
0167:00419F5B  MOV      EAX,[EBP-50]
0167:00419F5E  MOV      ECX,[EAX]
0167:00419F60  XOR      ECX,[004256E8]
0167:00419F66  MOV      [EBP-48],ECX       <-- [EBP-48]=[ECX*4+00429FA4+000002B8+000002AC+00] XOR [004256E8]
0167:00419F69  MOV      EDX,[EBP-50]
0167:00419F6C  MOV      EAX,[EDX+04]
0167:00419F6F  XOR      EAX,[004256E4]
0167:00419F75  MOV      [EBP-44],EAX       <-- [EBP-44]=[ECX*4+00429FA4+000002B8+000002AC+04] XOR [004256E4]
0167:00419F78  MOV      ECX,[EBP-50]
0167:00419F7B  MOV      EDX,[ECX+08]
0167:00419F7E  XOR      EDX,[004256E0]
0167:00419F84  MOV      [EBP-40],EDX       <-- [EBP-40]=[ECX*4+00429FA4+000002B8+000002AC+08] XOR [004256E0]
0167:00419F87  MOV      EAX,[EBP-44]
0167:00419F8A  XOR      EAX,[EBP-48]
0167:00419F8D  MOV      ECX,[EBP-40]
0167:00419F90  ADD      ECX,EAX
0167:00419F92  MOV      [EBP-3C],ECX       <-- [EBP-3C]=([EBP-44] XOR [EBP-48]) ADD [EBP-40]
0167:00419F95  MOV      EDX,[EBP-04]
0167:00419F98  ADD      EDX,000002B8
0167:00419F9E  MOV      [EBP-08],EDX
0167:00419FA1  MOV      EAX,[EBP-08]
0167:00419FA4  ADD      EAX,000002AC
0167:00419FA9  MOV      [00426E00],EAX
0167:00419FAE  MOV      ECX,[EBP-08]
0167:00419FB1  ADD      ECX,14
0167:00419FB4  MOV      [00429F80],ECX
0167:00419FBA  MOV      DWORD PTR [EBP-24],000000A5
0167:00419FC1  JMP      00419FCC
0167:00419FC3  MOV      EDX,[EBP-24]
0167:00419FC6  SUB      EDX,01
0167:00419FC9  MOV      [EBP-24],EDX
0167:00419FCC  CMP      DWORD PTR [EBP-24],00
0167:00419FD0  JL        0041A002
0167:00419FD2  MOV      EAX,[EBP-3C]
0167:00419FD5  XOR      EAX,[EBP-24]
0167:00419FD8  MOV      ECX,[EBP-24]
0167:00419FDB  MOV      EDX,[00429F80]
0167:00419FE1  MOV      ECX,[ECX*4+EDX-04]
0167:00419FE5  XOR      ECX,EAX
0167:00419FE7  MOV      EDX,[EBP-24]
0167:00419FEA  MOV      EAX,[00429F80]
0167:00419FEF  MOV      EDX,[EDX*4+EAX]
0167:00419FF2  XOR      EDX,ECX
0167:00419FF4  MOV      EAX,[EBP-24]
0167:00419FF7  MOV      ECX,[00429F80]
0167:00419FFD  MOV      [EAX*4+ECX],EDX
0167:0041A000  JMP      00419FC3
0167:0041A002  MOV      EDX,[00429F80]
0167:0041A008  MOV      EAX,[EDX]
0167:0041A00A  XOR      EAX,[EBP-3C]
0167:0041A00D  MOV      ECX,[00429F80]
0167:0041A013  MOV      [ECX],EAX
0167:0041A015  MOV      EDX,[EBP-04]
0167:0041A018  ADD      EDX,14
0167:0041A01B  MOV      [EBP-54],EDX
0167:0041A01E  MOV      EAX,[EBP-08]
0167:0041A021  ADD      EAX,14
0167:0041A024  MOV      [EBP-58],EAX
0167:0041A027  MOV      ECX,[EBP+10]
0167:0041A02A  ADD      ECX,14
0167:0041A02D  MOV      [EBP-5C],ECX
0167:0041A030  MOV      DWORD PTR [EBP-24],000000A5
0167:0041A037  JMP      0041A042
0167:0041A039  MOV      EDX,[EBP-24]
0167:0041A03C  SUB      EDX,01
0167:0041A03F  MOV      [EBP-24],EDX
0167:0041A042  CMP      DWORD PTR [EBP-24],01
0167:0041A046  JL        0041A076
0167:0041A048  MOV      EAX,[EBP-24]
0167:0041A04B  MOV      ECX,[EBP-54]
0167:0041A04E  MOV      EDX,[EBP-24]
0167:0041A051  MOV      ESI,[EBP-5C]
0167:0041A054  MOV      EAX,[EAX*4+ECX]
0167:0041A057  CMP      EAX,[EDX*4+ESI]
0167:0041A05A  JNZ      0041A070
0167:0041A05C  MOV      ECX,[EBP-24]
0167:0041A05F  MOV      EDX,[EBP-58]
0167:0041A062  MOV      EAX,[EBP-24]
0167:0041A065  MOV      ESI,[EBP-5C]
0167:0041A068  MOV      ECX,[ECX*4+EDX]
0167:0041A06B  CMP      ECX,[EAX*4+ESI]
0167:0041A06E  JZ        0041A074
0167:0041A070  XOR      EAX,EAX
0167:0041A072  JMP      0041A07E
0167:0041A074  JMP      0041A039
0167:0041A076  MOV      EDX,[EBP+14]
0167:0041A079  MOV      EAX,[EDX]
0167:0041A07B  XOR      EAX,-01
0167:0041A07E  POP      ESI
0167:0041A07F  MOV      ESP,EBP
0167:0041A081  POP      EBP
0167:0041A082  RET      0010
。。。

17. 增大眼睛看清楚上面的程式段,大體上和98系列的相應程式是一樣的,最明顯的地方就是這裡的異或因子XOR_FACTOR計算方法和以前不一樣:
  第一輪的異或因子XOR_FACTOR1=[EBP-0C]=[EBP-20] XOR [EBP-1C] XOR [EBP-14],其中:[EBP-20]=[00429FA0+0C] XOR [004256E8]、[EBP-1C]=[00429FA0+10] XOR [004256E4]、[EBP-14]=[00429FA0+14] XOR [004256E0];
  第二輪的異或因子XOR_FACTOR2=[EBP-3C]=[EBP-40] ADD [EBP-44] ADD [EBP-48],其中:[EBP-48]=[ECX*4+00429FA4+000002AC+00] XOR [004256E8]、[EBP-44]=[ECX*4+00429FA4+000002AC+04] XOR [004256E4]、 [EBP-40]=[ECX*4+00429FA4+000002AC+08] XOR [004256E0];
  第三輪的異或因子XOR_FACTOR3=[EBP-3C]=([EBP-44] XOR [EBP-48]) ADD [EBP-40],其中:[EBP-48]=[ECX*4+00429FA4+000002B8+000002AC+00] XOR [004256E8]、 [EBP-44]=[ECX*4+00429FA4+000002B8+000002AC+04] XOR [004256E4]、[EBP-40]=[ECX*4+00429FA4+000002B8+000002AC+08] XOR [004256E0];
  看明白了嗎?其實只是在98系列異或因子計算的基礎上每個對應項都異或了[004256E8]、[004256E4]和[004256E0]三個值中的某一個,也就是隻要將異或這三個值的地方拿掉就和98系列的子程式一模一樣了!

18. 從上面的子程式CALL 00419C0B出來後我們走到步驟12中這個CALL下面的語句0167:0041A189 CALL 0041A085處停下,然後按F8進去:
。。。
0167:0041A085  PUSH      EBP
0167:0041A086  MOV      EBP,ESP
0167:0041A088  PUSH      ECX
0167:0041A089  MOV      DWORD PTR [EBP-04],00000000 <-- 迴圈計數值[EBP-04]初值為00
0167:0041A090  JMP      0041A09B
0167:0041A092  MOV      EAX,[EBP-04]
0167:0041A095  ADD      EAX,01
0167:0041A098  MOV      [EBP-04],EAX
0167:0041A09B  MOV      ECX,[EBP-04]
0167:0041A09E  CMP      ECX,[EBP+10]       <-- 迴圈次數是否已到[EBP+10]=00000298次
0167:0041A0A1  JGE      0041A0C1         <-- 迴圈完畢則跳到0041A0C1去
0167:0041A0A3  MOV      EDX,[EBP+08]       <-- [EBP+08]=00429394
0167:0041A0A6  ADD      EDX,[EBP-04]       <-- 加上偏移值
0167:0041A0A9  XOR      EAX,EAX         <-- EAX清零
0167:0041A0AB  MOV      AL,[EDX]         <-- 取出記憶體地址00429394偏移[EBP-04]的字元放入AL
0167:0041A0AD  MOV      ECX,[EBP+0C]       <-- [EBP+0C]指向解密後的資料
0167:0041A0B0  ADD      ECX,[EBP-04]       <-- 加上偏移值
0167:0041A0B3  XOR      EDX,EDX         <-- EDX清零
0167:0041A0B5  MOV      DL,[ECX]         <-- 取出解密資料偏移[EBP-04]的字元放入DL
0167:0041A0B7  CMP      EAX,EDX         <-- 對應的字元是否相等
0167:0041A0B9  JZ        0041A0BF         <-- 相等則繼續
0167:0041A0BB  XOR      EAX,EAX         <-- 不等則EAX清零,子程式返回
0167:0041A0BD  JMP      0041A0C6
0167:0041A0BF  JMP      0041A092
0167:0041A0C1  MOV      EAX,00000001       <-- 如果所有字元相等,則將00000001作為子程式返回值
0167:0041A0C6  MOV      ESP,EBP
0167:0041A0C8  POP      EBP
0167:0041A0C9  RET      000C
。。。

19. 上面這段程式作用非常簡單,就是比較地址00429394開始的00000298個字元資料是否和被解密後的資料完全相同,如果相同返回1,否則返回0,顯然返回0是表示錯誤的;但是當我們用 D 00429394 檢視記憶體的時候發現裡面全是00,怎麼搞的,程式居然將解密後的資料和00來比較,怎麼可能相等呢!!!我們可以試著多次退出ExeSpyME然後再來到這裡,發現無論怎樣00429394開始的地方永遠都是00,為什麼呀???好好想想,然後回頭看看步驟12,哈哈,是不是那個“EXEMEKEY.DLL”搞的鬼呢?還記得0167:0041A122 CALL [EBP-20]這句嗎,這個CALL是“EXEMEKEY.DLL”中索引值為65的引出函式,當時我們不清楚它的作用,現在我們可以回顧一下,自從呼叫了這個函式以後,程式就開始設定[004256E0]、[004256E4]、[004256E8]和[004256EC]的值,然後CALL 00419C0B用其中的[004256E0]、[004256E4]和[004256E8]計算異或因子XOR_FACTOR,隨後校驗KEY FILE“EXEMEUE.DAT”,再下來CALL 0041A085將解密後的資料與記憶體地址00429394(00429380偏移14處)開始的00000298個字元資料相比較,但是我們只看見00429394中是一堆的00,而CALL [EBP-20]的入口引數是[EBP-18](程式返回後這裡開始的值用來給[004256E0]、[004256E4]、[004256E8]和[004256EC]賦值)、000002AC(正好是00000298加上14)和記憶體地址00429380,所以我們可以肯定CALL [EBP-20]的作用一是返回用來計算異或因子XOR_FACTOR的值,二是將解密後的000002AC個字元資料複製到記憶體地址00429380開始的區域中;

20. 現在我們又進一步知道了KEY FILE“EXEMEKEY.DLL”中引出函式的作用,現在就要來寫這個子程式了,那麼我們如何在“EXEMEKEY.DLL”中將記憶體地址00429380開始的000002AC個字元區域變成解密資料呢?一種方法是在“EXEMEKEY.DLL”中用匯程式設計序實現KEY FILE“EXEMEUE.DAT”中的第一輪加解密資料演算法得到加密資料並將其解密,然後將對應的解密資料複製到記憶體00429380中,這種方法必須用匯編實現KEY FILE“EXEMEUE.DAT”的加解密演算法得到解密資料,比較麻煩;另外一種笨辦法是當程式走到上面的0167:0041A0AD MOV ECX,[EBP+0C]處時用命令 D EBP+0C L 00000298,將這些字元資料全部記下來,然後在程式中直接將這些資料作為固定資料複製到記憶體00429394中,這種辦法比較煩瑣,但是實現起來比較簡單;
  注意:因為程式中只是比較00429394開始的00000298個字元資料,所以當我們用笨辦法實現DLL的時候只需要將EBP+0C處開始的00000298個解密資料複製到記憶體00429394中就可以了,至於00429380到00429394之間的14個字元因為程式沒有使用,所以可以不去管它,下面是笨辦法的某一DLL實現程式(只針對某一特定的KEY FILE“EXEMEUE.DAT”,因為不同的“EXEMEUE.DAT”對應不同的“EXEMEKEY.DLL”,需要修改相應的解密資料):
-------------------------------------------------------------------------------------------------------------------------
;Exemekey.asm

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
data_decoded DB 2Dh,1Fh,47h,1Eh,45h,78h,65h,53h,70h,79h,20h,4Dh,69h,6Ch,6Ch,65h  ;-.G.ExeSpy Mille
            DB 6Eh,6Eh,69h,75h,6Dh,20h,45h,64h,69h,74h,69h,6Fh,6Eh,20h,66h,6Fh  ;nnium Edition fo
            DB 72h,20h,57h,69h,6Eh,64h,6Fh,77h,73h,20h,4Dh,45h,2Fh,39h,38h,2Fh  ;r Windows ME/98/
            DB 39h,35h,00h,00h,05h,00h,00h,00h,06h,00h,00h,00h,07h,00h,00h,00h  ;95..............
            DB 18h,00h,00h,00h,19h,00h,00h,00h,73h,3Fh,44h,4Ch,2Eh,5Ch,45h,58h  ;........s?DL.\EX
            DB 45h,4Dh,45h,55h,52h,2Eh,44h,41h,54h,00h,00h,00h,1Fh,00h,00h,00h  ;EMEUR.DAT.......
            DB 10h,00h,00h,00h,11h,00h,00h,00h,12h,00h,00h,00h,13h,00h,00h,00h  ;................
            DB 14h,00h,00h,00h,15h,00h,00h,00h,16h,00h,00h,00h,17h,00h,00h,00h  ;................
            DB 28h,00h,00h,00h,29h,00h,00h,00h,2Ah,00h,00h,00h,2Bh,00h,00h,00h  ;(...)...*...+...
            DB 2Ch,00h,00h,00h,2Dh,00h,00h,00h,2Eh,00h,00h,00h,2Fh,00h,00h,00h  ;,...-......./...
            DB 20h,00h,00h,00h,21h,00h,00h,00h,22h,00h,00h,00h,23h,00h,00h,00h  ; ...!..."...#...
            DB 24h,00h,00h,00h,25h,00h,00h,00h,26h,00h,00h,00h,27h,00h,00h,00h  ;$...%...&...'...
            DB 38h,00h,00h,00h,39h,00h,00h,00h,3Ah,00h,00h,00h,3Bh,00h,00h,00h  ;8...9...:...;...
            DB 3Ch,00h,00h,00h,3Dh,00h,00h,00h,3Eh,00h,00h,00h,3Fh,00h,00h,00h  ;<...=...>...?...
            DB 30h,00h,00h,00h,31h,00h,00h,00h,32h,00h,00h,00h,33h,00h,00h,00h  ;0...1...2...3...
            DB 34h,00h,00h,00h,35h,00h,00h,00h,36h,00h,00h,00h,37h,00h,00h,00h  ;4...5...6...7...
            DB 48h,00h,00h,00h,49h,00h,00h,00h,4Ah,00h,00h,00h,4Bh,00h,00h,00h  ;H...I...J...K...
            DB 4Ch,00h,00h,00h,4Dh,00h,00h,00h,4Eh,00h,00h,00h,4Fh,00h,00h,00h  ;L...M...N...O...
            DB 40h,00h,00h,00h,41h,00h,00h,00h,42h,00h,00h,00h,43h,00h,00h,00h  ;@...A...B...C...
            DB 44h,00h,00h,00h,45h,00h,00h,00h,46h,00h,00h,00h,47h,00h,00h,00h  ;D...E...F...G...
            DB 58h,00h,00h,00h,59h,00h,00h,00h,5Bh,08h,64h,6Fh,68h,6Fh,64h,6Fh  ;X...Y...[.dohodo
            DB 6Eh,67h,00h,00h,5Dh,00h,00h,00h,5Eh,00h,00h,00h,5Fh,00h,00h,00h  ;ng..]...^..._...
            DB 50h,00h,00h,00h,51h,00h,00h,00h,52h,00h,00h,00h,53h,00h,00h,00h  ;P...Q...R...S...
            DB 54h,00h,00h,00h,55h,00h,00h,00h,56h,00h,00h,00h,57h,00h,00h,00h  ;T...U...V...W...
            DB 68h,00h,00h,00h,69h,00h,00h,00h,6Ah,00h,00h,00h,6Bh,00h,00h,00h  ;h...i...j...k...
            DB 6Ch,00h,00h,00h,6Dh,00h,00h,00h,6Eh,00h,00h,00h,6Fh,00h,00h,00h  ;l...m...n...o...
            DB 60h,00h,00h,00h,61h,00h,00h,00h,62h,00h,00h,00h,63h,00h,00h,00h  ;`...a...b...c...
            DB 64h,00h,00h,00h,65h,00h,00h,00h,66h,00h,00h,00h,67h,00h,00h,00h  ;d...e...f...g...
            DB 78h,00h,00h,00h,79h,00h,00h,00h,7Ah,00h,00h,00h,7Bh,00h,00h,00h  ;x...y...z...{...
            DB 7Ch,00h,00h,00h,7Dh,00h,00h,00h,7Eh,00h,00h,00h,7Fh,00h,00h,00h  ;|...}...~......
            DB 70h,00h,00h,00h,71h,00h,00h,00h,72h,00h,00h,00h,73h,00h,00h,00h  ;p...q...r...s...
            DB 74h,00h,00h,00h,75h,00h,00h,00h,76h,00h,00h,00h,77h,00h,00h,00h  ;t...u...v...w...
            DB 88h,00h,00h,00h,89h,00h,00h,00h,8Ah,00h,00h,00h,8Bh,00h,00h,00h  ;................
            DB 8Ch,00h,00h,00h,8Dh,00h,00h,00h,8Eh,00h,00h,00h,8Fh,00h,00h,00h  ;................
            DB 80h,00h,00h,00h,81h,00h,00h,00h,82h,00h,00h,00h,83h,00h,00h,00h  ;................
            DB 84h,00h,00h,00h,85h,00h,00h,00h,86h,00h,00h,00h,87h,00h,00h,00h  ;................
            DB 98h,00h,00h,00h,99h,00h,00h,00h,49h,47h,45h,52h,01h,00h,00h,00h  ;........IGER....
            DB 01h,00h,00h,00h,49h,47h,45h,52h,45h,53h,00h,00h,44h,53h,00h,00h  ;....IGERES..DS..
            DB 90h,00h,00h,00h,91h,00h,00h,00h,92h,00h,00h,00h,93h,00h,00h,00h  ;................
            DB 94h,00h,00h,00h,8Bh,0Ch,6Eh,67h,73h,69h,6Eh,67h,6Ch,65h,00h,00h  ;......ngsingle..
            DB 0A8h,00h,00h,00h,0A9h,00h,00h,00h,0AAh,00h,00h,00h,0ABh,00h,00h,00h  ;................
            DB 0ACh,00h,00h,00h,0ADh,00h,00h,00h    
     
.code
DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
      mov  eax,TRUE
      ret
DllEntry Endp


Call_ebp_20 proc
      push ebp
      mov ebp,esp
     
      mov eax,[ebp+10h]                    <-- 對應程式中的入口引數EBP-18
      mov dword ptr [eax+00h],006BE048h    <-- 可以隨意,這是沒有這個函式時程式的預設值,對應[004256E0]
      mov dword ptr [eax+04h],00000008h    <-- 可以隨意,這是沒有這個函式時程式的預設值,對應[004256E4]
      mov dword ptr [eax+08h],00429FA0h    <-- 可以隨意,這是沒有這個函式時程式的預設值,對應[004256E8]
      mov dword ptr [eax+0Ch],000003B2h    <-- 可以隨意,這是沒有這個函式時程式的預設值,對應[004256EC]
     
      mov edi,[ebp+08h]                    <-- 對應程式中的入口引數00429380
      add edi,14                            <-- 只需要比較偏移14開始的資料(笨辦法^_^)
      lea esi,data_decoded
      mov ecx,[ebp+0Ch]                    <-- 對應程式中的入口引數000002AC
      sub ecx,14                            <-- 只需要比較00000298個字元(笨辦法^_^)
      rep movsb
       
      mov eax,00000001
      mov esp,ebp
      pop ebp
      ret 0ch
Call_ebp_20 Endp

End DllEntry

;Exemekey.def和build.bat跟上面的一樣

-----------------------------------------------------------------------------------------------------------------------

21. 將上面的程式編譯成新的“EXEMEKEY.DLL”放在C盤根目錄,然後重新來到步驟12,按F10一步一步往下走,哈哈,現在是不是可以正大光明的走到最後啦^_^, 接下來我們按F10返回到步驟12 --> 步驟11,然後從步驟9最後面的程式繼續往下走:
。。。
0167:00411CA9  JNZ      00411CC6
0167:00411CAB  PUSH      10
0167:00411CAD  PUSH      004251BC
0167:00411CB2  PUSH      004251C4
0167:00411CB7  MOV      EAX,[EBP+08]
0167:00411CBA  PUSH      EAX
0167:00411CBB  CALL      [USER32!MessageBoxA]
0167:00411CC1  JMP      00411DD5
0167:00411CC6  PUSH      65             <-- 常數65壓棧
0167:00411CC8  MOV      ECX,[EBP+08]        <-- [EBP+08]為對話方塊控制程式碼
0167:00411CCB  PUSH      ECX
0167:00411CCC  PUSH      0042009C          <-- 地址0042009C指向字串“.\EXEMEUE.DAT”
0167:00411CD1  LEA      EDX,[EBP+FFFFDCA4]    <-- [EBP+FFFFDCA4]為解密後的KEY FILE資料
0167:00411CD7  PUSH      EDX
0167:00411CD8  MOV      EAX,[EBP+FFFFDC9C]    <-- [EBP+FFFFDC9C]為前面驗證程式的返回值
0167:00411CDE  PUSH      EAX
0167:00411CDF  CALL      0041A240          <-- 繼續驗證KEY FILE“.\EXEMEUE.DAT”,作用和98系列的CALL  0040C780完全一樣
0167:00411CE4  TEST      EAX,EAX
0167:00411CE6  JZ        00411DA9
0167:00411CEC  PUSH      00
0167:00411CEE  LEA      ECX,[EBP-50]
0167:00411CF1  PUSH      ECX
0167:00411CF2  CALL      [KERNEL32!_lopen]     <-- 開啟KEY FILE檔案“c:\EXEMEUE.DAT”
0167:00411CF8  MOV      [EBP-00A8],EAX
0167:00411CFE  PUSH      00
0167:00411D00  PUSH      0042009C
0167:00411D05  CALL      [KERNEL32!_lcreat]     <-- 在EXESPYME的當前目錄建立檔案“.\EXEMEUE.DAT”
0167:00411D0B  MOV      [EBP-00AC],EAX
0167:00411D11  CMP      DWORD PTR [EBP-00AC],-01
0167:00411D18  JNZ      00411D3F
0167:00411D1A  PUSH      10
0167:00411D1C  PUSH      004251F0
0167:00411D21  PUSH      004251F8
0167:00411D26  MOV      EDX,[EBP+08]
0167:00411D29  PUSH      EDX
0167:00411D2A  CALL      [USER32!MessageBoxA]
0167:00411D30  MOV      EAX,[EBP-00A8]
0167:00411D36  PUSH      EAX
0167:00411D37  CALL      [KERNEL32!_lclose]
0167:00411D3D  JMP      00411DA7
0167:00411D3F  PUSH      50
0167:00411D41  LEA      ECX,[EBP-00A0]
0167:00411D47  PUSH      ECX
0167:00411D48  MOV      EDX,[EBP-00A8]
0167:00411D4E  PUSH      EDX
0167:00411D4F  CALL      [KERNEL32!_hread]     <-- 讀檔案“c:\EXEMEUE.DAT”
0167:00411D55  MOV      [EBP+FFFFDC98],EAX
0167:00411D5B  CMP      DWORD PTR [EBP+FFFFDC98],00
0167:00411D62  JLE      00411D81
0167:00411D64  MOV      EAX,[EBP+FFFFDC98]
0167:00411D6A  PUSH      EAX
0167:00411D6B  LEA      ECX,[EBP-00A0]
0167:00411D71  PUSH      ECX
0167:00411D72  MOV      EDX,[EBP-00AC]
0167:00411D78  PUSH      EDX
0167:00411D79  CALL      [KERNEL32!_hwrite]     <-- 寫檔案“.\EXEMEUE.DAT”
0167:00411D7F  JMP      00411D3F
0167:00411D81  MOV      EAX,[EBP-00AC]
0167:00411D87  PUSH      EAX
0167:00411D88  CALL      [KERNEL32!_lclose]     <-- 關閉檔案“.\EXEMEUE.DAT”
0167:00411D8E  MOV      ECX,[EBP-00A8]
0167:00411D94  PUSH      ECX
0167:00411D95  CALL      [KERNEL32!_lclose]     <-- 關閉檔案“c:\EXEMEUE.DAT”
0167:00411D9B  PUSH      01
0167:00411D9D  MOV      EDX,[EBP+08]
0167:00411DA0  PUSH      EDX
0167:00411DA1  CALL      [USER32!EndDialog]
0167:00411DA7  JMP      00411DD5
0167:00411DA9  PUSH      00
0167:00411DAB  PUSH      0042009C
0167:00411DB0  CALL      [KERNEL32!_lcreat]
0167:00411DB6  MOV      [EBP-00AC],EAX
0167:00411DBC  MOV      EAX,[EBP-00A8]
0167:00411DC2  PUSH      EAX
0167:00411DC3  CALL      [KERNEL32!_lclose]
0167:00411DC9  PUSH      00
0167:00411DCB  MOV      ECX,[EBP+08]
0167:00411DCE  PUSH      ECX
0167:00411DCF  CALL      [USER32!EndDialog]
0167:00411DD5  JMP      00411DED
0167:00411DD7  PUSH      10
0167:00411DD9  PUSH      00425220
0167:00411DDE  PUSH      00425228
0167:00411DE3  MOV      EDX,[EBP+08]
0167:00411DE6  PUSH      EDX
0167:00411DE7  CALL      [USER32!MessageBoxA]
0167:00411DED  JMP      00411DFB
0167:00411DEF  PUSH      00
0167:00411DF1  MOV      EAX,[EBP+08]
0167:00411DF4  PUSH      EAX
0167:00411DF5  CALL      [USER32!EndDialog]
0167:00411DFB  JMP      00411E0F
0167:00411DFD  PUSH      00
0167:00411DFF  MOV      ECX,[EBP+08]
0167:00411E02  PUSH      ECX
0167:00411E03  CALL      [USER32!EndDialog]
0167:00411E09  JMP      00411E0F
0167:00411E0B  XOR      EAX,EAX
0167:00411E0D  JMP      00411E14
0167:00411E0F  MOV      EAX,00000001
0167:00411E14  MOV      ESP,EBP
0167:00411E16  POP      EBP
0167:00411E17  RET      0010
。。。

22. 上面的程式跟98系列是一樣的,只不過驗證“.DAT”KEY FILE時其驗證字串多了個字首“.\”(98系列為“SET98UR.DAT”,ME系列為“.\EXEMEUE.DAT”),程式後面同樣是將KEY FILE“EXEMEUE.DAT”複製到EXESPYME的當前目錄下;

23. 好了,到這裡我就不再往後講了,因為這篇文章主要是討論98系列跟ME系列的不同之處(主要是針對KEY FILE“EXEMEKEY.DLL”),從這裡以後的程式雖然跟98系列的不完全一樣(因為ME系列是“SPY2”型的嘛!),但是對於有效的註冊KEY FILE來說(REG_TYPE="REGI"),程式功能作用完全一致,也就是說從這裡以後可以繼續沿用98系列的序號產生器演算法,只需要將相應的字串資訊換掉即可,後面程式的具體細節自己去看吧,這篇文章的目的已經達到,我要休息啦,真的好累,啊啊啊。。。!!!

24. 注意:附件所帶的序號產生器C語言源程式中KEY FILE“EXEMEKEY.DLL”的產生方法是先用匯編生成“EXEMEKEY.DLL”,然後將整個“EXEMEKEY.DLL”檔案的資料放在源程式中,並根據程式需要修改相應部分的資料(對應產生的KEY FILE“EXEMEUR.DAT”),另外程式中“EXEMEKEY.DLL”對應的彙編源程式和上面講解的彙編源程式有一點不同,所以希望大家不要奇怪為什麼源程式中的程式結構和破解檔案中不一致;

25. 附錄:下面放上程式中用到的幾個相關API函式的原型:
HINSTANCE LoadLibrary(

    LPCTSTR lpLibFileName     // address of filename of executable module
  );
 
FARPROC GetProcAddress(

    HMODULE hModule,    // handle to DLL module 
    LPCSTR lpProcName     // name of function
  );
 
BOOL FreeLibrary(

    HMODULE hLibModule     // handle to loaded library module 
  );


標 題:序號產生器 (33千字)

  • 作 者::娃娃[CCG]
  • 時 間:2001-11-19 17:47:43
    詳細資訊:
  • /* key_file Generator for ExeSpyME V5.0 Author: ddcrack  Written by: 2001/10/08 */

    /* #define Program_name  "ExeSpy Millennium Edition for Windows ME/98/95"*/ /* addr: ebp+0x018 */
      #define key_file_name  "EXEMEUR.DAT"    /* addr: ebp+0x060 */
      #define dll_file_name  "EXEMEKEY.DLL"  /* generated dll file name*/
      #define dll_data_memo_addr 0x00429394  /* the location of dll data in system memory */
                                              /* got by finding "00000298" in W32Dasm or tracing in softice */
      #define Version        0x00000005      /* addr: ebp+0x000 */
    /* #define Username      input by user    /* addr: ebp+0x160 */
    /* #define SN_Header      "PD"          /* addr: ebp+0x26C */
    /* #define SN_Tail      "ES"          /* addr: ebp+0x28C */
      #define VersionEx      0x00000001      /* addr: ebp+0x260 */
    /* #define User_ID        generated by random addr: ebp+0x264 */
      #define Reg_Type      0x52454749      /* addr: ebp+0x268 */
      /* Reg_Type: 0x52454749 --> "REGI"
                    0x53485050 --> "SHPP"
            0x4556414C --> "EVAL" */
      #define Free_year    2025          /* free update date addr: ebp+0x05C */
      #define Free_month    12                /* Free_year=year+7CD, max year=0x3F*/
      #define Free_day      12                /* year<=0x1F=31, so Free_year<=2028*/
      #define Free_hour    12
      #define Free_minute  12
      #define Free_second  12

      #define addr_004256EC **********        /* function unknown, can be any value */
      #define addr_004256E8 0x00429FA0        /* one of XOR factors, can be any value */
      #define addr_004256E4 0x00000008        /* one of XOR factors, can be any value */
      #define addr_004256E0 0x006BE048        /* one of XOR factors, can be any value */


    #include <stdio.h>
    #include <string.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <time.h>

    void main(void)
    {
        unsigned char key_file[]=
        {'S','P','Y','2',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*encoded data start addr: ebp+0x00*/
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,/* addr offset: 0x014 */
        0x00,0x00,0x00,0x00,/* XOR_NO=1 */
        0x00,0x00,0x00,0x00,/* XOR_NO=2 */
        0x00,0x00,0x00,0x00,/* XOR_NO=3 */
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,/* XOR_NO=A3 */
        0x00,0x00,0x00,0x00,/* XOR_NO=A4 */
        0x00,0x00,0x00,0x00,/* XOR_NO=A5 */
        0x00,0x00,0x00,0x00,/*  first    */  /*Next_XOR_Factor1=first^addr_004256E8+second^addr_004256E4+third^addr_004256E0 */
        0x00,0x00,0x00,0x00,/*  second  */
        0x00,0x00,0x00,0x00,/*  third    */
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,/* new addr offset1: 0x14+000002B8 */
        0x00,0x00,0x00,0x00,/* XOR_NO=1 */
        0x00,0x00,0x00,0x00,/* XOR_NO=2 */
        0x00,0x00,0x00,0x00,/* XOR_NO=3 */
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,/* XOR_NO=A3 */
        0x00,0x00,0x00,0x00,/* XOR_NO=A4 */
        0x00,0x00,0x00,0x00,/* XOR_NO=A5 */
        0x00,0x00,0x00,0x00,/*  first    */ /*Next_XOR_Factor2=(first^addr_004256E8)^(second^addr_004256E4)+third^addr_004256E0 */
        0x00,0x00,0x00,0x00,/*  second  */
        0x00,0x00,0x00,0x00,/*  third    */
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,/* new addr offset2: 0x14+000002B8+000002B8 */
        0x00,0x00,0x00,0x00,/* XOR_NO=1 */
        0x00,0x00,0x00,0x00,/* XOR_NO=2 */
        0x00,0x00,0x00,0x00,/* XOR_NO=3 */
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,/* XOR_NO=A3 */
        0x00,0x00,0x00,0x00,/* XOR_NO=A4 */
        0x00,0x00,0x00,0x00,/* XOR_NO=A5 */
            'T','H','E','E','N','D'};

        const unsigned char * Program_name="ExeSpy Millennium Edition for Windows ME/98/95";
        const unsigned char * key_name=".\\EXEMEUR.DAT";
        const unsigned char * SN_Header="PD";
        const unsigned char * SN_Tail="ES";
            unsigned char * Username="";

            void put_dword_value();
        unsigned long get_dword_value();
            void create_key_file();
        void create_dll_file();
        void data_encryptor();

        unsigned long eax,edx,temp,XOR_Factor,XOR_NO,User_ID;
        unsigned char i,dword_count;
        unsigned char * pkey,* p1,* p2;

        unsigned char char_data[0x40]=
        {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        

        randomize();

        /* XOR_Factor can not equal to 0x00000000 or 0x00000001 */
        /* Here assume [key_file+0x0C]=addr_004256E8,[key_file+0x10]=addr_004256E4,[key_file+0x14]=random number */
        temp=addr_004256E8;
        put_dword_value(temp,key_file+0x0C);
        temp=random(65536);
        if((temp^addr_004256E4)<=1) temp+=2;
        put_dword_value(temp,key_file+0x10);
        temp=addr_004256E0;
        put_dword_value(temp,key_file+0x14);
            XOR_Factor=(get_dword_value(key_file+0x0C)^addr_004256E8)^(get_dword_value(key_file+0x10)^addr_004256E4)^(get_dword_value(key_file+0x14)^addr_004256E0);
        /* then, XOR_Factor=addr_004256E4^random(65536) */

    /* think about next calculator */
    /*    eax=get_dword_value(key_file+0x04);
        eax^=get_dword_value(key_file+0x08);
        if(eax&0x80000000) edx=0xFFFFFFFF;
        else edx=0x00000000;
        edx&=0x03;
        eax+=edx;
        eax=eax>>0x02;
        eax+=0x06; */
        /* now eax must less than 0x00002800 */
        /* so, here assume [key_file+0x04]=[key_file+0x08], then eax=0x06 */
        temp=(unsigned long)random(65536);
        put_dword_value(temp,key_file+0x04);
            put_dword_value(temp,key_file+0x08);

        eax=get_dword_value(key_file+0x04);
        eax^=get_dword_value(key_file+0x08);
        if(eax&0x80000000) edx=0xFFFFFFFF;
        else edx=0x00000000;
        edx&=0x03;
        eax+=edx;
        eax=eax>>0x02;
        eax+=0x06; 


        /* think about next calculator */
    /*    temp=eax;
        eax=get_dword_value(key_file+(unsigned char)temp*0x04);
        if(eax&0x80000000) edx=0xFFFFFFFF;
        else edx=0x00000000;
        edx&=0x03;
        eax+=edx;
        eax=eax>>0x02;
        edx=eax+temp+1;*/
        /* now edx must less than 0x00002800  more than 0x00000000*/
        /* because temp=0x06, so here assume [key_file+0x04*6]=[key_file+0x18]=0, then edx=0x07 */
        temp=0x00000000;
        put_dword_value(temp,key_file+(unsigned char)eax*0x04);

        temp=eax;
        eax=get_dword_value(key_file+(unsigned char)temp*0x04);
        if(eax&0x80000000) edx=0xFFFFFFFF;
        else edx=0x00000000;
        edx&=0x03;
        eax+=edx;
        eax=eax>>0x02;
        edx=eax+temp+1;


        /* think about next calculator */
    /*    temp=edx;
        eax=get_dword_value(key_file+(unsigned char)temp*0x04);
            edx=eax+temp+1; */
        /* now edx must less than 0x00002800 and more than 0x00000000*/
        /* because temp=0x07, so here assume [key_file+0x04*7]=[key_file+0x1C]=0, then edx=0x08 */
        temp=0x00000000;
        put_dword_value(temp,key_file+(unsigned char)edx*0x04);

        /* Now ebp=key_file+edx*0x04+0x04 */

        clrscr();
        printf("\n************************************************************************\n");
        printf("ExeSpyME Key File Generator\n");
        printf("Author: ddcrack ( 2001/10/08 )\n");
        printf("************************************************************************\n\n");

    /* -------------- create "ExeSpy Millennium Edition for Windows ME/98/95" --------------------*/
        
        temp=0x00000000;

        for(i=0;i<(unsigned char)strlen(Program_name);i++) char_data[i]=*(Program_name+i);
        dword_count=strlen(Program_name)/4+1;
        for(i=strlen(Program_name);i<(strlen(Program_name)strlen(Program_name)%4);i++) char_data[i]=0x00;
        XOR_NO=(0x18-0x14)/4;
        pkey=&key_file[edx*4+0x04+0x18];
            data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);
       
    /* -------------- create "ExeSpy Millennium Edition for Windows ME/98/95" end--------------------*/

    /* -------------- create Free_update_date and ".\EXEMEUR.DAT" --------------------*/
            temp=Free_year-0x07CD;
        temp=temp<<4;
        temp=temp|Free_month;
        temp=temp<<5;
        temp=temp|Free_day;
        temp=temp<<5;
            temp=temp|Free_hour;
        temp=temp<<6;
        temp=temp|Free_minute;
        temp=temp<<6;
        temp=temp|Free_second;

        put_dword_value(temp,char_data);
        temp=0x00000000;
        for(i=0;i<(unsigned char)strlen(key_name);i++) char_data[i+4]=*(key_name+i);
        dword_count=strlen(key_name)/4+1+1;
        for(i=(strlen(key_name)+4);i<(strlen(key_name)+4strlen(key_name)%4);i++) char_data[i]=0x00;
            XOR_NO=(0x5C-0x14)/4;
            pkey=&key_file[edx*4+0x04+0x5C];
            data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

    /* -------------- create Free_update_date and ".\EXEMEUR.DAT" end--------------------*/

    /* -----set value of addr ebp+260, ebp+264 and ebp+268------*/
        temp=VersionEx;
        put_dword_value(temp,char_data);
            User_ID=random(50000)*20;                  /* User_ID has six digits */
        put_dword_value(User_ID,char_data+0x04);
        temp=Reg_Type;
        put_dword_value(temp,char_data+0x08);

        temp=0x00000000; 
        dword_count=3;
            XOR_NO=(0x260-0x14)/4;
        pkey=&key_file[edx*4+0x04+0x260];
            data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

    /* -----set value of addr ebp+260, ebp+264 and ebp+268 end------*/

    /* -----set value of addr ebp+160 : Username ------*/
        printf("Input your name : ");
        scanf("%s",Username);

        temp=0x00000000;
        for(i=0;i<(unsigned char)strlen(Username);i++) char_data[i]=*(Username+i);
        dword_count=strlen(Username)/4+1;
        for(i=strlen(Username);i<(strlen(Username)strlen(Username)%4);i++) char_data[i]=0x00;
            XOR_NO=(0x160-0x14)/4;
            pkey=&key_file[edx*4+0x04+0x160];
            data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

    /* -----set value of addr ebp+160 : Username end------*/

    /* -----set value of addr ebp+26C/ebp+28C : S_N head/tail ------*/
        temp=get_dword_value(&key_file[edx*4+0x04+0x268]);

        for(i=0;i<(unsigned char)strlen(SN_Header);i++) char_data[i]=*(SN_Header+i);
        dword_count=strlen(SN_Header)/4+1;
        for(i=strlen(SN_Header);i<(strlen(SN_Header)strlen(SN_Header)%4);i++) char_data[i]=0x00;
            XOR_NO=(0x26C-0x14)/4;
            pkey=&key_file[edx*4+0x04+0x26C];
            data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

        temp=0x00000000;
        for(i=0;i<(unsigned char)strlen(SN_Tail);i++) char_data[i]=*(SN_Tail+i);
        dword_count=strlen(SN_Tail)/4+1;
        for(i=strlen(SN_Tail);i<(strlen(SN_Tail)strlen(SN_Tail)%4);i++) char_data[i]=0x00;
            XOR_NO=(0x28C-0x14)/4;
            pkey=&key_file[edx*4+0x04+0x28C];
            data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,temp);

    /* -----set value of addr ebp+26C/ebp+28C : S_N head/tail end------*/

    /* -----set value of addr ebp+0x00, ebp+0x04, ebp+0x08, 0x0C ------ */

    /* each value can not equal to 0x00000000 */
        
        pkey=&key_file[edx*4+0x04];

        temp=Version;
            put_dword_value(temp,pkey);
        temp=0x00000001;
            put_dword_value(temp,pkey+0x04); /* let [ebp+0x04]=0x00000001 */
        temp=0x00000001;
            put_dword_value(temp,pkey+0x08); /* let [ebp+0x08]=0x00000001 */
        temp=0x00000001;
            put_dword_value(temp,pkey+0x0C); /* let [ebp+0x0C]=0x00000001 */

    /* -----set value of Next_XOR_Factor1 ------*/

            pkey=&key_file[edx*0x04+0x04+0x02AC];

            /*  Next_XOR_Factor1=[pkey+0x00]=([pkey+0x04]^addr_004256E8)+([pkey+0x08]^addr_004256E4)+([pkey+0x0C]^addr_004256E0) */
            /*  here let us make Next_XOR_Factor1=XOR_Factor */

        temp=addr_004256E8;
        put_dword_value(temp,pkey+0x00); /* first */
        temp=get_dword_value(key_file+0x10);
        put_dword_value(temp,pkey+0x04); /* second */
        temp=addr_004256E0;
        put_dword_value(temp,pkey+0x08); /* third */

    /* -----set value of Next_XOR_Factor1 end------*/

    /* -----set value of Next_XOR_Factor2 ------*/
       
        pkey=&key_file[edx*0x04+0x04+0x02AC+0x02B8];

            /*  Next_XOR_Factor2=[pkey+0x00]=([pkey+0x04]^addr_004256E8)^([pkey+0x08]^addr_004256E4)+([pkey+0x0C]^addr_004256E0) */
            /*  here let us make Next_XOR_Factor2=XOR_Factor */

        temp=addr_004256E8;
        put_dword_value(temp,pkey+0x00); /* first */
        temp=get_dword_value(key_file+0x10);               
        put_dword_value(temp,pkey+0x04); /* second */
        temp=addr_004256E0;
        put_dword_value(temp,pkey+0x08); /* third */

    /* -----set value of Next_XOR_Factor2 end------*/

        p1=&key_file[edx*4+0x04+0x14];
        p2=&key_file[edx*4+0x04+0x14+0x02B8];
        for(i=0;i<=0xA5;i++) put_dword_value(get_dword_value(p1+i*4),p2+i*4);

        p1=&key_file[edx*4+0x04+0x14];
        p2=&key_file[edx*4+0x04+0x14+0x02B8+0x02B8];
        for(i=0;i<=0xA5;i++) put_dword_value(get_dword_value(p1+i*4),p2+i*4);
        
        create_key_file(key_file);
            create_dll_file(key_file+0x20+0x14,XOR_Factor);

            getch();
    }

    unsigned long get_dword_value(addr)
    unsigned char * addr;
    {
        unsigned long number=0;

        number=*(addr+3);
        number=number<<0x08;
        number=number|*(addr+2);
        number=number<<0x08;
        number=number|*(addr+1);
        number=number<<0x08;
        number=number|*addr;
        return number;
    }

    void put_dword_value(number,addr)
    unsigned char * addr;
    unsigned long number;
    {
        unsigned char al=0;

        al=(unsigned char)(number&0x000000FF);
        *(addr+0)=al;
        al=(unsigned char)((number&0x0000FF00)>>0x08);
        *(addr+1)=al;
        al=(unsigned char)((number&0x00FF0000)>>0x10);
        *(addr+2)=al;
        al=(unsigned char)((number&0xFF000000)>>0x18);
        *(addr+3)=al;
    }

    void data_encryptor(char_data,dword_count,XOR_Factor,XOR_NO,pkey,forward_data)
    unsigned char * char_data;
    unsigned char dword_count;
    unsigned long XOR_Factor;
    unsigned long XOR_NO;
    unsigned char * pkey;
    unsigned long forward_data;
    {
        void put_dword_value();
        unsigned long get_dword_value();

        unsigned long temp;
        unsigned char i;

        temp=forward_data;
        put_dword_value(temp,pkey-0x04);
        for(i=0;i<dword_count;i++)
        {
            temp=get_dword_value(pkey+0x04*i-0x04)^get_dword_value(char_data+0x04*i)^XOR_Factor^(XOR_NO+i);
            put_dword_value(temp,pkey+0x04*i);
        }
    }

    void create_key_file(key_file)
    unsigned char key_file[];
    {
        FILE *fp;
        int i=0;
        unsigned char * file_name=key_file_name;

        if((fp=fopen(file_name,"wb+"))==NULL)
        {
            printf("\nCan not create %s !\n",file_name);
            exit(0);
        }
        for(;;)
        {
            if(key_file[i]=='T'&&key_file[i+1]=='H'&&key_file[i+2]=='E'&&key_file[i+3]=='E'&&key_file[i+4]=='N'&&key_file[i+5]=='D') break;
            if(fputc(key_file[i],fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                fclose(fp);
                exit(0);
            }
            i++;
        }
        fclose(fp);
        printf("\n%s has been created successfully !\n",file_name);

    }

    void create_dll_file(data_addr,XOR_Factor)
    unsigned char * data_addr;
    unsigned long XOR_Factor;
    {
        unsigned char data_000h_to_25Fh[0x0260]=
        {0x4D,0x5A,0x90,0x00,0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,
        0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,
        0x0E,0x1F,0xBA,0x0E,0x00,0xB4,0x09,0xCD,0x21,0xB8,0x01,0x4C,0xCD,0x21,0x54,0x68,
        0x69,0x73,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x63,0x61,0x6E,0x6E,0x6F,
        0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6E,0x20,0x69,0x6E,0x20,0x44,0x4F,0x53,0x20,
        0x6D,0x6F,0x64,0x65,0x2E,0x0D,0x0D,0x0A,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x71,0xD4,0xF7,0xDB,0x35,0xB5,0x99,0x88,0x35,0xB5,0x99,0x88,0x35,0xB5,0x99,0x88,
        0xC9,0x95,0x8B,0x88,0x34,0xB5,0x99,0x88,0xBB,0xAA,0x8A,0x88,0x34,0xB5,0x99,0x88,
        0x52,0x69,0x63,0x68,0x35,0xB5,0x99,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x50,0x45,0x00,0x00,0x4C,0x01,0x04,0x00,0x34,0x02,0xBC,0x3B,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0xE0,0x00,0x0E,0x21,0x0B,0x01,0x05,0x0C,0x00,0x02,0x00,0x00,
        0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,
        0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,
        0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x50,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
        0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,
        0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x4B,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x40,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2E,0x74,0x65,0x78,0x74,0x00,0x00,0x00,
        0x49,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x60,
        0x2E,0x72,0x64,0x61,0x74,0x61,0x00,0x00,0x4B,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
        0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x2E,0x64,0x61,0x74,0x61,0x00,0x00,0x00,
        0x98,0x02,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0xC0,
        0x2E,0x72,0x65,0x6C,0x6F,0x63,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x40,0x00,0x00,
        0x00,0x02,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

        /* FROM 260H TO 3FFH, TOTAL 1A0H BYTES */

        unsigned char data_400h_to_44Fh[0x0050]=
        {0x55,0x8B,0xEC,0x83,0x7D,0x0C,0x01,0x75,0x12,0xBF,'?','?','?','?',0x8D,0x35,/* '?' -->the location of dll data in system memory */
        0x00,0x30,0x00,0x10,0xB9,0x98,0x02,0x00,0x00,0xF3,0xA4,0xB8,0x01,0x00,0x00,0x00,
        0xC9,0xC2,0x0C,0x00,0x55,0x8B,0xEC,0x8B,0x45,0x10,0xC7,0x00,'#','#','#','#',/* '#' -->the value of addr_004256E0 */
        0xC7,0x40,0x04,'$','$','$','$',0xC7,0x40,0x08,'&','&','&','&',0xB8,0x01,/* '$' -->the value of addr_004256E4 */
        0x00,0x00,0x00,0x8B,0xE5,0x5D,0xC2,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* '&' -->the value of addr_004256E4 */

        /* FROM 450H TO 5FFH, TOTAL 1B0H BYTES */

        unsigned char data_600h_to_64Fh[0x0050]=
        {0x00,0x00,0x00,0x00,0x34,0x02,0xBC,0x3B,0x00,0x00,0x00,0x00,0x32,0x20,0x00,0x00,
        0x65,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x28,0x20,0x00,0x00,
        0x2C,0x20,0x00,0x00,0x30,0x20,0x00,0x00,0x24,0x10,0x00,0x00,0x3F,0x20,0x00,0x00,
        0x00,0x00,0x45,0x78,0x65,0x6D,0x65,0x6B,0x65,0x79,0x2E,0x64,0x6C,0x6C,0x00,0x43,
        0x61,0x6C,0x6C,0x5F,0x65,0x62,0x70,0x5F,0x32,0x30,0x00,0x00,0x00,0x00,0x00,0x00};

        /* FROM 650H TO 7FFH, TOTAL 1B0H BYTES */

        unsigned char data_800h_to_A97h[0x0298];

        /* FROM A98H TO BFFH, TOTAL 168H BYTES */

        unsigned char data_C00h_to_C0Fh[0x0010]=
        {0x00,0x10,0x00,0x00,0x0C,0x00,0x00,0x00,0x10,0x30,0x00,0x00,0x00,0x00,0x00,0x00};

        /* FROM C10H TO DFFH, TOTAL 1F0H BYTES */

        /* DLL FILE TOTAL 3,584 BYTES */

            void put_dword_value();
        unsigned long get_dword_value();

        FILE *fp;
        unsigned char * file_name=dll_file_name;
        unsigned char i;
        unsigned int j;
        unsigned long temp;

        for(i=0;i<0xA5;i++)/* decode data */
        {
            temp=get_dword_value(data_addr+(0xA5-i)*4);
            temp^=get_dword_value(data_addr+(0xA5-i-1)*4);
            temp^=XOR_Factor^(0xA5-i);
            put_dword_value(temp,&data_800h_to_A97h[(0xA5-i)*4]);
        }
        temp=get_dword_value(data_addr);
            put_dword_value(temp,data_800h_to_A97h);

        temp=dll_data_memo_addr;
            put_dword_value(temp,&data_400h_to_44Fh[0x0A]);
       
        temp=addr_004256E0;
            put_dword_value(temp,&data_400h_to_44Fh[0x2C]);
            temp=addr_004256E4;
            put_dword_value(temp,&data_400h_to_44Fh[0x33]);
            temp=addr_004256E8;
            put_dword_value(temp,&data_400h_to_44Fh[0x3A]);
        
        if((fp=fopen(file_name,"wb+"))==NULL)
        {
            printf("\nCan not create %s !\n",file_name);
            exit(0);
        }

        for(j=0;j<0x0260;j++)/* FROM 000H TO 25FH, TOTAL 260H BYTES */
        {
            if(fputc(data_000h_to_25Fh[j],fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }


        for(j=0;j<0x01A0;j++)/* FROM 260H TO 3FFH, TOTAL 1A0H BYTES */
        {
            if(fputc(0x00,fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x0050;j++)/* FROM 400H TO 44FH, TOTAL 050H BYTES */
        {
            if(fputc(data_400h_to_44Fh[j],fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x01B0;j++) /* FROM 450H TO 5FFH, TOTAL 1B0H BYTES */
        {
            if(fputc(0x00,fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }



        for(j=0;j<0x01A0;j++)/* FROM 260H TO 3FFH, TOTAL 1A0H BYTES */
        {
            if(fputc(0x00,fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x0050;j++)/* FROM 400H TO 44FH, TOTAL 050H BYTES */
        {
            if(fputc(data_400h_to_44Fh[j],fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x01B0;j++) /* FROM 450H TO 5FFH, TOTAL 1B0H BYTES */
        {
            if(fputc(0x00,fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x0050;j++)/* FROM 600H TO 64FH, TOTAL 050H BYTES */
        {
            if(fputc(data_600h_to_64Fh[j],fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x01B0;j++)/* FROM 650H TO 7FFH, TOTAL 1B0H BYTES */
        {
            if(fputc(0x00,fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x0298;j++)/* FROM 800H TO A97H, TOTAL 298H BYTES */
        {
            if(fputc(data_800h_to_A97h[j],fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x0168;j++)/* FROM A98H TO BFFH, TOTAL 168H BYTES */
        {
            if(fputc(0x00,fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x0010;j++)/* FROM C00H TO C0FH, TOTAL 010H BYTES */
        {
            if(fputc(data_C00h_to_C0Fh[j],fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        for(j=0;j<0x01F0;j++)/* FROM C10H TO DFFH, TOTAL 1F0H BYTES */
        {
            if(fputc(0x00,fp)==EOF)
            {
                printf("\nWrite file %s error !\n",file_name);
                            fclose(fp);
                exit(0);
            }
        }

        fclose(fp);
        printf("\n%s has been created successfully !\n\n",file_name);

    }

    相關文章