-
-
[原创]让iijj Crackme (3)支持中文用户名
-
发表于: 2011-11-25 12:20 4182
-
【文章标题】: 让iijj Crackme (3)支持中文用户名
【文章作者】: 柳州小林
【作者QQ号】: 55713720
【软件名称】: riijj Crackme (3)
【下载地址】: http://bbs.pediy.com/upload/file/2004/11/riijj_cm_20041121.zip_081.zip
【加壳方式】: 无
【保护方式】: SEH,
【编写语言】: VC6
【使用工具】: OD,IDA
【操作平台】: WIN7
【软件介绍】:
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
今天看完了riijj Crackme (3)详解,并用IDA跟踪了一回,分析了算法,如:
char *EnRiijj3(char *name)
{
char key[]
="fytugjhkuijonlbpvqmcnxbvzdaeqrwtryetdgfkgphonuivmdbxfanqydexzwztqnkcfkvcpvlbmho
tyiufdkdnjxuzyqhfstae";
int namelen=strlen(name);
char *sn=new char[namelen*2];
int i=0,j=0,k=0;
for (i=0;i<namelen;i++)
{
j=name[i];
j=j & 0x0FF;//中文用户专用
j=j%0x62;
sn[k]=key[j];
sn[k+1]=key[j+1];
k+=2;
}
return sn;
}
但发现无法使用中文用户名,因为当name[i]的值超过0x80以后,j会变成负数(j=0xFFFFFFC1),造
成之后的一系列错误.
要修复只要加一句j=j & 0x0FF就OK
但在DLL里怎样改呢,来看看吧.
1:
先了解DLL是怎样被调用的.如果你用PEID分析pf1.dll会发现不是PE文件,因为它是加密的,在载入
文件后,在EXE里解密.
2:
根据CreateFile可以找到相应代码.
00401260 /$ 55 push ebp
00401261 |. 56 push esi
00401262 |. 57 push edi
00401263 |. BF 30604000 mov edi, riijj_cr.00406030 ; ASCII
"pf1.dll"
00401268 |. 83C9 FF or ecx, FFFFFFFF
0040126B |. 33C0 xor eax, eax
0040126D |. F2:AE repne scas byte ptr es:[edi]
0040126F |. F7D1 not ecx
00401271 |. 2BF9 sub edi, ecx
00401273 |. 50 push eax ;
/FailIfExists => FALSE
00401274 |. 8BF7 mov esi, edi ; |
00401276 |. 8BD1 mov edx, ecx ; |
00401278 |. BF 80694000 mov edi, riijj_cr.00406980 ; |
0040127D |. 83C9 FF or ecx, FFFFFFFF ; |
00401280 |. F2:AE repne scas byte ptr es:[edi] ; |
00401282 |. 8BCA mov ecx, edx ; |
00401284 |. 4F dec edi ; |
00401285 |. C1E9 02 shr ecx, 2 ; |
00401288 |. F3:A5 rep movs dword ptr es:[edi], dword p>; |
0040128A |. 8BCA mov ecx, edx ; |
0040128C |. 68 80694000 push riijj_cr.00406980 ; |
NewFileName = ""
00401291 |. 83E1 03 and ecx, 3 ; |
00401294 |. 68 30604000 push riijj_cr.00406030 ; |
ExistingFileName = "pf1.dll"
00401299 |. F3:A4 rep movs byte ptr es:[edi], byte ptr>; |
0040129B |. FF15 1C504000 call dword ptr ds:[<&KERNEL32.CopyFil>; \CopyFileA
004012A1 |. 6A 00 push 0 ;
/hTemplateFile = NULL
004012A3 |. 6A 00 push 0 ; |
Attributes = 0
004012A5 |. 6A 03 push 3 ; |Mode =
OPEN_EXISTING
004012A7 |. 6A 00 push 0 ; |pSecurity
= NULL
004012A9 |. 6A 00 push 0 ; |ShareMode
= 0
004012AB |. 68 000000C0 push C0000000 ; |Access =
GENERIC_READ|GENERIC_WRITE
004012B0 |. 68 80694000 push riijj_cr.00406980 ; |FileName
= ""
004012B5 |. FF15 18504000 call dword ptr ds:[<&KERNEL32.CreateF>;
\CreateFileA
先复制到C盘的临时文件夹,再打开,后取得文件大小,后面有几个我没有用过的函数
CreateFileMappingA 映射文件返回映射地址
MapViewOfFile 映射文件到当前进程
UnmapViewOfFile 解除映射
当映射文件到当前进程后,就开始解密它
004012F0 |. 33C9 xor ecx, ecx
004012F2 |. 85FF test edi, edi
004012F4 |. 76 17 jbe short riijj_cr.0040130D
004012F6 |. 53 push ebx
004012F7 8A1401 /mov dl, byte ptr ds:[ecx+eax]
004012FA 8A1D 886B4000 |mov bl, byte ptr ds:[406B88]
00401300 32D3 |xor dl, bl
00401302 32D1 |xor dl, cl
00401304 881401 |mov byte ptr ds:[ecx+eax], dl
00401307 41 |inc ecx
00401308 3BCF |cmp ecx, edi
0040130A ^ 72 EB \jb short riijj_cr.004012F7 ; 解密DLL
解密再关闭映射,直到当前函数返回这里:
004013B0 /$ E8 ABFEFFFF call riijj_cr.00401260
004013B5 |. 68 80694000 push riijj_cr.00406980 ; /FileName
= ""
004013BA |. FF15 24504000 call dword ptr ds:[<&KERNEL32.LoadLib>;
\LoadLibraryA
004013C0 |. 68 40604000 push riijj_cr.00406040 ;
/ProcNameOrOrdinal = "happytime"
004013C5 |. 50 push eax ; |hModule
004013C6 |. FF15 20504000 call dword ptr ds:[<&KERNEL32.GetProc>;
\GetProcAddress
004013CC |. A3 7C6B4000 mov dword ptr ds:[406B7C], eax
004013D1 \. C3 retn
解密后的DLL,就是标准的PE格式,所用LoadLibraryA载入它,用GetProcAddress调用它里面
的"happytime"函数,函数句柄保存在406b7c里.在读完用户名和注册码后,会用它来测试,是否进入
该函数.
3:
进入"happytime",找到关键代码
1000108C > /0FBE0419 movsx eax, byte ptr ds:[ecx+ebx]
这句相当于j=name[i];所以在它后面加入j=j & 0x0FF(and eax,0ff)就可以了.
这时要看看前后的代码有没有空间,用跳出去再跳回来的方法加入代码
"happytime"函数的返回后面倒是有,但空间不够,会影响下面的10001120的代码,所以在10003bc6
里加.()
10001090 cdq 改成 jmp 10003bc6
10001095 mov edi,62 改成 edq
还好,没有影响到10001096
10003BC6 这样写
10003BC6 > \BF 62000000 mov edi, 62
10003BCB . 25 FF000000 and eax, 0FF
10003BD0 ^ E9 C0D4FFFF jmp pf1.10001095
保存试试,记得把解密DLL的代码NOP,一次OK.
其实是好多次
1.忘记NOP解密DLL的代码
2.写在10001113,影响了10001120的代码,以至DLL无法载入,406b7c没有句柄,就不会call 10001010
3.忽略了cdq命令,一定在它之前或0xFF,当eax为负数时cdq后edx也是负数
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2011年11月23日 13:49:27
【文章作者】: 柳州小林
【作者QQ号】: 55713720
【软件名称】: riijj Crackme (3)
【下载地址】: http://bbs.pediy.com/upload/file/2004/11/riijj_cm_20041121.zip_081.zip
【加壳方式】: 无
【保护方式】: SEH,
【编写语言】: VC6
【使用工具】: OD,IDA
【操作平台】: WIN7
【软件介绍】:
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
今天看完了riijj Crackme (3)详解,并用IDA跟踪了一回,分析了算法,如:
char *EnRiijj3(char *name)
{
char key[]
="fytugjhkuijonlbpvqmcnxbvzdaeqrwtryetdgfkgphonuivmdbxfanqydexzwztqnkcfkvcpvlbmho
tyiufdkdnjxuzyqhfstae";
int namelen=strlen(name);
char *sn=new char[namelen*2];
int i=0,j=0,k=0;
for (i=0;i<namelen;i++)
{
j=name[i];
j=j & 0x0FF;//中文用户专用
j=j%0x62;
sn[k]=key[j];
sn[k+1]=key[j+1];
k+=2;
}
return sn;
}
但发现无法使用中文用户名,因为当name[i]的值超过0x80以后,j会变成负数(j=0xFFFFFFC1),造
成之后的一系列错误.
要修复只要加一句j=j & 0x0FF就OK
但在DLL里怎样改呢,来看看吧.
1:
先了解DLL是怎样被调用的.如果你用PEID分析pf1.dll会发现不是PE文件,因为它是加密的,在载入
文件后,在EXE里解密.
2:
根据CreateFile可以找到相应代码.
00401260 /$ 55 push ebp
00401261 |. 56 push esi
00401262 |. 57 push edi
00401263 |. BF 30604000 mov edi, riijj_cr.00406030 ; ASCII
"pf1.dll"
00401268 |. 83C9 FF or ecx, FFFFFFFF
0040126B |. 33C0 xor eax, eax
0040126D |. F2:AE repne scas byte ptr es:[edi]
0040126F |. F7D1 not ecx
00401271 |. 2BF9 sub edi, ecx
00401273 |. 50 push eax ;
/FailIfExists => FALSE
00401274 |. 8BF7 mov esi, edi ; |
00401276 |. 8BD1 mov edx, ecx ; |
00401278 |. BF 80694000 mov edi, riijj_cr.00406980 ; |
0040127D |. 83C9 FF or ecx, FFFFFFFF ; |
00401280 |. F2:AE repne scas byte ptr es:[edi] ; |
00401282 |. 8BCA mov ecx, edx ; |
00401284 |. 4F dec edi ; |
00401285 |. C1E9 02 shr ecx, 2 ; |
00401288 |. F3:A5 rep movs dword ptr es:[edi], dword p>; |
0040128A |. 8BCA mov ecx, edx ; |
0040128C |. 68 80694000 push riijj_cr.00406980 ; |
NewFileName = ""
00401291 |. 83E1 03 and ecx, 3 ; |
00401294 |. 68 30604000 push riijj_cr.00406030 ; |
ExistingFileName = "pf1.dll"
00401299 |. F3:A4 rep movs byte ptr es:[edi], byte ptr>; |
0040129B |. FF15 1C504000 call dword ptr ds:[<&KERNEL32.CopyFil>; \CopyFileA
004012A1 |. 6A 00 push 0 ;
/hTemplateFile = NULL
004012A3 |. 6A 00 push 0 ; |
Attributes = 0
004012A5 |. 6A 03 push 3 ; |Mode =
OPEN_EXISTING
004012A7 |. 6A 00 push 0 ; |pSecurity
= NULL
004012A9 |. 6A 00 push 0 ; |ShareMode
= 0
004012AB |. 68 000000C0 push C0000000 ; |Access =
GENERIC_READ|GENERIC_WRITE
004012B0 |. 68 80694000 push riijj_cr.00406980 ; |FileName
= ""
004012B5 |. FF15 18504000 call dword ptr ds:[<&KERNEL32.CreateF>;
\CreateFileA
先复制到C盘的临时文件夹,再打开,后取得文件大小,后面有几个我没有用过的函数
CreateFileMappingA 映射文件返回映射地址
MapViewOfFile 映射文件到当前进程
UnmapViewOfFile 解除映射
当映射文件到当前进程后,就开始解密它
004012F0 |. 33C9 xor ecx, ecx
004012F2 |. 85FF test edi, edi
004012F4 |. 76 17 jbe short riijj_cr.0040130D
004012F6 |. 53 push ebx
004012F7 8A1401 /mov dl, byte ptr ds:[ecx+eax]
004012FA 8A1D 886B4000 |mov bl, byte ptr ds:[406B88]
00401300 32D3 |xor dl, bl
00401302 32D1 |xor dl, cl
00401304 881401 |mov byte ptr ds:[ecx+eax], dl
00401307 41 |inc ecx
00401308 3BCF |cmp ecx, edi
0040130A ^ 72 EB \jb short riijj_cr.004012F7 ; 解密DLL
解密再关闭映射,直到当前函数返回这里:
004013B0 /$ E8 ABFEFFFF call riijj_cr.00401260
004013B5 |. 68 80694000 push riijj_cr.00406980 ; /FileName
= ""
004013BA |. FF15 24504000 call dword ptr ds:[<&KERNEL32.LoadLib>;
\LoadLibraryA
004013C0 |. 68 40604000 push riijj_cr.00406040 ;
/ProcNameOrOrdinal = "happytime"
004013C5 |. 50 push eax ; |hModule
004013C6 |. FF15 20504000 call dword ptr ds:[<&KERNEL32.GetProc>;
\GetProcAddress
004013CC |. A3 7C6B4000 mov dword ptr ds:[406B7C], eax
004013D1 \. C3 retn
解密后的DLL,就是标准的PE格式,所用LoadLibraryA载入它,用GetProcAddress调用它里面
的"happytime"函数,函数句柄保存在406b7c里.在读完用户名和注册码后,会用它来测试,是否进入
该函数.
3:
进入"happytime",找到关键代码
1000108C > /0FBE0419 movsx eax, byte ptr ds:[ecx+ebx]
这句相当于j=name[i];所以在它后面加入j=j & 0x0FF(and eax,0ff)就可以了.
这时要看看前后的代码有没有空间,用跳出去再跳回来的方法加入代码
"happytime"函数的返回后面倒是有,但空间不够,会影响下面的10001120的代码,所以在10003bc6
里加.()
10001090 cdq 改成 jmp 10003bc6
10001095 mov edi,62 改成 edq
还好,没有影响到10001096
10003BC6 这样写
10003BC6 > \BF 62000000 mov edi, 62
10003BCB . 25 FF000000 and eax, 0FF
10003BD0 ^ E9 C0D4FFFF jmp pf1.10001095
保存试试,记得把解密DLL的代码NOP,一次OK.
其实是好多次
1.忘记NOP解密DLL的代码
2.写在10001113,影响了10001120的代码,以至DLL无法载入,406b7c没有句柄,就不会call 10001010
3.忽略了cdq命令,一定在它之前或0xFF,当eax为负数时cdq后edx也是负数
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2011年11月23日 13:49:27
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [转帖]cyclops's Jade Crackme详解 4775
- [讨论]Crack Me技术等级自测4级请教思路! 5819
- [原创]该程序可以生成OD用的LIB 6968
- [分享]2007看雪金山2-1详解 4636
- 金山2007逆向分析挑战赛第一阶段第二题详解 8916
看原图
赞赏
雪币:
留言: