TheCjw 发表于 2010-1-10 19:44

[LCG原创] 也谈SkinSharp的破解

起因:最近MM写东西,想找个漂亮的皮肤献殷勤。昨天晚上,在Hmily的帖子了买了一个SkinSharp,5CB。今天上来一看,那家伙居然给降价了。心里不平衡啊不平衡,遂自己动手破解之。



破解SkinSharp,就是去掉窗口和菜单上的小图标。


今天用SkinHu.dll做演示,别的应该都差不多。

为了调试dll先写个MFC的exe,然后用OD加载那个exe,方便调试。


1,去掉窗口上的小图标
画窗口我也少有研究,我们注意到,标题一般都是使用DrawTextA/W画上去的。画标题的附近应该就有画小图标的地方。

于是bp DrawTextW,断下的时候观察堆栈,看看到主窗口的标题就可以返回了。
第一次断下之后返回到这里:

1002177D   51                     push    ecx
1002177E   FF15 C8620210          call    dword ptr          ; USER32.DrawTextW
10021784   8B5424 10            mov   edx, dword ptr
10021788   8B4424 18            mov   eax, dword ptr


向上翻翻这个函数,看到一些GetWindowText、SetTextColor之类的,就可以断定,这个就是画界面的函数了,于是在函数头下断点,断下后单步跟踪,到这里的时候,出现了一些可疑的数字:

100215F0   A1 68CC0210            mov   eax, dword ptr       ; eax = 10
100215F5   8B0D 64CC0210          mov   ecx, dword ptr       ; ecx = 10
100215FB   8B15 5CCC0210          mov   edx, dword ptr
10021601   57                     push    edi
10021602   68 FF00FF00            push    0xFF00FF
10021607   50                     push    eax
10021608   51                     push    ecx
10021609   6A 00                  push    0x0
1002160B   6A 00                  push    0x0
1002160D   52                     push    edx
1002160E   8B96 B0010000          mov   edx, dword ptr
10021614   50                     push    eax
10021615   8B86 B8010000          mov   eax, dword ptr
1002161B   51                     push    ecx
1002161C   8D4410 F0            lea   eax, dword ptr
10021620   99                     cdq
10021621   2BC2                   sub   eax, edx
10021623   D1F8                   sar   eax, 1
10021625   50                     push    eax
10021626   8B86 B4010000          mov   eax, dword ptr
1002162C   2BC1                   sub   eax, ecx
1002162E   83E8 0C                sub   eax, 0xC
10021631   50                     push    eax
10021632   55                     push    ebp
10021633   E8 1898FEFF            call    1000AE50

看到eax,ecx都为10,而目测那个图标的大小,应该也是10,于是猜测这里就是画小图标的函数。
适当的处理掉一些参数,看看效果如何。把10021632处的push ebp改成push eax,让程序跑起来,窗口上的小图标就消失了。



2,去掉菜单上的小图标
还是从API入手,寻思着,肯定要得到菜单的Rect,于是目标锁定在GetMenuItemRect上。
在GetMenuItemRect上下断点,切换窗口时立即断了下来,于是加上一个条件筛选掉主窗口的hMenu,就是判断!。

在点击内部菜单后,断下来了,返回到这里:

1000F205   896C24 3C            mov   dword ptr , ebp
1000F209   FF15 00620210          call    dword ptr          ; USER32.GetMenuItemRect
1000F20F   8B4C24 30            mov   ecx, dword ptr
1000F213   8B7C24 14            mov   edi, dword ptr


有了第一个的经验后,我们就在这个函数内找压栈比较多的函数,不一会,找到这个:

