首页
社区
课程
招聘
[原创]让iijj Crackme (3)支持中文用户名
发表于: 2011-11-25 12:20 4182

[原创]让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

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//