【文章标题】: 进程执法官v1.801详细分析过程
【文章作者】: ljy3282393
【软件名称】: 进程执法官1.801
【下载地址】: 自己搜索下载
【加壳方式】: ASPack 2.12
【软件介绍】: 进程执法官是一款强悍的手工杀毒与系统监控软件。
【作者声明】: 主要是写给亲手看的,高手请跳过。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
PEID查壳:ASPack 2.12!
对于简单的压缩壳加密的软件的破解我一般不用脱壳的,免得软件带有自校验反而带来不必要的麻烦。
OD载入软件后,按F9键直接让软件运行起来!软件运行起来之后我一般都会搜索字符串参考看看有没有“注册成功”、“注册失败”、“rigistercode”等之类的敏感字符。不过如果这时搜索字符串的话,则会什么也搜不到!为什么?因为我是带壳调试软件的,并且调试时没有经过OEP而是直接按F9键让软件运行起来的,这时OD还停在壳的领空!只有让OD到达程序的领空才能搜到相关的字符。为了让OD到达程序的领空我们需要对程序的代码段下内存访问一次性断点!(注:在这里最好不要下内存访问断点,否则当OD到达程序的领空后,还要删除内存断点,多一个步骤。)下断方法:ALT+M,对程序的代码段按F2键即可!(由于本文主要是写给新手看的,所以写得详细、噜嗦些)
下好内存断点后,OD即时中断在程序的领空。这时就可利用OD的搜索字符串插件搜索相关字符串了,如下图:
看到上图的“rigistercode”吗?不过先别忙在这里下断点,为了找到全部的“rigistercode”,需要先将光标移到字符串查找窗口的第一行代码,然后按CTRL+F,在弹出的查找窗口中输入“rigistercode”,按“确定”键,光标将会停在第一个“rigistercode”的地方!
按“N”键,继续下一个查找,光标将会停在第二个“rigistercode”的地方。继续按“N”键,直到查找完毕之后,在所有查找到“rigistercode”的地方按F2键下断点!然后按F9键再次让软件运行起来,接着输入用户名和假注册码后,经过几次中断后(每次中断后都按F9键)便会来到以下关键的地方:
00419D05 |. 6A 00 push 0
00419D07 |. 68 C0914600 push 004691C0 ; rigistercode
00419D0C |. 8D5424 28 lea edx, [esp+28]
00419D10 |. 68 D0914600 push 004691D0 ; rigistersettings
00419D15 |. 52 push edx
00419D16 |. 8BC8 mov ecx, eax
00419D18 |. E8 A3410300 call <jmp.&mfc42.#3522_CWinApp::GetProfi>
00419D1D |. 50 push eax
00419D1E |. 8D4C24 14 lea ecx, [esp+14]
00419D22 |. C64424 38 06 mov byte ptr [esp+38], 6
00419D27 |. E8 A83F0300 call <jmp.&mfc42.#858_CString::operator=>
00419D2C |. 8D4C24 20 lea ecx, [esp+20]
00419D30 |. 885C24 34 mov [esp+34], bl
00419D34 |. E8 993E0300 call <jmp.&mfc42.#800_CString::~CString>
00419D39 |. 8B4424 18 mov eax, [esp+18]
00419D3D |. 8B4C24 14 mov ecx, [esp+14]
00419D41 |. 50 push eax ; 机器码入栈
00419D42 |. 51 push ecx ; 注册名入栈
00419D43 |. 8D5424 14 lea edx, [esp+14]
00419D47 |. 68 40AD4600 push 0046AD40 ; %s@%s
00419D4C |. 52 push edx
00419D4D |. E8 AA3E0300 call <jmp.&mfc42.#2818_CString::Format> ; 将注册名和机器码通过字符@连接起来
00419D52 |. 83C4 10 add esp, 10
00419D55 |. 8D4C24 1C lea ecx, [esp+1C]
00419D59 |. E8 42160100 call 0042B3A0
00419D5E |. 6A 10 push 10
00419D60 |. C64424 38 07 mov byte ptr [esp+38], 7
00419D65 |. 6A 00 push 0
00419D67 |. 8D4424 2C lea eax, [esp+2C]
00419D6B |. 50 push eax
00419D6C |. 51 push ecx
00419D6D |. 8D5424 1C lea edx, [esp+1C]
00419D71 |. 8BCC mov ecx, esp
00419D73 |. 896424 38 mov [esp+38], esp
00419D77 |. 52 push edx
00419D78 |. E8 5D3F0300 call <jmp.&mfc42.#535_CString::CString>
00419D7D |. 8D4424 38 lea eax, [esp+38]
00419D81 |. 50 push eax
00419D82 |. E8 59160100 call 0042B3E0 ; 算法call,跟进!
00419D87 |. 83C4 08 add esp, 8
00419D8A |. 8BC8 mov ecx, eax
00419D8C |. C64424 40 08 mov byte ptr [esp+40], 8
00419D91 |. E8 1A420300 call <jmp.&mfc42.#4278_CString::Mid>
00419D96 |. 8BF0 mov esi, eax
00419D98 6A 10 push 10 ; 压入数字16(10进制)
00419D9A |. 8D4C24 24 lea ecx, [esp+24]
00419D9E |. 6A 00 push 0
00419DA0 |. 51 push ecx
00419DA1 |. 8D4C24 1C lea ecx, [esp+1C]
00419DA5 |. C64424 40 09 mov byte ptr [esp+40], 9
00419DAA |. E8 01420300 call <jmp.&mfc42.#4278_CString::Mid> ; 截取真注册码(由算法call产生)的前16个字符
00419DAF |. 8B36 mov esi, [esi]
00419DB1 |. 8B00 mov eax, [eax]
00419DB3 |. 56 push esi ; /s2
00419DB4 |. 50 push eax ; |s1
00419DB5 |. FF15 106C4500 call [<&msvcrt._mbscmp>] ; \比较真假注册码
00419DBB |. 83C4 08 add esp, 8
00419DBE |. 8D4C24 20 lea ecx, [esp+20]
00419DC2 |. 85C0 test eax, eax
00419DC4 |. 0F944424 0B sete [esp+B]
00419DC9 |. E8 043E0300 call <jmp.&mfc42.#800_CString::~CString>
跟进算法call后来到这里:
0042B3E0 /$ 6A FF push -1
0042B3E2 |. 68 67364500 push 00453667 ; SE 处理程序安装
0042B3E7 |. 64:A1 0000000>mov eax, fs:[0]
0042B3ED |. 50 push eax
0042B3EE |. 64:8925 00000>mov fs:[0], esp
0042B3F5 |. 83EC 0C sub esp, 0C
0042B3F8 |. 53 push ebx
0042B3F9 |. 55 push ebp
0042B3FA |. 56 push esi
0042B3FB |. 57 push edi
0042B3FC |. C74424 18 000>mov dword ptr [esp+18], 0
0042B404 |. BF 94CB4600 mov edi, 0046CB94 ; processjudgerhaha1234567890abcdefghijklmnopqrstuvwxyz
0042B409 |. 83C9 FF or ecx, FFFFFFFF
0042B40C |. 33C0 xor eax, eax
0042B40E |. C74424 24 010>mov dword ptr [esp+24], 1
0042B416 |. F2:AE repne scas byte ptr es:[edi]
0042B418 |. F7D1 not ecx
0042B41A |. 51 push ecx
0042B41B |. E8 42280200 call <jmp.&mfc42.#823_operator new>
0042B420 |. 8BE8 mov ebp, eax
0042B422 |. BF C8A14600 mov edi, 0046A1C8 ; processjudger
0042B427 |. 83C9 FF or ecx, FFFFFFFF
0042B42A |. 33C0 xor eax, eax
0042B42C |. 83C4 04 add esp, 4
0042B42F |. F2:AE repne scas byte ptr es:[edi]
0042B431 |. F7D1 not ecx
0042B433 |. 2BF9 sub edi, ecx
0042B435 |. 8BC1 mov eax, ecx
0042B437 |. 8BF7 mov esi, edi
0042B439 |. 8BFD mov edi, ebp
0042B43B |. C1E9 02 shr ecx, 2
0042B43E |. F3:A5 rep movs dword ptr es:[edi], dword p>
0042B440 |. 8BC8 mov ecx, eax
0042B442 |. 33C0 xor eax, eax
0042B444 |. 83E1 03 and ecx, 3
0042B447 |. F3:A4 rep movs byte ptr es:[edi], byte ptr>
0042B449 |. 8B4C24 30 mov ecx, [esp+30] ; 取字符串“注册名@机器码”
0042B44D |. 8BFD mov edi, ebp
0042B44F |. 8B51 F8 mov edx, [ecx-8] ; 取该字符串的长度给edx
0042B452 |. 83C9 FF or ecx, FFFFFFFF
0042B455 |. F2:AE repne scas byte ptr es:[edi]
0042B457 |. F7D1 not ecx
0042B459 |. 8BC2 mov eax, edx
0042B45B |. 49 dec ecx ; 取字符串“ProcessJudger"的长度给ecx
0042B45C |. 33D2 xor edx, edx
0042B45E |. F7F1 div ecx ; edx除以ecx
0042B460 |. 8D4C24 10 lea ecx, [esp+10]
0042B464 >|. 8BDA mov ebx, edx ; 取余数赋给ebx
0042B466 |. E8 79270200 call <jmp.&mfc42.#540_CString::CStrin>
0042B46B |. 8B4424 30 mov eax, [esp+30]
0042B46F |. 33F6 xor esi, esi
0042B471 |. C64424 24 02 mov byte ptr [esp+24], 2
0042B476 |. 8B48 F8 mov ecx, [eax-8]
0042B479 |. 85C9 test ecx, ecx
0042B47B |. 7E 4D jle short 0042B4CA
0042B47D |> 8A1406 /mov dl, [esi+eax] ; 取字符串“注册名@机器码”的第esi个字符的ASCII值赋给dl(设该值为x),开始计算注册码!
0042B480 |. 8BFD |mov edi, ebp ; edi指向字符ProcessJudger
0042B482 |. 83C9 FF |or ecx, FFFFFFFF
0042B485 |. 33C0 |xor eax, eax
0042B487 |. F2:AE |repne scas byte ptr es:[edi]
0042B489 |. F7D1 |not ecx
0042B48B |. 885424 14 |mov [esp+14], dl
0042B48F |. 49 |dec ecx ; ecx为字符串“Processjudger"的长度
0042B490 |. 8D041E |lea eax, [esi+ebx] ; eax=esi+ebx
0042B493 |. 33D2 |xor edx, edx
0042B495 |. F7F1 |div ecx ; 将eax除以ecx的余数赋给edx
0042B497 |. 8B4C24 14 |mov ecx, [esp+14] ; 将x赋给ecx
0042B49B |. 33C0 |xor eax, eax
0042B49D |. 81E1 FF000000 |and ecx, 0FF
0042B4A3 |. 8A042A |mov al, [edx+ebp] ; 取字符串“Processjudger"的第edx个字符的ASCII值赋给al(设该值为y)!
0042B4A6 |. 8B5424 10 |mov edx, [esp+10]
0042B4AA |. 33C1 |xor eax, ecx ; x与y进行异或
0042B4AC |. 50 |push eax ; 异或结果入栈
0042B4AD |. 52 |push edx
0042B4AE |. 8D4424 18 |lea eax, [esp+18]
0042B4B2 |. 68 8CCB4600 |push 0046CB8C ; %s%02x
0042B4B7 |. 50 |push eax
0042B4B8 |. E8 3F270200 |call <jmp.&mfc42.#2818_CString::Form>; 将异或结果保存并连接起来!
0042B4BD |. 8B4424 40 |mov eax, [esp+40]
0042B4C1 |. 83C4 10 |add esp, 10
0042B4C4 |. 46 |inc esi
0042B4C5 |. 3B70 F8 |cmp esi, [eax-8] ; 计算完了吗?
0042B4C8 |.^ 7C B3 \jl short 0042B47D ; 没计算完就跳回去继续计算
0042B4CA |> 55 push ebp ; /block
0042B4CB |. E8 2A260200 call <jmp.&mfc42.#825_operator delete>; \free
0042B4D0 |. 8B7424 30 mov esi, [esp+30]
0042B4D4 |. 83C4 04 add esp, 4
0042B4D7 |. 8D4C24 10 lea ecx, [esp+10]
0042B4DB |. 51 push ecx
0042B4DC |. 8BCE mov ecx, esi
0042B4DE |. E8 F7270200 call <jmp.&mfc42.#535_CString::CStrin>
0042B4E3 |. C74424 18 010>mov dword ptr [esp+18], 1
0042B4EB |. 8D4C24 10 lea ecx, [esp+10]
0042B4EF |. C64424 24 01 mov byte ptr [esp+24], 1
0042B4F4 |. E8 D9260200 call <jmp.&mfc42.#800_CString::~CStri>
0042B4F9 |. 8D4C24 30 lea ecx, [esp+30]
0042B4FD |. C64424 24 00 mov byte ptr [esp+24], 0
0042B502 |. E8 CB260200 call <jmp.&mfc42.#800_CString::~CStri>
0042B507 |. 8B4C24 1C mov ecx, [esp+1C]
0042B50B |. 8BC6 mov eax, esi
0042B50D |. 5F pop edi
0042B50E |. 5E pop esi
0042B50F |. 5D pop ebp
0042B510 |. 5B pop ebx
0042B511 |. 64:890D 00000>mov fs:[0], ecx
0042B518 |. 83C4 18 add esp, 18
0042B51B \. C3 retn
--------------------------------------------------------------------------------
算法总结:设用户名+"@"+机器码组成的字符串为S,S的长度为L; L除以13(13为字符串“Processjudger"的长度)的余数为n,则字符串“Processjudger"从第n位(注:字符串“Processjudger"的“P”为第“0”位,第一位为“r”,其余类推)开始与字符串S循环异或,将异或结果的前16位保存并连接起来就是真正的注册码!
VB注册机源代码:
Dim str1 As String
Dim str2 As String
Dim c As String
str1 = Text1.Text + "@" + Text2.Text //Text1.Text=注册用户名,Text2.Text=机器码。
str2 = "ProcessJudger"
nlen = Len(str1)
For i = 1 To 8
n = nlen Mod 13
n = n + 1 //汇编语言中的第n个字符相当于VB中的第n+1个字符
b = Hex(Asc(Mid(str2, n, 1)) Xor Asc(Mid(str1, i, 1)))
If Len(b) < 2 Then b = "0" & b //如果异或结果不是两位数则在前面加“0”
c = c & b
nlen = nlen + 1
Next i
Text3.Text = c //Text3.Text 显示注册码
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: