史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > 資訊系統安全備援防護技術文件
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2006-02-13, 01:12 PM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 ACProtect脫殼——同益起名大師 V3.36

ACProtect脫殼——同益起名大師 V3.36
下載頁面: http://www.skycn.com/soft/109.html
軟體大小: 6507 KB
軟體語言: 簡體中文
軟體類別: 大陸軟體 / 共享版 / 測字算命
套用平台: Win9x/NT/2000/XP
加入時間: 2005-02-04 12:01:23
下載次數: 288768
推薦等級: ****
開 發 商: http://www.goodyour.com/
軟體介紹: 是一個專業的起名測名軟體,可以說是最優秀、最專業的,絕對100%精品。它有個人起名、公司行號命名、商標樓號命名、姓名八卦、吉號選項、姓名分析、名稱分析、號碼吉凶分析等及參考名字查詢、成語查詢、偏旁查字等多種活字典辭典功能。是姓名學愛好者及研究人員的得力工具,讓您真正放心、方便、快捷地為您的公司商行或親朋好友起個好名。
【脫殼程序】:


同益起名大師加殼時使用了ACProtect專業版的幾個特色功能,使得脫殼、修復時麻煩不少。
複製OllyDbg.exe重新命名為cmd.exe或者eXpLorEr.exe,這樣就避開了ACProtect對父工作名檢測。
設定OllyDbg忽略所有的異常選項。用IsDebug插件去掉OllyDbg的偵錯器標誌。
—————————————————————————————————
一、殼中殼的IAT


0067C000 60 pushad
//進入OllyDbg後暫停在這
0067C001 E8 01000000 call 0067C007

因為加殼時選項了ACProtect專業版功能之「使用DRx解碼」,導致硬體斷點不可隨意使用。
沒關係,我們可以用記憶體訪問斷點,或者在函數段末尾下普通斷點。
Ctrl+G:GetModuleHandleA 設定記憶體訪問斷點
Shift+F9執行,中斷後取消斷點。Alt+F9返回

0068E9E2 0FB600 movzx eax,byte ptr ds:[eax]
//中斷在這裡
0068E9E5 83E8 33 sub eax,33
0068E9E8 3D 99000000 cmp eax,99
0068E9ED 74 10 je short 0068E9FF
0068E9EF 90 nop
0068E9F0 90 nop
0068E9F1 90 nop
0068E9F2 90 nop
0068E9F3 58 pop eax
0068E9F4 FF95 90E24100 call dword ptr ss:[ebp+41E290]
//[00699290]=7C80B529 (kernel32.GetModuleHandleA)

0068C51C FF95 8CE24100 call dword ptr ss:[ebp+41E28C]
//[0069928C]=7C80AC28 (kernel32.GetProcAddress)

下面這段是處理殼所使用的輸入表函數,因為EMbedded Protector要使用殼程式碼,所以我們要保留這些函數
Ctrl+F在當前位置下搜尋指令:rep stos byte ptr es:[edi]
找到在0068EC9A處,直接F4至0068EC9A

0068EC8A 8DBD 5CFF4000 lea edi,dword ptr ss:[ebp+40FF5C]
0068EC90 8D8D CA004100 lea ecx,dword ptr ss:[ebp+4100CA]
0068EC96 2BCF sub ecx,edi
0068EC98 33C0 xor eax,eax
0068EC9A F3:AA rep stos byte ptr es:[edi]
//清除DLL、函數名 不讓殼清除,NOP掉 ★
0068EC9C C3 retn

006916BC E8 0CD3FFFF call 0068E9CD
006916C1 E8 3EF9FFFF call 00691004
//返回這裡

記住call 0068E9CD是處理殼所使用函數的地方


—————————————————————————————————
二、搞定輸入表


繼續在GetModuleHandleA處設定記憶體訪問斷點
Shift+F9執行,中斷後取消斷點。Alt+F9返回

0069082F 8B95 1FFC4000 mov edx,dword ptr ss:[ebp+40FC1F]
00690835 8BB5 E0FC4000 mov esi,dword ptr ss:[ebp+40FCE0]
0069083B 03F2 add esi,edx
0069083D 8B46 0C mov eax,dword ptr ds:[esi+C]
00690840 0BC0 or eax,eax
00690842 0F84 25020000 je 00690A6D
00690848 8366 0C 00 and dword ptr ds:[esi+C],0
//這裡清空ImageImportDescriptor的Name! NOP掉 1 ★
當我們中斷後返回0069086B時,這裡已經執行過一次了,清除了第一個Name游標。
可以根據當時的暫存器情況來恢復這個游標。在0069086B時ESI=00581000,[esi+C]=[0058100C]=00 00,而EBX=00581904 ASCII "KERNEL32.dll" 是第一個處理的DLL名,所以可以確定[0058100C]=00181904,修改之,否則DLLName會有錯誤 ★
0069084C 03C2 add eax,edx
0069084E 8BD8 mov ebx,eax
00690850 56 push esi
00690851 57 push edi
00690852 50 push eax
00690853 8BF3 mov esi,ebx
00690855 8BFB mov edi,ebx
00690857 AC lods byte ptr ds:[esi]
00690858 C0C0 03 rol al,3
//解碼出DLL名 ★
0069085B AA stos byte ptr es:[edi]
0069085C 803F 00 cmp byte ptr ds:[edi],0
0069085F 75 F6 jnz short 00690857
00690861 58 pop eax
00690862 5F pop edi
00690863 5E pop esi
00690864 50 push eax
00690865 FF95 90E24100 call dword ptr ss:[ebp+41E290]
0069086B 0BC0 or eax,eax
//返回這裡 此時ESI=00581000-00400000=00181000 輸入表的RVA ★
0069086D 75 43 jnz short 006908B2
0069086F 90 nop
00690870 90 nop
00690871 90 nop
00690872 90 nop
00690873 53 push ebx
00690874 FF95 94E24100 call dword ptr ss:[ebp+41E294]
0069087A 0BC0 or eax,eax
0069087C 75 34 jnz short 006908B2
0069087E 90 nop
0069087F 90 nop
00690880 90 nop
00690881 90 nop
00690882 8B95 1FFC4000 mov edx,dword ptr ss:[ebp+40FC1F]
00690888 0195 1D1F4000 add dword ptr ss:[ebp+401F1D],edx
0069088E 0195 211F4000 add dword ptr ss:[ebp+401F21],edx
00690894 6A 00 push 0
00690896 FFB5 1D1F4000 push dword ptr ss:[ebp+401F1D]
0069089C FFB5 211F4000 push dword ptr ss:[ebp+401F21]
006908A2 6A 00 push 0
006908A4 FF95 9CE24100 call dword ptr ss:[ebp+41E29C]
006908AA 6A 00 push 0
006908AC FF95 98E24100 call dword ptr ss:[ebp+41E298]
006908B2 60 pushad
006908B3 2BC0 sub eax,eax
006908B5 8803 mov byte ptr ds:[ebx],al
//用完之後清空DLL名 NOP掉 2! ★
006908B7 43 inc ebx
006908B8 3803 cmp byte ptr ds:[ebx],al
006908BA 75 F9 jnz short 006908B5
006908BC 61 popad
006908BD 8985 17FC4000 mov dword ptr ss:[ebp+40FC17],eax
//儲存DLL基址
006908C3 C785 1BFC4000 0>mov dword ptr ss:[ebp+40FC1B],0
006908CD 8B95 1FFC4000 mov edx,dword ptr ss:[ebp+40FC1F]
006908D3 8B06 mov eax,dword ptr ds:[esi]
006908D5 0BC0 or eax,eax
006908D7 75 07 jnz short 006908E0
006908D9 90 nop
006908DA 90 nop
006908DB 90 nop
006908DC 90 nop
006908DD 8B46 10 mov eax,dword ptr ds:[esi+10]
006908E0 03C2 add eax,edx
006908E2 0385 1BFC4000 add eax,dword ptr ss:[ebp+40FC1B]
006908E8 8B18 mov ebx,dword ptr ds:[eax]
006908EA 8B7E 10 mov edi,dword ptr ds:[esi+10]
006908ED 03FA add edi,edx
006908EF 03BD 1BFC4000 add edi,dword ptr ss:[ebp+40FC1B]
006908F5 85DB test ebx,ebx
006908F7 0F84 62010000 je 00690A5F
006908FD F7C3 00000080 test ebx,80000000
00690903 75 1D jnz short 00690922
00690905 90 nop
00690906 90 nop
00690907 90 nop
00690908 90 nop
00690909 03DA add ebx,edx
0069090B 83C3 02 add ebx,2
0069090E 56 push esi
0069090F 57 push edi
00690910 50 push eax
00690911 8BF3 mov esi,ebx
00690913 8BFB mov edi,ebx
00690915 AC lods byte ptr ds:[esi]
00690916 C0C0 03 rol al,3
//解碼出函數名 ★
00690919 AA stos byte ptr es:[edi]
0069091A 803F 00 cmp byte ptr ds:[edi],0
0069091D 75 F6 jnz short 00690915
0069091F 58 pop eax
00690920 5F pop edi
00690921 5E pop esi
00690922 3B9D 1FFC4000 cmp ebx,dword ptr ss:[ebp+40FC1F]
00690928 7C 11 jl short 0069093B
0069092A 90 nop
0069092B 90 nop
0069092C 90 nop
0069092D 90 nop
0069092E 83BD 02244000 0>cmp dword ptr ss:[ebp+402402],0
00690935 75 0A jnz short 00690941
00690937 90 nop
00690938 90 nop
00690939 90 nop
0069093A 90 nop
0069093B 81E3 FFFFFF0F and ebx,0FFFFFFF
00690941 53 push ebx
00690942 FFB5 17FC4000 push dword ptr ss:[ebp+40FC17]
00690948 FF95 8CE24100 call dword ptr ss:[ebp+41E28C]
0069094E 3B9D 1FFC4000 cmp ebx,dword ptr ss:[ebp+40FC1F]
00690954 7C 0F jl short 00690965
00690956 90 nop
00690957 90 nop
00690958 90 nop
00690959 90 nop
0069095A 60 pushad
0069095B 2BC0 sub eax,eax
0069095D 8803 mov byte ptr ds:[ebx],al
//用完之後清空函數名 NOP掉 3! ★
0069095F 43 inc ebx
00690960 3803 cmp byte ptr ds:[ebx],al
00690962 75 F9 jnz short 0069095D
00690964 61 popad
00690965 0BC0 or eax,eax
00690967 0F84 15FFFFFF je 00690882
0069096D 3B85 9CE24100 cmp eax,dword ptr ss:[ebp+41E29C]
//是否是MessageBoxA ?EMbedded Protector 專用APT接頭
00690973 74 20 je short 00690995
00690975 90 nop
00690976 90 nop
00690977 90 nop
00690978 90 nop
00690979 3B85 9D014100 cmp eax,dword ptr ss:[ebp+41019D]
//是否是RegisterHotKey ?
0069097F 74 09 je short 0069098A
00690981 90 nop
00690982 90 nop
00690983 90 nop
00690984 90 nop
00690985 EB 14 jmp short 0069099B
00690987 90 nop
00690988 90 nop
00690989 90 nop
0069098A 8D85 0A024100 lea eax,dword ptr ss:[ebp+41020A]
00690990 EB 09 jmp short 0069099B
00690992 90 nop
00690993 90 nop
00690994 90 nop
00690995 8D85 24024100 lea eax,dword ptr ss:[ebp+410224]
0069099B 56 push esi
0069099C FFB5 17FC4000 push dword ptr ss:[ebp+40FC17]
006909A2 5E pop esi
006909A3 39B5 FA234000 cmp dword ptr ss:[ebp+4023FA],esi
//比較是否是Kernel32.DLL基址
006909A9 74 15 je short 006909C0
006909AB 90 nop
006909AC 90 nop
006909AD 90 nop
006909AE 90 nop
006909AF 39B5 FE234000 cmp dword ptr ss:[ebp+4023FE],esi
//比較是否是User32.DLL基址
006909B5 74 09 je short 006909C0
006909B7 90 nop
006909B8 90 nop
006909B9 90 nop
006909BA 90 nop
006909BB EB 63 jmp short 00690A20
006909BD 90 nop
006909BE 90 nop
006909BF 90 nop
006909C0 80BD D2594100 0>cmp byte ptr ss:[ebp+4159D2],0
006909C7 74 57 je short 00690A20
//Magic Jump! 如果用ImportREC修復輸入表,則可以修改這裡為:jmp 00690A20
006909C9 90 nop
006909CA 90 nop
006909CB 90 nop
006909CC 90 nop
006909CD EB 07 jmp short 006909D6
//下面就是加密了
006909CF 90 nop
006909D0 90 nop
006909D1 90 nop
006909D2 0100 add dword ptr ds:[eax],eax
006909D4 0000 add byte ptr ds:[eax],al
006909D6 8BB5 E4FC4000 mov esi,dword ptr ss:[ebp+40FCE4]
006909DC 83C6 0D add esi,0D
006909DF 81EE EA1B4000 sub esi,401BEA
006909E5 2BF5 sub esi,ebp
006909E7 83FE 00 cmp esi,0
006909EA 7F 34 jg short 00690A20
006909EC 90 nop
006909ED 90 nop
006909EE 90 nop
006909EF 90 nop
006909F0 8BB5 E4FC4000 mov esi,dword ptr ss:[ebp+40FCE4]
006909F6 53 push ebx
006909F7 50 push eax
006909F8 E8 A3B2FFFF call 0068BCA0
006909FD 8BD8 mov ebx,eax
006909FF 58 pop eax
00690A00 33C3 xor eax,ebx
//函數加密只是簡單異或
00690A02 C606 68 mov byte ptr ds:[esi],68
00690A05 8946 01 mov dword ptr ds:[esi+1],eax
00690A08 C746 05 8134240>mov dword ptr ds:[esi+5],243481
00690A0F 895E 08 mov dword ptr ds:[esi+8],ebx
00690A12 C646 0C C3 mov byte ptr ds:[esi+C],0C3
00690A16 5B pop ebx
00690A17 8BC6 mov eax,esi
00690A19 8385 E4FC4000 0>add dword ptr ss:[ebp+40FCE4],0D
00690A20 5E pop esi
00690A21 60 pushad
00690A22 8BD0 mov edx,eax
00690A24 2BBD 1FFC4000 sub edi,dword ptr ss:[ebp+40FC1F]
00690A2A 8BC7 mov eax,edi
00690A2C B9 01010000 mov ecx,101
00690A31 8DBD D3F04000 lea edi,dword ptr ss:[ebp+40F0D3]
00690A37 F2:AF repne scas dword ptr es:[edi]
00690A39 0BC9 or ecx,ecx
00690A3B 74 13 je short 00690A50
00690A3D 90 nop
00690A3E 90 nop
00690A3F 90 nop
00690A40 90 nop
00690A41 81E9 01010000 sub ecx,101
00690A47 F7D1 not ecx
00690A49 89948D D3EC4000 mov dword ptr ss:[ebp+ecx*4+40ECD3],edx
//注意[ebp+ecx*4+40ECD3]從00689CD3開始到0068A0D3結束 ★ Size=400

00690A49處就是處理「API轉發IP到一個位址」的地方!其實這裡和0058117C至0058159C之間的函數是一樣的(去除裡面的00000000)。修復程式碼見最後一節。

00690A50 61 popad
00690A51 8907 mov dword ptr ds:[edi],eax
//API函數的系統位址(或者加密位址)填充到IAT中 NOP掉!4 ★
00690A53 8385 1BFC4000 0>add dword ptr ss:[ebp+40FC1B],4
00690A5A E9 6EFEFFFF jmp 006908CD
00690A5F 83C6 14 add esi,14
00690A62 8B95 1FFC4000 mov edx,dword ptr ss:[ebp+40FC1F]
00690A68 E9 D0FDFFFF jmp 0069083D
//循環處理
00690A6D 8DBD D3F04000 lea edi,dword ptr ss:[ebp+40F0D3]
//修改上面4處後直接F4到這裡 輸入表處理完畢了
00690A73 33C0 xor eax,eax
00690A75 B9 00010000 mov ecx,100
00690A7A F3:AB rep stos dword ptr es:[edi]
00690A7C 60 pushad
00690A7D E8 00000000 call 00690A82

執行LordPE完全Dump出這個工作,修正dumped.exe的Import Table RVA=00181000


—————————————————————————————————
三、OEP Stolen Code


Alt+M 開啟記憶體檢視視窗,在401000第二區段上設定記憶體訪問斷點,Shift+F9執行

004067F4 53 push ebx
//中斷在這裡,取消斷點
004067F5 8BD8 mov ebx,eax
004067F7 33C0 xor eax,eax
004067F9 A3 9CB05700 mov dword ptr ds:[57B09C],eax
004067FE 6A 00 push 0
00406800 E8 25542800 call 0068BC2A
00406805 A3 68065800 mov dword ptr ds:[580668],eax
0040680A A1 68065800 mov eax,dword ptr ds:[580668]
0040680F A3 A8B05700 mov dword ptr ds:[57B0A8],eax
00406814 33C0 xor eax,eax
00406816 A3 ACB05700 mov dword ptr ds:[57B0AC],eax
0040681B 33C0 xor eax,eax
0040681D A3 B0B05700 mov dword ptr ds:[57B0B0],eax
00406822 E8 C1FFFFFF call 004067E8
00406827 BA A4B05700 mov edx,57B0A4
0040682C 8BC3 mov eax,ebx
0040682E E8 9DD7FFFF call 00403FD0
00406833 5B pop ebx
00406834 C3 retn

很明顯,這是Delphi入口後的第一個CALL程式碼,OEP處的程式碼已經被Stloen了
————————————————————————
此時暫存器和堆疊情況如下:

EAX 0057A00C GoodName.0057A00C
ECX 0013FFB0
EDX 7C92EB94 ntdll.KiFastSystemCallRet
EBX 7FFDF000
ESP 0013FFA4 ASCII "jvi"
EBP 0013FFC0
ESI 00000020
EDI 00791000
EIP 004067F4 GoodName.004067F4

0013FFA4 0069766A 返回到 GoodName.0069766A 來自 GoodName.004067F4
0013FFA8 00000020
0013FFAC 7FFDF000
0013FFB0 7C92EB94 ntdll.KiFastSystemCallRet
0013FFB4 00000020
0013FFB8 00000020
0013FFBC 00791000
0013FFC0 0013FFF0
————————————————————————
Ctrl+G:0069766A處看看:

0069761B 8B05 11CC6700 mov eax,dword ptr ds:[67CC11]; GoodName.0067CDC5
00697621 8F05 85CD6700 pop dword ptr ds:[67CD85]
00697627 8B0D 85CD6700 mov ecx,dword ptr ds:[67CD85]
0069762D 8930 mov dword ptr ds:[eax],esi
0069762F 8F05 D9CC6700 pop dword ptr ds:[67CCD9] ; GoodName.0057A00C
00697635 56 push esi
00697636 BE D9CC6700 mov esi,67CCD9
0069763B 8B06 mov eax,dword ptr ds:[esi]
0069763D 5E pop esi
0069763E 8F05 75CD6700 pop dword ptr ds:[67CD75]
00697644 890D E9CE6700 mov dword ptr ds:[67CEE9],ecx
0069764A FF35 E9CE6700 push dword ptr ds:[67CEE9]
00697650 68 75CD6700 push 67CD75
00697655 59 pop ecx
00697656 8B31 mov esi,dword ptr ds:[ecx]
00697658 8F05 B9CC6700 pop dword ptr ds:[67CCB9]
0069765E 8B0D B9CC6700 mov ecx,dword ptr ds:[67CCB9]
00697664 FF15 C5CD6700 call dword ptr ds:[67CDC5] ; GoodName.004067F4
0069766A 90 nop

————————————————————————
結合Delphi程序的一般入口特徵程式碼分析,可以分析出OEP處的前面幾行程式碼:
push ebp
mov ebp,esp
add esp,-10
push ebx
push esi
mov eax,0057A00C
call 004067F4

Ctrl+F9返回0069766A後繼續在401000第二區段上設定記憶體訪問斷點,Shift+F9執行

0057A4BD E8 72C5E8FF call 00406A34
//中斷這裡
0057A4C2 8BD8 mov ebx,eax
0057A4C4 85DB test ebx,ebx
0057A4C6 74 17 je short 0057A4DF

可以看出下面已經是主幹程式碼了,OEP處的Stolen Code到此結束

暫存器和堆疊情況如下:
EAX 00000000
ECX 0013FF94
EDX 0013FFB4
EBX 7FFDA000
ESP 0013FF9C
EBP 0013FFC0
ESI 00580C0C GoodName.00580C0C
EDI 00000040
EIP 0057A4BD GoodName.0057A4BD

0013FF9C 00000000
0013FFA0 FFFFFFFF
0013FFA4 0057A530 ASCII "GoodName"

分析出這幾行程式碼:
mov esi,dword ptr ds:[00XXXXXX]; 00580C0C
push 0057A530
push -1
push 0

如何確定[00XXXXXX]?可以在CODE和DATA段內搜尋0C0C5800,一般在CODE末尾或者DATA段開始
找到:0057F018 0C 0C 58 00

OEP處Stolen Code修復如下:
0057A49C 55 push ebp
0057A49D 8BEC mov ebp,esp
0057A49F 83C4 F0 add esp,-10
0057A4A2 53 push ebx
0057A4A3 56 push esi
0057A4A4 B8 0CA05700 mov eax,57A00C
0057A4A9 E8 46C3E8FF call 004067F4
0057A4AE 8B35 18F05700 mov esi,dword ptr ds:[57F018]
0057A4B4 68 30A55700 push 57A530 ; ASCII "GoodName"
0057A4B9 6A FF push -1
0057A4BB 6A 00 push 0
0057A4BD E8 72C5E8FF call 00406A34

用LordPE修正dumped.exe的OEP RVA=0017A49C


—————————————————————————————————
四、修復殼中啟始化資料之1


現在脫殼文件是無法執行的。設定OllyDbg不忽略記憶體訪問異常選項,載入dumped.exe

0067D612 8BBD 23FC4000 mov edi,dword ptr ss:[ebp+40FC23]
0067D618 B8 0A000000 mov eax,0A
0067D61D F7E1 mul ecx
0067D61F 03F8 add edi,eax
0067D621 8A9D 06244000 mov bl,byte ptr ss:[ebp+402406]
0067D627 B9 0A000000 mov ecx,0A
0067D62C AC lods byte ptr ds:[esi]
0067D62D 32C3 xor al,bl
0067D62F AA stos byte ptr es:[edi]
0067D630 E2 FA loopd short 0067D62C
//訪問違反: 寫入到 [00143C10]

在資料視窗Ctrl+G:ebp+40FC23
0068AC23 E8 36 14 00

這個地方的資料在殼中啟始化過了,現在要找到哪裡進行啟始化的。
載入原版GoodName.exe,在0068AC23處設定記憶體寫入斷點,Shift+F9

0067CB7F 8937 mov dword ptr ds:[edi],esi
//中斷第1次

0068E938 FF95 D8004100 call dword ptr ss:[ebp+4100D8]
//申請記憶體
0068E93E 8985 23FC4000 mov dword ptr ss:[ebp+40FC23],eax
//中斷第2次,申請到的記憶體位址寫入[ebp+40FC23] ★
0068E944 59 pop ecx
0068E945 58 pop eax
0068E946 0385 1FFC4000 add eax,dword ptr ss:[ebp+40FC1F]
0068E94C 8BF0 mov esi,eax
0068E94E 50 push eax
0068E94F 8BBD 23FC4000 mov edi,dword ptr ss:[ebp+40FC23]
0068E955 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
0068E957 58 pop eax
0068E958 50 push eax
0068E959 FFB5 23FC4000 push dword ptr ss:[ebp+40FC23]
0068E95F E8 CBA50000 call 00698F2F
0068E964 FFB5 23FC4000 push dword ptr ss:[ebp+40FC23]
0068E96A FF95 DC004100 call dword ptr ss:[ebp+4100DC]
0068E970 5E pop esi
0068E971 83C6 08 add esi,8
0068E974 EB B1 jmp short 0068E927

Ctrl+F9返回006916CB處

006916C6 E8 9FD0FFFF call 0068E76A
//這裡面申請記憶體
006916CB E8 42FBFFFF call 00691212
//返回這裡

0068E76A C3 retn
//殼執行過會把這裡修改為C3,因此我們要重新跟蹤得到此處的程式碼:60 修改之

在入口修復程式碼裡要增加:call 0068E76A


—————————————————————————————————
五、修復EMbedded Protector


用LordPE修正dumped.exe的OEP RVA=0027C000,按鍵輸入以下程式碼:

0067C000 60 pushad
0067C001 E8 64270100 call 0068E76A
//修復殼中啟始化資料之1
0067C006 61 popad
0067C007 E9 90E4EFFF jmp 0057A49C

BP MessageBoxA Shift+F9,中斷下來
0013FD2C 00570121 CALL 到 MessageBoxA 來自 dumped.0057011C

00570112 61 popad
00570113 60 pushad
00570114 6A 05 push 5
00570116 6A 00 push 0
00570118 6A 00 push 0
0057011A 6A FF push -1
0057011C E8 8372E9FF call 004073A4 ; <jmp.&user32.MessageBoxA>
//EMbedded Protector
00570121 61 popad
00570122 90 nop
00570123 60 pushad
00570124 40 inc eax
00570125 87D0 xchg eax,edx

004073A4 FF25 2C165800 jmp dword ptr ds:[58162C]; user32.MessageBoxA
//跟蹤原版,得出這裡的值=0068B224 ★


—————————————————————————————————
六、修復殼中啟始化資料之2


0068BB64 8BB48D 251F4000 mov esi,dword ptr ss:[ebp+ecx*4+401F25]
0068BB6B 03B5 1FFC4000 add esi,dword ptr ss:[ebp+40FC1F]
0068BB71 8B948D B5204000 mov edx,dword ptr ss:[ebp+ecx*4+4020B5]
0068BB78 8BBC8D 45224000 mov edi,dword ptr ss:[ebp+ecx*4+402245]
0068BB7F 87CA xchg edx,ecx
0068BB81 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
//訪問違反: 寫入到 [0019C420]

在資料視窗Ctrl+G:ebp+eDx*4+402245
0067D2A9 20 C4 19 00

偵錯原版GoodName.exe,在0067D2A9處設定記憶體寫入斷點,Shift+F9

00691426 60 pushad
00691427 E8 A6B0FFFF call 0068C4D2
0069142C 33D2 xor edx,edx
0069142E 8BB495 251F4000 mov esi,dword ptr ss:[ebp+edx*4+401F25]
00691435 0BF6 or esi,esi
00691437 74 31 je short 0069146A
00691439 90 nop
0069143A 90 nop
0069143B 90 nop
0069143C 90 nop
0069143D 03B5 1FFC4000 add esi,dword ptr ss:[ebp+40FC1F]
00691443 8B8C95 B5204000 mov ecx,dword ptr ss:[ebp+edx*4+4020B5]
0069144A 60 pushad
0069144B 52 push edx
0069144C 51 push ecx
0069144D 6A 40 push 40
0069144F FF95 D8004100 call near dword ptr ss:[ebp+4100D8]
//申請記憶體
00691455 5A pop edx
00691456 898495 45224000 mov dword ptr ss:[ebp+edx*4+402245],eax
//中斷第2次,申請到的記憶體位址寫入[ebp+edx*4+402245] ★
0069145D 61 popad
0069145E 8BBC95 45224000 mov edi,dword ptr ss:[ebp+edx*4+402245]
00691465 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00691467 42 inc edx
00691468 EB C4 jmp short 0069142E
0069146A 61 popad
0069146B C3 retn

在入口修復程式碼裡要增加:call 00691426


—————————————————————————————————
七、最終修復程式碼


0067C000 60 pushad
0067C001 36:A1 D0115800 mov eax,dword ptr ss:[5811D0]
//GetModuleHandleA
0067C007 36:A3 90926900 mov dword ptr ss:[699290],eax
0067C00D A3 10B16800 mov dword ptr ds:[68B110],eax
0067C012 36:A1 CC115800 mov eax,dword ptr ss:[5811CC]
//GetProcAddress
0067C018 36:A3 8C926900 mov dword ptr ss:[69928C],eax
0067C01E 36:A3 0CB16800 mov dword ptr ss:[68B10C],eax
0067C024 E8 A4290100 call 0068E9CD
//處理「殼中之殼」所使用的函數
0067C029 E8 3C270100 call 0068E76A
//修復殼中啟始化資料之1
0067C02E E8 F3530100 call 00691426
//修復殼中啟始化資料之2
0067C033 BF D39C6800 mov edi,689CD3
0067C038 BE 7C115800 mov esi,58117C
0067C03D 8B06 mov eax,dword ptr ds:[esi]
0067C03F 85C0 test eax,eax
0067C041 74 05 je short 0067C048
0067C043 8907 mov dword ptr ds:[edi],eax
0067C045 83C7 04 add edi,4
0067C048 83C6 04 add esi,4
0067C04B 81FF D3A06800 cmp edi,68A0D3
0067C051 75 EA jnz short 0067C03D
//上面這個循環是把0058117C-0058159C之間的函數(去除00000000)複製到00689CD3-0068A0D3
//修復「API轉發IP到一個位址」所用到的函數
0067C053 36:A1 D4125800 mov eax,dword ptr ss:[5812D4]
//LoadLibraryA 跨系統平台測試時發現這幾個地方還需要修復
0067C059 36:A3 14B16800 mov dword ptr ss:[68B114],eax
0067C05F 36:A3 94926900 mov dword ptr ss:[699294],eax
0067C065 36:A1 EC115800 mov eax,dword ptr ss:[5811EC]
//ExitProcess
0067C06B 36:A3 18B16800 mov dword ptr ss:[68B118],eax
0067C071 36:A3 98926900 mov dword ptr ss:[699298],eax
0067C077 36:A1 2C165800 mov eax,dword ptr ss:[58162C]
//MessageBoxA
0067C07D 36:A3 9C926900 mov dword ptr ss:[69929C],eax
0067C083 36:C705 2C16580>mov dword ptr ss:[58162C],68B224
//EMbedded Protector
0067C08E 36:C705 639D680>mov dword ptr ss:[689D63],68B224
//EMbedded Protector
0067C099 61 popad
0067C09A E9 FDE3EFFF jmp 0057A49C
//返回OEP繼續執行,OK!
脫殼後的程序中關於註冊的關鍵程式碼段還是帶殼的(這就是SDK?),要想爆破,還得把這部分程式碼脫出來。可這個程序又是多點校驗,想要把所有的關鍵段都脫出來,可不是件容易事。因此破解它還是要跟註冊碼。註冊訊息儲存在下面註冊表項下:

HKEY_LOCAL_MACHINE\SOFTWARE\GoodSoft\GoodName

其中有一項"Appid",程序在發現有人為對註冊表改動後,會把"Appid"的值改為"4D",然後程序就不能註冊了,發生這種情況後可以用regedit手動把這一項改為0,就又可以註冊了。設定OD忽略所有異常,載入程序後,先下斷:

bp RegQuery類型ExA

然後執行程序,中斷後看堆疊第三行,不出現"Appid"就F9執行,出現"Appid"後,關閉RegQuery類型ExA這個斷點,Alt+F9返回,再經過兩個ret,來到這裡:

005735C6 mov edx,UnPacKed.00573AE0 ; ASCII "Appid"
005735CB mov eax,dword ptr ss:[ebp-14]
005735CE call UnPacKed.0043D0EC
005735D3 mov dword ptr ss:[ebp-8],eax <====返回這裡
005735D3 mov dword ptr ss:[ebp-8],eax
005735D6 lea ecx,dword ptr ss:[ebp-C]
005735D9 mov edx,UnPacKed.00573AF0 ; ASCII "Serial"
005735DE mov eax,dword ptr ss:[ebp-14]
005735E1 call UnPacKed.0043D060
005735E6 lea ecx,dword ptr ss:[ebp-10]
005735E9 mov edx,UnPacKed.00573B00 ; ASCII "FName"
005735EE mov eax,dword ptr ss:[ebp-14]
005735F1 call UnPacKed.0043D060
005735F6 lea edx,dword ptr ss:[ebp-24]
005735F9 mov eax,dword ptr ss:[ebp-10]
005735FC call UnPacKed.00408B60 <====從執行前後記憶體中資料可以看出,這個call是複製字元串

這裡就是啟動的驗證段,但這裡沒有對註冊碼的完整的校驗,在點擊「註冊」以後有完整的校驗,因此要找到點擊「註冊」以後的程式碼。算註冊碼的時候離不開複製字元串的操作,因此下斷:bp 00408B60,可是使用得太多,仔細觀察了一下,發現其它使用點一般都在00500000以下,所以把00408B60的斷點加上條件:[esp]>00500000,找到了點「註冊」以後的程式碼段:

0055A090 lea edx,dword ptr ss:[ebp-20]
0055A093 mov eax,dword ptr ss:[ebp-4]
0055A096 mov eax,dword ptr ds:[eax+32C]
0055A09C call UnPacKed.004569A8 取序列號
0055A0A1 mov eax,dword ptr ss:[ebp-20]
0055A0A4 lea edx,dword ptr ss:[ebp-1C]
0055A0A7 call UnPacKed.00408B60 複製序列號
0055A0AC mov eax,dword ptr ss:[ebp-1C]
0055A0AF call UnPacKed.00404584 查序列號位數
0055A0B4 cmp eax,0A 這裡要求序列號大於10位
0055A0B7 jge short UnPacKed.0055A0C1
.............
0055A2F2 mov eax,dword ptr ss:[ebp-4]
0055A2F5 call UnPacKed.005565EC 跟進後有解壓縮程式碼,估計是關鍵程式碼。

跟進call UnPacKed.005565EC,經過下面一段後,就是解壓縮啦,壓縮方式仍然是ACProtect,施展跟蹤ACProect的本領來跟吧:

00556616 call UnPacKed.004767E8 這裡不用解壓,可在此處下一個斷點
0055661B pushad

【3. 程式碼粗跟蹤】

跟蹤ACProtect,大家可以各顯其才。我提供一種方法供參考,其實這是我剛發現的方法,我在一開始跟蹤時也不知道這個方法,我跟蹤時用的方法要比這個費勁得多。
這個軟體嵌入的解碼有個特點,都有一次int3異常,這使得硬體斷點不能直接使用。但也不是絕對地不能用,要在發生int3異常以後再用才行。對於此例,到達00556616處,esp=12f8b8。設定OD不忽略「int3中斷」和「同時忽略以下指定的異常或者異常範圍」,其餘全忽略。F9執行程序,在00558058處發生異常,這時下:hr 12f8b4,F9執行,第3次中斷時解碼完畢,斷下後取消硬體斷點。其餘地方可按此法處理,不再贅述。

對點「註冊」以後的程式碼粗跟蹤如下:

