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 过程相关推荐

  1. 【安全技术】关于几种dll注入方式的学习

    何为dll注入 DLL注入技术,一般来讲是向一个正在运行的进程插入/注入代码的过程.我们注入的代码以动态链接库(DLL)的形式存在.DLL文件在运行时将按需加载(类似于UNIX系统中的共享库(shar ...

  2. Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术

    catalogue 1. 引言 2. 使用注册表注入DLL 3. 使用Windows挂钩来注入DLL 4. 使用远程线程来注入DLL 5. 使用木马DLL来注入DLL 6. 把DLL作为调试器来注入 ...

  3. C++动态链接库dll及静态链接库lib制作及使用教程

    现需将C++函数封装成动态链接库dll,网上看了好多博客教程,说的都不够全面,现提供一个很有用的视频,亲测有效,启发很大,附上链接: 视频网址 下面自己根据视频记录下制作动态链接库dll过程,防止忘记 ...

  4. 天马行空W:在C++中调用DLL中的函数

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  5. 用VC开发串口通信dll控件

    VC串口通信技术网<VC串口上位机编程方法简介>介绍了串口编程的常见方法,其中就有使用串口dll控件的方法,dll是一种动态链接库,使用起来非常方便. 本文利用VC编程工具,对Window ...

  6. C#调用C++ DLL的方式

    动态链接库(DLL)是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件.可以说在windows操作系统中随处可见,打开主分区盘下的system32.在一些项目中,如果有大量运算或者涉 ...

  7. 怎样在C++Builder中创建使用DLL

    动态链接库(DLL)是Windows编程常遇到的编程方法,下面我就介绍一下在 BCB (C++Builder下简称BCB) 中如何创建使用DLL和一些技巧. 一.创建: 使用BCB File|NEW建 ...

  8. VS2013 C#中调用DLL

    winform界面中,使用C#编程调用DLL过程记录: (1)什么是DLL 动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL 是一个包含可由多个程序同时使用的代码 ...

  9. 在C++中调用DLL中的函数

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

最新文章

  1. 决策树--信息增益,信息增益比,Geni指数的理解
  2. 本地提交到yarn_Hadoop(四) Yarn
  3. C++ primer 14章习题答案
  4. linux提权辅助工具(二):linux-exploit-suggester-2.pl
  5. 1.视频压缩编码综述
  6. Linux Tun/Tap网口(/dev/net/tun)的读写方法
  7. x264编码参数大测试:05 subme与crf(g)
  8. Android Studio Gradle Plugin开发入门指南
  9. 学校计算机教室自查报告,学校专用教室自查报告范文
  10. python实例(二):判断输入的车牌归属地
  11. php丢色子,jQuery+PHP实现的掷色子抽奖游戏实例_PHP
  12. 【PC】TP-LINK WDN5200 AP模式无网络连接权限解决
  13. 2021科技圈十大事件盘点
  14. cad画固定长度的弧线_CAD中如何绘制指定弧长的圆弧
  15. latex插入pdf
  16. CSS - 让整个页面变成灰色(一行代码)
  17. 魔兽世界修改服务器配置文件,魔兽世界怀旧服出生参数修改和技能学习
  18. 变分原理(Variational Principle)
  19. 用jq做一个点击图片放大消失
  20. 简洁、快速、节约内存的Excel处理工具EasyExcel

热门文章

  1. 从源码角度解析ArrayList.subList的几个坑
  2. Spring整合Quartz定时任务 在集群、分布式系统中的应用
  3. Acwing 734. 能量石
  4. vue中的 $children 和 $parent
  5. javascript this的意思
  6. 用Convert类实现数据类型转换
  7. ZOJ 1234 UVA 10271 Chopsticks
  8. .NET 中使用 SQlite 数据库_1.新数据库的创建
  9. Delphi – 我的代码之简单五子棋
  10. 案例:监听域对象的生命周期