-
-
[原创]简单的crakcme
-
发表于: 2008-12-15 10:16 3896
-
基础薄弱 只得从crackme上练习
crackmes.de上 搜索难度2的 goodcrackmes 搜出的第一个居然是05年的crackme。。。
看了下比较简单 相关文件均在附件了
Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows
Language: Assembler
分析如下:
FSG的壳 脱壳后还有两种花 正好想学OD脚本 花了点时间看了遍手册
终于弄出个脚本。。。。
第一种花:
seg000:004016FC 000 51 push ecx
seg000:004016FD 004 EB 01 jmp short loc_401700
seg000:004016FD ; ---------------------------------------------------------------------------
seg000:004016FF 004 69 db 69h
seg000:00401700 ; ---------------------------------------------------------------------------
seg000:00401700
seg000:00401700 loc_401700: ; CODE XREF: start+Dj
seg000:00401700 004 EB 02 jmp short loc_401704
seg000:00401700 ; ---------------------------------------------------------------------------
seg000:00401702 004 CD 20 dw 20CDh
seg000:00401704 ; ---------------------------------------------------------------------------
seg000:00401704
seg000:00401704 loc_401704: ; CODE XREF: start:loc_401700j
seg000:00401704 004 6A 10 push 10h
seg000:00401706 008 59 pop ecx
seg000:00401707 004 E8 01 00 00 00 call sub_40170D
seg000:0040170C 004 5A pop edx
seg000:0040170C start endp ; sp-analysis failed
seg000:0040170C
seg000:0040170D
seg000:0040170D ; =============== S U B R O U T I N E =======================================
seg000:0040170D
seg000:0040170D
seg000:0040170D sub_40170D proc near ; CODE XREF: start+17p
seg000:0040170D ; sub_40170D+9j
seg000:0040170D
seg000:0040170D
seg000:0040170D 000 76 03 jbe short loc_401712
seg000:0040170F 000 C1 F1 00 sal ecx, 0
seg000:00401712
seg000:00401712 loc_401712: ; CODE XREF: sub_40170Dj
seg000:00401712 000 EB 01 jmp short loc_401715
seg000:00401714 ; ---------------------------------------------------------------------------
seg000:00401714 000 5A pop edx
seg000:00401715
seg000:00401715 loc_401715: ; CODE XREF: sub_40170D:loc_401712j
seg000:00401715 -04 49 dec ecx
seg000:00401716 -04 75 F5 jnz short sub_40170D
seg000:00401718 -04 59 pop ecx
seg000:00401719 -08 E3 01 jecxz short loc_40171C
seg000:0040171B -08 59 pop ecx
seg000:0040171C
seg000:0040171C loc_40171C: ; CODE XREF: sub_40170D+Cj
seg000:0040171C -0C EB 01 jmp short loc_40171F
第2种花:
seg000:0040171C -0C EB 01 jmp short loc_40171F
seg000:0040171C ; ---------------------------------------------------------------------------
seg000:0040171E -0C 69 db 69h
seg000:0040171F ; ---------------------------------------------------------------------------
seg000:0040171F
seg000:0040171F loc_40171F: ; CODE XREF: sub_40170D:loc_40171Cj
seg000:0040171F -0C EB 07 jmp short loc_401728
seg000:0040171F ; ---------------------------------------------------------------------------
seg000:00401721 -0C 5A DB db 5Ah, 0DBh
seg000:00401723 ; ---------------------------------------------------------------------------
seg000:00401723
seg000:00401723 loc_401723: ; CODE XREF: sub_40172Ej
seg000:00401723 -0C 83 C4 04 add esp, 4
seg000:00401726 -10 EB 08 jmp short loc_401730
seg000:00401728 ; ---------------------------------------------------------------------------
seg000:00401728
seg000:00401728 loc_401728: ; CODE XREF: sub_40170D:loc_40171Fj
seg000:00401728 -0C E8 01 00 00 00 call sub_40172E
seg000:0040172D -0C 5A pop edx
seg000:0040172D sub_40170D endp ; sp-analysis failed
seg000:0040172D
seg000:0040172E
seg000:0040172E ; =============== S U B R O U T I N E =======================================
seg000:0040172E
seg000:0040172E
seg000:0040172E sub_40172E proc near ; CODE XREF: sub_40170D:loc_401728p
seg000:0040172E 000 EB F3 jmp short loc_401723
seg000:0040172E sub_40172E endp
seg000:0040172E
算法:
seg000:004018EC push 64h ; cchMax
seg000:004018EE push offset fake_serial ; lpString
seg000:004018F3 push 68h ; nIDDlgItem
seg000:004018F5 push [ebp+hWnd] ; hDlg
seg000:004018F8 call GetDlgItemTextA ;取得fake_serial
seg000:00401931 cmp eax, 8 ; fake_serial.length > =8
seg000:00401934 jb loc_401ABD
seg000:0040196E mov length_fake_serial, eax
seg000:00401984 mov ecx, eax
seg000:004019BA mov esi, offset fake_serial ;&fake_serial[0]送esi
seg000:004019E2 mov ebx, [esi] ; (int)fake_serial[0]
seg000:004019E4 add ebx, [esi+4] ; (int)fake_serial[1]
;这里就是把fake_serial的前8位变成2个双字相加
seg000:004019E7
seg000:004019E7 loc_4019E7: ; CODE XREF: DialogFunc+23Fj
seg000:004019E7 sub ebx, 29Ah
seg000:004019ED add ebx, 43278h
seg000:004019F3 sub ebx, 0B34Ch
seg000:004019F9 inc esi
seg000:004019FA loop loc_4019E7 ; + length*(-29ah + 43278h, 0b34ch)计算出的值记为new_serial
seg000:004019FC mov ecx, offset new_serial
seg000:00401A12 push edx
seg000:00401A13 mov edx, offset new_serial
seg000:00401A18 mov [edx], ebx
seg000:00401A1A pop edx
seg000:00401A1B push 20h
seg000:00401A1D push offset new_serial
seg000:00401A22 push offset buffer
seg000:00401A27 call fake_md5 ;这个似乎是变形MD5算法 一开始没注意到 试图写逆算法 无果
;最终只得穷举
seg000:00401A2C mov ecx, 4
seg000:00401A31 mov edx, offset buffer
seg000:00401A36
seg000:00401A36 loc_401A36: ; CODE XREF: DialogFunc+286j
seg000:00401A36 sub ebx, [edx]
seg000:00401A38 sub ebx, 3E8h
seg000:00401A3E add edx, 4
seg000:00401A41 loop loc_401A36
seg000:00401A66 sub ebx, 0CE99D6E6h ;ebx = 0CE99D66 H 则注册成功
seg000:00401A6C jz short loc_401A93
整个算法过程 只用到了 serial的前8位, 变形MD5穷举本来是不可能的任务 但是 fake_serial计算出的new_serial
只是一个4字节的值 传入fake_md5 的字符串 剩余字节全为0 所以 整个字符串的变化只有2的32次方
算法注册机如下:
kengen.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned int ULONG;
extern void * __stdcall fake_md5(void * m, ULONG * x, ULONG size);
unsigned int get_result(void);
void main(int argc, char **argv)
{
ULONG result1, result2;
int i;
int serial[3] = {0};
ULONG m;
//可以调用get_result穷举
//result1 = get_result();
result1 = 0xD6D76C6A;
//整个算法 只用到了 serial的前8位
//所以这里假设serial只有8位 事实上大于等于8位都行
#define length 8
result2 = result1 + length * (0x29a - 0x43278 + 0xb34c);
printf("%X\n", result2);
//只要serial的前8个字符 分为2个int后 相加值为result2 即可注册成功
//对随机算法不清楚 所以这里只弄一组。。。这还叫注册机吗?。。。
serial[0] = 0x61613161;
serial[1] = result2 - serial[0];
printf("serial:%s\n",(char *)serial);
getchar();
}
//穷举法得到一个值y[0] = 0xD6D76C6A
//可能还有其它值但是 我没有继续计算
//太耗时间了= =
unsigned int get_result(void)
{
unsigned int y[9] = {0};
int buffer[8];
unsigned int i,x;
y[0] = 0x6a8b481c;
for(y[0] = 0xFFFFFFFF; y[0] >=0 ; y[0]--)
{
x = y[0];
fake_md5(buffer, &y[0], 0x20);
for(i = 0; i < 4; i++)
{
x= x-buffer[i]-0x3e8;
}
//printf("%X %X\n", y[0], x);
if(x == 0xCE99D6E6)
{
printf("ok\n");
break;
}
}
if(y[0] == 0)
printf("error\n");
printf("%X\n", y[0]);
return y[0];
}
编译选项cl /c kengen.c
md5.asm 中 是直接把IDA中fake_md5 复制出来 处理了下 代码太长 不列出来了 看附件
编译选项nasm -fwin32 md5.asm
链接选项link kengen.obj md5.obj
crackmes.de上 搜索难度2的 goodcrackmes 搜出的第一个居然是05年的crackme。。。
看了下比较简单 相关文件均在附件了
Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows
Language: Assembler
分析如下:
FSG的壳 脱壳后还有两种花 正好想学OD脚本 花了点时间看了遍手册
终于弄出个脚本。。。。
第一种花:
seg000:004016FC 000 51 push ecx
seg000:004016FD 004 EB 01 jmp short loc_401700
seg000:004016FD ; ---------------------------------------------------------------------------
seg000:004016FF 004 69 db 69h
seg000:00401700 ; ---------------------------------------------------------------------------
seg000:00401700
seg000:00401700 loc_401700: ; CODE XREF: start+Dj
seg000:00401700 004 EB 02 jmp short loc_401704
seg000:00401700 ; ---------------------------------------------------------------------------
seg000:00401702 004 CD 20 dw 20CDh
seg000:00401704 ; ---------------------------------------------------------------------------
seg000:00401704
seg000:00401704 loc_401704: ; CODE XREF: start:loc_401700j
seg000:00401704 004 6A 10 push 10h
seg000:00401706 008 59 pop ecx
seg000:00401707 004 E8 01 00 00 00 call sub_40170D
seg000:0040170C 004 5A pop edx
seg000:0040170C start endp ; sp-analysis failed
seg000:0040170C
seg000:0040170D
seg000:0040170D ; =============== S U B R O U T I N E =======================================
seg000:0040170D
seg000:0040170D
seg000:0040170D sub_40170D proc near ; CODE XREF: start+17p
seg000:0040170D ; sub_40170D+9j
seg000:0040170D
seg000:0040170D
seg000:0040170D 000 76 03 jbe short loc_401712
seg000:0040170F 000 C1 F1 00 sal ecx, 0
seg000:00401712
seg000:00401712 loc_401712: ; CODE XREF: sub_40170Dj
seg000:00401712 000 EB 01 jmp short loc_401715
seg000:00401714 ; ---------------------------------------------------------------------------
seg000:00401714 000 5A pop edx
seg000:00401715
seg000:00401715 loc_401715: ; CODE XREF: sub_40170D:loc_401712j
seg000:00401715 -04 49 dec ecx
seg000:00401716 -04 75 F5 jnz short sub_40170D
seg000:00401718 -04 59 pop ecx
seg000:00401719 -08 E3 01 jecxz short loc_40171C
seg000:0040171B -08 59 pop ecx
seg000:0040171C
seg000:0040171C loc_40171C: ; CODE XREF: sub_40170D+Cj
seg000:0040171C -0C EB 01 jmp short loc_40171F
第2种花:
seg000:0040171C -0C EB 01 jmp short loc_40171F
seg000:0040171C ; ---------------------------------------------------------------------------
seg000:0040171E -0C 69 db 69h
seg000:0040171F ; ---------------------------------------------------------------------------
seg000:0040171F
seg000:0040171F loc_40171F: ; CODE XREF: sub_40170D:loc_40171Cj
seg000:0040171F -0C EB 07 jmp short loc_401728
seg000:0040171F ; ---------------------------------------------------------------------------
seg000:00401721 -0C 5A DB db 5Ah, 0DBh
seg000:00401723 ; ---------------------------------------------------------------------------
seg000:00401723
seg000:00401723 loc_401723: ; CODE XREF: sub_40172Ej
seg000:00401723 -0C 83 C4 04 add esp, 4
seg000:00401726 -10 EB 08 jmp short loc_401730
seg000:00401728 ; ---------------------------------------------------------------------------
seg000:00401728
seg000:00401728 loc_401728: ; CODE XREF: sub_40170D:loc_40171Fj
seg000:00401728 -0C E8 01 00 00 00 call sub_40172E
seg000:0040172D -0C 5A pop edx
seg000:0040172D sub_40170D endp ; sp-analysis failed
seg000:0040172D
seg000:0040172E
seg000:0040172E ; =============== S U B R O U T I N E =======================================
seg000:0040172E
seg000:0040172E
seg000:0040172E sub_40172E proc near ; CODE XREF: sub_40170D:loc_401728p
seg000:0040172E 000 EB F3 jmp short loc_401723
seg000:0040172E sub_40172E endp
seg000:0040172E
算法:
seg000:004018EC push 64h ; cchMax
seg000:004018EE push offset fake_serial ; lpString
seg000:004018F3 push 68h ; nIDDlgItem
seg000:004018F5 push [ebp+hWnd] ; hDlg
seg000:004018F8 call GetDlgItemTextA ;取得fake_serial
seg000:00401931 cmp eax, 8 ; fake_serial.length > =8
seg000:00401934 jb loc_401ABD
seg000:0040196E mov length_fake_serial, eax
seg000:00401984 mov ecx, eax
seg000:004019BA mov esi, offset fake_serial ;&fake_serial[0]送esi
seg000:004019E2 mov ebx, [esi] ; (int)fake_serial[0]
seg000:004019E4 add ebx, [esi+4] ; (int)fake_serial[1]
;这里就是把fake_serial的前8位变成2个双字相加
seg000:004019E7
seg000:004019E7 loc_4019E7: ; CODE XREF: DialogFunc+23Fj
seg000:004019E7 sub ebx, 29Ah
seg000:004019ED add ebx, 43278h
seg000:004019F3 sub ebx, 0B34Ch
seg000:004019F9 inc esi
seg000:004019FA loop loc_4019E7 ; + length*(-29ah + 43278h, 0b34ch)计算出的值记为new_serial
seg000:004019FC mov ecx, offset new_serial
seg000:00401A12 push edx
seg000:00401A13 mov edx, offset new_serial
seg000:00401A18 mov [edx], ebx
seg000:00401A1A pop edx
seg000:00401A1B push 20h
seg000:00401A1D push offset new_serial
seg000:00401A22 push offset buffer
seg000:00401A27 call fake_md5 ;这个似乎是变形MD5算法 一开始没注意到 试图写逆算法 无果
;最终只得穷举
seg000:00401A2C mov ecx, 4
seg000:00401A31 mov edx, offset buffer
seg000:00401A36
seg000:00401A36 loc_401A36: ; CODE XREF: DialogFunc+286j
seg000:00401A36 sub ebx, [edx]
seg000:00401A38 sub ebx, 3E8h
seg000:00401A3E add edx, 4
seg000:00401A41 loop loc_401A36
seg000:00401A66 sub ebx, 0CE99D6E6h ;ebx = 0CE99D66 H 则注册成功
seg000:00401A6C jz short loc_401A93
整个算法过程 只用到了 serial的前8位, 变形MD5穷举本来是不可能的任务 但是 fake_serial计算出的new_serial
只是一个4字节的值 传入fake_md5 的字符串 剩余字节全为0 所以 整个字符串的变化只有2的32次方
算法注册机如下:
kengen.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned int ULONG;
extern void * __stdcall fake_md5(void * m, ULONG * x, ULONG size);
unsigned int get_result(void);
void main(int argc, char **argv)
{
ULONG result1, result2;
int i;
int serial[3] = {0};
ULONG m;
//可以调用get_result穷举
//result1 = get_result();
result1 = 0xD6D76C6A;
//整个算法 只用到了 serial的前8位
//所以这里假设serial只有8位 事实上大于等于8位都行
#define length 8
result2 = result1 + length * (0x29a - 0x43278 + 0xb34c);
printf("%X\n", result2);
//只要serial的前8个字符 分为2个int后 相加值为result2 即可注册成功
//对随机算法不清楚 所以这里只弄一组。。。这还叫注册机吗?。。。
serial[0] = 0x61613161;
serial[1] = result2 - serial[0];
printf("serial:%s\n",(char *)serial);
getchar();
}
//穷举法得到一个值y[0] = 0xD6D76C6A
//可能还有其它值但是 我没有继续计算
//太耗时间了= =
unsigned int get_result(void)
{
unsigned int y[9] = {0};
int buffer[8];
unsigned int i,x;
y[0] = 0x6a8b481c;
for(y[0] = 0xFFFFFFFF; y[0] >=0 ; y[0]--)
{
x = y[0];
fake_md5(buffer, &y[0], 0x20);
for(i = 0; i < 4; i++)
{
x= x-buffer[i]-0x3e8;
}
//printf("%X %X\n", y[0], x);
if(x == 0xCE99D6E6)
{
printf("ok\n");
break;
}
}
if(y[0] == 0)
printf("error\n");
printf("%X\n", y[0]);
return y[0];
}
编译选项cl /c kengen.c
md5.asm 中 是直接把IDA中fake_md5 复制出来 处理了下 代码太长 不列出来了 看附件
编译选项nasm -fwin32 md5.asm
链接选项link kengen.obj md5.obj
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- 删帖吧 3455
- [原创]virut分析 14615
- [原创]求职 病毒分析 软件安全 4591
- [原创]telock0.98分析 8276
- [原创]UPX解压缩算法逆向 19559
看原图
赞赏
雪币:
留言: