PCWorker 破解(算法)分析
【破文标题】:PCWorker 破解(算法)分析
【破文作者】:Skyer
【软件名称】:PCWorker
【软件大小】:325 KB
【使用平台】:Win9x/Me/NT/2000/XP
【发布公司】:http://www.pcworker.net
【软件简介】:像按键精灵可自动按键 (可免费注册)
【加密方式】:License File
【编译语言】:VC 6
【功能限制】:时间限制
【调试环境】:WinXP, OllyDBG 1.10
【破解日期】:2005-04-02
【破解目的】:研究算法分析 (此软件注册不用钱, 作者只是想了解有那些人在使用这软件)
【作者声明】:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
─────────────────────────────────
【破解过程】:
第一次发文,请多指教..
1. 先执行一次 pcworker,记下 PCKEY,并去除 -,关闭
2. OD 载入 pcworker.exe 执行到
PCWorker.ii 是注册档,向 PCWorker 注册后,作者会发 email 到你的信箱
00432BC2 > \68 24E74400 push PCWorker.0044E724 ; ASCII "\PCWorker.ii"
00432BC7 . 8D4424 1C lea eax ,dword ptr ss :[esp +1C]
00432BCB . 68 4C144500 push offset <PCWorker.EXEPath>
00432BD0 . 50 push eax
00432BD1 . E8 3C570000 call <jmp.&MFC42.#924_operator+>
00432BD6 . 8B4C24 18 mov ecx ,dword ptr ss :[esp +18]
00432BDA . C68424 C412000>mov byte ptr ss :[esp +12C4],8
00432BE2 . 51 push ecx
00432BE3 . FF15 80F84300 call dword ptr ds :[<&PCWorker.KMCF_Acc>; PCWork_1.KMCF_AccessFile
00432BE9 . 8B2D 54F84300 mov ebp ,dword ptr ds :[<&PCWorker.CKMC_>; PCWork_1.CKMC_IniFile::GetValue
00432BEF . 83C4 04 add esp ,4
00432BF2 . 84C0 test al ,al
00432BF4 . 0F84 BC030000 je PCWorker.00432FB6
继续往下执行到
0043363B . 68 1CE74400 push PCWorker.0044E71C ; ASCII "PCKEY"
00433640 . E8 794C0000 call <jmp.&MFC42.#537_CString::CString>
00433645 . 8B15 D0E54400 mov edx ,dword ptr ds :[44E5D0] ; PCWorker.0044E5D4
0043364B . 51 push ecx
0043364C . 8BCC mov ecx ,esp
0043364E . 896424 40 mov dword ptr ss :[esp +40],esp
00433652 . 52 push edx
00433653 . C68424 D412000>mov byte ptr ss :[esp +12D4],34
0043365B . E8 5E4C0000 call <jmp.&MFC42.#537_CString::CString>
00433660 . 8D4424 1C lea eax ,dword ptr ss :[esp +1C]
00433664 . 8BCD mov ecx ,ebp
00433666 . 50 push eax
00433667 . C68424 D412000>mov byte ptr ss :[esp +12D4],7
0043366F . FF15 54F84300 call dword ptr ds :[<&PCWorker.CKMC_Ini>; PCWork_1.CKMC_IniFile::GetValue
这里会从 pcworker.ini 读取 [Registration] 下的注册信息,但我们的设定文件无此信息, 手动加上
[Registration]
PCKEY=填入第一次执行 pcworker 记录的 pckey
Name=Skyer
Birthday=1981/01/30
Serial=kKR7sky $
本文主要要找出 Serial 的算法
重新分析 pcworker.exe (Ctrl+F2),执行到
004337E1 . 8B0F mov ecx ,dword ptr ds :[edi ] ; Serial
004337E3 . BB 0A000000 mov ebx ,0A ; 长度一定要为 10
004337E8 . 3959 F8 cmp dword ptr ds :[ecx -8],ebx
004337EB . 7D 1A jge short PCWorker.00433807
了解 Serial 长度必为 10
再往下到
004338E8 > /8A0408 mov al ,byte ptr ds :[eax +ecx ]
004338EB . |8B1D 24144500 mov ebx ,dword ptr ds :[<PCKeyXOR>]
004338F1 . |884424 10 mov byte ptr ss :[esp +10],al
004338F5 . |8B4424 10 mov eax ,dword ptr ss :[esp +10]
004338F9 . |25 FF000000 and eax ,0FF
004338FE . |33D8 xor ebx ,eax
00433900 . |41 inc ecx
00433901 . |891D 24144500 mov dword ptr ds :[<PCKeyXOR>],ebx
00433907 . |8B02 mov eax ,dword ptr ds :[edx ]
00433909 . |3B48 F8 cmp ecx ,dword ptr ds :[eax -8]
0043390C .^\7C DA jl short PCWorker.004338E8
这里是算 pckey 的 xor 编码 (由左至右一个一个 xor) => 取名 PCKeyXOR
转成代码大概是:
int sum=0;
for (i=0; i<PCKeyLength; i++)
sum = sum ^ PCKey[ i ]
0043392C > /8A1408 mov dl ,byte ptr ds :[eax +ecx ]
0043392F . |8B2D 18144500 mov ebp ,dword ptr ds :[<PCKeyAdd>]
00433935 . |885424 10 mov byte ptr ss :[esp +10],dl
00433939 . |8B5424 10 mov edx ,dword ptr ss :[esp +10]
0043393D . |81E2 FF000000 and edx ,0FF
00433943 . |03EA add ebp ,edx
00433945 . |40 inc eax
00433946 . |892D 18144500 mov dword ptr ds :[<PCKeyAdd>],ebp
0043394C . |8B51 F8 mov edx ,dword ptr ds :[ecx -8]
0043394F . |3BC2 cmp eax ,edx
00433951 .^\7C D9 jl short PCWorker.0043392C
pckey 的 add 编码 (由左至右一个一个 add) => 取名 PCKeyAdd
转成代码大概是:
int sum=0;
for (i=0; i<PCKeyLength; i++)
sum = sum + PCKey[ i ]
00433955 . 8B96 11010000 mov edx ,dword ptr ds :[esi +111] ; Serial
0043395B . 8BE8 mov ebp ,eax
0043395D . 33C0 xor eax ,eax
0043395F . B9 01000000 mov ecx ,1
00433964 > 0FBE1C0A movsx ebx ,byte ptr ds :[edx +ecx ]
00433968 . 03C3 add eax ,ebx
0043396A . 41 inc ecx
0043396B . 83F9 08 cmp ecx ,8
0043396E .^ 7E F4 jle short PCWorker.00433964
00433970 . 8B8E 19010000 mov ecx ,dword ptr ds :[esi +119]
00433976 . BB 5F000000 mov ebx ,5F
0043397B . 41 inc ecx
0043397C . 898E 19010000 mov dword ptr ds :[esi +119],ecx
00433982 . 8A0A mov cl ,byte ptr ds :[edx ]
00433984 . 33D2 xor edx ,edx
00433986 . F7F3 div ebx
00433988 . 0FBEC9 movsx ecx ,cl
0043398B . 0FBEC2 movsx eax ,dl ; 编码 / 5F 的余数
0043398E . 83C0 20 add eax ,20
00433991 . 3BC8 cmp ecx ,eax
00433993 . 74 08 je short PCWorker.0043399D
检查 Serial 是否正确
转成代码大概是:
int key1 = Serial[0];
int sum=0;
int key2;
for (i=1; i<9; i++)
sum += Serial[ i ]
key2 = (sum % 0x5f) + 0x20
if (key1 == key2)
正确!!
004339DA > \2BFD sub edi ,ebp ; 比较执行时间!! 有没有低于 0.5 s
004339DC . 81FF F4010000 cmp edi ,1F4
004339E2 . 76 08 jbe short PCWorker.004339EC
这里判断有没有被调试,强迫跳到 004339EC 吧
00433C55 > /8A0408 mov al ,byte ptr ds :[eax +ecx ]
00433C58 . |884424 10 mov byte ptr ss :[esp +10],al
00433C5C . |8B5424 10 mov edx ,dword ptr ss :[esp +10]
00433C60 . |A1 28144500 mov eax ,dword ptr ds :[<NameADD>]
00433C65 . |81E2 FF000000 and edx ,0FF
00433C6B . |03C2 add eax ,edx
00433C6D . |41 inc ecx
00433C6E . |A3 28144500 mov dword ptr ds :[<NameADD>],eax
00433C73 . |8B07 mov eax ,dword ptr ds :[edi ]
00433C75 . |3B48 F8 cmp ecx ,dword ptr ds :[eax -8]
00433C78 .^\7C DB jl short PCWorker.00433C55
Name 的 add 编码 (由左至右一个一个 add) => 取名 NameADD
00433C7A > \A1 04144500 mov eax ,dword ptr ds :[<PCKey>] ; PCKey
00433C7F . 8A48 02 mov cl ,byte ptr ds :[eax +2]
00433C82 . 8D4424 10 lea eax ,dword ptr ss :[esp +10]
00433C86 . 884C24 10 mov byte ptr ss :[esp +10],cl
00433C8A . 8B5424 10 mov edx ,dword ptr ss :[esp +10]
00433C8E . 52 push edx ; 第 3 byte 为 rand key
00433C8F . 50 push eax
00433C90 . E8 8BE9FFFF call <PCWorker.算 PCKey>
00433C95 . 8B00 mov eax ,dword ptr ds :[eax ]
00433C97 . 8B8E 05010000 mov ecx ,dword ptr ds :[esi +105]
00433C9D . 50 push eax
00433C9E . 51 push ecx
00433C9F . FFD5 call ebp
00433CA1 . 83C4 10 add esp ,10
00433CA4 . 8D4C24 10 lea ecx ,dword ptr ss :[esp +10]
00433CA8 . 85C0 test eax ,eax
00433CAA . 0F95C3 setne bl
这里是验证 PCKey 的正确性,因为我们的 PCKey 是一开始执行时由 pcworker 产生的
一定正确! 有兴趣研究的朋友们,可进入 00433C90 这个 call 研究研究
00433CD1 > /8A1408 mov dl ,byte ptr ds :[eax +ecx ]
00433CD4 . |885424 10 mov byte ptr ss :[esp +10],dl
00433CD8 . |8B4424 10 mov eax ,dword ptr ss :[esp +10]
00433CDC . |8B15 28144500 mov edx ,dword ptr ds :[<NameXOR>]
00433CE2 . |25 FF000000 and eax ,0FF
00433CE7 . |33D0 xor edx ,eax
00433CE9 . |41 inc ecx
00433CEA . |8915 28144500 mov dword ptr ds :[<NameXOR>],edx
00433CF0 . |8B07 mov eax ,dword ptr ds :[edi ]
00433CF2 . |3B48 F8 cmp ecx ,dword ptr ds :[eax -8]
00433CF5 .^\7C DA jl short PCWorker.00433CD1
Name 的 xor 编码 (由左至右一个一个 xor) => 取名 NameXOR
00433D9A . 8B96 11010000 mov edx ,dword ptr ds :[esi +111]
00433DA0 . 33C0 xor eax ,eax
00433DA2 . 8BCB mov ecx ,ebx
00433DA4 > 0FBE3C11 movsx edi ,byte ptr ds :[ecx +edx ]
00433DA8 . 33C7 xor eax ,edi
00433DAA . 41 inc ecx
00433DAB . 83F9 08 cmp ecx ,8
00433DAE .^ 7E F4 jle short PCWorker.00433DA4
00433DB0 . 8A4A 09 mov cl ,byte ptr ds :[edx +9]
00433DB3 . 33D2 xor edx ,edx
00433DB5 . BF 5F000000 mov edi ,5F
00433DBA . F7F7 div edi
00433DBC . 80C2 20 add dl ,20
00433DBF . 3ACA cmp cl ,dl
00433DC1 . 74 07 je short PCWorker.00433DCA
检查 Serial 是否正确
转成代码大概是:
int key1 = Serial[9];
int sum=0;
int key2;
for (i=1; i<9; i++)
sum = sum ^ Serial[ i ]
key2 = (sum % 0x5f) + 0x20
if (key1 == key2)
正确!!
004340FD > /8A0408 mov al ,byte ptr ds :[eax +ecx ]
00434100 . |8B1D 2C144500 mov ebx ,dword ptr ds :[45142C]
00434106 . |884424 10 mov byte ptr ss :[esp +10],al
0043410A . |8B4424 10 mov eax ,dword ptr ss :[esp +10]
0043410E . |25 FF000000 and eax ,0FF
00434113 . |33D8 xor ebx ,eax
00434115 . |41 inc ecx
00434116 . |891D 2C144500 mov dword ptr ds :[45142C],ebx
0043411C . |8B02 mov eax ,dword ptr ds :[edx ]
0043411E . |3B48 F8 cmp ecx ,dword ptr ds :[eax -8]
00434121 .^\7C DA jl short PCWorker.004340FD
Birthday 的 xor 编码 (由左至右一个一个 xor) => 取名 BirthdayXOR
00434141 > /8A1408 mov dl ,byte ptr ds :[eax +ecx ]
00434144 . |8B1D 20144500 mov ebx ,dword ptr ds :[<BirthdayAdd>]
0043414A . |885424 10 mov byte ptr ss :[esp +10],dl
0043414E . |8B5424 10 mov edx ,dword ptr ss :[esp +10]
00434152 . |81E2 FF000000 and edx ,0FF
00434158 . |03DA add ebx ,edx
0043415A . |40 inc eax
0043415B . |891D 20144500 mov dword ptr ds :[<BirthdayAdd>],ebx
00434161 . |8B51 F8 mov edx ,dword ptr ds :[ecx -8]
00434164 . |3BC2 cmp eax ,edx
00434166 .^\7C D9 jl short PCWorker.00434141
Birthday 的 add 编码 (由左至右一个一个 add) => 取名 BirthdayAdd
在 4513f8 下内存访问断点,可找到所有比较 Serial 的规则
00408674 . 8B85 1B0C0000 mov eax ,dword ptr ss :[ebp +C1B] ; PCKeyAdd编码
0040867A . 8B15 20144500 mov edx ,dword ptr ds :[<BirthdayAdd编码>]
00408680 . 8B3D 1C144500 mov edi ,dword ptr ds :[<NameAdd编码>]
00408686 . 03C2 add eax ,edx
00408688 . 03C7 add eax ,edi
0040868A . 33D2 xor edx ,edx
0040868C . BE 5F000000 mov esi ,5F
00408691 . 8B0D F8134500 mov ecx ,dword ptr ds :[<Serial>]
00408697 . F7F6 div esi
00408699 . 8A49 01 mov cl ,byte ptr ds :[ecx +1]
0040869C . 0FBEC1 movsx eax ,cl
0040869F . 0FBED2 movsx edx ,dl
004086A2 . 83C2 20 add edx ,20
004086A5 . 3BC2 cmp eax ,edx
004086A7 . 74 07 je short PCWorker.004086B0
这里是比较 Serial[1]
转换成代码如下..
int sum = PCKeyAdd + BirthdayAdd + NameAdd
char s1 = (sum % 0x5f) + 0x20
比较 Serial[2]
转换成代码如下..
int sum = PCKeyXor ^ BirthdayXor ^ NameXor
char s2 = (sum % 0x5f) + 0x20
比较 Serial[3]
转换成代码如下..
int sum = PCKeyAdd ^ BirthdayAdd ^ NameAdd
char s3 = (sum % 0x5f) + 0x20
比较 Serial[4]
转换成代码如下..
int sum = PCKeyXor + BirthdayXor + NameXor
char s4 = (sum % 0x5f) + 0x20
比较 Serial[8]
转换成代码如下..
int sum = BirthdayXor & NameAdd | PCKeyXor
char s8 = (sum % 0x5f) + 0x20
其中 Serial[5] ~ Serial[7] 随便,不重要 最后,来整理一下算法..
1. Serial 是依 PCKey, Name, Birthday 算出来的. 长度为 10 (Serial[0] ~ Serial[9])
2. 算出 pckey, name, birthday 的 add, xor 值
3. 算出 Serial[1], Serial[2], Serial[4], Serial[4], Serial[8]
4. Serial[5] ~ Serial[7] 随便填
5. 算出 Serial[0] & Serial[9]
6. 结束..
以下是 python 写的注册机 (python 2.4)
使用方式:
D:\Data\Python>python PcworkerReg.py F-QYUC-TFGY-NGBN Skyer 1932/01/34
会产生 pcworker.ii, 放到 pcworker 下即可
------------PcworkerReg.py-----------------
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)