R3修改线程上下文EIP实现的无模块注入

R3修改线程上下文EIP实现的无模块注入

http://blog.csdn.net/zfdyq0/article/details/40890521


[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  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位置。

运行结果:



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值