分享

Win7下dll远程注入

 梦醉千秋 2012-12-13

Win7 CreateRemoteThread 另类使用方法

分类: C、VC/MFC 3136人阅读 评论(14) 收藏 举报

同样的代码,在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 >

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多