[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呢~ Good,从限制入手很爽啊,学习!我是从他取完校验数据入手的,本来我是写了个正确的数据进去,让他怎么都是校验成正版,据海风说算法有漏洞,数据为0也可以通过验证,所以我改成直接取到的数据清0,也通过了他的校验.patch的地方就在它取了2个文件的MD5以后,进入VM开始的地方patch掉数据就可以了.加精鼓励! :hug:膜拜牛淫.~牛X 都是大牛 都有各自的见解啊 我还不懂哦 来学习一下 学习了,加油 强悍啊!!!
学习了 Good,从限制入手很爽啊,学习!我是从他取完校验数据入手的,本来我是写了个正确的数据进去,让他怎么都是校验成 ...
Hmily 发表于 2010-1-10 20:02 http://www.52pojie.cn/images/common/back.gif
我还没想那么多呢。。海风好牛逼啊,Hmily也很变态! LS的果然是高手,膜拜 历害,我分析授权文件,写出来生成授权的工具,没有分析出的核心算法,只能根据机器码和语言生成相应的语言授权文件,不能将真正的注册,贴出生成源码和签名工具,希望大牛们指点 再爆一个料,NN说过是这样的:
DOS头D0+C0 ^ AC = 2个文件的MD5 ^ AC