171028 逆向-以CM41为例进行Dll注入(上)
来源:互联网 发布:毕向东java视频百度云 编辑:程序博客网 时间:2024/06/06 13:12
1625-5 王子昂 总结《2017年10月28日》 【连续第393天总结】
A. CrackMe41–dll注入
B.
dll注入的原理是利用一个进程控制被注入进程执行LoadLibrary函数,将外部dll注入其内存中。注入以后由于共享内存空间,因此dll也就拥有了操作该进程内存的权限了。
当Dll被注入时会运行DllMain函数,这就是Dll的主函数。
由于之前没有写过Dll注入,因此这次准备先执行一个MessageBox作为Hook成功标志,明天再将前一次得到的成功经验照样通过dll注入来实现。
首先,Dll注入分为3个阶段:
1.外部函数控制被注入程序执行LoadLibrary函数加载外部Dll
2.Dll注入,执行DllMain函数
3.Hook住被注入程序的函数,当条件满足时触发Hook函数
依次完成,首先是外部函数:
#include <iostream>#include <windows.h>#include <tchar.h>using namespace std;BOOL InjectDll(int dwPID, LPCTSTR szDllPath){ HANDLE hProcess = NULL, hThread = NULL; HMODULE hMod = NULL; LPVOID pRemoteBuf = NULL; DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR); LPTHREAD_START_ROUTINE pThreadProc; // 获取目标进程句柄 if(!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) { cout<<dwPID<<endl; cout<<"failed!!!\n"; return FALSE; } // 在目标进程内存中分配szDllName大小的内存 pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); // 将myhack.dll路径写入分配的内存 WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL); // 获取LoadLibraryA地址 hMod = GetModuleHandle("kernel32.dll"); pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA"); // 运行线程 hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL); //等待该线程执行完毕 WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE;}int main(int argc, TCHAR *argv[]){ if(InjectDll(atoi(argv[1]), "F:\\C\\cm41_hoook\\bin\\Debug\\cm41_hoook.dll")) cout<<"Success "<<argv[2]<<endl; else cout<<"Failed"<<endl; return 0;}
参照书上代码,main函数接收被注入程序的PID,从而执行InjectDll函数
InjectDll函数通过PID获取该进程的句柄,然后将参数(外部Dll的路径)和函数(Kernel32.dll中的LoadLibrary函数)准备好,通过CreateRemoteThread函数来控制被注入进程开启一个新线程加载dll
注意这里LoadLibrary函数取的地址事实上是注入函数的,但由于dll共享内存,因此地址可以通用
注意LoadLibrary函数的W和A,刚开始在这里犯错了OTZ
W表示宽字符,A表示ASCII,默认字符串是ASCII的,因此使用A
PID通过任务管理器可以查看到
第二步编写DllMain函数:
BOOL NewMenu(){ return (MessageBoxA(NULL, "Hook success", "Second", MB_OKCANCEL));}extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ MessageBoxA(NULL, "Dll inject success", "First", MB_OK); switch (fdwReason) { case DLL_PROCESS_ATTACH: // attach to process // return FALSE to fail DLL load hook_by_code((PROC)NewMenu); break; } return TRUE; // succesful}
hook_by_code就是修改代码来hook的函数,NewMenu是hook目标函数
hook_by_code取得目标函数的地址作为参数,来修改代码:
BOOL hook_by_code(PROC pfnNew){ HANDLE hProcess; DWORD* pfnOrg; //push的机器码 byte pBuf[6] = {0x68}; DWORD oldProtect; //Hook地址 pfnOrg = (DWORD*)0x430535; //将hook目标函数的地址送入缓冲区中 memcpy(&pBuf[1], &pfnNew, 4); //ret的机器码 pBuf[5] = 0xc3; //修改内存属性为可写 VirtualProtect((LPVOID)pfnOrg, 10, PAGE_EXECUTE_READWRITE, &oldProtect); //将缓冲区写入被注入程序的内存 memcpy(pfnOrg, pBuf, 6); return TRUE;}
目前需要程序运行的内容为(汇编):
push 0xaaaaaaaa ;目标函数地址ret ;call 目标函数地址
刚开始执行的时候花式报错,原来是data节区没有可写属性,因此需要用VirtualProtect函数开启该权限
hook的地址还是老地方:
这样注入以后,就能实现弹窗了
查到PID以后通过命令行执行程序:
看到弹出注入成功的弹窗,说明DllMain已经开始执行,Dll成功加载入该程序中
点击二级菜单后弹出Hook成功的弹窗,说明代码成功被Hook
虽然点完确定以后就会出现内存错误的警报,但这是预料之中的—因为我们只设置了Hook,没有令它返回嘛
明天来完善Hook程序,以及正常返回~
C. 明日计划
dll注入(下)
- 171028 逆向-以CM41为例进行Dll注入(上)
- 171029 逆向-以CM41为例进行Dll注入(中)
- 171031 逆向-以CM41为例进行Dll注入(下)
- 171016 逆向-DLL注入基础知识
- DCNN-tensorflow(深度卷积) 以MNIST集合上进行分类为例
- 171114 逆向-以CM为例学习MFC机制
- pandas和数据库进行交互(以mysql为例)
- 以杯子为例进行测试设计
- pycharm上安装库(以pandas为例)
- 远程线程注入技术(3)之DLL以数据形式注入
- 以mysql为例介绍PreparedStatement防止sql注入原理
- swig--在java、C#中调用c++写的DLL(以vs2012配置为例)
- swig--在java、C#中调用c++写的DLL(以vs2012配置为例)
- 配置st_geometry.dll(以ArcGIS10.5.1+Oracle12c R1为例)
- 如何在sourceforge上找到开源项目并在centos进行安装-以htop的安装为例
- 171024 逆向-以Xp0int的so fun为例利用Zjdroid安卓脱壳
- 史上最强在Myeclipse上安装插件的方法(以 aptana为例)
- 进行DLL注入的三种方法
- PyQt5学习教程12:数学表达式解析程序
- Ubuntu16.04LTS上安装Python3.6.3
- MAC显示隐藏文件
- ajax接收后台的text、HTML、xml、json数据,及其文件数据
- linux下的初始状态下,根目录各个文件夹的作用与说明
- 171028 逆向-以CM41为例进行Dll注入(上)
- linux redhat安装git
- Salesforce修改相关列表标签名
- 基于树莓派使用DuerOS的笔记,待续
- 关于java中的static关键词
- 没事不要用 rxjava 的create 操作符
- dijkstra板子
- 机器学习信仰之朴素贝叶斯法
- 好好活