对某图标替换器的算法分析
本帖最后由 我是用户 于 2013-10-23 18:49 编辑前言:
最近由于要修改程序的图标,上网找的这个程序,竟然发现要注册,没注册的替换的图标有X线,研究了下他的算法,无奈他的是试用版,没有完整的功能,后来在网上搜到了完整版,好久没发贴了,就顺手写了这篇文章,写的不好,多多包涵。
1.查壳
ASPACK的壳,ESP或者脱壳机脱去。
BC++写的。
丢入DEDE,按钮事件一目了然
2.分析
程序的注册码要求0x2C位,且注册码分多次验证,具有全局注册标志,但修改无用。注册信息保存在注册表中,重启验证。
具体算法分析CALL:
00414488/$55 push ebp
00414489|.8BEC mov ebp, esp
0041448B|.81C4 44FFFFFF add esp, -0xBC
00414491|.B8 508C4E00 mov eax, 004E8C50
00414496|.53 push ebx
00414497|.56 push esi
00414498|.57 push edi
00414499|.E8 66E90A00 call <@__InitExceptBlockLDTC>
0041449E|.C745 F8 01000>mov dword ptr , 0x1
004144A5|.8D55 08 lea edx, dword ptr
004144A8|.8D45 08 lea eax, dword ptr
004144AB|.E8 BC990B00 call <@System@AnsiString@$bctr$qqrrx1>
004144B0|.FF45 F8 inc dword ptr
004144B3|.66:C745 EC 08>mov word ptr , 0x8
004144B9|.C645 DB 00 mov byte ptr , 0x0
004144BD|.837D 08 00 cmp dword ptr , 0x0
004144C1|.74 08 je short 004144CB
004144C3|.8B55 08 mov edx, dword ptr
004144C6|.8B4A FC mov ecx, dword ptr
004144C9|.EB 02 jmp short 004144CD
004144CB|>33C9 xor ecx, ecx
004144CD|>83F9 18 cmp ecx, 0x18 ;判断注册码长度是否为0x18位
004144D0|.0F85 A5000000 jnz 0041457B
004144D6|.BE C8844E00 mov esi, offset <a1z1h2a0n0g8y9a> ;1z1h+2a0n-0g8y*9a1n|
004144DB|.8D7D 9C lea edi, dword ptr
004144DE|.B9 05000000 mov ecx, 0x5
004144E3|.F3:A5 rep movs dword ptr es:, dword p>
004144E5|.A4 movs byte ptr es:, byte ptr [esi>
004144E6|.837D 08 00 cmp dword ptr , 0x0
004144EA|.74 05 je short 004144F1
004144EC|.8B45 08 mov eax, dword ptr
004144EF|.EB 05 jmp short 004144F6
004144F1|>B8 90864E00 mov eax, 004E8690
004144F6|>8BF8 mov edi, eax
004144F8|.33C0 xor eax, eax
004144FA|.83C9 FF or ecx, -0x1
004144FD|.8D75 B4 lea esi, dword ptr
00414500|.F2:AE repne scas byte ptr es:
00414502|.F7D1 not ecx
00414504|.2BF9 sub edi, ecx
00414506|.8BD1 mov edx, ecx
00414508|.87F7 xchg edi, esi
0041450A|.C1E9 02 shr ecx, 0x2
0041450D|.8BC7 mov eax, edi
0041450F|.F3:A5 rep movs dword ptr es:, dword p>
00414511|.8BCA mov ecx, edx
00414513|.83E1 03 and ecx, 0x3
00414516|.F3:A4 rep movs byte ptr es:, byte ptr>
00414518|.33C9 xor ecx, ecx
0041451A|.8D7D 9C lea edi, dword ptr
0041451D|.BE 68994F00 mov esi, 004F9968
00414522|.8D5D B4 lea ebx, dword ptr
00414525|>8D41 01 /lea eax, dword ptr
00414528|.51 |push ecx
00414529|.B9 05000000 |mov ecx, 0x5
0041452E|.99 |cdq
0041452F|.F7F9 |idiv ecx
00414531|.59 |pop ecx
00414532|.85D2 |test edx, edx
00414534|.74 3C |je short 00414572
00414536|.8A06 |mov al, byte ptr
00414538|.3207 |xor al, byte ptr
0041453A|.0FBED0 |movsx edx, al
0041453D|.8955 D4 |mov dword ptr , edx
00414540|.8B45 D4 |mov eax, dword ptr
00414543|.51 |push ecx
00414544|.99 |cdq
00414545|.33C2 |xor eax, edx
00414547|.B9 1A000000 |mov ecx, 0x1A
0041454C|.2BC2 |sub eax, edx
0041454E|.8BD0 |mov edx, eax
00414550|.8D0482 |lea eax, dword ptr
00414553|.8D0442 |lea eax, dword ptr
00414556|.C1E0 04 |shl eax, 0x4
00414559|.2BC2 |sub eax, edx
0041455B|.C1E0 04 |shl eax, 0x4
0041455E|.99 |cdq
0041455F|.F7F9 |idiv ecx
00414561|.0FBE03 |movsx eax, byte ptr
00414564|.83C2 41 |add edx, 0x41
00414567|.59 |pop ecx
00414568|.3BD0 |cmp edx, eax
0041456A|.74 06 |je short 00414572
0041456C|.C645 DB 00 |mov byte ptr , 0x0
00414570|.EB 09 |jmp short 0041457B
00414572|>41 |inc ecx
00414573|.47 |inc edi
00414574|.46 |inc esi
00414575|.43 |inc ebx
00414576|.83F9 14 |cmp ecx, 0x14
00414579|.^ 7C AA \jl short 00414525
0041457B|>837D 08 00 cmp dword ptr , 0x0
0041457F|.74 08 je short 00414589
00414581|.8B4D 08 mov ecx, dword ptr
00414584|.8B41 FC mov eax, dword ptr
00414587|.EB 02 jmp short 0041458B
00414589|>33C0 xor eax, eax
0041458B|>83F8 2C cmp eax, 0x2C
0041458E|.0F85 B0010000 jnz 00414744
00414594|.BE DD844E00 mov esi, offset <a1z1h2a0n0g8y_0> ;1z1h+2a0n-0g8y*9a1n|
00414599|.8DBD 58FFFFFF lea edi, dword ptr
0041459F|.B9 05000000 mov ecx, 0x5
004145A4|.F3:A5 rep movs dword ptr es:, dword p>
004145A6|.A4 movs byte ptr es:, byte ptr [esi>
004145A7|.66:C745 EC 08>mov word ptr , 0x8
004145AD|.837D 08 00 cmp dword ptr , 0x0
004145B1|.74 05 je short 004145B8
004145B3|.8B45 08 mov eax, dword ptr
004145B6|.EB 05 jmp short 004145BD
004145B8|>B8 91864E00 mov eax, 004E8691
004145BD|>0FBE50 28 movsx edx, byte ptr
004145C1|.83FA 36 cmp edx, 0x36 ;判断注册码第0x29位是否为6
004145C4|.74 23 je short 004145E9
004145C6|.33C0 xor eax, eax
004145C8|.BA 02000000 mov edx, 0x2
004145CD|.50 push eax
004145CE|.8D45 08 lea eax, dword ptr
004145D1|.FF4D F8 dec dword ptr
004145D4|.E8 5F990B00 call 004CDF38
004145D9|.58 pop eax
004145DA|.8B55 DC mov edx, dword ptr
004145DD|.64:8915 00000>mov dword ptr fs:, edx
004145E4|.E9 7A010000 jmp 00414763
004145E9|>837D 08 00 cmp dword ptr , 0x0
004145ED|.74 05 je short 004145F4
004145EF|.8B4D 08 mov ecx, dword ptr
004145F2|.EB 05 jmp short 004145F9
004145F4|>B9 92864E00 mov ecx, 004E8692
004145F9|>8BF9 mov edi, ecx
004145FB|.33C0 xor eax, eax
004145FD|.83C9 FF or ecx, -0x1
00414600|.8DB5 70FFFFFF lea esi, dword ptr
00414606|.F2:AE repne scas byte ptr es:
00414608|.F7D1 not ecx
0041460A|.2BF9 sub edi, ecx
0041460C|.8BD1 mov edx, ecx
0041460E|.87F7 xchg edi, esi
00414610|.C1E9 02 shr ecx, 0x2
00414613|.8BC7 mov eax, edi
00414615|.F3:A5 rep movs dword ptr es:, dword p>
00414617|.8BCA mov ecx, edx
00414619|.83E1 03 and ecx, 0x3
0041461C|.F3:A4 rep movs byte ptr es:, byte ptr>
0041461E|.0FBE85 71FFFF>movsx eax, byte ptr
00414625|.83F8 23 cmp eax, 0x23 ;判断第二位是否为#
00414628|.74 09 je short 00414633
0041462A|.83F8 2A cmp eax, 0x2A ;判断第二位是否为*
0041462D|.0F85 11010000 jnz 00414744
00414633|>C645 DB 01 mov byte ptr , 0x1 ;标志位为1
00414637|.BE 02000000 mov esi, 0x2
0041463C|.8D9D 5AFFFFFF lea ebx, dword ptr
00414642|.8D8D 7BFFFFFF lea ecx, dword ptr
00414648|>0FBE3B /movsx edi, byte ptr ;第一部分
0041464B|.0FBE41 F6 |movsx eax, byte ptr
0041464F|.03F8 |add edi, eax
00414651|.0FBE51 F7 |movsx edx, byte ptr
00414655|.33FA |xor edi, edx
00414657|.0FBE03 |movsx eax, byte ptr
0041465A|.33F8 |xor edi, eax
0041465C|.8BC7 |mov eax, edi
0041465E|.99 |cdq
0041465F|.33C2 |xor eax, edx
00414661|.2BC2 |sub eax, edx
00414663|.BF 1A000000 |mov edi, 0x1A
00414668|.99 |cdq
00414669|.F7FF |idiv edi
0041466B|.83C2 41 |add edx, 0x41
0041466E|.0FBE01 |movsx eax, byte ptr
00414671|.3BD0 |cmp edx, eax
00414673|.74 06 |je short 0041467B
00414675|.C645 DB 00 |mov byte ptr , 0x0 ;如果不等则标志位为0
00414679|.EB 08 |jmp short 00414683
0041467B|>46 |inc esi
0041467C|.43 |inc ebx
0041467D|.41 |inc ecx
0041467E|.83FE 0A |cmp esi, 0xA
00414681|.^ 7C C5 \jl short 00414648
00414683|>807D DB 00 cmp byte ptr , 0x0 ;判断标志位是否为0
00414687|.0F84 A7000000 je 00414734
0041468D|.66:C745 EC 08>mov word ptr , 0x8
00414693|.BF 18000000 mov edi, 0x18
00414698|.8DB5 44FFFFFF lea esi, dword ptr
0041469E|.8D9D 72FFFFFF lea ebx, dword ptr
004146A4|>0FBE43 FF /movsx eax, byte ptr ;用来生成0x10位的密钥
004146A8|.B9 06000000 |mov ecx, 0x6
004146AD|.99 |cdq
004146AE|.F7F9 |idiv ecx
004146B0|.8BCA |mov ecx, edx
004146B2|.0FBE03 |movsx eax, byte ptr
004146B5|.D3E0 |shl eax, cl
004146B7|.0FBE53 01 |movsx edx, byte ptr
004146BB|.0BC2 |or eax, edx
004146BD|.8945 D0 |mov dword ptr , eax
004146C0|.8B45 D0 |mov eax, dword ptr
004146C3|.99 |cdq
004146C4|.33C2 |xor eax, edx
004146C6|.2BC2 |sub eax, edx
004146C8|.B9 1A000000 |mov ecx, 0x1A
004146CD|.99 |cdq
004146CE|.F7F9 |idiv ecx
004146D0|.80C2 61 |add dl, 0x61
004146D3|.8816 |mov byte ptr , dl
004146D5|.47 |inc edi
004146D6|.46 |inc esi
004146D7|.43 |inc ebx
004146D8|.83FF 28 |cmp edi, 0x28
004146DB|.^ 7C C7 \jl short 004146A4
004146DD|.C685 54FFFFFF>mov byte ptr , 0x5A
004146E4|.C685 55FFFFFF>mov byte ptr , 0x59
004146EB|.66:C745 EC 08>mov word ptr , 0x8
004146F1|.BE 18000000 mov esi, 0x18
004146F6|.8D8D 44FFFFFF lea ecx, dword ptr
004146FC|.8D5D 88 lea ebx, dword ptr
004146FF|>0FBE39 /movsx edi, byte ptr ;第二部分
00414702|.C1E7 04 |shl edi, 0x4
00414705|.0FBE41 01 |movsx eax, byte ptr
00414709|.D1F8 |sar eax, 1
0041470B|.33F8 |xor edi, eax
0041470D|.8BC7 |mov eax, edi
0041470F|.99 |cdq
00414710|.33C2 |xor eax, edx
00414712|.2BC2 |sub eax, edx
00414714|.BF 1A000000 |mov edi, 0x1A
00414719|.99 |cdq
0041471A|.F7FF |idiv edi
0041471C|.83C2 41 |add edx, 0x41
0041471F|.0FBE03 |movsx eax, byte ptr
00414722|.3BD0 |cmp edx, eax
00414724|.74 06 |je short 0041472C
00414726|.C645 DB 00 |mov byte ptr , 0x0 ;如果不等则标志位为0
0041472A|.EB 08 |jmp short 00414734
0041472C|>46 |inc esi
0041472D|.41 |inc ecx
0041472E|.43 |inc ebx
0041472F|.83FE 28 |cmp esi, 0x28
00414732|.^ 7C CB \jl short 004146FF
00414734|>0FBE95 7AFFFF>movsx edx, byte ptr ;判断第0xB位是否为Y
0041473B|.83FA 59 cmp edx, 0x59
0041473E|.74 04 je short 00414744
00414740|.C645 DB 00 mov byte ptr , 0x0 ;不等则标志位为0
00414744|>8A45 DB mov al, byte ptr ;al为返回值
00414747|.BA 02000000 mov edx, 0x2
0041474C|.50 push eax
0041474D|.8D45 08 lea eax, dword ptr
00414750|.FF4D F8 dec dword ptr
00414753|.E8 E0970B00 call 004CDF38
00414758|.58 pop eax
00414759|.8B55 DC mov edx, dword ptr
0041475C|.64:8915 00000>mov dword ptr fs:, edx
00414763|>5F pop edi
00414764|.5E pop esi
00414765|.5B pop ebx
00414766|.8BE5 mov esp, ebp
00414768|.5D pop ebp
00414769\.C3 retn
以上代码所对应的C++代码如下
#include "stdafx.h"
#include <windows.h>
#include <math.h>
int main(int argc, char* argv[])
{
char cKey[]="1z1h+2a0n-0g8y*9a1n|";
char cInputKey[]="1#3456189AYIRNVRBHK56701XBKARZCPQKFSKTOP6XYZ";
char cEnKey;
BYTE dwTemp;
int i=0;
//第一部分
for (i=2;i<0xA;i++)
{
dwTemp=((cKey+cInputKey)^cInputKey^cKey)%0x1A+0x41;
cInputKey=dwTemp;
printf("%c",dwTemp);
}
printf("\n");
//生成0x10密钥
for (i=0;i<0x10;i++)
{
dwTemp=(int(cInputKey*pow(2,(cInputKey%6)))|cInputKey)%0x1A+0x61;
cEnKey=dwTemp;
printf("%c",dwTemp);
}
cEnKey='Z';
cEnKey='Y';
printf("\n");
//第二部分
for (i=0;i<0x10;i++)
{
dwTemp=(int(cEnKey*pow(2,4))^(cEnKey/2))%0x1A+0x41;
cInputKey=dwTemp;
printf("%c",dwTemp);
}
printf("\n");
cInputKey=cInputKey+1;
cInputKey=cInputKey-1;
printf("%s",cInputKey);
printf("\n");
return 0;
}
这个CALL只计算大部分的注册码,还有一些小部分是单独判断的,且是唯一的。如果强改全局注册位,会使程序退出,或者关机,且试用版的话还要验证一个全局变量,如果不通过
,且替换后的图标会有条X线,而且这个全局变量在程序初始化时是写死的,因为他没有完整的功能。
其他的验证,大家可以对全局标志位下内存断点,或者对EXITPROCESS和EXITWINDOWS下CC断点,进行分析,下面是我找的。
第0x2位必须为#或*
第0x7位必须为1
第0x6位必须为数字
第0x18位必须为数字
第0xB位必须为Y
第0x29位必须为6
第0x15位要等于第0x1位加1
第0x16位要等于第0x13位减1
附我成功转换后的图:
不错的!{:1_918:} 受教了!
学习了 学习了。。。。。 貌似非常好,感谢分享文章。 谢谢楼主的分享 已加分 看看。非常不错。支持下。 暂时还看不懂,还在学习中,哈哈 这个软件我一直用一个老的版本,有注册码,还是挺好用的,收藏了,以后慢慢看算法 楼主,没注册啊