给Source Insight做个外挂系列之三--构建外挂软件的定制代码框架
上一篇文章介绍了“TabSiPlus”是如何进行代码注入的,本篇将介绍如何构建一个外挂软件最重要的部分,也就是为其扩展功能的定制代码。本文前面提到过,由于windows进程管理的限制,扩展代码必须以动态链接库的形式挂载到被挂程序的进程空间中,使用上一篇介绍的方法已经可以通过创建远程线程的方式启动一个线程,让这个线程加载我们的定制动态链接库,现在就看看这个动态链接库是如何实现的。
首先这是一个动态链接库,因为考虑到扩展功能中有大量的界面操作,所以选择支持MFC,同时,还要提供一个名为“InitFunc”的导出函数,供在被挂程序中启动的远程线程调用,以初始化外挂动态链接库,这个导出函数的原型是这样的:
typedef DWORD (WINAPI *PFN)();
没有参数,但是有一个返回值用于表示初始化是否成功。现在就用Visual C++的向导生成一个支持MFC的动态链接库的框架,并手工添加一个名为“InitFunc”的导出函数,如果你还不清楚怎么做,那么可以停止看本文了,因为本文可能对你毫无用处。
在生成的代码中,MFC对DllMain进行了封装,所以有了一个CxxxApp的类,xxx与你的动态链接库的名字一致,TabSiPlus使用的是CTabSiPlusApp,现在有三个地方需要特别注意,一个是CTabSiPlusApp::InitInstance(),一个是CTabSiPlusApp::ExitInstance(),另一个就是我们的导出函数“InitFunc”。当远程线程中LoadLibrary()调用我们的定制动态链接库时,CTabSiPlusApp::InitInstance()被调用,当FreeLibrary()调用发生时,CTabSiPlusApp::ExitInstance()被调用,当然,伴随而出现的还有两个函数调用,那就是CTabSiPlusApp类的构造函数和析构函数,部分初始化代码也可以放在构造函数中完成,不过并不推荐这样做,因为如果因为构造函数触发异常导致LoadLibrary()失败,那么随后的析构函数也不会被调用,因为构造函数没有完成对象的构造,同时,由于LoadLibrary()失败,使得FreeLibrary()调用分支没有执行,那么导致CTabSiPlusApp::ExitInstance()也没有被调用,这会引起资源释放的异常。
很显然,CTabSiPlusApp::InitInstance()的调用发生在InitFunc函数的调用之前,所以要控制好初始化代码之前的先后关系。CTabSiPlusApp::InitInstance()中布置对资源初始化的代码,而诸如创建文件标签栏窗口,Hook “Source Insight”窗口消息,管理这些消息的代码则可以布置到InitFunc函数中实现。这里需要注意的是由于我们的外挂代码是以动态链接库的形式挂载到“Source Insight”进程中的,所以它没有消息循环,所有的窗口UI系统无法正常工作,解决的办法有两个,一个是在InitFunc函数创建窗口之后人为地添加一个消息循环,关于这一点如何实现可以参考Windows SDK编程的方法;另一个方法就是不要把主要的工作放在InitFunc,而是在InitFunc函数中再创建一个本地线程,把窗口UI这些麻烦的东西放在这个线程中处理,这样就可以利用这个线程的消息循环使窗口UI系统工作起来,这样做还有一个好处,就是InitFunc函数可以立即返回,加载外挂的宿主程序也可以及时得到外挂的加载情况,以便根据情况安排下一次加载动作(就是调用CreateRemoteThread()),同时还可以及时释放在被挂程序中分配的内存。TabSiPlus就是采用的第二种方法,下面就是TabSiPlus的InitFunc函数实现,当然省去了一些代码,主要核心就是一行:
DWORD WINAPI InitFunc()
{
//其它初始化操作
g_pTabWndUIThread = (CTabWndUIThread *)AfxBeginThread(RUNTIME_CLASS(CTabWndUIThread),THREAD_PRIORITY_NORMAL,0,0,NULL);
//其它操作
return (g_pTabWndUIThread != NULL);
}
在CTabWndUIThread类的InitInstance()函数中创建标签栏窗口,hook “Source Insight”中相关窗口的消息:
BOOL CTabWndUIThread::InitInstance()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
g_pSiFrameWnd = new CSIFrameWnd(); //CWnd::FromHandle(hDevStudioWnd);
g_pSiFrameWnd->Attach(hWndSIFrame); //hook SI主窗口
HWND hMDIWnd = g_pSiFrameWnd->GetMDIClientWnd();
//UINT uThressID = GetCurrentThreadId();
// create the tabs window
m_pTabbarWnd = new CTabBarsWnd();
m_pTabbarWnd->Create(CWnd::FromHandle(g_pSiFrameWnd->GetSafeHwnd()),
RBS_BANDBORDERS | RBS_AUTOSIZE | RBS_FIXEDORDER | RBS_DBLCLKTOGGLE,
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CBRS_TOP | CBRS_SIZE_FIXED, AFX_IDW_REBAR );
m_pMainWnd = m_pTabbarWnd;//这很重要,否则这个线程就无法退出
g_pSiFrameWnd->SetTabbarWnd(m_pTabbarWnd->GetSafeHwnd());
g_MdiChildMng.SetTabbarWnd(m_pTabbarWnd->GetSafeHwnd());
m_pTabbarWnd->SetWindowPos(CWnd::FromHandle(hMDIWnd)->GetWindow(GW_HWNDPREV), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
g_pSiMDIClientWnd = new CSiMDIWnd();
g_pSiMDIClientWnd->SetTabbarWnd(m_pTabbarWnd->GetSafeHwnd());
DebugTracing(gnDbgLevelNormalDebug,_T("MDI Client Attach..."));
g_pSiMDIClientWnd->Attach(hMDIWnd);
DebugTracing(gnDbgLevelNormalDebug,_T("MDI Client Enum..."));
g_pSiMDIClientWnd->EnumMdiChildWnd(g_MdiChildMng,TRUE);
DebugTracing(gnDbgLevelNormalDebug,_T("MDI Client Enum end (%d)"),g_MdiChildMng.GetChildCount());
pGlobalActiveSIWindow = g_MdiChildMng.LookupMdiChild(g_pSiMDIClientWnd->MDIGetActive(NULL));
g_pSiMDIClientWnd->SetManaging(true);
return TRUE;
}
是不是很象标准单文档结构的MFC程序中的CxxxApp::InitInstance()函数?特别是对m_pMainWnd的赋值?对m_pMainWnd赋值其实很重要,否则线程就会直接退出,对m_pMainWnd赋值还有一个好处,就是关闭m_pTabbarWnd窗口就会中止CTabWndUIThread线程,这和标准单文档结构的MFC程序中的结果一样。
CTabWndUIThread::InitInstance()函数中有很多是对“Source Insight”内部窗口进行hook的代码,那么TabSiPlus是如何得到这些窗口的句柄呢,又是如何关联它们之间的消息呢,请看下篇:给Source Insight做个外挂系列之四--分析“Source Insight”
Source Insignt文件标签外挂:TabSiPlus的下载地址:
http://blog.csdn.net/orbit/
给Source Insight做个外挂系列之三--构建外挂软件的定制代码框架的更多相关文章
- 给Source Insight做个外挂系列之一--发现Source Insight
一提到外挂程序,大家肯定都不陌生,QQ就有很多个版本的去广告外挂,很多游戏也有用于扩展功能或者作弊的工具,其中很多也是以外挂的形式提供的.外挂和插件的区别在于插件通常依赖于程序的支持,如果程序不支持插 ...
- 给Source Insight做个外挂系列之六--“TabSiPlus”的其它问题
关于如何做一个Source Insight外挂插件的全过程都已经写完了,这么一点东西拖了一年的时间才写完,足以说明我是一个很懒的人,如果不是很多朋友的关心和督促,恐怕是难以完成了.许多朋友希望顺着本文 ...
- 给Source Insight做个外挂系列之二--将本地代码注入到Source Insight进程
上一篇文章介绍了如何发现正在运行的“Source Insight”窗口,本篇将介绍“TabSiPlus”是如何进行代码注入的.Windows 9x以后的Windows操作系统都对进程空间进行了严格的保 ...
- 给Source Insight做个外挂系列之五--Insight “TabSiPlus”
“TabSiPlus 外挂插件”主要有两部分组成,分别是“外挂插件加载器”和“插件动态库”.“插件动态库”完成Source Insight窗口的Hook,显示Tab标签栏,截获Source Insig ...
- 给Source Insight做个外挂系列之四--分析“Source Insight”
外挂的目的就是将代码注入到其它进程中,所以必须要有目标进程才能完成注入,而所谓的目标进程通常是某软件的一部分或者是全部,所以要对目标程序有深入地了解.一般外挂都是针对某个应用程序开发的,其装载.运行都 ...
- 【转】破解Source Insight 3.5.0072过程 附:安装软件+注册机
转载地址:http://blog.csdn.net/qs_hud/article/details/8884867 注册机及软件下载地址:http://download.csdn.net/detail/ ...
- Source Insight 3.X 标签插件v1.0发布
Source Insight可以说是一款程序员必备的开发/阅读源码工具,美中不足的是SI没有标签栏,多个源码之间切换很不方便,于是我就乘闲暇之余写了该作品sihook:标签插件;不过严格意义上来说si ...
- Source Insight 插件
一提到外挂程序,大家肯定都不陌生,QQ就有很多个版本的去广告外挂,很多游戏也有用于扩展功能或者作弊的工具,其中很多也是以外挂的形式提供的.外挂和插件的区别在于插件通常依赖于程序的支持,如果程序不支持插 ...
- Source Insight 4.0安装使用教程
一.说明 Source Insight是什么:Source Insight是一款代码编缉.浏览.分析工具. Source Insight与文本编缉器有什么区别:Notepad++等文本编缉器也可以编缉 ...
随机推荐
- poj 1270(toposort)
http://poj.org/problem?id=1270 题意:给一个字符串,然后再给你一些规则,要你把所有的情况都按照字典序进行输出. 思路:很明显这肯定要用到拓扑排序,当然看到discuss里 ...
- MySQL 编译安装并且开启DEBUG模式
因为想分析下mysql中一些操作的内部执行过程,单纯的看源码太枯燥了,所以决定结合mysql的执行过程来分析,mysql作为一款成熟的数据库软件,在设计的时候就考虑到了调试的问题,只是想开启调试模式的 ...
- Hotaru's problem(hdu 5371)
题意:给出一个数字串,询问最长的子串,满足以下要求:将子串平均分为三部分,一三部分相等,一二部分对衬. /* 在manachar的基础上,枚举回文串的中心,再找第三部分. */ #include< ...
- SQL入门语句之LIKE、GLOB和LIMIT
一.SQL入门语句之LIKE LIKE用来匹配通配符指定模式的文本值.如果搜索表达式与模式表达式匹配,LIKE 运算符将返回真(true),也就是 1.这里有两个通配符与 LIKE 运算符一起使用,百 ...
- mysql知识
1.Limit 在语句的最后,起到限制条目的作用 Limit [offset,] [N] offset:偏移量 N:取出条目 例子:select * from stu limit 3,3; 2.左连接 ...
- Jmeter连接Mysql
1.下载连接mysql数据库jar包,地址:http://files.cnblogs.com/files/xiaoxitest/mysql-connector-java-5.1.28.zip(因不支持 ...
- 9.JAVA中的正则表达式
一.JAVA中的正则表达式 1.概念:以某种特定的方式描述字符串 1.Java中正则表达式的规则 ? #{0,1}-?有一个-或者没有 \\ #表示一个" ...
- oracle的回收站介绍
昨天做的展示oracle表空间功能剩余空间的功能,发现查询表dba_free_space时特别慢,经网上搜索,说是由于表空间碎片和回收站(Oracle 10g以后才有)引起的,后来搜到一片介绍回收站的 ...
- 《DSP using MATLAB》示例Example5.12
代码: n = 0:10; x = 10*(0.8) .^ n; y = cirshftt(x,6,15); n = 0:14; x = [x, zeros(1,4)]; %% ----------- ...
- BZOJ 2115 [Wc2011] Xor ——线性基
[题目分析] 显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可. 但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有 ...