1000F339   8B3D AC620210          mov   edi, dword ptr       ; USER32.OffsetRect
1000F33F   8B15 64CC0210          mov   edx, dword ptr
1000F345   8B1D 5CCC0210          mov   ebx, dword ptr
1000F34B   8D4E 30                lea   ecx, dword ptr
1000F34E   51                     push    ecx
1000F34F   8B0D 68CC0210          mov   ecx, dword ptr
1000F355   68 FF00FF00            push    0xFF00FF
1000F35A   51                     push    ecx
1000F35B   52                     push    edx
1000F35C   55                     push    ebp
1000F35D   55                     push    ebp
1000F35E   53                     push    ebx
1000F35F   51                     push    ecx
1000F360   2BC1                   sub   eax, ecx
1000F362   8B4C24 34            mov   ecx, dword ptr
1000F366   52                     push    edx
1000F367   2BC1                   sub   eax, ecx
1000F369   8B4C24 3C            mov   ecx, dword ptr
1000F36D   83E8 05                sub   eax, 0x5
1000F370   2BCA                   sub   ecx, edx
1000F372   8B5424 74            mov   edx, dword ptr
1000F376   50                     push    eax
1000F377   2B4C24 38            sub   ecx, dword ptr
1000F37B   83E9 06                sub   ecx, 0x6
1000F37E   51                     push    ecx
1000F37F   52                     push    edx
1000F380   E8 CBBAFFFF            call    1000AE50

同样的把Call前面的那个push改掉。菜单的小图标就没了。

Patch只需两字节。

3,其实,自己写的程序,就不用破解啦,写段代码就行,适用VC的于Unicode版,别的只是偏移的问题。


        HMODULE hSkinBase = GetModuleHandleW(L"SkinHu.dll");
        unsigned char *pPatchByte = NULL;
        DWORD dwOldProtect = 0;
        if ( hSkinBase == NULL )
        {
                return ;
        }
        //10021632       55                   push    ebp
        pPatchByte = (unsigned char*)((DWORD)hSkinBase + 0x00021632);
        VirtualProtectEx(GetCurrentProcess(),pPatchByte,4,PAGE_EXECUTE_READWRITE,&dwOldProtect);
        *pPatchByte = 0x50;

        //1000F37F       52                   push    edx
        pPatchByte = (unsigned char*)((DWORD)hSkinBase + 0x0000F37F);
        VirtualProtectEx(GetCurrentProcess(),pPatchByte,4,PAGE_EXECUTE_READWRITE,&dwOldProtect);
        *pPatchByte = 0x50;


不知道Hmily是怎么样搞的~谁去骚扰一下Hmily呢~

Hmily 发表于 2010-1-10 20:02

Good,从限制入手很爽啊,学习!我是从他取完校验数据入手的,本来我是写了个正确的数据进去,让他怎么都是校验成正版,据海风说算法有漏洞,数据为0也可以通过验证,所以我改成直接取到的数据清0,也通过了他的校验.patch的地方就在它取了2个文件的MD5以后,进入VM开始的地方patch掉数据就可以了.加精鼓励!

hackwm 发表于 2010-1-10 20:31

:hug:膜拜牛淫.~牛X

紫色 发表于 2010-1-10 20:41

都是大牛 都有各自的见解啊 我还不懂哦 来学习一下

sooaoo 发表于 2010-1-10 20:43

学习了,加油

assume 发表于 2010-1-10 20:57

强悍啊!!!
学习了

TheCjw 发表于 2010-1-10 21:06

Good,从限制入手很爽啊,学习!我是从他取完校验数据入手的,本来我是写了个正确的数据进去,让他怎么都是校验成 ...
Hmily 发表于 2010-1-10 20:02 http://www.52pojie.cn/images/common/back.gif

我还没想那么多呢。。海风好牛逼啊,Hmily也很变态!

小糊涂虫 发表于 2010-1-10 22:08

LS的果然是高手,膜拜

gjianbo 发表于 2010-1-10 22:41

历害,我分析授权文件,写出来生成授权的工具,没有分析出的核心算法,只能根据机器码和语言生成相应的语言授权文件,不能将真正的注册,贴出生成源码和签名工具,希望大牛们指点

Hmily 发表于 2010-1-10 23:57

再爆一个料,NN说过是这样的:

DOS头D0+C0 ^ AC = 2个文件的MD5 ^ AC
页: [1] 2 3 4 5
查看完整版本: [LCG原创] 也谈SkinSharp的破解