00559AEC call UnPacKed.0050A150 根據系統算出申請碼
........................
00559B5B mov edx,dword ptr ss:[ebp-38] 對話視窗中的申請碼
00559B5E mov eax,dword ptr ss:[ebp-C] 根據系統算出的申請碼
00559B61 call UnPacKed.004046D0 兩個申請碼比較
00559B66 jnz UnPacKed.00559ED7
................
00559C41 lea eax,dword ptr ss:[ebp-70]
00559C44 push eax
00559C45 lea edx,dword ptr ss:[ebp-74]
00559C48 mov eax,dword ptr ss:[ebp-C]
00559C4B call UnPacKed.00408B60 複製申請碼
00559C50 lea eax,dword ptr ss:[ebp-74]
00559C53 mov edx,UnPacKed.00559FD8 ; ASCII " "
00559C58 call UnPacKed.0040458C 申請碼後面加空格
00559C5D mov eax,dword ptr ss:[ebp-74]
00559C60 mov ecx,8
00559C65 mov edx,1
00559C6A call UnPacKed.004047E4 取前8位
00559C6F lea eax,dword ptr ss:[ebp-70]
00559C72 push eax
00559C73 lea edx,dword ptr ss:[ebp-7C]
00559C76 mov eax,dword ptr ds:[esi+300]
00559C7C call UnPacKed.004569A8 從對話視窗中取姓
00559C81 mov eax,dword ptr ss:[ebp-7C]
00559C84 lea edx,dword ptr ss:[ebp-78]
00559C87 call UnPacKed.00408B60 複製姓
00559C8C mov edx,dword ptr ss:[ebp-78]
00559C8F pop eax
00559C90 call UnPacKed.0040458C 把姓連在申請碼之後
00559C95 mov eax,dword ptr ss:[ebp-70]
00559C98 lea edx,dword ptr ss:[ebp-6C]
00559C9B call UnPacKed.004E00B8 加密(每位和1F異或)
00559CA0 mov edx,dword ptr ss:[ebp-6C]
00559CA3 mov eax,dword ptr ds:[57F108]
00559CA8 call UnPacKed.00404318 儲存加密後申請碼的位址
00559CAD lea edx,dword ptr ss:[ebp-8C]
00559CB3 mov eax,dword ptr ds:[esi+32C]
00559CB9 call UnPacKed.004569A8 取序列號
00559CBE mov eax,dword ptr ss:[ebp-8C]
00559CC4 lea edx,dword ptr ss:[ebp-88]
00559CCA call UnPacKed.00408B60 複製序列號
00559CCF mov eax,dword ptr ss:[ebp-88]
00559CD5 lea edx,dword ptr ss:[ebp-84]
00559CDB call UnPacKed.00513FFC 序列號調位
00559CE0 mov eax,dword ptr ss:[ebp-84]
00559CE6 lea edx,dword ptr ss:[ebp-80]
00559CE9 call UnPacKed.004E00B8 加密(每位和1F異或)
00559CEE mov edx,dword ptr ss:[ebp-80]
00559CF1 mov eax,dword ptr ds:[57EB9C] 儲存位址
00559CF6 call UnPacKed.00404318
00559CFB lea edx,dword ptr ss:[ebp-C]
00559CFE mov eax,dword ptr ds:[57F108]
00559D03 mov eax,dword ptr ds:[eax]
00559D05 call UnPacKed.004FBC54 對由申請碼和姓字元串變換f1()得一字元串A
00559D0A lea eax,dword ptr ss:[ebp-94]
00559D10 push eax
00559D11 lea edx,dword ptr ss:[ebp-98]
00559D17 mov eax,dword ptr ds:[57EB9C]
00559D1C mov eax,dword ptr ds:[eax]
00559D1E call UnPacKed.004E00B8 對序列號的變換結果再變換,即還原出序列號
00559D23 mov eax,dword ptr ss:[ebp-98]
00559D29 mov ecx,5
00559D2E mov edx,17 從17H=23位開始取5位
00559D33 call UnPacKed.004047E4
00559D38 mov eax,dword ptr ss:[ebp-94]
00559D3E lea edx,dword ptr ss:[ebp-90]
00559D44 call UnPacKed.004ED010 對23~27位變換f2(),得到B
00559D49 mov edx,dword ptr ss:[ebp-90] B
00559D4F mov eax,dword ptr ss:[ebp-C] 正確值A
00559D52 call UnPacKed.004046D0 比較
00559D57 jnz UnPacKed.00559ED7 關鍵之一
00559D5D lea eax,dword ptr ss:[ebp-A0]
00559D63 push eax
00559D64 lea edx,dword ptr ss:[ebp-A4]
00559D6A mov eax,dword ptr ds:[57EB9C]
00559D6F mov eax,dword ptr ds:[eax]
00559D71 call UnPacKed.004E00B8
00559D76 mov eax,dword ptr ss:[ebp-A4]
00559D7C mov ecx,5
00559D81 mov edx,17
00559D86 call UnPacKed.004047E4
00559D8B mov eax,dword ptr ss:[ebp-A0]
00559D91 lea edx,dword ptr ss:[ebp-9C]
00559D97 call UnPacKed.004ED010
00559D9C mov edx,dword ptr ss:[ebp-9C]
00559DA2 mov eax,dword ptr ss:[ebp-C]
00559DA5 call UnPacKed.004046D0 比較之二,與比較之一相同
00559DAA jnz UnPacKed.00559E6A
00559DB0 lea eax,dword ptr ss:[ebp-A8]
00559DB6 push eax
00559DB7 lea edx,dword ptr ss:[ebp-AC]
00559DBD mov eax,dword ptr ds:[57EB9C]
00559DC2 mov eax,dword ptr ds:[eax]
00559DC4 call UnPacKed.004E00B8
00559DC9 mov eax,dword ptr ss:[ebp-AC]
00559DCF mov ecx,3
00559DD4 mov edx,1D
00559DD9 call UnPacKed.004047E4 取29~31位
00559DDE mov eax,dword ptr ss:[ebp-A8]
00559DE4 call UnPacKed.004E9BE0 對29~31位變換
00559DE9 mov ebx,eax
00559DEB lea eax,dword ptr ss:[ebp-B0]
00559DF1 push eax
00559DF2 lea edx,dword ptr ss:[ebp-B4]
00559DF8 mov eax,dword ptr ds:[57EB9C]
00559DFD mov eax,dword ptr ds:[eax]
00559DFF call UnPacKed.004E00B8
00559E04 mov eax,dword ptr ss:[ebp-B4]
00559E0A mov ecx,1C
00559E0F mov edx,1
00559E14 call UnPacKed.004047E4 取1~28位
00559E19 mov eax,dword ptr ss:[ebp-B0]
00559E1F call UnPacKed.004F0748 對1~28位變換
00559E24 cmp ebx,eax 關鍵比較之三
00559E26 jnz UnPacKed.00559ED7
00559E2C mov eax,UnPacKed.00559FF8 ; ASCII "111"
00559E31 call UnPacKed.00506940 關鍵之四,校驗17~22位
00559E36 mov byte ptr ss:[ebp-1],al
00559E39 cmp byte ptr ss:[ebp-1],0
00559E3D je short UnPacKed.00559E4C
00559E3F lea eax,dword ptr ss:[ebp-C]
00559E42 mov edx,UnPacKed.00559FF8 ; ASCII "111"
00559E47 call UnPacKed.0040435C
00559E4C cmp byte ptr ss:[ebp-1],0
00559E50 je UnPacKed.00559ED7
00559E56 mov eax,dword ptr ss:[ebp-C]
00559E59 mov edx,UnPacKed.00559FF8 ; ASCII "111"
00559E5E call UnPacKed.004046D0
00559E63 jnz short UnPacKed.00559E6A
00559E65 call UnPacKed.00503320 關鍵之五,校驗1~16位

跟蹤時發現,根據系統計算申請碼時用到了cpuid這個API,可是在我的電腦上多次執行這個API,返回值中ebx的值是在兩個值中變的,因此算出的申請碼也有兩種,程序發現兩個申請碼不同也會通不過註冊,因此跟蹤時要注意一下00559B66這個地方。我覺得這也算是軟體的一個BUG。
對註冊碼驗證前先對註冊碼調位,使用點如00559CDB。調位的方法是第1、4位互換,第5、8位互換,4*i+1位和4*(i+1)位互換,i=0,1,2,...,末尾不足4位時,最後兩位互換。以下所講的除非特別說明的以外,均是調位以後的註冊碼,程序把註冊碼分成四段進行校驗。

【4. 對23~27位的校驗】

其校驗程序大致是:由申請碼加上姓得到一個字元串,加密(每位和1F異或)後,再進去行較複雜的運算f1(),得到A。註冊碼的23~27位進行另一種變換f2(),得到B,A和B進行比較。f1()不必求逆,直接用結果就行。跟進call UnPacKed.004ED010,看看f2()是什麼:

