manbug 发表于 2010-10-12 17:05

三谈SkinSharp的破解,附上VC内存皮肤源代码(不释放DLL)

本帖最后由 manbug 于 2010-10-14 08:22 编辑

看了 CjwNull 大的文章 和 Hmily 大的文章,深受启发,因为对皮肤很感兴趣,所以自己也试着破了一下,并试着做成内存加载DLL(免费版不支持静态编译),顺便也可以复习一下PE结构;
参考文章:
也谈SkinSharp的破解
SkinSharp CracKed By LCG

按照CjwNull 大的方法直接找到关键地点:

10021570    A1 98CA0210   mov   eax, dword ptr       ; 大小
10021575    8B0D 94CA0210   mov   ecx, dword ptr       ; 大小
1002157B    8B15 8CCA0210   mov   edx, dword ptr
10021581    57            push    edi
10021582    68 FF00FF00   push    0FF00FF
10021587    50            push    eax
10021588    51            push    ecx
10021589    6A 00         push    0
1002158B    6A 00         push    0
1002158D    52            push    edx
1002158E    8B96 B0010000   mov   edx, dword ptr
10021594    50            push    eax
10021595    8B86 B8010000   mov   eax, dword ptr
1002159B    51            push    ecx
1002159C    8D4410 F0       lea   eax, dword ptr
100215A0    99            cdq
100215A1    2BC2            sub   eax, edx
100215A3    D1F8            sar   eax, 1
100215A5    50            push    eax
100215A6    8B86 B4010000   mov   eax, dword ptr
100215AC    2BC1            sub   eax, ecx
100215AE    83E8 0C         sub   eax, 0C
100215B1    50            push    eax
100215B2    55            push    ebp
100215B3    E8 8898FEFF   call    1000AE40   ;这个call其实是关键了

CjwNull 大说只要将 100215B2 这处改成push eax或其它的就行了,我试了,的确可行(废话),但是CjwNull 大并未说为什么要改这处,于是自己调试了,载入作者提供的演示版程序在100215B3处下断,断下来后单步步入call,会看到:

1000AE40    8B4424 30       mov   eax, dword ptr
1000AE44    85C0            test    eax, eax
1000AE46    74 06         je      short 1000AE4E
1000AE48    C700 00000000   mov   dword ptr , 0
1000AE4E    53            push    ebx
1000AE4F    8B5C24 14       mov   ebx, dword ptr
1000AE53    56            push    esi
1000AE54    57            push    edi
1000AE55    85DB            test    ebx, ebx
1000AE57    0F8E FF000000   jle   1000AF5C
1000AE5D    8B5424 30       mov   edx, dword ptr
1000AE61    85D2            test    edx, edx
1000AE63    0F8E F3000000   jle   1000AF5C
1000AE69    8B7C24 20       mov   edi, dword ptr
1000AE6D    85FF            test    edi, edi
1000AE6F    0F8E E7000000   jle   1000AF5C
1000AE75    8B4424 34       mov   eax, dword ptr
1000AE79    85C0            test    eax, eax
1000AE7B    0F8E DB000000   jle   1000AF5C
1000AE81    8B4C24 24       mov   ecx, dword ptr
1000AE85    85C9            test    ecx, ecx
1000AE87    0F84 CF000000   je      1000AF5C
1000AE8D    3BDA            cmp   ebx, edx
1000AE8F    75 31         jnz   short 1000AEC2
1000AE91    3BF8            cmp   edi, eax
1000AE93    75 2D         jnz   short 1000AEC2
1000AE95    8B7424 38       mov   esi, dword ptr     ;上面有很多跳转
1000AE99    56            push    esi
1000AE9A    50            push    eax
1000AE9B    8B4424 34       mov   eax, dword ptr
1000AE9F    52            push    edx
1000AEA0    8B5424 34       mov   edx, dword ptr
1000AEA4    50            push    eax
1000AEA5    8B4424 28       mov   eax, dword ptr
1000AEA9    52            push    edx
1000AEAA    8B5424 24       mov   edx, dword ptr     ;我们改的参数给了edx
1000AEAE    51            push    ecx
1000AEAF    8B4C24 2C       mov   ecx, dword ptr
1000AEB3    57            push    edi
1000AEB4    53            push    ebx
1000AEB5    50            push    eax
1000AEB6    51            push    ecx
1000AEB7    52            push    edx
1000AEB8    FF15 34610210   call    near dword ptr       ; MSIMG32.TransparentBlt

一直单步到1000AEB8此处,我们会发现原来CjwNull 大让我们改的实际上是给TransparentBlt这个函数的第一个参数,我们看看这个函数的原型:

