当前位置:   article > 正文

R3修改线程上下文EIP实现的无模块注入_无痕注入c++源码

无痕注入c++源码
  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <iostream>
  4. using std::cin;
  5. DWORD dwOldEip = 0;
  6. DWORD funRemote = 0;
  7. BYTE shellCode[25] = {
  8. 0x68, 0x78, 0x56, 0x34, 0x12, //push 12345678h
  9. 0x9C, //pushfd
  10. 0x60, //pushad
  11. 0x6A, 0x00, //push 0
  12. 0x6A, 0x00, //push 0
  13. 0x6A, 0x00, //push 0
  14. 0x6A, 0x00, //push 0
  15. 0xB8, 0x78, 0x56, 0x34, 0x12, //mov eax, 12345678h
  16. 0xFF, 0xD0, //call eax
  17. 0x61, //popad
  18. 0x9D, //popfd
  19. 0xC3, //ret
  20. };
  21. BOOL ThreadContextTest(DWORD dwProcessId, DWORD dwMemSize)
  22. {
  23. HWND hwnd = FindWindow(NULL, L"Dependency Walker");
  24. if (!hwnd)
  25. return FALSE;
  26. printf("hwnd:%p\n", hwnd);
  27. // 打开进程
  28. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
  29. if (!hProcess)
  30. return FALSE;
  31. // 获取主线程ID
  32. DWORD dwThreadId = GetWindowThreadProcessId(hwnd, NULL);
  33. printf("dwThreadId:%d\n", dwThreadId);
  34. HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadId);
  35. // 暂停主线程
  36. DWORD dwSuspendCount = SuspendThread(hThread);
  37. printf("暂停线程,任意键恢复线程,dwSuspendCount:%d\n", dwSuspendCount);
  38. CONTEXT stcContext = { CONTEXT_FULL };
  39. if (!GetThreadContext(hThread, &stcContext))
  40. return FALSE;
  41. HMODULE hModule = LoadLibrary(L"User32.dll");
  42. funRemote = (DWORD)GetProcAddress(hModule, "MessageBoxA");
  43. // 获取原始EIP
  44. dwOldEip = stcContext.Eip;
  45. printf("stcContext.Eip:%p\n", stcContext.Eip);
  46. // 申请内存
  47. LPVOID lpAddr = VirtualAllocEx(hProcess, NULL, dwMemSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  48. if (!lpAddr)
  49. return FALSE;
  50. printf("lpAddr:%p\n", lpAddr);
  51. // 构造shellCode
  52. memcpy(&shellCode[16], &funRemote, 4);
  53. memcpy(&shellCode[1], &dwOldEip, 4);
  54. // 写入内存
  55. BOOL bRet = WriteProcessMemory(hProcess, lpAddr, shellCode, dwMemSize, NULL);
  56. if (!bRet)
  57. return FALSE;
  58. // 设置EIP
  59. stcContext.Eip = (DWORD)lpAddr;
  60. SetThreadContext(hThread, &stcContext);
  61. //system("pause");
  62. DWORD dwResumeCount = ResumeThread(hThread);
  63. printf("恢复线程,dwResumeCount:%d\n", dwResumeCount);
  64. return TRUE;
  65. }
  66. int _tmain(int argc, _TCHAR* argv[])
  67. {
  68. DWORD dwLen = sizeof(shellCode);
  69. DWORD dwProcessId = 0;
  70. cin >> dwProcessId;
  71. ThreadContextTest(dwProcessId, dwLen);
  72. system("pause");
  73. return 0;
  74. }

我把执行的代码写成了ShellCode,就是弹一个 MessageBox,但是前面一句和最后一句是重点,第一句是把当前EIP 压栈,最后的RET就是

返回到正确EIP  这个是必须有的,在这里RET指令的内部操作是:栈顶字单元出栈,其值赋给IP寄存器。即实现了一个程序的转移,将栈顶字单元保存

的偏移地址作为下一条指令的偏移地址。

        当然也可以把你自己的执行代码写成函数,遇到的问题就是计算函数的大小,一般方法就是搜索特征码Ret(高老湿说滴),然后特征码地址减

去,函数地址,就是大小~~

由于EIP必须在运行的时候才能得到,所以我把获得的EIP直接MEMCOPY到相应shellCode位置。

运行结果:


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/204202
推荐阅读
相关标签
  

闽ICP备14008679号