004F026F call UnPacKed.0040435C
004F0274 mov eax,ebx
004F0276 call UnPacKed.004042C4
004F027B mov esi,1
004F0280 mov eax,edi
004F0282 call UnPacKed.00404584 查位數
004F0287 mov dword ptr ss:[ebp-4],eax
004F028A mov eax,dword ptr ss:[ebp-4]
004F028D mov ecx,5
004F0292 cdq
004F0293 idiv ecx
004F0295 test eax,eax
004F0297 jle UnPacKed.004F03AD
004F029D mov dword ptr ss:[ebp-20],eax
004F02A0 lea eax,dword ptr ss:[ebp-24]
004F02A3 mov dl,byte ptr ds:[edi+esi-1] 取出第一位
004F02A7 call UnPacKed.004044AC
004F02AC mov eax,dword ptr ss:[ebp-24]
004F02AF mov edx,dword ptr ss:[ebp-1C]
004F02B2 call UnPacKed.004048C8 查表 EBP-1C 0> 004F060C ASCII "0KMT1EIJ2AB34FGH56PYZ7NRS89CDUVX"
004F02B7 dec eax
004F02B8 mov dword ptr ss:[ebp-8],eax 儲存
004F02BB lea eax,dword ptr ss:[ebp-28]
004F02BE mov dl,byte ptr ds:[edi+esi] 取出第二位
004F02C1 call UnPacKed.004044AC
004F02C6 mov eax,dword ptr ss:[ebp-28]
004F02C9 mov edx,dword ptr ss:[ebp-1C]
004F02CC call UnPacKed.004048C8
004F02D1 dec eax
004F02D2 mov dword ptr ss:[ebp-C],eax
004F02D5 lea eax,dword ptr ss:[ebp-2C]
004F02D8 mov dl,byte ptr ds:[edi+esi+1] 取出第三位
004F02DC call UnPacKed.004044AC
004F02E1 mov eax,dword ptr ss:[ebp-2C]
004F02E4 mov edx,dword ptr ss:[ebp-1C]
004F02E7 call UnPacKed.004048C8 查表
004F02EC dec eax
004F02ED mov dword ptr ss:[ebp-10],eax 儲存
004F02F0 lea eax,dword ptr ss:[ebp-30]
004F02F3 mov dl,byte ptr ds:[edi+esi+2] 取出第四位
004F02F7 call UnPacKed.004044AC
004F02FC mov eax,dword ptr ss:[ebp-30]
004F02FF mov edx,dword ptr ss:[ebp-1C]
004F0302 call UnPacKed.004048C8
004F0307 dec eax
004F0308 mov dword ptr ss:[ebp-14],eax
004F030B lea eax,dword ptr ss:[ebp-34]
004F030E mov dl,byte ptr ds:[edi+esi+3] 取出第五位
004F0312 call UnPacKed.004044AC
004F0317 mov eax,dword ptr ss:[ebp-34]
004F031A mov edx,dword ptr ss:[ebp-1C]
004F031D call UnPacKed.004048C8
004F0322 dec eax
004F0323 mov dword ptr ss:[ebp-18],eax
004F0326 add esi,5
004F0329 lea eax,dword ptr ss:[ebp-38]
004F032C mov edx,dword ptr ss:[ebp-8] 取出第一位查表得的數
004F032F shl edx,3 左移3位
004F0332 and edx,0F8 取高五位
004F0338 mov ecx,dword ptr ss:[ebp-C] 取第二位的數
004F033B shr ecx,2 右移2位
004F033E and ecx,7 取低3位
004F0341 or edx,ecx 兩數取或,這就是結果第一字元,應為52
004F0343 call UnPacKed.004044AC 儲存
004F0348 mov edx,dword ptr ss:[ebp-38]
004F034B mov eax,ebx
004F034D call UnPacKed.0040458C
004F0352 lea eax,dword ptr ss:[ebp-3C]
004F0355 mov edx,dword ptr ss:[ebp-14] 取第四位的數
004F0358 shl edx,3 左移3位
004F035B and edx,0C0 取高2位
004F0361 mov ecx,dword ptr ss:[ebp-C] 取第2位的數
004F0364 shl ecx,4 左移4位
004F0367 and ecx,30 取高2位
004F036A or edx,ecx 取或
004F036C mov ecx,dword ptr ss:[ebp-10] 取第3位的數
004F036F and ecx,0F 取低4位
004F0372 or edx,ecx 取或
004F0374 call UnPacKed.004044AC
004F0379 mov edx,dword ptr ss:[ebp-3C]
004F037C mov eax,ebx
004F037E call UnPacKed.0040458C
004F0383 lea eax,dword ptr ss:[ebp-40]
004F0386 mov edx,dword ptr ss:[ebp-14] 取第四位的數
004F0389 shl edx,5 左移5位
004F038C and edx,0E0 取高3位
004F0392 or edx,dword ptr ss:[ebp-18] 與第五位的數取或
004F0395 call UnPacKed.004044AC 儲存
004F039A mov edx,dword ptr ss:[ebp-40]
004F039D mov eax,ebx
004F039F call UnPacKed.0040458C 連接52 35 26
004F03A4 dec dword ptr ss:[ebp-20] 計算結果應為52 36 46,有時變為31 4B 4B
004F03A7 jnz UnPacKed.004F02A0

總結:f2()具體變換是:首先按位在"0KMT1EIJ2AB34FGH56PYZ7NRS89CDUVX"中查表,得到數a、b、c、d、e,然後對a、b、c、d、e進行移位,重新組合成三個字元即數B,調位方法:

a4,a3,a2,a1,a0,b4,b3,b2
d4,d3,b1,b0,c3,c2,c1,c0
d2,d1,d0,e4,e3,e2,e1,e0

求逆方法:

1. 執行到00559D0A,然後下:d [ebp-c],記下資料區顯示的正確值x,y,z;
2. 對3個字元的正確值進行調位,得到灌水限制節a,b,c,d,e,調位方法為:

0,0,0,x7,x6,x5,x4,x3
0,0,0,x2,x1,x0,y5,y4
0,0,0,0 ,y3,y2,y1,y0
0,0,0,y7,y6,z7,z6,z5
0,0,0,z4,z3,z2,z1,z0

3. 根據灌水限制節查表"0KMT1EIJ2AB34FGH56PYZ7NRS89CDUVX",得到5位註冊碼即為23~27位。

【5. 對29~31位的校驗】

29~31位相當於前28位的校驗和,首先求29~31位的值,跟進call UnPacKed.004E9BE0:

004ECE3B mov eax,dword ptr ss:[ebp-8]
004ECE3E call UnPacKed.00404584 查位數
004ECE43 mov esi,eax
004ECE45 mov al,byte ptr ds:[edi+esi-1]
004ECE49 call UnPacKed.004ECFF0 在此表中查位置"0AH6CD3BEF4TRS2PUV5K1MN78YZ9GIJ"
004ECE4E mov dword ptr ss:[ebp-4],eax
004ECE51 cmp esi,1
004ECE54 jle short UnPacKed.004ECE8E
004ECE56 mov ebx,esi
004ECE58 dec ebx
004ECE59 cmp ebx,1
004ECE5C jl short UnPacKed.004ECE8E
004ECE5E push 4003
004ECE63 push F8000000 浮點數31
004ECE68 push 0
004ECE6A mov eax,esi
004ECE6C sub eax,ebx
004ECE6E call UnPacKed.0042EE28 計算31的n次方
004ECE73 call UnPacKed.00402B80 從浮點棧中彈出計算結果
004ECE78 push eax
004ECE79 mov al,byte ptr ds:[edi+ebx-1]
004ECE7D call UnPacKed.004ECFF0
004ECE82 pop edx
004ECE83 imul edx,eax
004ECE86 add dword ptr ss:[ebp-4],edx
004ECE89 dec ebx
004ECE8A test ebx,ebx
004ECE8C jnz short UnPacKed.004ECE5E

然後對1~28位求和,跟進call UnPacKed.004F0748,當然也可以不看這一段算法:

004F3983 call UnPacKed.00404584
004F3988 mov edx,eax
004F398A test dl,dl
004F398C jbe short UnPacKed.004F39A0
004F398E mov al,1
004F3990 xor ecx,ecx
004F3992 mov cl,al
004F3994 movzx ecx,byte ptr ds:[edi+ecx-1] 取1~28位中的一位
004F3999 add esi,ecx 累加
004F399B inc eax
004F399C dec dl
004F399E jnz short UnPacKed.004F3990
004F39A0 xor eax,eax
004F39A2 mov al,byte ptr ds:[edi+2] 取第3位
004F39A5 mov ecx,0A
004F39AA xor edx,edx
004F39AC div ecx 除以10
004F39AE mov eax,edx
004F39B0 test al,al 看餘數,如為0則置為10
004F39B2 jnz short UnPacKed.004F39B6
004F39B4 mov al,0A
004F39B6 and eax,0FF
004F39BB imul esi 累加和乘以這個餘數
004F39BD mov esi,eax
004F39BF cmp esi,6978 結果與27000比較,如大於這個數,則除以這個數取余
004F39C5 jle short UnPacKed.004F39D3
004F39C7 mov eax,esi
004F39C9 mov ecx,6978
004F39CE cdq
004F39CF idiv ecx
004F39D1 mov esi,edx

對1~28位各位ASCII碼之累加和,再乘以第3位除以10的餘數,如乘積大於27000,則除以27000取余;然後把29~31位看成是31進制數,求16進制值,其變換表為:"0AH6CD3BEF4TRS2PUV5K1MN78YZ9GIJ",所得結果和1~28位的累加和進行比較。

求逆方法:

1. 執行到00559E24,記下eax中的值x,或按照上面的方法計算出這個值;
2. x除以31,用餘數查表"0AH6CD3BEF4TRS2PUV5K1MN78YZ9GIJ",所得字元作為第31位;
3. 第2步的商除以31,用餘數查表,作為第30位;
4. 第3步的商查表,作為第29位。

由於這一步要先確定前28的值,所以這一步可以在把別的碼都求出以後再重跟一遍時進行。

【6. 對17~22位的校驗】

跟進call UnPacKed.00506940:

00509DB6 lea ecx,dword ptr ss:[ebp-60]
00509DB9 mov edx,dword ptr ss:[ebp-20]
00509DBC mov eax,dword ptr ss:[ebp-1C]
00509DBF call UnPacKed.004F46B4 這一步就求出結果,[ebp-60]指向該結果,前6位有效
00509DC4 mov edx,dword ptr ss:[ebp-60]
....................
00509E32 lea edx,dword ptr ss:[ebp-70]
00509E35 mov eax,dword ptr ds:[57EB9C]
00509E3A mov eax,dword ptr ds:[eax]
00509E3C call UnPacKed.004E00B8 還原出註冊碼
00509E41 lea eax,dword ptr ss:[ebp-70]
00509E44 mov edx,UnPacKed.0050A114 ; ASCII " "
00509E49 call UnPacKed.0040458C 註冊碼後面加一串空格
00509E4E mov eax,dword ptr ss:[ebp-70]
00509E51 mov ecx,6
00509E56 mov edx,11
00509E5B call UnPacKed.004047E4 從第17位開始取6位註冊碼
00509E60 mov eax,dword ptr ss:[ebp-6C]
00509E63 lea edx,dword ptr ss:[ebp-68]
00509E66 call UnPacKed.004F0630 註冊碼加密
00509E6B mov eax,dword ptr ss:[ebp-68]
00509E6E push eax
00509E6F lea eax,dword ptr ss:[ebp-78]
00509E72 push eax
00509E73 lea eax,dword ptr ss:[ebp-7C]
00509E76 mov ecx,UnPacKed.0050A138 ; ASCII "2AB75ADD"
00509E7B mov edx,dword ptr ss:[ebp-20]
00509E7E call UnPacKed.004045D0 連接兩個字元串,其中一個為申請碼來的串
00509E83 mov eax,dword ptr ss:[ebp-7C]
00509E86 mov ecx,6
00509E8B mov edx,1
00509E90 call UnPacKed.004047E4 取前6位,即是正確值
00509E95 mov eax,dword ptr ss:[ebp-78]
00509E98 lea edx,dword ptr ss:[ebp-74]
00509E9B call UnPacKed.004F0630 加密,與註冊碼加密算法相同
00509EA0 mov edx,dword ptr ss:[ebp-74]
00509EA3 pop eax
00509EA4 call UnPacKed.004046D0 比較
00509EA9 jnz short UnPacKed.00509EC5