BOOL TransparentBlt(
HDC hdcDest,      // handle to destination DC
int nXOriginDest,   // x-coord of destination upper-left corner
int nYOriginDest,   // y-coord of destination upper-left corner
int nWidthDest,   // width of destination rectangle
int hHeightDest,    // height of destination rectangle
HDC hdcSrc,         // handle to source DC
int nXOriginSrc,    // x-coord of source upper-left corner
int nYOriginSrc,    // y-coord of source upper-left corner
int nWidthSrc,      // width of source rectangle
int nHeightSrc,   // height of source rectangle
UINT crTransparent// color to make transparent
);
原来是修改的目标HDC,让TransparentBlt 相当于执行失败,这就说明TransparentBlt 就是画的那个小衣服啰;为了验证想法的正确性,我将1000AE93处改成jmp试试,结果小衣服变成了如下图的样子:

说明这个就是画小衣服的地方了。
衣服虽然是去掉了,但多了一个灰块,那我们把这段nop掉(从1000AE95至1000AEB8)之后,界面会变成下面这样了:

说明还有其它程序调用这段call不能直接nop掉,再一次膜拜 CjwNull 大 的意识,在前一个call就把这个参数能干掉了。利害。
看来关键点还是在100215B3这之前的参数了,如果我们把这个call给nop掉试试(不用nop这个callr 压栈参数,因为下面有调整栈的代码);会发现程序给直接挂了,不知道原因,也没有仔细去找挂的原因(水平有限),看来还只是按照 CjwNull 大 的办法去改push的参数了, CjwNull 大说只用改两个push,但是我下的最新版的要改三个参数,如果按 CjwNull 大的只改两处的话,当设置玻璃效果时那个小衣服又会出现,不设置玻璃效果不会出现,这三处是:
1000F36F    52            push    edx
10005059    55            push    ebp
100215B2    55            push    ebp
将以上三处改成push eax 就可以了;

实际上还有一个更简单的办法,我们发现TransparentBlt,会提示要画的高度和宽度,我们只要把那个衣服的高度或宽度改成0则相当于没有画了,经过上面的分析,我们实际上已经知道了地址1002CA94和1002CA98存放的是衣服的高度和宽度了,我们只要将此处任意一个改为0就OK了。细心的朋友可以更进一步分析一下,在SkinH.dll未调用DLLMain之前这处地址是为0,调用了DllMain之后这个地址的值才会被初使化为0x10,那么就是说如果想用这种办法的话非要SkinH.dll调用DllMain之后才行,也就是说最简单的办法就是可以在自己的程序里面打补丁(和 CjwNull 大打补丁的方法类似,只不过只要补丁一处就可以了)。

总结:破解skinsharp的三种方法:
1.将以下三处改为push eax
1000F36F    52            push    edx
10005059    55            push    ebp
100215B2    55            push    ebp
可以带壳破解,这样比较完美,不用脱壳,具体就是在
1003A352- E9 E19CFEFF   jmp   10024038
这个地址处开始写补丁,然后 再跳转到入口点。

2.在自己程序里面打补丁,补丁掉1002CA94和1002CA98任意一处为0即可(注意有可能重定位)
3.按 CjwNull 大的方法在程序中补丁1中说明的三处

最后附上我自己写的一个类,可以将DLL文件放到资源中,从资源装载DLL的一个通过类,类封装得不好,望大家批评指正:
具体为:
声明一个全局变量
CDllFromMem abc;
然后从资源中装载DLL;相当于LoadLibrary()函数
abc.LoadLibraryFromRs(hInstance,"DLL",MAKEINTRESOURCE(IDR_DLL2));
最后得到所需函数和入口点,
typedef int (WINAPI *SkinHAttach)();
SkinHAttach SkinH_Attach;
SkinH_Attach=(SkinHAttach)abc.GetProcAddressFromRs("SkinH_attach"); //相当于GetProcAddress()函数了
最后就是调用啦,呵呵;
(*SkinH_Attach)();

我在类里面加了个PatchData();补丁函数,用来打补丁的,如果不用打补丁可以把这个函数删了,呵呵!就这些了!



示例程序是用向导生成的hello word程序,然后自己把动态链接库加入到了资源中
附件:

ly2008v 发表于 2010-10-12 20:32

有点意思 谢谢哦

VIPLZM 发表于 2010-10-12 22:33

精华帖!顶一个!做板凳咯

O_o 发表于 2010-10-13 11:11

回复 1# manbug


    我编译有错误呢。
你传一个示范的VC工程上来可以吗?

876571657 发表于 2010-10-13 12:18

前排留名
在仔细阅读~

wan 发表于 2010-10-13 12:47

v好文,有时间也弄一个来玩玩

manbug 发表于 2010-10-13 19:17

回复manbug


    我编译有错误呢。
你传一个示范的VC工程上来可以吗?
O_o 发表于 2010-10-13 11:11 http://bbs.52pojie.cn/images/common/back.gif


明天到公司后我把示例附上来!

O_o 发表于 2010-10-13 19:24

回复 7# manbug


   非常感谢。

52tc007 发表于 2010-10-13 19:32

精品教程啊`谢谢了哈!

Vicious 发表于 2010-10-13 19:34

非常强大!!
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 三谈SkinSharp的破解,附上VC内存皮肤源代码(不释放DLL)