首页
社区
课程
招聘
[旧帖] [原创]Detour补丁实现加载任意SkinSharp皮肤文件(有码) 0.00雪花
发表于: 2012-6-14 16:03 2301

[旧帖] [原创]Detour补丁实现加载任意SkinSharp皮肤文件(有码) 0.00雪花

2012-6-14 16:03
2301
标 题: 【原创】Detour补丁实现加载任意SkinSharp皮肤文件(有码)
作 者: NoGood
时 间: 2012-06-14,16:05:11
链 接: http://bbs.pediy.com/showthread.php?p=1080040#post1080040

开篇:
      古老的技术,大牛绕道吧。如果版主觉得对初学者有帮助就给个那啥吧。挂机好无聊的。

      最近买了本看雪的《加密与解密第三版》,看到PE文件那章时,自己用VS2010仿写了书上的PEInfo程序。不过最后完工时发现界面不美观。

      于是,便给程序价格皮肤,用的是Skin++,可不知怎么的,就是编译不过,以前用VS2008没出现过,心想可能它不支持VS2010吧。于是乎,在网上搜有关的皮肤文件,忽然看到一篇博文(VC皮肤库SkinSharp 1.0.6.6的使用):
        VC皮肤库SkinSharp 1.0.6.6的使用
        按照上面方法一时果然成功。
        不过,我发现它只能加载本目录下的skinh.she皮肤文件,如果想加载其他皮肤文件,必须把文件名改成skinh.she才行。Oh My god,不能加载任意皮肤,让我感觉很是不爽。于是便有了下文:

分析篇:
        根据那篇博文的描述可知:
        1.SkinH_Attach() 加载本目录下的skinh.she皮肤文件
        2. 如果第1条成立,那么它肯定在代码中用到了skinh.she文件名作为参数,再如果它
           没有对字符串加密的话,我们可以很轻松地替换这个字符串为我们自己指定的皮肤文
          件名,实现加载任意皮肤文件的目的。

嗯,说干就干,咱们现在就开始分析这个SkinH_Attach函数。那怎么找到这个函数呢?
我用的方法是:
      1.在调用SkinH_Attach前,先调用MessageBox函数,里面指定特殊的字符串
      2.我们在OD中查找此字符串,这样可以找到MessageBox的函数调用处。进而在它   
        (MessageBox)下面的函数调用就是SkinH_Attach了。这样我们就可以分析它了。

      以下是我在MFC的OnInitDialog函数中的代码:
	MessageBox( "Test" );	//在OD中查找Test,来到MessageBox函数调用处,
	SkinH_Attach();		//进而来到SkinH_Attach函数调用处。


1.OD中查找Test:


2.对找到的Test字符串双击或回车:


3.此时我们便来到函数调用处:


4.我们对此行(SkinH_Attach的调用处)单击并按回车


5. 来到如下代码处:咦,怎么不是函数体而是一个跳转?我们对这个跳转按回车跟进去


6.来到了真正的函数体部分:哇!代码好多啊,不必惊慌,这些都不是我们要分析的,我们主要看能不能找含有字符串“skinh.she”的部分。


7.滚动鼠标的滑轮或下拉右侧的滚动条,并注意观察OD反汇编窗口中的注释部分,走着走着,果然不出我们所料,就在100195DC这行我们找到了字符串“skinh.she”。
它应该是个相对路径并且是UNICODE字符串,因为有个'\',而且还调用了wcscat进行串联。

继续分析,我们看到这句PUSH SkinHu.1002A644(机器码为:68 44A60210)压入的是绝对地址,也就说这个字符串它在全局数据段,它是个全局变量或静态变量。

总结:

1.函数的开头是一个固定的jmp指令(因为用的是偏移地址,而不是绝对地址,如果是绝对地址,可能要重定位,改变指令机器码),由它跳转到真正的函数体部分,我们可以将此指令作为特征码,对函数进行匹配并获取真正的函数体部分。

2.函数体中字符串“skinh.she”是个存放在全局数据段UNICODE字符串,而且它是个相对路径,也就是说我们要替换的话一定要注意这一点。

