吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 38508|回复: 101
收起左侧

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

  [复制链接]
manbug 发表于 2010-10-12 17:05
本帖最后由 manbug 于 2010-10-14 08:22 编辑

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

按照CjwNull 大的方法直接找到关键地点:
10021570    A1 98CA0210     mov     eax, dword ptr [1002CA98]        ; 大小
10021575    8B0D 94CA0210   mov     ecx, dword ptr [1002CA94]        ; 大小
1002157B    8B15 8CCA0210   mov     edx, dword ptr [1002CA8C]
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 [esi+1B0]
10021594    50              push    eax
10021595    8B86 B8010000   mov     eax, dword ptr [esi+1B8]
1002159B    51              push    ecx
1002159C    8D4410 F0       lea     eax, dword ptr [eax+edx-10]
100215A0    99              cdq
100215A1    2BC2            sub     eax, edx
100215A3    D1F8            sar     eax, 1
100215A5    50              push    eax
100215A6    8B86 B4010000   mov     eax, dword ptr [esi+1B4]
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 [esp+30]
1000AE44    85C0            test    eax, eax
1000AE46    74 06           je      short 1000AE4E
1000AE48    C700 00000000   mov     dword ptr [eax], 0
1000AE4E    53              push    ebx
1000AE4F    8B5C24 14       mov     ebx, dword ptr [esp+14]
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 [esp+30]
1000AE61    85D2            test    edx, edx
1000AE63    0F8E F3000000   jle     1000AF5C
1000AE69    8B7C24 20       mov     edi, dword ptr [esp+20]
1000AE6D    85FF            test    edi, edi
1000AE6F    0F8E E7000000   jle     1000AF5C
1000AE75    8B4424 34       mov     eax, dword ptr [esp+34]
1000AE79    85C0            test    eax, eax
1000AE7B    0F8E DB000000   jle     1000AF5C
1000AE81    8B4C24 24       mov     ecx, dword ptr [esp+24]
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 [esp+38]    ;上面有很多跳转
1000AE99    56              push    esi
1000AE9A    50              push    eax
1000AE9B    8B4424 34       mov     eax, dword ptr [esp+34]
1000AE9F    52              push    edx
1000AEA0    8B5424 34       mov     edx, dword ptr [esp+34]
1000AEA4    50              push    eax
1000AEA5    8B4424 28       mov     eax, dword ptr [esp+28]
1000AEA9    52              push    edx
1000AEAA    8B5424 24       mov     edx, dword ptr [esp+24]    ;我们改的参数给了edx
1000AEAE    51              push    ecx
1000AEAF    8B4C24 2C       mov     ecx, dword ptr [esp+2C]
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 [10026134]        ; 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试试,结果小衣服变成了如下图的样子:
QQ截图未命名.jpg
说明这个就是画小衣服的地方了。
衣服虽然是去掉了,但多了一个灰块,那我们把这段nop掉(从1000AE95至1000AEB8)之后,界面会变成下面这样了:
未命名.jpg
说明还有其它程序调用这段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();补丁函数,用来打补丁的,如果不用打补丁可以把这个函数删了,呵呵!就这些了!

DllFromMem.rar (2.78 KB, 下载次数: 280)

示例程序是用向导生成的hello word程序,然后自己把动态链接库加入到了资源中
附件: SkinSharpTest.rar (168.93 KB, 下载次数: 478)

免费评分

参与人数 3热心值 +3 收起 理由
vigers + 1 用心讨论,共获提升!
xiaobai + 1 恶意灌水,不解释
O_o + 1 恶意灌水,不解释。

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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



  明天到公司后我把示例附上来!
O_o 发表于 2010-10-13 19:24
回复 7# manbug


     非常感谢。
52tc007 发表于 2010-10-13 19:32
精品教程啊`谢谢了哈!
Vicious 发表于 2010-10-13 19:34
非常强大!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-18 02:39

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表