Inject Dll 过程
1.openprocess:打开对应进程,获得句柄
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | // Required by AlphaPROCESS_CREATE_THREAD | // For CreateRemoteThreadPROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeExPROCESS_VM_WRITE, // For WriteProcessMemoryFALSE, dwPid);
其中dwpid表示对应进程的pid值
2.创建内存空间
currentAddress = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024); //类似于自己管理堆栈分配。//GetProcessHeap():返回进程默认堆句柄if (NULL == currentAddress){nRet = Error_HeapAlloc;break;}
3.分配虚拟内存空间
targetWorkspace = VirtualAllocEx(hProcess, 0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //在进程的虚拟空间保留或提交内存区域,返回值为分配区域的地址//判断分配是否成功if (NULL == targetWorkspace){nRet = Error_VirtualAllocEx;break;}DWORD targetAddress = PtrToUlong(targetWorkspace); //PtrToUlong:指针转dword:unsigned long类型
4.准备机器代码,然后获取系统函数的地址,用来调用:
HMODULE kernel32 = LoadLibraryA("kernel32.dll");FARPROC loadlibrary = GetProcAddress(kernel32, bLoadDll ? "LoadLibraryA" : "GetModuleHandleA");//GetModuleHandle:获取一个应用程序或动态链接库的模块句柄。只有在当前进程的场景中,这个句柄才会有效。FARPROC getprocaddress = GetProcAddress(kernel32, "GetProcAddress"); //获得DLL的指定函数地址 FARPROC exitthread = GetProcAddress(kernel32, "ExitThread");FARPROC freelibraryandexitthread = GetProcAddress(kernel32, "FreeLibraryAndExitThread");
5.填充字符串,并且保存真正的代码开始位置:
// 索引DWORD currentIdx = 0;DWORD dwTmp = 0;// 4.2. 填充三个指针空间size_t sizePtr = sizeof(int*);const size_t addressCount = 3;for (size_t i = 0 ; i < addressCount * sizePtr; i++){currentAddress[i] = 0x00; //分配字节;(空字节)}currentIdx += addressCount * sizePtr; // 推进索引DWORD user32Addr = targetAddress + 0; // 存放User32.dll的模块地址DWORD msgboxAddr = targetAddress + 4; // 存放User32.dll中MessageBoxA的模块地址DWORD injectDllAddr = targetAddress + 8; // 存放待注入的dll的加载地址// 4.3. 填充字符串char user32Name[MAX_PATH + 1] = {0};char msgboxName[MAX_PATH + 1] = {0};char injectDllName[MAX_PATH + 1] = {0};char injectFuncName[MAX_PATH + 1] = {0};char injectParam[MAX_PATH*2 + 1] = {0};char injectErrorTitle[MAX_PATH + 1] = {0};char injectErrorMsg1[MAX_PATH + 1] = {0};char injectErrorMsg2[MAX_PATH + 1] = {0};_snprintf_s(injectDllName, MAX_PATH, MAX_PATH-1, "%s", dllname);//格式化字符串_snprintf_s(injectFuncName, MAX_PATH, MAX_PATH-1, "%s", funcname);_snprintf_s(injectParam, MAX_PATH*2, MAX_PATH*2-1, "%s", param);_snprintf_s(user32Name, MAX_PATH, MAX_PATH-1, "user32.dll");_snprintf_s(msgboxName, MAX_PATH, MAX_PATH-1, "MessageBoxA");_snprintf_s(injectErrorTitle, MAX_PATH, MAX_PATH-1, "Error");_snprintf_s(injectErrorMsg1, MAX_PATH, MAX_PATH-1, "Could not load the dll: %s", injectDllName);_snprintf_s(injectErrorMsg2, MAX_PATH, MAX_PATH-1, "Could not load the function: %s", injectFuncName);DWORD user32NameAddr = 0;DWORD msgboxNameAddr = 0;DWORD injectDllNameAddr = 0;DWORD injectFuncNameAddr = 0;DWORD injectParamAddr = 0;DWORD injectErrorTitleAddr = 0;DWORD injectErrorMsg1Addr = 0;DWORD injectErrorMsg2Addr = 0;FillInString(user32NameAddr, user32Name)FillInString(msgboxNameAddr, msgboxName)FillInString(injectDllNameAddr, injectDllName)FillInString(injectFuncNameAddr, injectFuncName)FillInString(injectParamAddr, injectParam)FillInString(injectErrorTitleAddr, injectErrorTitle)FillInString(injectErrorMsg1Addr, injectErrorMsg1)FillInString(injectErrorMsg2Addr, injectErrorMsg2)// 4.4. 填充一些int3来分隔字符串区和代码区const size_t int3_count = 3;for (size_t i = 0 ; i < int3_count; i++){currentAddress[currentIdx++] = 0xCC;}// 4.5 保存真正的代码开始位置DWORD targetExcuteCodeAddress = targetAddress + currentIdx;
6.修正代码区,并且提高权限,使得可以对内存区进行读写。
// 4.6. 修正代码区memcpy(injectCode_Head_NoSilent + 1, &user32NameAddr, 4);memcpy(injectCode_Head_NoSilent + 6, &loadlibrary, 4);memcpy(injectCode_Head_NoSilent + 13, &msgboxNameAddr, 4);memcpy(injectCode_Head_NoSilent + 19, &getprocaddress, 4);memcpy(injectCode_Head_NoSilent + 26, &msgboxAddr, 4);memcpy(injectCode_Head_NoSilent + 31, &injectDllNameAddr, 4);memcpy(injectCode_Head_NoSilent + 36, &loadlibrary, 4);memcpy(injectCode_Head_NoSilent + 50, &injectErrorTitleAddr, 4);memcpy(injectCode_Head_NoSilent + 55, &injectErrorMsg1Addr, 4);memcpy(injectCode_Head_NoSilent + 62, &msgboxAddr, 4);memcpy(injectCode_Head_NoSilent + 71, &exitthread, 4);memcpy(injectCode_Head_NoSilent + 78, &injectDllAddr, 4);memcpy(injectCode_Head_NoSilent + 83, &injectFuncNameAddr, 4);memcpy(injectCode_Head_NoSilent + 89, &getprocaddress, 4);memcpy(injectCode_Head_NoSilent + 103, &injectErrorTitleAddr, 4);memcpy(injectCode_Head_NoSilent + 108, &injectErrorMsg2Addr, 4);memcpy(injectCode_Head_NoSilent + 115, &msgboxAddr, 4);memcpy(injectCode_Head_NoSilent + 124, &exitthread, 4);memcpy(injectCode_Head_NoSilent + 129, &injectParamAddr, 4);memcpy(currentAddress + currentIdx, injectCode_Head_NoSilent ,sizeof(injectCode_Head_NoSilent));currentIdx += sizeof(injectCode_Head_NoSilent);if (bUnloadDll){memcpy(injectCode_Tail_FreeLibraryAndET + 4, &injectDllAddr, 4);memcpy(injectCode_Tail_FreeLibraryAndET + 9, &freelibraryandexitthread, 4);memcpy(currentAddress + currentIdx, injectCode_Tail_FreeLibraryAndET ,sizeof(injectCode_Tail_FreeLibraryAndET));currentIdx += sizeof(injectCode_Tail_FreeLibraryAndET);}else{memcpy(injectCode_Tail_ExitThread + 3, &exitthread, 4);memcpy(currentAddress + currentIdx, injectCode_Tail_ExitThread ,sizeof(injectCode_Tail_ExitThread));currentIdx += sizeof(injectCode_Tail_ExitThread);}// Step5. Change page protection so we can write executable codeDWORD oldProtect = 0; VirtualProtectEx(hProcess, targetWorkspace, currentIdx, PAGE_EXECUTE_READWRITE, &oldProtect);
写入进程内存,并且恢复属性,
// Step6. Write out the patchDWORD bytesRet = 0;if (!WriteProcessMemory(hProcess, targetWorkspace, currentAddress, currentIdx, &bytesRet)){nRet = Error_WriteProcessMemory;break;}// Step7. Restore page protectionVirtualProtectEx(hProcess, targetWorkspace, currentIdx, oldProtect, &oldProtect);// Step8. Make sure our changes are written right awayFlushInstructionCache(hProcess, targetWorkspace, currentIdx);// Step9. Execute the thread now and wait for it to exit, note we execute where the code starts, and not the codecave start// (since we wrote strings at the start of the codecave) -- NOTE: void* used for VC6 compatibility instead of UlongToPtrhThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)((void*)targetExcuteCodeAddress), 0, 0, NULL);if (NULL == hThread){nRet = Error_CreateRemoteThread;break;}WaitForSingleObject(hThread, INFINITE);
最后结束,关闭句柄等信息:
CloseHandle(hProcess);
CloseHandle(hThread);if (targetWorkspace){VirtualFreeEx(hProcess, targetWorkspace, 0, MEM_RELEASE);}// Free the currentAddress memoryif (currentAddress){HeapFree(GetProcessHeap(), 0, currentAddress);}
Inject Dll 过程相关推荐
- 【安全技术】关于几种dll注入方式的学习
何为dll注入 DLL注入技术,一般来讲是向一个正在运行的进程插入/注入代码的过程.我们注入的代码以动态链接库(DLL)的形式存在.DLL文件在运行时将按需加载(类似于UNIX系统中的共享库(shar ...
- Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术
catalogue 1. 引言 2. 使用注册表注入DLL 3. 使用Windows挂钩来注入DLL 4. 使用远程线程来注入DLL 5. 使用木马DLL来注入DLL 6. 把DLL作为调试器来注入 ...
- C++动态链接库dll及静态链接库lib制作及使用教程
现需将C++函数封装成动态链接库dll,网上看了好多博客教程,说的都不够全面,现提供一个很有用的视频,亲测有效,启发很大,附上链接: 视频网址 下面自己根据视频记录下制作动态链接库dll过程,防止忘记 ...
- 天马行空W:在C++中调用DLL中的函数
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...
- 用VC开发串口通信dll控件
VC串口通信技术网<VC串口上位机编程方法简介>介绍了串口编程的常见方法,其中就有使用串口dll控件的方法,dll是一种动态链接库,使用起来非常方便. 本文利用VC编程工具,对Window ...
- C#调用C++ DLL的方式
动态链接库(DLL)是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件.可以说在windows操作系统中随处可见,打开主分区盘下的system32.在一些项目中,如果有大量运算或者涉 ...
- 怎样在C++Builder中创建使用DLL
动态链接库(DLL)是Windows编程常遇到的编程方法,下面我就介绍一下在 BCB (C++Builder下简称BCB) 中如何创建使用DLL和一些技巧. 一.创建: 使用BCB File|NEW建 ...
- VS2013 C#中调用DLL
winform界面中,使用C#编程调用DLL过程记录: (1)什么是DLL 动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL 是一个包含可由多个程序同时使用的代码 ...
- 在C++中调用DLL中的函数
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...
最新文章
- 决策树--信息增益,信息增益比,Geni指数的理解
- 本地提交到yarn_Hadoop(四) Yarn
- C++ primer 14章习题答案
- linux提权辅助工具(二):linux-exploit-suggester-2.pl
- 1.视频压缩编码综述
- Linux Tun/Tap网口(/dev/net/tun)的读写方法
- x264编码参数大测试:05 subme与crf(g)
- Android Studio Gradle Plugin开发入门指南
- 学校计算机教室自查报告,学校专用教室自查报告范文
- python实例(二):判断输入的车牌归属地
- php丢色子,jQuery+PHP实现的掷色子抽奖游戏实例_PHP
- 【PC】TP-LINK WDN5200 AP模式无网络连接权限解决
- 2021科技圈十大事件盘点
- cad画固定长度的弧线_CAD中如何绘制指定弧长的圆弧
- latex插入pdf
- CSS - 让整个页面变成灰色(一行代码)
- 魔兽世界修改服务器配置文件,魔兽世界怀旧服出生参数修改和技能学习
- 变分原理(Variational Principle)
- 用jq做一个点击图片放大消失
- 简洁、快速、节约内存的Excel处理工具EasyExcel