补丁篇:
有了上面的成果后,我们就可以编程实现Detour补丁了。
      具体步骤如下:
        1.获取SkinH_Attach函数入口地址,对它的第一条指令进行解析(字节码匹配和获取真正的函数体)
        2.在真正的函数体中,定位含有字符串“skinh.she”的代码,并替换里面的路径名为
          我们自己的皮肤文件路径名。

以下是我实现的代码:
BOOL DetourPatchSkinName( WCHAR szPath[] )
{
	#define ADDR_SIZE	4		//地址长度,32位为4字节
	#define PAGE_SIZE	0x2000	//按页搜索
	byte JumpCode[] = { 0xE9, 0xEB, 0x58, 0xFF, 0xFF };	//第一处特征码
	byte PushCode[] = { 0x68, 0x44, 0xA6, 0x02, 0x10 };	//第二处特征码

	LPBYTE	skinFunc;	//待解析的函数(也就是SkinH_Attach)
	DWORD	codeSize;	//第一处特征码长度
	DWORD	pathAddr;	//新路径名的地址
	int		destAddr;	//跳转到真函数体的偏移
	DWORD	i;			//扫描特征码时要用的索引
	static	WCHAR	SkinPath[MAX_PATH] = {0};	//皮肤文件路径名,要注意放在数据段,因为SkinH_Attach函数用的是绝对地址

	//Step 1.Copy path of skin into static buffer.
	memcpy( SkinPath, szPath, wcslen( szPath ) * sizeof(WCHAR) );
	
	//Step 2.Check first feature code.
	skinFunc = (LPBYTE)SkinH_Attach;
	codeSize = sizeof( JumpCode );
	i = 0;	//从偏移0开始匹配
	while ( codeSize-- ){
		if ( skinFunc[i] != JumpCode[i] ){
			MessageBox( NULL, "特征码不匹配!", "Hint", MB_OK );
			break;
		}
		i++;
	}

	//Step 3.Check second feature code.
	memcpy( &destAddr, (skinFunc+1), ADDR_SIZE ); //得到偏移
	skinFunc += destAddr;	//移动到真正的函数体部分
	i = 0;	//从偏移0开始匹配
	while ( TRUE ){
		if ( skinFunc[i+0] == 0x68 &&	
			 skinFunc[i+1] == 0x44 &&
			 skinFunc[i+2] == 0xA6 &&
			 skinFunc[i+3] == 0x02 &&
			 skinFunc[i+4] == 0x10 )
		{
			//MessageBox( NULL, "Found it!", "Hint", MB_OK );
			break;
		}else if ( i >= PAGE_SIZE ){	//按页搜索
			//MessageBox( NULL, "Don't Found it!", "Hint", MB_OK );
			return FALSE;	//找不到,走人
		}
		i++;
	}

	//Step 4.Detour patch.
	pathAddr = (DWORD)SkinPath;	//新皮肤路径地址
	memcpy( &skinFunc[i+1], &pathAddr, ADDR_SIZE ); //替换旧的

	return TRUE;
}


OnInitDialog函数体进行调用:


如果必要请改下SkinH_Attach函数所在section的属性为可写。
最后附上源码和皮肤文件:
      源码和皮肤文件

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 44
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
算我眼拙。
工程为多字节时:
#include "SkinH.h"

#pragma comment(lib, "skinH.lib")  

...
SkinH_AttachEx( ".\\深藏青.she", NULL );
2012-6-14 17:36
0
雪    币: 44
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不过,用我的方法,在界面上没有那个小衣服。
上传的附件:
  • 9.jpg (81.14kb,35次下载)
2012-6-14 17:44
0
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
哈哈,楼主真可爱。。。
我看了一楼,刚想和你说有个SkinH_AttachEx(函数,结果再看二楼你自己已经发现了。。。
2012-12-15 09:15
0
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
[QUOTE=NoGood;1080059]不过,用我的方法,在界面上没有那个小衣服。
[/QUOTE]

不过你这个方法可以去掉小衣服logo真好,我正在搞这个控件的破解呢,就看到这个帖子了,谢谢
2012-12-15 09:17
0
游客
登录 | 注册 方可回帖
返回
//