Jan
15
【文章标题】: IMToo系列软件的算法分析
【软件名称】: IMToo系列软件
【详细过程】
同样是一个通过专用DLL来验证程序,通过在DLL里查看导出函数,很快就能找到:
UILib8_M.ImRegUserInfo::IsValidRegInfo_private
双击来到段着下断:
0046D040 UILib8>/$ 6A FF push -1
0046D042 |. 68 BB914A00 push UILib8_M.004A91BB ; SE 句柄安装
0046D047 |. 64:A1 00000000 mov eax,dword ptr fs:[0]
0046D04D |. 50 push eax
0046D04E |. 64:8925 00000000 mov dword ptr fs:[0],esp
0046D055 |. 81EC B8000000 sub esp,0B8
经过一段注册表的读取过程,很快来到这里:
0046D225 |> \6A 14 push 14 ; /Arg2 = 00000014
0046D227 |. 8D4C24 0C lea ecx,dword ptr ss:[esp+C] ; |
0046D22B |. 51 push ecx ; |Arg1 = 0013E8AC
0046D22C |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18] ; |取输入的假码前20位,设为:szConst
0046D230 |. FF15 C8E54A00 call dword ptr ds:[<&MFC71U.#3990>] ; \MFC71U.7C29977E
继续单步,就看到了对注册码的长度的比较:
0046D27F |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
0046D283 |. FF15 8CE54A00 call dword ptr ds:[<&MFC71U.#2895>] ; MFC71U.7C256550
0046D289 |. 83F8 27 cmp eax,27 ; 将注册码长度与0x27比较
0046D28C |. 0F85 D3030000 jnz UILib8_M.0046D665 ; 不等则失败
0046D2D6 |. 50 push eax ; 出现字符:ImTOOavimpegconverter5
0046D2D7 |. 6A 00 push 0 ; 我们记为:sName
0046D2D9 |. E8 824B0000 call UILib8_M.CImTools::WC_A
继续单步吧,很快就来到了注册算法的关键部分了,呵呵
0046D343 |. 8B4C24 20 mov ecx,dword ptr ss:[esp+20] ; 将ECX指向字符串
0046D347 |. 8B41 F4 mov eax,dword ptr ds:[ecx-C] ; 将字符串的长度存储到EAX
0046D34A |. 33F6 xor esi,esi
0046D34C |. 85C0 test eax,eax
0046D34E |. C68424 C8000000 0>mov byte ptr ss:[esp+C8],9
0046D356 |. 7E 5D jle short UILib8_M.0046D3B5
0046D358 |. EB 06 jmp short UILib8_M.0046D360
0046D35A | 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
0046D360 |> 8BD6 /mov edx,esi
0046D362 |. 81E2 01000080 |and edx,80000001
0046D368 |. 79 05 |jns short UILib8_M.0046D36F
0046D36A |. 4A |dec edx
0046D36B |. 83CA FE |or edx,FFFFFFFE
0046D36E |. 42 |inc edx
0046D36F |> 75 38 |jnz short UILib8_M.0046D3A9 ; 测试EDX是否为0
0046D371 |. 56 |push esi
0046D372 |. 8D4C24 24 |lea ecx,dword ptr ss:[esp+24]
0046D376 |. FF15 7CE34A00 |call dword ptr ds:[<&MFC71U.#861>] ; MFC71U.7C29986D
0046D37C |. 8D4C24 0C |lea ecx,dword ptr ss:[esp+C]
0046D380 |. 50 |push eax
0046D381 |. FF15 44E34A00 |call dword ptr ds:[<&MFC71U.#904>] ; MFC71U.7C29B289
0046D387 |. 8D46 01 |lea eax,dword ptr ds:[esi+1] ; 将ESI+1的结果保存到EAX
0046D38A |. 99 |cdq
0046D38B |. B9 FF000000 |mov ecx,0FF
0046D390 |. F7F9 |idiv ecx ; 然后除以0xFF
0046D392 |. 84D2 |test dl,dl ; 比较余数不否为0
0046D394 |. 885424 08 |mov byte ptr ss:[esp+8],dl
0046D398 |. 74 0F |je short UILib8_M.0046D3A9 ; 为0则跳转,否则保存到ESP+8的位置
0046D39A |. 8B5424 08 |mov edx,dword ptr ss:[esp+8]
0046D39E |. 52 |push edx
0046D39F |. 8D4C24 10 |lea ecx,dword ptr ss:[esp+10]
0046D3A3 |. FF15 44E34A00 |call dword ptr ds:[<&MFC71U.#904>] ; MFC71U.7C29B289
0046D3A9 |> 8B4C24 20 |mov ecx,dword ptr ss:[esp+20]
0046D3AD |. 8B41 F4 |mov eax,dword ptr ds:[ecx-C]
0046D3B0 |. 46 |inc esi
0046D3B1 |. 3BF0 |cmp esi,eax
0046D3B3 |.^ 7C AB \jl short UILib8_M.0046D360
0046D3B5 |> 8B41 F4 mov eax,dword ptr ds:[ecx-C]
用代码来表示如下:
【软件名称】: IMToo系列软件
【详细过程】
同样是一个通过专用DLL来验证程序,通过在DLL里查看导出函数,很快就能找到:
UILib8_M.ImRegUserInfo::IsValidRegInfo_private
双击来到段着下断:
0046D040 UILib8>/$ 6A FF push -1
0046D042 |. 68 BB914A00 push UILib8_M.004A91BB ; SE 句柄安装
0046D047 |. 64:A1 00000000 mov eax,dword ptr fs:[0]
0046D04D |. 50 push eax
0046D04E |. 64:8925 00000000 mov dword ptr fs:[0],esp
0046D055 |. 81EC B8000000 sub esp,0B8
经过一段注册表的读取过程,很快来到这里:
0046D225 |> \6A 14 push 14 ; /Arg2 = 00000014
0046D227 |. 8D4C24 0C lea ecx,dword ptr ss:[esp+C] ; |
0046D22B |. 51 push ecx ; |Arg1 = 0013E8AC
0046D22C |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18] ; |取输入的假码前20位,设为:szConst
0046D230 |. FF15 C8E54A00 call dword ptr ds:[<&MFC71U.#3990>] ; \MFC71U.7C29977E
继续单步,就看到了对注册码的长度的比较:
0046D27F |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
0046D283 |. FF15 8CE54A00 call dword ptr ds:[<&MFC71U.#2895>] ; MFC71U.7C256550
0046D289 |. 83F8 27 cmp eax,27 ; 将注册码长度与0x27比较
0046D28C |. 0F85 D3030000 jnz UILib8_M.0046D665 ; 不等则失败
0046D2D6 |. 50 push eax ; 出现字符:ImTOOavimpegconverter5
0046D2D7 |. 6A 00 push 0 ; 我们记为:sName
0046D2D9 |. E8 824B0000 call UILib8_M.CImTools::WC_A
继续单步吧,很快就来到了注册算法的关键部分了,呵呵
0046D343 |. 8B4C24 20 mov ecx,dword ptr ss:[esp+20] ; 将ECX指向字符串
0046D347 |. 8B41 F4 mov eax,dword ptr ds:[ecx-C] ; 将字符串的长度存储到EAX
0046D34A |. 33F6 xor esi,esi
0046D34C |. 85C0 test eax,eax
0046D34E |. C68424 C8000000 0>mov byte ptr ss:[esp+C8],9
0046D356 |. 7E 5D jle short UILib8_M.0046D3B5
0046D358 |. EB 06 jmp short UILib8_M.0046D360
0046D35A | 8D9B 00000000 lea ebx,dword ptr ds:[ebx]
0046D360 |> 8BD6 /mov edx,esi
0046D362 |. 81E2 01000080 |and edx,80000001
0046D368 |. 79 05 |jns short UILib8_M.0046D36F
0046D36A |. 4A |dec edx
0046D36B |. 83CA FE |or edx,FFFFFFFE
0046D36E |. 42 |inc edx
0046D36F |> 75 38 |jnz short UILib8_M.0046D3A9 ; 测试EDX是否为0
0046D371 |. 56 |push esi
0046D372 |. 8D4C24 24 |lea ecx,dword ptr ss:[esp+24]
0046D376 |. FF15 7CE34A00 |call dword ptr ds:[<&MFC71U.#861>] ; MFC71U.7C29986D
0046D37C |. 8D4C24 0C |lea ecx,dword ptr ss:[esp+C]
0046D380 |. 50 |push eax
0046D381 |. FF15 44E34A00 |call dword ptr ds:[<&MFC71U.#904>] ; MFC71U.7C29B289
0046D387 |. 8D46 01 |lea eax,dword ptr ds:[esi+1] ; 将ESI+1的结果保存到EAX
0046D38A |. 99 |cdq
0046D38B |. B9 FF000000 |mov ecx,0FF
0046D390 |. F7F9 |idiv ecx ; 然后除以0xFF
0046D392 |. 84D2 |test dl,dl ; 比较余数不否为0
0046D394 |. 885424 08 |mov byte ptr ss:[esp+8],dl
0046D398 |. 74 0F |je short UILib8_M.0046D3A9 ; 为0则跳转,否则保存到ESP+8的位置
0046D39A |. 8B5424 08 |mov edx,dword ptr ss:[esp+8]
0046D39E |. 52 |push edx
0046D39F |. 8D4C24 10 |lea ecx,dword ptr ss:[esp+10]
0046D3A3 |. FF15 44E34A00 |call dword ptr ds:[<&MFC71U.#904>] ; MFC71U.7C29B289
0046D3A9 |> 8B4C24 20 |mov ecx,dword ptr ss:[esp+20]
0046D3AD |. 8B41 F4 |mov eax,dword ptr ds:[ecx-C]
0046D3B0 |. 46 |inc esi
0046D3B1 |. 3BF0 |cmp esi,eax
0046D3B3 |.^ 7C AB \jl short UILib8_M.0046D360
0046D3B5 |> 8B41 F4 mov eax,dword ptr ds:[ecx-C]
用代码来表示如下:




OJOsoft系列软件的注册算法
一个CM的脱壳与爆破
