WIN32练习项目(函数调用监视器)
一、简介
这是滴水三期WIN32最后一个项目,进程通信用的是共享内存的方式。
通过内存注入方式向目标进程victim注入DLL,监视程序可以通过IAT HOOK监视目标进程调用MessageBoxA,CreateFileA,通过inline HOOK监视victim自己实现的Add函数。另外,监视程序还可以远程调用这三个函数。
二、运行结果
注入
监控MessageBoxA
项目和可执行文件可以到我的github下载
https://github.com/Kwansy98/WIN32hanshudiaoyongjianshiqi
三、目标程序Victim.exe
victim是要注入的程序,界面如下图:
这个程序可以创建对话框,调用CreateFileA获取文件句柄并打印文件大小,可以做加法运算。没什么特别的,你可以自己写一个。
四、控制程序HackVictim.exe
这个程序的界面如下图:
为了方便调试,我创建该项目时用的是控制台项目的模板,在main函数里画界面。这样可以方便的printf。
该程序的功能是将DLL用内存注入的方式注入到指定进程,注入成功后可以监视目标程序的函数调用,前两个函数是IAT表里有的,第三个函数是目标程序自己实现的加法函数。
点击“开始监控”后,在目标程序victim调用函数后,会有控制台输出。也可以点击“远程调用”来远程调用指定函数。
IAT HOOK和Inline HOOK经测试可以正常卸载。
讲一下控制程序的注意点(坑点和难点)
内存注入这块,我是从文件系统中读取dll,然后拉伸,然后修复IAT,然后修复重定位,然后用VirtualAllocEx 和WriteProcessMemory完成注入的。需要注意一点就是IAT表里面只有kernel32.dll和user32.dll的函数是正确的(比如LoadLibrary,MessageBox),因为这两个dll不管在哪个进程里位置都固定,其他dll里的函数的地址全是错的。
注入之后要计算入口点地址,创建远程线程时传的地址是远程进程中的入口函数,这个值得计算方法是: 入口点到DLL基址的偏移 + 远程DLL基址。
五、DLL
这部分是核心,是本项目最难的环节。DLL被控制程序注入到目标程序后,很多函数都要自己手动获取函数地址(通过LoadLibrary+GetProcAddress)。
typedef int (*PFNSPRINTF)( char *, const char *,...);
typedef void* (*PFNMALLOC)(size_t);
typedef void (*PFNFREE)(void*);
typedef void* (*PFNMEMSET)(void*,int,size_t);
typedef void* (*PFNMEMCPY)(void*,void*,size_t);
typedef size_t (*PFNSTRLEN)(const char *);
......
PFNSPRINTF _sprintf;
PFNMALLOC _malloc;
PFNFREE _free;
PFNMEMSET _memset;
PFNMEMCPY _memcpy;
PFNSTRLEN _strlen;
......
// 手动加载要用到的函数
HMODULE hModule = LoadLibraryA("MSVCRT.dll");
_sprintf = (PFNSPRINTF)GetProcAddress(hModule, "sprintf");
_malloc = (PFNMALLOC)GetProcAddress(hModule, "malloc");
_free = (PFNFREE)GetProcAddress(hModule, "free");
_memset = (PFNMEMSET)GetProcAddress(hModule, "memset");
_memcpy = (PFNMEMCPY)GetProcAddress(hModule, "memcpy");
_strlen = (PFNSTRLEN)GetProcAddress(hModule, "strlen");
为了方便调试,我给DLL申请了个控制台,自己封装了一个输出函数,当然,肯定没有printf好用了。
// 申请控制台
AllocConsole();
g_hStdout = CreateFileA("CONOUT$",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
//SetStdHandle(STD_OUTPUT_HANDLE,hStdout);
Log("申请控制台成功\n");
......
void Log(LPCSTR text)
{WriteFile(g_hStdout,text,_strlen(text),0,0);
}
有一个坑点需要注意,我们写自己修改的MessageBoxA,CreateFileA函数时,记得要写上调用约定WINAPI,不写的话程序会崩溃。
// 被监控的MessageBox
int WINAPI MyMessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{typedef int (WINAPI *PFNMESSAGEBOX)(HWND,LPCTSTR,LPCTSTR,UINT); PFNMESSAGEBOX pFnMessageBox = (PFNMESSAGEBOX)GetProcAddress(LoadLibraryA("user32.dll"), "MessageBoxA");char szOutput[1000] = {0};_sprintf(szOutput,"MessageBoxA(%X, %s, %s, %X)\n", hWnd, lpText, lpCaption, uType);Log(szOutput);return pFnMessageBox(hWnd,lpText,lpCaption,uType);
}
inline hook部分,我们写自定义Add函数时,要注意堆栈平衡,切记不要在裸函数里定义局部变量,除非你自己提升了堆栈,否则会把上层函数的数据覆盖掉的。我这里用最简单的做法,就是使用全局变量。
// 被监控的Add
void __declspec(naked)MyAdd()
{ // 获取关心的寄存器状态__asm{mov g_context.Esp,espmov g_context.Eax,eaxmov g_context.Ecx,ecxmov g_context.Edx,edxmov g_context.Ebx,ebx} // 保存8个常用寄存器和标志寄存器__asm{pushadpushfd}// 我的代码,注意堆栈平衡 __asm{ mov eax,g_context.Espmov ecx,[eax+0x4]mov g_num1,ecxmov eax,g_context.Espmov ecx,[eax+0x8]mov g_num2,ecx}_sprintf(g_szLogBuffer, "Add(%d, %d)\n", g_num1,g_num2);Log(g_szLogBuffer);// 恢复寄存器,执行被替换的代码,然后返回// 004011D0 55 push ebp// 004011D1 8B EC mov ebp,esp// 004011D3 83 EC 40 sub esp,40h__asm{popfdpopadpush ebpmov ebp,espsub esp,40hjmp g_ret}
}
六、总结
这个项目我写了4、5天,基本上都是用的前面的知识,确实有点难度,但总体上还是顺利做出来了,卡得最久的还是进程通信那块。
WIN32练习项目(函数调用监视器)相关推荐
- Jawin –Java/Win32互动项目 可调用DLL及COM的调用项目
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Jawi ...
- VS2005不能新建Win32 智能设备项目的解决办法(转)
Visual Studio 2005和Windows Mobile 5.0 Smartphone SDK并都已安装,并重启,但是无法创建Visual C++ -->智能设备 -->Win3 ...
- Win32汇编项目总结——猎杀潜航
必须得承认,这个项目的名字<猎杀潜航>起得大了点,一开始设想的挺好的,想用刚学到的win32汇编做点有意义的项目,都说名字是成功的一半,所以想了老半天,看了很多小游戏,觉得这种" ...
- win32小项目之截图软件
截图思路: ①先获取整个桌面的图像 创建桌面环境句柄,memDc句柄 ,画布(HBITMAP bmp) 将画布放入memDc ,将获取的桌面图像放入memDc ②设置一个任意的矩形剪切框 ...
- Win32 C++项目移植到 Win10 UWP
本文可能对谁有帮助 如果你正在做将现有的Win32 静态库 或 DLL 工程移植到Win10 UWP(通用 Windows) 环境,这篇文章可能会对你有帮助. 概述 在VS2015的 新建项目 -&g ...
- 摘录cocos2d-x 从环境搭建到win32项目移植android平台
软件:cocos2d-x-2.2.3:android-ndk-r9d:adt-bundle-windows-x86_64-20131030:python-2.7.6: 1安装配置python 安装没什 ...
- win32项目和win32控制台程序的区别
回答1: 1.win32应用程序是指窗口类的,像QQ之类的,有图形化界面,而控制台是指运行在黑框下的,像cmd之类的: 2.win32控制台项目指在32位Windows命令提示符(即所谓的dos)环境 ...
- Hey,别搞错了Win32项目和Win32控制台程序
你是否和我一样呢,写了很多控制台程序,特别熟悉cout.main函数等等. 但是你同样也听说过win32 api !!当在你的控制台应用程序中写下某个api函数的时候,你也许会窃喜api函数带来的方便 ...
- win32 DLL 学习总结
DLL的开发与调用(一)--创建导出函数的Win32 DLL http://www.cnblogs.com/Pickuper/articles/2053745.html Visual C++6.0 中 ...
最新文章
- 加密软件究竟有哪些作用呢?
- 大唐联仪推出下一代移动通信测试解决方案
- MobileNetV2-YoloV3
- 大势至电脑文件防泄密软件_有了数据防泄密软件,还会担心企业文件泄漏吗?...
- WebApi中跨域解决办法
- 跟我学 Java 8 新特性之 Stream 流(三)缩减操作
- [C++]variadic function template expansion 变元函数参数的展开规则
- HandlerThread原理和实际应用
- 有趣的算法(四)最通俗易懂的KMP算法解析
- ajax交互的两种方式:html与xml
- mini2440裸机之Touchpanel
- WIN7下弹出应用程序兼容性助手解决
- leetcode感想
- linux下挂载硬盘!
- HD Tune结合硬盘再生器HDDREG快速修复硬盘错误
- 【CODEVS 3287】【NOIP2013】火车运输
- Linux的发音问题
- AL 人工智能学习书籍 视频 课程
- opencv计算机视觉_opencv是计算机视觉的至尊工具
- C# Console Application 带参数调试
热门文章
- AI:2020年6月21日北京智源大会演讲分享之09:40Judea教授《 The New Science of Cause and Effect with reflections ondata s》
- DL之CNN:卷积神经网络算法简介之原理简介——CNN网络的3D可视化(LeNet-5为例可视化)
- Dataset之Handwritten Digits:Handwritten Digits(手写数字图片识别)数据集简介、安装、使用方法之详细攻略
- Matlab:绘制简单能量的接收机工作特性曲线(Energy_detection_simulation_ok)
- Matlab:单幅图象的暗原色先验去雾改进算法,能够很好地改进天空或明亮部分色彩失真问题
- PyTorch:采用sklearn 工具生成这样的合成数据集+利用PyTorch实现简单合成数据集上的线性回归进行数据分析
- uc/os-ii中最高优先级计算(如何查表)
- 野路子码农系列(3)plotly可视化的简单套路
- Talend open studio数据导入、导出、同步Mysql、oracle、sqlserver简单案例
- C#+uploadify3.1上传示例,可使用中文按钮