正確碼和待較驗的碼進行相同的加密算法後再進去行比較,但加密之前可以看到正確碼。

求逆方法:

執行到00509DC4,下:d [ebp-60],看到一個字元串,記下前6位,即是正確的17~22位。

【7. 對1~16位的校驗】

跟進call UnPacKed.00503320:

0050659F lea edx,dword ptr ss:[ebp-18]
005065A2 mov eax,dword ptr ds:[57F108]
005065A7 mov eax,dword ptr ds:[eax]
005065A9 call UnPacKed.004F51C0 由申請碼加姓計算得一個數
005065AE lea eax,dword ptr ss:[ebp-18]
005065B1 lea edx,dword ptr ss:[ebp-8]
005065B4 call UnPacKed.004F5234 查表變成字元串
005065B9 lea eax,dword ptr ss:[ebp-20]
005065BC push eax
005065BD lea edx,dword ptr ss:[ebp-24]
005065C0 mov eax,dword ptr ds:[57EB9C]
005065C5 mov eax,dword ptr ds:[eax]
005065C7 call UnPacKed.004E00B8 還原出註冊碼
005065CC mov eax,dword ptr ss:[ebp-24]
005065CF mov ecx,10
005065D4 mov edx,1
005065D9 call UnPacKed.004047E4 取註冊碼的前16位
005065DE mov eax,dword ptr ss:[ebp-20] 註冊碼前16位
005065E1 lea ecx,dword ptr ss:[ebp-1C]
005065E4 mov edx,dword ptr ss:[ebp-8] 申請碼變來的字元串
005065E7 call UnPacKed.004F4728 用DES加密算法計算得一個8字元的數 ★ 只要這個數等於S2即可
005065EC mov eax,dword ptr ss:[ebp-1C]
005065EF lea edx,dword ptr ss:[ebp-18]
005065F2 call UnPacKed.004F51C0 計算得一個數C1
005065F7 lea eax,dword ptr ss:[ebp-18]
005065FA push eax
005065FB lea edx,dword ptr ss:[ebp-38]
005065FE mov eax,dword ptr ds:[57F108]
00506603 mov eax,dword ptr ds:[eax] 加密過的申請碼加姓
00506605 call UnPacKed.004F893C 計算得一個字元串S2
0050660A mov eax,dword ptr ss:[ebp-38]
0050660D lea edx,dword ptr ss:[ebp-34]
00506610 call UnPacKed.004F51C0 計算得一個數C2
00506615 lea eax,dword ptr ss:[ebp-34]
00506618 pop edx
00506619 call UnPacKed.004F52B8 關鍵比較,大數比較
0050661E mov ebx,eax 標誌存在bl裡,後面有五次檢測此標誌,把這個標誌改為1,後面即可暢通無阻
00506620 test bl,bl 第一次檢測標誌
00506622 jnz short UnPacKed.00506638
00506624 xor eax,eax
00506626 call UnPacKed.00518794 清除註冊訊息

跟進call UnPacKed.004F4728:

004F475A lea edx,dword ptr ss:[ebp-C]
004F475D mov eax,dword ptr ss:[ebp-4]
004F4760 call UnPacKed.004E6784 把註冊碼每兩位一組查表,看成31進制數求值。表為:"0AH6CD3BEF4TRS2PUV5K1MN78YZ9GIJ"
004F4765 mov ecx,ebx
004F4767 mov edx,dword ptr ss:[ebp-8] 申請碼變來的字元串
004F476A mov eax,dword ptr ss:[ebp-C] 註冊碼變來的數
004F476D call UnPacKed.004F4438 DES計算
004F4772 xor eax,eax

跟進call UnPacKed.004F4438

004F4498 xor ebx,ebx
004F449A lea eax,dword ptr ss:[ebp-24]
004F449D /mov edx,dword ptr ss:[ebp-8]
004F44A0 |mov dl,byte ptr ds:[edx+ebx]
004F44A3 |mov byte ptr ds:[eax],dl
004F44A5 |inc ebx
004F44A6 |inc eax
004F44A7 |cmp ebx,8
004F44AA \jnz short UnPacKed.004F449D 取申請碼來的串的前8個字元,作為64位的密鑰
004F44AC push 0F
004F44AE mov ecx,UnPacKed.00580E1C 子密鑰要存放的位址
004F44B3 lea eax,dword ptr ss:[ebp-24]
004F44B6 mov edx,7
004F44BB call UnPacKed.004F3E24 設定子密鑰
004F44C0 lea eax,dword ptr ss:[ebp-28]
004F44C3 call UnPacKed.004042C4
004F44C8 mov eax,dword ptr ss:[ebp-4]
004F44CB call UnPacKed.00404584
004F44D0 test eax,eax
004F44D2 jns short UnPacKed.004F44D7
004F44D4 add eax,7
004F44D7 sar eax,3
004F44DA dec eax
004F44DB test eax,eax
004F44DD jl short UnPacKed.004F455D
004F44DF inc eax
004F44E0 mov dword ptr ss:[ebp-30],eax
004F44E3 mov dword ptr ss:[ebp-2C],0
004F44EA /xor ebx,ebx
004F44EC |lea eax,dword ptr ss:[ebp-14]
004F44EF |/mov edx,dword ptr ss:[ebp-2C]
004F44F2 ||shl edx,3
004F44F5 ||add edx,ebx
004F44F7 ||mov ecx,dword ptr ss:[ebp-4]
004F44FA ||mov dl,byte ptr ds:[ecx+edx]
004F44FD ||mov byte ptr ds:[eax],dl
004F44FF ||inc ebx
004F4500 ||inc eax
004F4501 ||cmp ebx,8
004F4504 |\jnz short UnPacKed.004F44EF 取註冊碼變來的數 分組
004F4506 |lea eax,dword ptr ss:[ebp-1C]
004F4509 |push eax ; /Arg2
004F450A |push 7 ; |Arg1 = 00000007
004F450C |lea edx,dword ptr ss:[ebp-14] ; |
004F450F |mov ecx,7 ; |
004F4514 |mov al,1 ; |
004F4516 |call UnPacKed.004F407C ; \UnPacKed.004F407C DES運算
004F451B |mov ebx,8
004F4520 |lea esi,dword ptr ss:[ebp-1C]
004F4523 |/lea eax,dword ptr ss:[ebp-34]
004F4526 ||mov dl,byte ptr ds:[esi]
004F4528 ||call UnPacKed.004044AC
004F452D ||mov edx,dword ptr ss:[ebp-34]
004F4530 ||lea eax,dword ptr ss:[ebp-28]
004F4533 ||call UnPacKed.0040458C
004F4538 ||inc esi
004F4539 ||dec ebx
004F453A |\jnz short UnPacKed.004F4523 複製運算結果

跟進call UnPacKed.004F407C:

004F407C push ebp
004F407D mov ebp,esp
004F407F add esp,-18
004F4082 push ebx
004F4083 push esi
004F4084 push edi
004F4085 mov ebx,ecx
004F4087 test ebx,ebx
004F4089 js short UnPacKed.004F4095
004F408B shr ebx,2
004F408E /mov esi,dword ptr ds:[edx+ebx*4]
004F4091 |dec ebx
004F4092 |push esi
004F4093 \jns short UnPacKed.004F408E
004F4095 mov edx,esp
004F4097 mov dword ptr ss:[ebp-4],edx
004F409A mov ebx,eax
004F409C mov dword ptr ss:[ebp-8],8
004F40A3 mov eax,dword ptr ss:[ebp-4]
004F40A6 mov ecx,dword ptr ss:[ebp+C]
004F40A9 /mov dl,byte ptr ds:[eax]
004F40AB |mov byte ptr ds:[ecx],dl
004F40AD |inc ecx
004F40AE |inc eax
004F40AF |dec dword ptr ss:[ebp-8]
004F40B2 \jnz short UnPacKed.004F40A9
004F40B4 mov eax,dword ptr ss:[ebp+C]
004F40B7 mov edx,dword ptr ss:[ebp+8]
004F40BA call UnPacKed.004F3A40 DES加密程序的第一步,IP置換
004F40BF test bl,bl
004F40C1 jnz UnPacKed.004F417C 跳,因為在使用004F407C前設定了al=1,又有bl=al,所以這裡肯定跳
..............
004F417C cmp bl,1 跳到這兒
004F417F jnz UnPacKed.004F4237
004F4185 mov dword ptr ss:[ebp-8],-10 循環次數
004F418C mov ebx,UnPacKed.00580E76 第一個子密鑰位址。一個子密鑰占6字元,最後一個子密鑰位址為00580E1C,做逆運算時改成它
004F4191 /mov eax,4
004F4196 |mov edx,dword ptr ss:[ebp+C]
004F4199 |lea esi,dword ptr ss:[ebp-C] 這裡是對消息進行分組,把64位的消息分為L0和R0
004F419C |/mov cl,byte ptr ds:[edx]
004F419E ||mov byte ptr ds:[esi],cl
004F41A0 ||inc esi
004F41A1 ||inc edx
004F41A2 ||dec eax
004F41A3 |\jnz short UnPacKed.004F419C 取出4個待加密的資料,即L0
004F41A5 |mov eax,4
004F41AA |mov edx,dword ptr ss:[ebp+C]
004F41AD |add edx,4
004F41B0 |/mov cl,byte ptr ds:[edx] R0
004F41B2 ||mov byte ptr ds:[edx-4],cl
004F41B5 ||inc edx
004F41B6 ||dec eax
004F41B7 |\jnz short UnPacKed.004F41B0 這個循環是作L1=R0
004F41B9 |push 5 ; /Arg3 = 00000005
004F41BB |lea eax,dword ptr ss:[ebp-10] ; |
004F41BE |push eax ; |Arg2
004F41BF |push 3 ; |Arg1 = 00000003
004F41C1 |mov ecx,ebx ; |
004F41C3 |mov eax,dword ptr ss:[ebp+C] ; |
004F41C6 |mov edx,dword ptr ss:[ebp+8] ; |
004F41C9 |call UnPacKed.004F3F54 ; \UnPacKed.004F3F54 DES中的F函數
004F41CE |mov eax,4
004F41D3 |lea edx,dword ptr ss:[ebp-C] L[i-1]
004F41D6 |lea esi,dword ptr ss:[ebp-10] F函數的結果
004F41D9 |mov ecx,dword ptr ss:[ebp+C]
004F41DC |add ecx,4
004F41DF |mov dword ptr ss:[ebp-18],ecx
004F41E2 |/mov cl,byte ptr ds:[edx] R=L[i-1]^F(R[i-1],K[15-i])
004F41E4 ||xor cl,byte ptr ds:[esi]
004F41E6 ||mov edi,dword ptr ss:[ebp-18]
004F41E9 ||mov byte ptr ds:[edi],cl R
004F41EB ||inc dword ptr ss:[ebp-18]
004F41EE ||inc esi
004F41EF ||inc edx
004F41F0 ||dec eax
004F41F1 |\jnz short UnPacKed.004F41E2
004F41F3 |sub ebx,6 子密鑰位址,作逆運算時改為add ebx,6
004F41F6 |inc dword ptr ss:[ebp-8]
004F41F9 \jnz short UnPacKed.004F4191
004F41FB mov eax,4
004F4200 mov edx,dword ptr ss:[ebp+C]
004F4203 add edx,4
004F4206 lea ebx,dword ptr ss:[ebp-C]
004F4209 /mov cl,byte ptr ds:[edx] R[15]
004F420B |mov byte ptr ds:[ebx],cl
004F420D |inc ebx
004F420E |inc edx
004F420F |dec eax
004F4210 \jnz short UnPacKed.004F4209
004F4212 mov eax,4
004F4217 mov ebx,dword ptr ss:[ebp+C]
004F421A /mov dl,byte ptr ds:[ebx] L[15]
004F421C |mov byte ptr ds:[ebx+4],dl
004F421F |inc ebx
004F4220 |dec eax
004F4221 \jnz short UnPacKed.004F421A
004F4223 mov eax,4
004F4228 lea ebx,dword ptr ss:[ebp-C]
004F422B mov edx,dword ptr ss:[ebp+C]
004F422E /mov cl,byte ptr ds:[ebx]
004F4230 |mov byte ptr ds:[edx],cl
004F4232 |inc edx
004F4233 |inc ebx
004F4234 |dec eax
004F4235 \jnz short UnPacKed.004F422E
004F4237 mov eax,dword ptr ss:[ebp+C]
004F423A mov edx,dword ptr ss:[ebp+8]
004F423D call UnPacKed.004F3AC4 DES加密程序的第三步,IP逆置換
004F4242 mov edi,dword ptr ss:[ebp-24]
004F4245 mov esi,dword ptr ss:[ebp-20]
004F4248 mov ebx,dword ptr ss:[ebp-1C]
004F424B mov esp,ebp
004F424D pop ebp
004F424E retn 8

看「看雪精華5」中 風雨無阻 的「公路坐標計算系統 1.0」,(這篇文章寫得很好,看了這一篇你就會明白DES加密的原理,如果沒這篇文章,我的破解還真難完成呢,不過我們這裡不需要完全明白DES),得知DES的加密程序主要分為三步:

1. 待加密資料進行IP置換;
2. 進行16輪變換,每一輪一個子密鑰;
3. 進行IP逆置換。

解密程序和加密程序基本一樣,不同的是把16子密鑰倒轉順序,這一點最重要! 這也是我破解此軟體的核心。再參考一下「看雪精華6」中 cnbragon 的「XPSecurity2005c註冊算法分析---標準DES+變形MD5」,分析出了DES運算的流程(竟然除了位址不同外,程式碼均一樣!?)。因此在我們知道了其子密鑰的位址以後,就有了下面的求逆方法,讓起名大師幫我們解密。

求逆方法:

1. 首先執行到0050660D,下:d eax,記下要做DES逆運算的8字元資料;
2. 設斷於004F476D,重新執行,中斷後下:d edx,更改資料為第1步的資料;
3. 更改004F418C、004F41F3處程式碼:
004F418C mov ebx,UnPacKed.00580E1C
004F41F3 add ebx,6
4. 設斷於004F4772,F9執行,斷下後下:d [ebx],記下其註冊碼應該變成的資料;
5. 作004F4760 call UnPacKed.004E6784 的逆運算,即從前面的資料中取一個字元,除以31,用商在表"0AH6CD3BEF4TRS2PUV5K1MN78YZ9GIJ"中查出一個字元,用餘數再查出一個字元,連續寫下來,就得到了正確的前16位註冊碼。
按以上方法求註冊碼,可其中沒有涉及第28位(調位前是第25位)註冊碼,隨便取一個值,提示註冊成功。可是用一下「個人起名」功能以後,軟體又會提示「軟體尚未註冊」。設斷於004E00B8,點「開始分析」,可以跟到:

0054F2CE lea eax,dword ptr ss:[ebp-4C]
0054F2D1 push eax
0054F2D2 lea edx,dword ptr ss:[ebp-50]
0054F2D5 mov eax,dword ptr ds:[57EB9C]
0054F2DA mov eax,dword ptr ds:[eax]
0054F2DC call UnPacKed.004E00B8 還原出註冊碼
0054F2E1 mov eax,dword ptr ss:[ebp-50]
0054F2E4 mov ecx,1
0054F2E9 mov edx,1C
0054F2EE call UnPacKed.004047E4 取第28位
0054F2F3 mov eax,dword ptr ss:[ebp-4C]
0054F2F6 call UnPacKed.004E9BE0 查表"0AH6CD3BEF4TRS2PUV5K1MN78YZ9GIJ"求值
0054F2FB mov edi,eax 暫存於edi
0054F2FD lea eax,dword ptr ss:[ebp-54]
0054F300 push eax
0054F301 lea eax,dword ptr ss:[ebp-58]
0054F304 push eax
0054F305 mov ecx,2
0054F30A mov edx,1
0054F30F mov eax,dword ptr ss:[ebp-8]
0054F312 call UnPacKed.004047E4 取姓第一個漢字
0054F317 mov edx,dword ptr ss:[ebp-58]
0054F31A mov eax,dword ptr ds:[57EC3C]
0054F31F mov eax,dword ptr ds:[eax]
0054F321 mov eax,dword ptr ds:[eax+3BC]
0054F327 mov ecx,UnPacKed.0054F908 ; ASCII "113"
0054F32C call UnPacKed.005200D0 算漢字筆劃數,得到的是字元串
0054F331 mov eax,dword ptr ss:[ebp-54]
0054F334 call UnPacKed.00409034 變成數位
0054F339 cmp edi,eax 比較
0054F33B je short UnPacKed.0054F398

原來是取姓氏筆劃數查表得一個字元作為第28位。至此,同益起名大師3,36註冊算法分析完畢。第28位的分析與okdodo大俠略有不同,可能是由於我沒有輸入公司名的原因吧。我在我的電腦上已測試通過。
這個校驗很隱蔽,不到最關鍵的時候不校驗,而且一次通不過這個校驗就會在系統裡留上標記(具體在哪兒不清楚),要重啟一下,下次才有可能通過。
__________________
http://bbsimg.qianlong.com/upload/01/08/29/68/1082968_1136014649812.gif
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
舊 2006-02-13, 10:34 PM   #2 (permalink)
註冊會員
 
六翼黑帝斯 的頭像
榮譽勳章

勳章總數
UID - 216546
在線等級: 級別:4 | 在線時長:34小時 | 升級還需:11小時級別:4 | 在線時長:34小時 | 升級還需:11小時級別:4 | 在線時長:34小時 | 升級還需:11小時級別:4 | 在線時長:34小時 | 升級還需:11小時
註冊日期: 2005-12-02
VIP期限: 2007-03
住址: 真實的內心
文章: 746
精華: 0
現金: 799 金幣
資產: 799 金幣
預設

太高級了~
我是很想學這種東西~
只不過沒人?玊琖而且現在也沒時間去學~
每天都要上課~
等我以後有空~一定要學這個ˋˊ
六翼黑帝斯 目前離線  
送花文章: 3, 收花文章: 5 篇, 收花: 8 次
 



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 07:25 PM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1