Win7 CreateRemoteThread 另类使用方法

同样的代码,在XP下面随便你怎么整,WIN7的话是相当纠结的,具体哪些错误就不解释了 ~~

 

gg点了二十多页,在韩国某大牛的博客上总算找到一点思路(虽然看不懂韩文,但代码还算勉强看得懂吧)

 

原来是要用动态调用ntdll.dll >> NtCreateRemoteThreadEx ,于是over~~

 

说明:

1、InjectDll.exe   是注入DLL的EXE

2、dummy.dll       是一个普通DLL,加载后弹出MessageBox

 

下面是一个XP中远程线程注入DLL的代码,在WIN7 + OD调试的例子:

 

 

看看错误信息:

 

 

杯具了,接着看! 重新运行OD调试,bp CreateRemoteThread :

 

 

看看CreateRemoteThread 中的几个参数:

 

 

上图重要标记的几个参数:

(1) svchost.exe (PID: 3184) 句柄

(2) kernel32.dll ! LoadLibarayA

(3) 在svchost中为C://Work//dummy.dll字符串所分配的首地址

 

进入CreateRemoteThread :

 

 

我们发现,实际上是调用kernelbase >> CreateRemoteThreadEx 函数。

 

(GG了这个DLL,原来是它是继VISTA/WIN7之后额外的DLL,负责协助Kernel32.dll的调用!)

 

那我们看看这个函数调用栈中的参数吧:

 

 

 

发现与kernel32.dll >> CreateRemoteThread 参数一模一样!

 

OK ! 我们再继续跟进kernelbase.dll >> CreateRemoteThreadEx :

 

 

那我们看看这个函数调用栈中的参数吧:

 

 

OK,这算到底儿了,因为ntdll.dll >> ZwCreateThreadEx 已经运行到了内核代码,我们的OD没办法再调试了!

 

于是请google sysenter吧!

 

特别说明,kernelbase.dll >> CreateRemoteThreadEx 是对 ntdll.dll >> ZwCreateThreadEx 的补充扩展!

 

那我们都得到这样的结果 :

 

 

ntdll.dll >> ZwCreateThreadEx 是未公开的API,MSDN、GG也很难找到相关资料!

 

下面是看看这个结构体伪代码:

 

  1. typedef DWORD (WINAPI *PFNTCREATETHREADEX)  
  2. (   
  3.     PHANDLE                 ThreadHandle,     
  4.     ACCESS_MASK             DesiredAccess,    
  5.     LPVOID                  ObjectAttributes,     
  6.     HANDLE                  ProcessHandle,    
  7.     LPTHREAD_START_ROUTINE  lpStartAddress,   
  8.     LPVOID                  lpParameter,      
  9.     BOOL                    CreateSuspended,      
  10.     DWORD                   dwStackSize,      
  11.     DWORD                   dw1,   
  12.     DWORD                   dw2,   
  13.     LPVOID                  Unknown   
  14. );   

 

OK ,那剩下的我们只需要重写CreateThreadEx 函数即可!

 

为了保证XP的兼容,所以需要判断一下OS版本,下面是完整的测试代码:

 

  1. #include "windows.h"  
  2. #include "stdio.h"  
  3. #include "tchar.h"  
  4. #pragma comment(lib,"Advapi32.lib")  
  5. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)   
  6. {  
  7.     TOKEN_PRIVILEGES tp;  
  8.     HANDLE hToken;  
  9.     LUID luid;  
  10.     if( !OpenProcessToken(GetCurrentProcess(),  
  11.                           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,   
  12.                           &hToken) )  
  13.     {  
  14.         _tprintf("OpenProcessToken error: %u/n", GetLastError());  
  15.         return FALSE;  
  16.     }  
  17.     if( !LookupPrivilegeValue(NULL,  
  18.                               lpszPrivilege,  
  19.                               &luid) )  
  20.     {  
  21.         _tprintf("LookupPrivilegeValue error: %u/n", GetLastError() );   
  22.         return FALSE;   
  23.     }  
  24.     tp.PrivilegeCount = 1;  
  25.     tp.Privileges[0].Luid = luid;  
  26.     if( bEnablePrivilege )  
  27.         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
  28.     else  
  29.         tp.Privileges[0].Attributes = 0;  
  30.     if( !AdjustTokenPrivileges(hToken,   
  31.                                FALSE,   
  32.                                &tp,   
  33.                                sizeof(TOKEN_PRIVILEGES),   
  34.                                (PTOKEN_PRIVILEGES) NULL,   
  35.                                (PDWORD) NULL) )  
  36.     {   
  37.         _tprintf("AdjustTokenPrivileges error: %u/n", GetLastError() );   
  38.         return FALSE;   
  39.     }   
  40.     if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )  
  41.     {  
  42.         _tprintf("The token does not have the specified privilege. /n");  
  43.         return FALSE;  
  44.     }   
  45.     return TRUE;  
  46. }  
  47. typedef DWORD (WINAPI *PFNTCREATETHREADEX)  
  48. (   
  49.     PHANDLE                 ThreadHandle,     
  50.     ACCESS_MASK             DesiredAccess,    
  51.     LPVOID                  ObjectAttributes,     
  52.     HANDLE                  ProcessHandle,    
  53.     LPTHREAD_START_ROUTINE  lpStartAddress,   
  54.     LPVOID                  lpParameter,      
  55.     BOOL                    CreateSuspended,      
  56.     DWORD                   dwStackSize,      
  57.     DWORD                   dw1,   
  58.     DWORD                   dw2,   
  59.     LPVOID                  Unknown   
  60. );   
  61. BOOL IsVistaOrLater()  
  62. {  
  63.     OSVERSIONINFO osvi;  
  64.     ZeroMemory(&osvi, sizeof(OSVERSIONINFO));  
  65.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  
  66.     GetVersionEx(&osvi);  
  67.     if( osvi.dwMajorVersion >= 6 )  
  68.         return TRUE;  
  69.     return FALSE;  
  70. }  
  71. BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)  
  72. {  
  73.     HANDLE      hThread = NULL;  
  74.     FARPROC     pFunc = NULL;  
  75.     if( IsVistaOrLater() )    // Vista, 7, Server2008  
  76.     {  
  77.         pFunc = GetProcAddress(GetModuleHandle("ntdll.dl"), "NtCreateThreadEx");  
  78.         if( pFunc == NULL )  
  79.         {  
  80.             printf("MyCreateRemoteThread() : GetProcAddress(/"NtCreateThreadEx/") 调用失败!错误代码: [%d]/n",  
  81.                    GetLastError());  
  82.             return FALSE;  
  83.         }  
  84.         ((PFNTCREATETHREADEX)pFunc)(&hThread,  
  85.                                     0x1FFFFF,  
  86.                                     NULL,  
  87.                                     hProcess,  
  88.                                     pThreadProc,  
  89.                                     pRemoteBuf,  
  90.                                     FALSE,  
  91.                                     NULL,  
  92.                                     NULL,  
  93.                                     NULL,  
  94.                                     NULL);  
  95.         if( hThread == NULL )  
  96.         {  
  97.             printf("MyCreateRemoteThread() : NtCreateThreadEx() 调用失败!错误代码: [%d]/n", GetLastError());  
  98.             return FALSE;  
  99.         }  
  100.     }  
  101.     else                    // 2000, XP, Server2003  
  102.     {  
  103.         hThread = CreateRemoteThread(hProcess,   
  104.                                      NULL,   
  105.                                      0,   
  106.                                      pThreadProc,   
  107.                                      pRemoteBuf,   
  108.                                      0,   
  109.                                      NULL);  
  110.         if( hThread == NULL )  
  111.         {  
  112.             printf("MyCreateRemoteThread() : CreateRemoteThread() 调用失败!错误代码: [%d]/n", GetLastError());  
  113.             return FALSE;  
  114.         }  
  115.     }  
  116.     if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )  
  117.     {  
  118.         printf("MyCreateRemoteThread() : WaitForSingleObject() 调用失败!错误代码: [%d]/n", GetLastError());  
  119.         return FALSE;  
  120.     }  
  121.     return TRUE;  
  122. }  
  123. BOOL InjectDll(DWORD dwPID, char *szDllName)  
  124. {  
  125.     HANDLE hProcess = NULL;  
  126.     LPVOID pRemoteBuf = NULL;  
  127.     FARPROC pThreadProc = NULL;  
  128.     DWORD dwBufSize = strlen(szDllName)+1;  
  129.     if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )  
  130.     {  
  131.         printf("[错误] OpenProcess(%d) 调用失败!错误代码: [%d]/n",   
  132.         dwPID, GetLastError());  
  133.         return FALSE;  
  134.     }  
  135.     pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,   
  136.                                 MEM_COMMIT, PAGE_READWRITE);  
  137.     WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName,   
  138.                        dwBufSize, NULL);  
  139.     pThreadProc = GetProcAddress(GetModuleHandle("kernel32.dl"),   
  140.                                  "LoadLibraryA");  
  141.     if( !MyCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf) )  
  142.     {  
  143.         printf("[错误] CreateRemoteThread() 调用失败!错误代码: [%d]/n", GetLastError());  
  144.         return FALSE;  
  145.     }  
  146.     VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);  
  147.     CloseHandle(hProcess);  
  148.     return TRUE;  
  149. }  
  150. int main(int argc, char *argv[])  
  151. {  
  152.     SetPrivilege(SE_DEBUG_NAME, TRUE);  
  153.     // InjectDll.exe <PID> <dllpath>  
  154.     if( argc != 3 )  
  155.     {  
  156.         printf("用法 : %s <进程PID> <dll路径>/n", argv[0]);  
  157.         return 1;  
  158.     }  
  159.     if( !InjectDll((DWORD)atoi(argv[1]), argv[2]) )  
  160.     {  
  161.         printf("InjectDll调用失败!/n");  
  162.         return 1;  
  163.     }  
  164.     printf("InjectDll调用成功!/n");  
  165.     return 0;  
  166. }  

 

DLL就不贴了吧,有兴趣的友友可以参考一下~~

 

<转载请注明出处:   http://blog.csdn.net/wangningyu/archive/2011/05/31/6456607.aspx >

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值