-
-
[旧帖] [原创]快刀斩乱麻 3.91算法分析与实现(把汇编嵌入C++中) 0.00雪花
-
发表于: 2009-5-6 15:01 2158
-
软件下载地址:http://www.newhua.com/soft/58.htm
用PEID查壳,没有壳,是Microsoft Visual C++ 6.0,这好办多了
假注册
用户名:renwoxiao
注册码:5201314
提示:“注册码不正确”
用OD载入,用插件查找此字符串
0040144F |. 83F8 1E cmp eax,1E ; 用户名长度和1E比较,也就是说用户名长度得小于30位,否则就报错
00401452 |. 7D 3A jge short x-cut.0040148E
00401454 |. 3BF3 cmp esi,ebx ;
00401456 |. 7E 66 jle short x-cut.004014BE
00401458 |> 68 68504100 /push x-cut.00415068 ; o0040145D |. 8D4424 18 |lea eax,dword ptr ss:[esp+18]
00401461 |. 68 685C4100 |push x-cut.00415C68
00401466 |. 50 |push eax
00401467 |. E8 6AC00000 |call <jmp.&MFC42.#924>
0040146C |. 50 |push eax
0040146D |. B9 685C4100 |mov ecx,x-cut.00415C68
00401472 |. C64424 28 01 |mov byte ptr ss:[esp+28],1
00401477 |. E8 60C00000 |call <jmp.&MFC42.#858>
0040147C |. 8D4C24 14 |lea ecx,dword ptr ss:[esp+14] ;
00401480 |. 885C24 24 |mov byte ptr ss:[esp+24],bl
00401484 |. E8 DBBF0000 |call <jmp.&MFC42.#800>
00401489 |. 4E |dec esi
0040148A |.^ 75 CC \jnz short x-cut.00401458 ; 上面全部是把用户名长度增加到30位后面补大写字母‘O‘,而不是数字0
如我的用户名就变成了renwoxiaoOOOOOOOOOOOOOOOOOOOOO
0040148C |. EB 30 jmp short x-cut.004014BE
0040148E |> 7E 2E jle short x-cut.004014BE
00401490 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
00401494 |. 6A 1E push 1E
00401496 |. 51 push ecx
00401497 |. B9 685C4100 mov ecx,x-cut.00415C68
0040149C |. E8 2FC00000 call <jmp.&MFC42.#4129>
004014A1 |. 50 push eax
004014A2 |. B9 685C4100 mov ecx,x-cut.00415C68
004014A7 |. C64424 28 02 mov byte ptr ss:[esp+28],2
004014AC |. E8 2BC00000 call <jmp.&MFC42.#858>
004014B1 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
004014B5 |. 885C24 24 mov byte ptr ss:[esp+24],bl
004014B9 |. E8 A6BF0000 call <jmp.&MFC42.#800>
004014BE |> 55 push ebp
004014BF |. 8B2D 685C4100 mov ebp,dword ptr ds:[415C68] ;
004014C5 |. 33C9 xor ecx,ecx ; 计数器ecx清0,共循环30次
004014C7 |> 8A0429 /mov al,byte ptr ds:[ecx+ebp] ; 取出用户名各位,我的第一位是 ‘r ’,算法 开始
004014CA |. 83E0 7F |and eax,7F ; eax 和7F着与运算 eax=’r‘ &&7F=00000072
004014CD |. 69C0 3B2E0800 |imul eax,eax,82E3B ; eax=eax*82E38=03A49646 edx=73E0E578,注意edx,有符号数的相乘,进位到edx
004014D3 |. 8BF0 |mov esi,eax esi=eax=03A49646
004014D5 |. B8 E10217B8 |mov eax,B81702E1 eax=0B81702E1
004014DA |. F7EE |imul esi ; eax=eax*esi=4D1E9F86 edx=FEFA0990
004014DC |. 03D6 |add edx,esi edx=edx+esi
004014DE |. C1FA 06 |sar edx,6 edx算术右移6位 edx=000A7A7F
004014E1 |. 8BC2 |mov eax,edx eax=edx=000A7A7F
004014E3 |. C1E8 1F |shr eax,1F eax逻辑右移30位,eax=00000000
004014E6 |. 03D0 |add edx,eax edx=edx+eax
004014E8 |. 41 |inc ecx 计数器加一
004014E9 |. 83F9 1E |cmp ecx,1E 判断循环是否结束
004014EC |. 8DBC17 7A0785>|lea edi,dword ptr ds:[edi+edx+85077A] 简单的加法edi=edi+edx+85077A
004014F3 >|.^ 7C D2 \jl short x-cut.004014C7
004014F5 |. A1 645C4100 mov eax,dword ptr ds:[415C64]
004014FA |. 5D pop ebp
004014FB |. 3BC7 cmp eax,edi 真假注册码比较,是16进制我的是004F5DA2==108A2DF3????
004014FD |. 74 14 je short x-cut.00401513 ; 关键跳
004014FF |. 53 push ebx
00401500 |. 53 push ebx
00401501 |. 68 58504100 push x-cut.00415058 ; 注册码不正确!
这个软件爆破比较简单,直接把关键跳NOP掉就可以了
内存注册机也可以,在 004014FB |. 3BC7 cmp eax,edi这个地方
注册机选 寄存器方式的EDI十进制
但是这个不好,卡巴斯基把它当木马,直接杀了
下面是我用BC++写的
算法分析是一回事,但是自己实现又是另外一回事
我不会,⊙﹏⊙b 汗 我就把算法的汇编嵌入c++中,我也是刚学的,菜鸟一个,^_^ , 昨天学了大半天
void __fastcall TForm1::btnGClick(TObject *Sender)
{
static long m;
static char a[31]={'0'};
int i,n;
String s=edt1->Text;
strcpy(a,s.c_str());
n=strlen(a);
for(i=n;i<30;i++)
a='O';
_asm{
push ebp
push ecx
push eax
push edx
push edi
lea ebp, a
xor ecx, ecx
mov edi, 1
mov eax, 1
mov edx, 073E0E578h
lab1: mov al, [ecx+ebp]
and eax, 07Fh
imul eax, 082E3Bh
mov esi, eax
mov eax, 0B81702E1h
imul esi
add edx, esi
sar edx, 6
mov eax, edx
shr eax, 01Fh
add edx, eax
inc ecx
cmp ecx, 01Eh
lea edi, [edi+edx+085077Ah]
jl lab1
mov m,edi
pop edi
pop edx
pop eax
pop ecx
pop ebp
}
edt2->Text=String(m);
}
注意寄存器的处理,
还有就是两个变量的处理
static long m;
static char a[31]={'0'};
这里的m和a只能是static类型,或者是全局变量
因为局部变量最终由寄存器来实现存取,这样就和上面的寄存器有冲突
而全局变量或者static类型的变量是通过内存来实现存取的!!!
用PEID查壳,没有壳,是Microsoft Visual C++ 6.0,这好办多了
假注册
用户名:renwoxiao
注册码:5201314
提示:“注册码不正确”
用OD载入,用插件查找此字符串
0040144F |. 83F8 1E cmp eax,1E ; 用户名长度和1E比较,也就是说用户名长度得小于30位,否则就报错
00401452 |. 7D 3A jge short x-cut.0040148E
00401454 |. 3BF3 cmp esi,ebx ;
00401456 |. 7E 66 jle short x-cut.004014BE
00401458 |> 68 68504100 /push x-cut.00415068 ; o0040145D |. 8D4424 18 |lea eax,dword ptr ss:[esp+18]
00401461 |. 68 685C4100 |push x-cut.00415C68
00401466 |. 50 |push eax
00401467 |. E8 6AC00000 |call <jmp.&MFC42.#924>
0040146C |. 50 |push eax
0040146D |. B9 685C4100 |mov ecx,x-cut.00415C68
00401472 |. C64424 28 01 |mov byte ptr ss:[esp+28],1
00401477 |. E8 60C00000 |call <jmp.&MFC42.#858>
0040147C |. 8D4C24 14 |lea ecx,dword ptr ss:[esp+14] ;
00401480 |. 885C24 24 |mov byte ptr ss:[esp+24],bl
00401484 |. E8 DBBF0000 |call <jmp.&MFC42.#800>
00401489 |. 4E |dec esi
0040148A |.^ 75 CC \jnz short x-cut.00401458 ; 上面全部是把用户名长度增加到30位后面补大写字母‘O‘,而不是数字0
如我的用户名就变成了renwoxiaoOOOOOOOOOOOOOOOOOOOOO
0040148C |. EB 30 jmp short x-cut.004014BE
0040148E |> 7E 2E jle short x-cut.004014BE
00401490 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
00401494 |. 6A 1E push 1E
00401496 |. 51 push ecx
00401497 |. B9 685C4100 mov ecx,x-cut.00415C68
0040149C |. E8 2FC00000 call <jmp.&MFC42.#4129>
004014A1 |. 50 push eax
004014A2 |. B9 685C4100 mov ecx,x-cut.00415C68
004014A7 |. C64424 28 02 mov byte ptr ss:[esp+28],2
004014AC |. E8 2BC00000 call <jmp.&MFC42.#858>
004014B1 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
004014B5 |. 885C24 24 mov byte ptr ss:[esp+24],bl
004014B9 |. E8 A6BF0000 call <jmp.&MFC42.#800>
004014BE |> 55 push ebp
004014BF |. 8B2D 685C4100 mov ebp,dword ptr ds:[415C68] ;
004014C5 |. 33C9 xor ecx,ecx ; 计数器ecx清0,共循环30次
004014C7 |> 8A0429 /mov al,byte ptr ds:[ecx+ebp] ; 取出用户名各位,我的第一位是 ‘r ’,算法 开始
004014CA |. 83E0 7F |and eax,7F ; eax 和7F着与运算 eax=’r‘ &&7F=00000072
004014CD |. 69C0 3B2E0800 |imul eax,eax,82E3B ; eax=eax*82E38=03A49646 edx=73E0E578,注意edx,有符号数的相乘,进位到edx
004014D3 |. 8BF0 |mov esi,eax esi=eax=03A49646
004014D5 |. B8 E10217B8 |mov eax,B81702E1 eax=0B81702E1
004014DA |. F7EE |imul esi ; eax=eax*esi=4D1E9F86 edx=FEFA0990
004014DC |. 03D6 |add edx,esi edx=edx+esi
004014DE |. C1FA 06 |sar edx,6 edx算术右移6位 edx=000A7A7F
004014E1 |. 8BC2 |mov eax,edx eax=edx=000A7A7F
004014E3 |. C1E8 1F |shr eax,1F eax逻辑右移30位,eax=00000000
004014E6 |. 03D0 |add edx,eax edx=edx+eax
004014E8 |. 41 |inc ecx 计数器加一
004014E9 |. 83F9 1E |cmp ecx,1E 判断循环是否结束
004014EC |. 8DBC17 7A0785>|lea edi,dword ptr ds:[edi+edx+85077A] 简单的加法edi=edi+edx+85077A
004014F3 >|.^ 7C D2 \jl short x-cut.004014C7
004014F5 |. A1 645C4100 mov eax,dword ptr ds:[415C64]
004014FA |. 5D pop ebp
004014FB |. 3BC7 cmp eax,edi 真假注册码比较,是16进制我的是004F5DA2==108A2DF3????
004014FD |. 74 14 je short x-cut.00401513 ; 关键跳
004014FF |. 53 push ebx
00401500 |. 53 push ebx
00401501 |. 68 58504100 push x-cut.00415058 ; 注册码不正确!
这个软件爆破比较简单,直接把关键跳NOP掉就可以了
内存注册机也可以,在 004014FB |. 3BC7 cmp eax,edi这个地方
注册机选 寄存器方式的EDI十进制
但是这个不好,卡巴斯基把它当木马,直接杀了
下面是我用BC++写的
算法分析是一回事,但是自己实现又是另外一回事
我不会,⊙﹏⊙b 汗 我就把算法的汇编嵌入c++中,我也是刚学的,菜鸟一个,^_^ , 昨天学了大半天
void __fastcall TForm1::btnGClick(TObject *Sender)
{
static long m;
static char a[31]={'0'};
int i,n;
String s=edt1->Text;
strcpy(a,s.c_str());
n=strlen(a);
for(i=n;i<30;i++)
a='O';
_asm{
push ebp
push ecx
push eax
push edx
push edi
lea ebp, a
xor ecx, ecx
mov edi, 1
mov eax, 1
mov edx, 073E0E578h
lab1: mov al, [ecx+ebp]
and eax, 07Fh
imul eax, 082E3Bh
mov esi, eax
mov eax, 0B81702E1h
imul esi
add edx, esi
sar edx, 6
mov eax, edx
shr eax, 01Fh
add edx, eax
inc ecx
cmp ecx, 01Eh
lea edi, [edi+edx+085077Ah]
jl lab1
mov m,edi
pop edi
pop edx
pop eax
pop ecx
pop ebp
}
edt2->Text=String(m);
}
注意寄存器的处理,
还有就是两个变量的处理
static long m;
static char a[31]={'0'};
这里的m和a只能是static类型,或者是全局变量
因为局部变量最终由寄存器来实现存取,这样就和上面的寄存器有冲突
而全局变量或者static类型的变量是通过内存来实现存取的!!!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: