代码注入是一种向目标进程插入独立运行代码并使之运行的技术,它一般调用CreateRemoteThread()API以远程线程形式运行插入的代码,所以也被称为线程注入。

和DLL注入相比代码注入占用内存少并难以查找痕迹。所以DLL注入技术主要用在代码量大且复杂的时候,而代码注入技术则适用于代码量小且简单的情况比如shellcode。下面我们先测试一下代码。
运行notepad.exe并查看PID。

在命令行窗口中输入命令与参数。

notepad.exe弹出一个消息框,如图所示。

我们来分析一下源代码,看看是怎么实现的。
首先看一下main函数。main函数用来调用InjectCode()函数,传入的函数参数为目标进程的PID。

[cpp] view plaincopy
  1. int main(int argc, char *argv[])
  2. {
  3. DWORD dwPID     = 0;
  4. if( argc != 2 )
  5. {
  6. printf("\n USAGE  : %s <pid>\n", argv[0]);
  7. return 1;
  8. }
  9. // change privilege
  10. if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
  11. return 1;
  12. // code injection
  13. dwPID = (DWORD)atol(argv[1]);
  14. InjectCode(dwPID);
  15. return 0;
  16. }

分析InjectCode()函数之前,先看一下要注入的目标进程的代码。函数中并未直接调用相关API,也未直接定义使用字符串,它们都通过THREAD_PARAM结构体以线程参数的形式传递调用。

[cpp] view plaincopy
  1. typedef struct _THREAD_PARAM
  2. {
  3. FARPROC pFunc[2];               // LoadLibraryA(), GetProcAddress()
  4. char    szBuf[4][128];          // "user32.dll", "MessageBoxA", "www.reversecore.com", "ReverseCore"
  5. } THREAD_PARAM, *PTHREAD_PARAM;
  6. typedef HMODULE (WINAPI *PFLOADLIBRARYA)
  7. (
  8. LPCSTR lpLibFileName
  9. );
  10. typedef FARPROC (WINAPI *PFGETPROCADDRESS)
  11. (
  12. HMODULE hModule,
  13. LPCSTR lpProcName
  14. );
  15. typedef int (WINAPI *PFMESSAGEBOXA)
  16. (
  17. HWND hWnd,
  18. LPCSTR lpText,
  19. LPCSTR lpCaption,
  20. UINT uType
  21. );
  22. DWORD WINAPI ThreadProc(LPVOID lParam)
  23. {
  24. PTHREAD_PARAM   pParam      = (PTHREAD_PARAM)lParam;
  25. HMODULE         hMod        = NULL;
  26. FARPROC         pFunc       = NULL;
  27. // LoadLibrary()
  28. hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);    // "user32.dll"
  29. if( !hMod )
  30. return 1;
  31. // GetProcAddress()
  32. pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]);  // "MessageBoxA"
  33. if( !pFunc )
  34. return 1;
  35. // MessageBoxA()
  36. ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
  37. return 0;
  38. }

InjectCode()是代码注入技术的核心部分。两次调用VirtualAllocEx和WriteProcessMemory,第一次调用分配内存空间并写入远程线程的数据,第二次调用分配内存空间并写入远程线程的代码。这是代码注入的一个非常重要的特征。

[cpp] view plaincopy
  1. BOOL InjectCode(DWORD dwPID)
  2. {
  3. HMODULE         hMod            = NULL;
  4. THREAD_PARAM    param           = {0,};
  5. HANDLE          hProcess        = NULL;
  6. HANDLE          hThread         = NULL;
  7. LPVOID          pRemoteBuf[2]   = {0,};
  8. DWORD           dwSize          = 0;
  9. hMod = GetModuleHandleA("kernel32.dll");
  10. // set THREAD_PARAM
  11. param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
  12. param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
  13. strcpy_s(param.szBuf[0], "user32.dll");
  14. strcpy_s(param.szBuf[1], "MessageBoxA");
  15. strcpy_s(param.szBuf[2], "www.reversecore.com");
  16. strcpy_s(param.szBuf[3], "ReverseCore");
  17. // Open Process
  18. if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS,   // dwDesiredAccess
  19. FALSE,                // bInheritHandle
  20. dwPID)) )             // dwProcessId
  21. {
  22. printf("OpenProcess() fail : err_code = %d\n", GetLastError());
  23. return FALSE;
  24. }
  25. // Allocation for THREAD_PARAM
  26. dwSize = sizeof(THREAD_PARAM);
  27. if( !(pRemoteBuf[0] = VirtualAllocEx(hProcess,          // hProcess
  28. NULL,                 // lpAddress
  29. dwSize,               // dwSize
  30. MEM_COMMIT,           // flAllocationType
  31. PAGE_READWRITE)) )    // flProtect
  32. {
  33. printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
  34. return FALSE;
  35. }
  36. if( !WriteProcessMemory(hProcess,                       // hProcess
  37. pRemoteBuf[0],                  // lpBaseAddress
  38. (LPVOID)¶m,                 // lpBuffer
  39. dwSize,                         // nSize
  40. NULL) )                         // [out] lpNumberOfBytesWritten
  41. {
  42. printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
  43. return FALSE;
  44. }
  45. // Allocation for ThreadProc()
  46. dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
  47. if( !(pRemoteBuf[1] = VirtualAllocEx(hProcess,          // hProcess
  48. NULL,                 // lpAddress
  49. dwSize,               // dwSize
  50. MEM_COMMIT,           // flAllocationType
  51. PAGE_EXECUTE_READWRITE)) )    // flProtect
  52. {
  53. printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
  54. return FALSE;
  55. }
  56. if( !WriteProcessMemory(hProcess,                       // hProcess
  57. pRemoteBuf[1],                  // lpBaseAddress
  58. (LPVOID)ThreadProc,             // lpBuffer
  59. dwSize,                         // nSize
  60. NULL) )                         // [out] lpNumberOfBytesWritten
  61. {
  62. printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
  63. return FALSE;
  64. }
  65. if( !(hThread = CreateRemoteThread(hProcess,            // hProcess
  66. NULL,                // lpThreadAttributes
  67. 0,                   // dwStackSize
  68. (LPTHREAD_START_ROUTINE)pRemoteBuf[1],     // dwStackSize
  69. pRemoteBuf[0],       // lpParameter
  70. 0,                   // dwCreationFlags
  71. NULL)) )             // lpThreadId
  72. {
  73. printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
  74. return FALSE;
  75. }
  76. WaitForSingleObject(hThread, INFINITE);
  77. CloseHandle(hThread);
  78. CloseHandle(hProcess);
  79. return TRUE;
  80. }

完整的代码如下。

[cpp] view plaincopy
  1. // CodeInjection.cpp
  2. // reversecore@gmail.com
  3. // http://www.reversecore.com
  4. #include "windows.h"
  5. #include "stdio.h"
  6. typedef struct _THREAD_PARAM
  7. {
  8. FARPROC pFunc[2];               // LoadLibraryA(), GetProcAddress()
  9. char    szBuf[4][128];          // "user32.dll", "MessageBoxA", "www.reversecore.com", "ReverseCore"
  10. } THREAD_PARAM, *PTHREAD_PARAM;
  11. typedef HMODULE (WINAPI *PFLOADLIBRARYA)
  12. (
  13. LPCSTR lpLibFileName
  14. );
  15. typedef FARPROC (WINAPI *PFGETPROCADDRESS)
  16. (
  17. HMODULE hModule,
  18. LPCSTR lpProcName
  19. );
  20. typedef int (WINAPI *PFMESSAGEBOXA)
  21. (
  22. HWND hWnd,
  23. LPCSTR lpText,
  24. LPCSTR lpCaption,
  25. UINT uType
  26. );
  27. DWORD WINAPI ThreadProc(LPVOID lParam)
  28. {
  29. PTHREAD_PARAM   pParam      = (PTHREAD_PARAM)lParam;
  30. HMODULE         hMod        = NULL;
  31. FARPROC         pFunc       = NULL;
  32. // LoadLibrary()
  33. hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);    // "user32.dll"
  34. if( !hMod )
  35. return 1;
  36. // GetProcAddress()
  37. pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]);  // "MessageBoxA"
  38. if( !pFunc )
  39. return 1;
  40. // MessageBoxA()
  41. ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
  42. return 0;
  43. }
  44. BOOL InjectCode(DWORD dwPID)
  45. {
  46. HMODULE         hMod            = NULL;
  47. THREAD_PARAM    param           = {0,};
  48. HANDLE          hProcess        = NULL;
  49. HANDLE          hThread         = NULL;
  50. LPVOID          pRemoteBuf[2]   = {0,};
  51. DWORD           dwSize          = 0;
  52. hMod = GetModuleHandleA("kernel32.dll");
  53. // set THREAD_PARAM
  54. param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
  55. param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
  56. strcpy_s(param.szBuf[0], "user32.dll");
  57. strcpy_s(param.szBuf[1], "MessageBoxA");
  58. strcpy_s(param.szBuf[2], "www.reversecore.com");
  59. strcpy_s(param.szBuf[3], "ReverseCore");
  60. // Open Process
  61. if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS,   // dwDesiredAccess
  62. FALSE,                // bInheritHandle
  63. dwPID)) )             // dwProcessId
  64. {
  65. printf("OpenProcess() fail : err_code = %d\n", GetLastError());
  66. return FALSE;
  67. }
  68. // Allocation for THREAD_PARAM
  69. dwSize = sizeof(THREAD_PARAM);
  70. if( !(pRemoteBuf[0] = VirtualAllocEx(hProcess,          // hProcess
  71. NULL,                 // lpAddress
  72. dwSize,               // dwSize
  73. MEM_COMMIT,           // flAllocationType
  74. PAGE_READWRITE)) )    // flProtect
  75. {
  76. printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
  77. return FALSE;
  78. }
  79. if( !WriteProcessMemory(hProcess,                       // hProcess
  80. pRemoteBuf[0],                  // lpBaseAddress
  81. (LPVOID)¶m,                 // lpBuffer
  82. dwSize,                         // nSize
  83. NULL) )                         // [out] lpNumberOfBytesWritten
  84. {
  85. printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
  86. return FALSE;
  87. }
  88. // Allocation for ThreadProc()
  89. dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
  90. if( !(pRemoteBuf[1] = VirtualAllocEx(hProcess,          // hProcess
  91. NULL,                 // lpAddress
  92. dwSize,               // dwSize
  93. MEM_COMMIT,           // flAllocationType
  94. PAGE_EXECUTE_READWRITE)) )    // flProtect
  95. {
  96. printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
  97. return FALSE;
  98. }
  99. if( !WriteProcessMemory(hProcess,                       // hProcess
  100. pRemoteBuf[1],                  // lpBaseAddress
  101. (LPVOID)ThreadProc,             // lpBuffer
  102. dwSize,                         // nSize
  103. NULL) )                         // [out] lpNumberOfBytesWritten
  104. {
  105. printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
  106. return FALSE;
  107. }
  108. if( !(hThread = CreateRemoteThread(hProcess,            // hProcess
  109. NULL,                // lpThreadAttributes
  110. 0,                   // dwStackSize
  111. (LPTHREAD_START_ROUTINE)pRemoteBuf[1],     // dwStackSize
  112. pRemoteBuf[0],       // lpParameter
  113. 0,                   // dwCreationFlags
  114. NULL)) )             // lpThreadId
  115. {
  116. printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
  117. return FALSE;
  118. }
  119. WaitForSingleObject(hThread, INFINITE);
  120. CloseHandle(hThread);
  121. CloseHandle(hProcess);
  122. return TRUE;
  123. }
  124. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
  125. {
  126. TOKEN_PRIVILEGES tp;
  127. HANDLE hToken;
  128. LUID luid;
  129. if( !OpenProcessToken(GetCurrentProcess(),
  130. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  131. &hToken) )
  132. {
  133. printf("OpenProcessToken error: %u\n", GetLastError());
  134. return FALSE;
  135. }
  136. if( !LookupPrivilegeValue(NULL,           // lookup privilege on local system
  137. lpszPrivilege,  // privilege to lookup
  138. &luid) )        // receives LUID of privilege
  139. {
  140. printf("LookupPrivilegeValue error: %u\n", GetLastError() );
  141. return FALSE;
  142. }
  143. tp.PrivilegeCount = 1;
  144. tp.Privileges[0].Luid = luid;
  145. if( bEnablePrivilege )
  146. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  147. else
  148. tp.Privileges[0].Attributes = 0;
  149. // Enable the privilege or disable all privileges.
  150. if( !AdjustTokenPrivileges(hToken,
  151. FALSE,
  152. &tp,
  153. sizeof(TOKEN_PRIVILEGES),
  154. (PTOKEN_PRIVILEGES) NULL,
  155. (PDWORD) NULL) )
  156. {
  157. printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
  158. return FALSE;
  159. }
  160. if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
  161. {
  162. printf("The token does not have the specified privilege. \n");
  163. return FALSE;
  164. }
  165. return TRUE;
  166. }
  167. int main(int argc, char *argv[])
  168. {
  169. DWORD dwPID     = 0;
  170. if( argc != 2 )
  171. {
  172. printf("\n USAGE  : %s <pid>\n", argv[0]);
  173. return 1;
  174. }
  175. // change privilege
  176. if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
  177. return 1;
  178. // code injection
  179. dwPID = (DWORD)atol(argv[1]);
  180. InjectCode(dwPID);
  181. return 0;
  182. }

说到shellcode,我们还可以把ThreadProc()的代码写成汇编的形式,效果是一样的。

[cpp] view plaincopy
  1. // CodeInjection2.cpp
  2. // reversecore@gmail.com
  3. // http://www.reversecore.com
  4. #include "windows.h"
  5. #include "stdio.h"
  6. typedef struct _THREAD_PARAM
  7. {
  8. FARPROC pFunc[2];               // LoadLibraryA(), GetProcAddress()
  9. } THREAD_PARAM, *PTHREAD_PARAM;
  10. BYTE g_InjectionCode[] =
  11. {
  12. 0x55, 0x8B, 0xEC, 0x8B, 0x75, 0x08, 0x68, 0x6C, 0x6C, 0x00,
  13. 0x00, 0x68, 0x33, 0x32, 0x2E, 0x64, 0x68, 0x75, 0x73, 0x65,
  14. 0x72, 0x54, 0xFF, 0x16, 0x68, 0x6F, 0x78, 0x41, 0x00, 0x68,
  15. 0x61, 0x67, 0x65, 0x42, 0x68, 0x4D, 0x65, 0x73, 0x73, 0x54,
  16. 0x50, 0xFF, 0x56, 0x04, 0x6A, 0x00, 0xE8, 0x0C, 0x00, 0x00,
  17. 0x00, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x43, 0x6F,
  18. 0x72, 0x65, 0x00, 0xE8, 0x14, 0x00, 0x00, 0x00, 0x77, 0x77,
  19. 0x77, 0x2E, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x63,
  20. 0x6F, 0x72, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x6A, 0x00,
  21. 0xFF, 0xD0, 0x33, 0xC0, 0x8B, 0xE5, 0x5D, 0xC3
  22. };
  23. /*
  24. 004010ED    55               PUSH EBP
  25. 004010EE    8BEC             MOV EBP,ESP
  26. 004010F0    8B75 08          MOV ESI,DWORD PTR SS:[EBP+8]       ; ESI = pParam
  27. 004010F3    68 6C6C0000      PUSH 6C6C
  28. 004010F8    68 33322E64      PUSH 642E3233
  29. 004010FD    68 75736572      PUSH 72657375
  30. 00401102    54               PUSH ESP                           ; - "user32.dll"
  31. 00401103    FF16             CALL DWORD PTR DS:[ESI]            ; LoadLibraryA("user32.dll")
  32. 00401105    68 6F784100      PUSH 41786F
  33. 0040110A    68 61676542      PUSH 42656761
  34. 0040110F    68 4D657373      PUSH 7373654D
  35. 00401114    54               PUSH ESP                           ; - "MessageBoxA"
  36. 00401115    50               PUSH EAX                           ; - hMod
  37. 00401116    FF56 04          CALL DWORD PTR DS:[ESI+4]          ; GetProcAddress(hMod, "MessageBoxA")
  38. 00401119    6A 00            PUSH 0                             ; - MB_OK (0)
  39. 0040111B    E8 0C000000      CALL 0040112C
  40. 00401120                     <ASCII>                            ; - "ReverseCore", 0
  41. 0040112C    E8 14000000      CALL 00401145
  42. 00401131                     <ASCII>                            ; - "www.reversecore.com", 0
  43. 00401145    6A 00            PUSH 0                             ; - hWnd (0)
  44. 00401147    FFD0             CALL EAX                           ; MessageBoxA(0, "www.reversecore.com", "ReverseCore", 0)
  45. 00401149    33C0             XOR EAX,EAX
  46. 0040114B    8BE5             MOV ESP,EBP
  47. 0040114D    5D               POP EBP
  48. 0040114E    C3               RETN
  49. */
  50. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
  51. {
  52. TOKEN_PRIVILEGES tp;
  53. HANDLE hToken;
  54. LUID luid;
  55. if( !OpenProcessToken(GetCurrentProcess(),
  56. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  57. &hToken) )
  58. {
  59. printf("OpenProcessToken error: %u\n", GetLastError());
  60. return FALSE;
  61. }
  62. if( !LookupPrivilegeValue(NULL,           // lookup privilege on local system
  63. lpszPrivilege,  // privilege to lookup
  64. &luid) )        // receives LUID of privilege
  65. {
  66. printf("LookupPrivilegeValue error: %u\n", GetLastError() );
  67. return FALSE;
  68. }
  69. tp.PrivilegeCount = 1;
  70. tp.Privileges[0].Luid = luid;
  71. if( bEnablePrivilege )
  72. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  73. else
  74. tp.Privileges[0].Attributes = 0;
  75. // Enable the privilege or disable all privileges.
  76. if( !AdjustTokenPrivileges(hToken,
  77. FALSE,
  78. &tp,
  79. sizeof(TOKEN_PRIVILEGES),
  80. (PTOKEN_PRIVILEGES) NULL,
  81. (PDWORD) NULL) )
  82. {
  83. printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
  84. return FALSE;
  85. }
  86. if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
  87. {
  88. printf("The token does not have the specified privilege. \n");
  89. return FALSE;
  90. }
  91. return TRUE;
  92. }
  93. BOOL InjectCode(DWORD dwPID)
  94. {
  95. HMODULE         hMod            = NULL;
  96. THREAD_PARAM    param           = {0,};
  97. HANDLE          hProcess        = NULL;
  98. HANDLE          hThread         = NULL;
  99. LPVOID          pRemoteBuf[2]   = {0,};
  100. hMod = GetModuleHandleA("kernel32.dll");
  101. // set THREAD_PARAM
  102. param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
  103. param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
  104. // Open Process
  105. if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS,               // dwDesiredAccess
  106. FALSE,                            // bInheritHandle
  107. dwPID)) )                         // dwProcessId
  108. {
  109. printf("OpenProcess() fail : err_code = %d\n", GetLastError());
  110. return FALSE;
  111. }
  112. // Allocation for THREAD_PARAM
  113. if( !(pRemoteBuf[0] = VirtualAllocEx(hProcess,                  // hProcess
  114. NULL,                      // lpAddress
  115. sizeof(THREAD_PARAM),      // dwSize
  116. MEM_COMMIT,                // flAllocationType
  117. PAGE_READWRITE)) )         // flProtect
  118. {
  119. printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
  120. return FALSE;
  121. }
  122. if( !WriteProcessMemory(hProcess,                               // hProcess
  123. pRemoteBuf[0],                          // lpBaseAddress
  124. (LPVOID)¶m,                         // lpBuffer
  125. sizeof(THREAD_PARAM),                   // nSize
  126. NULL) )                                 // [out] lpNumberOfBytesWritten
  127. {
  128. printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
  129. return FALSE;
  130. }
  131. // Allocation for ThreadProc()
  132. if( !(pRemoteBuf[1] = VirtualAllocEx(hProcess,                  // hProcess
  133. NULL,                      // lpAddress
  134. sizeof(g_InjectionCode),   // dwSize
  135. MEM_COMMIT,                // flAllocationType
  136. PAGE_EXECUTE_READWRITE)) ) // flProtect
  137. {
  138. printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
  139. return FALSE;
  140. }
  141. if( !WriteProcessMemory(hProcess,                               // hProcess
  142. pRemoteBuf[1],                          // lpBaseAddress
  143. (LPVOID)&g_InjectionCode,               // lpBuffer
  144. sizeof(g_InjectionCode),                // nSize
  145. NULL) )                                 // [out] lpNumberOfBytesWritten
  146. {
  147. printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
  148. return FALSE;
  149. }
  150. if( !(hThread = CreateRemoteThread(hProcess,                    // hProcess
  151. NULL,                        // lpThreadAttributes
  152. 0,                           // dwStackSize
  153. (LPTHREAD_START_ROUTINE)pRemoteBuf[1],
  154. pRemoteBuf[0],               // lpParameter
  155. 0,                           // dwCreationFlags
  156. NULL)) )                     // lpThreadId
  157. {
  158. printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
  159. return FALSE;
  160. }
  161. WaitForSingleObject(hThread, INFINITE);
  162. CloseHandle(hThread);
  163. CloseHandle(hProcess);
  164. return TRUE;
  165. }
  166. int main(int argc, char *argv[])
  167. {
  168. DWORD dwPID     = 0;
  169. if( argc != 2 )
  170. {
  171. printf("\n USAGE  : %s <pid>\n", argv[0]);
  172. return 1;
  173. }
  174. // change privilege
  175. if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
  176. return 1;
  177. // code injection
  178. dwPID = (DWORD)atol(argv[1]);
  179. InjectCode(dwPID);
  180. return 0;
  181. }

可以看到,_THREAD_PARAM结构体中并不包含字符串成员,并且图中的指令字节数组(g_InjectionCode)替代了用C语言编写的ThreadProc()函数。

逆向工程核心原理读书笔记-代码注入相关推荐

  1. 逆向工程核心原理读书笔记-API钩取之隐藏进程(一)

    简评: 整体看了下代码,其实就是应用层的inline hook, 钩子勾住ntdll.dll里面的ZwQuerySystemInformation函数, xp环境测试成功了,win7测试失败了,不知道 ...

  2. 逆向工程核心原理读书笔记-API钩取之IE浏览器连接控制

    我们通过一个示例来练习钩取IE8的InternetConnect函数,用IE8连接指定网站时,使之连接到另一个网站.和以前钩取CreateProcess不同,这次我们钩取更低级的ZwResumeThr ...

  3. 逆向工程核心原理读书笔记-API钩取之隐藏进程(二)

    上一篇文章我们实现的隐藏进程如果重新打开任务管理器或者被隐藏的进程就没有隐藏的效果了.为了弥补这个问题,我们不仅需要钩取当前运行的所有进程,还要钩取将来运行的所有进程.由于所有的进程都是由父进程使用C ...

  4. 逆向工程核心原理读书笔记-API钩取之计算器显示中文数字

    我们通过一个示例来练习向计算机进程插入用户的DLL文件,钩取负责向计算器显示文本的SetWindowTextW,使得计算器中显示中文数字而不是原来的阿拉伯数字.钩取前后的原理图如下所示. 下面我们先测 ...

  5. 逆向工程核心原理读书笔记-API钩取之记事本小写转大写

    我们通过一个示例来练习钩取Notepad.exe的WriteFile,保存文件时将小写字母全部转换为大写字母.下面我们先测试一下代码. 运行notepad.exe并查看PID. 在命令行窗口中输入命令 ...

  6. 逆向工程核心原理学习笔记(十四):栈帧1

    栈帧的话,直接截了一些图,大家看一下就好了,理解起来很简单,就是简单的参数转存. 看完之后,我们需要用一个小程序来进一步学习我们的栈帧了. 下载地址:http://t.cn/RaUSglI 代码写法: ...

  7. 逆向工程核心原理学习笔记(十三):分析abex' crackme #1 的延伸:将参数压入栈

    还是上一次的abex' crackme #1,我们用OD附加看一下. 我们发现在调用这个MessageBox函数的时候,用了4个PUSH指令,我们在后面的注释中可以清楚的看到压入参数的内容. 如果我们 ...

  8. 逆向工程核心原理学习笔记(九):小端序标记法2

    程序地址:http://t.cn/RXnT2pD 我们用OD查看小端序. 代码如下: 我们编译,然后拖进OD查看,直接跳到0x401000入口点. 我们看到几个位置: 由此处我们可以推测后面括号中存放 ...

  9. 逆向工程核心原理学习笔记(七):总结

    首先就是上一节,我们尝试把修改后的代码保存后运行,发现不可以,. 这是由于我们修改的那部分缓冲区造成的. 可执行文件加大再到内存中兵役进程的形式运行并非原封不动的载入内存,而是遵循一定的规则进行,这一 ...

最新文章

  1. nacos1.0.0 服务管理使用mysql
  2. 学python用什么系统好-学Python用什么系统?
  3. 命令行运行jmeter脚本
  4. soultion of mySQL disk exceeded problem
  5. 推荐一款专为新手用的Python开发工具
  6. 原来互联网公司想裁员还能这样玩?
  7. Hulu面试(或许待更)
  8. 2021-09-02 linux修改open files数
  9. 07. Python-异常
  10. vue项目无法启动,谷歌浏览器报:您与此网站之间建立的连接不安全,实际是cdn服务器过期
  11. 传销?花生日记罚款7456万元这个微信社群营销分钱模式要知道
  12. krpano相关笔记
  13. 武汉伯钧成科技有限公司之行的郁闷感受
  14. DirectX 9.0笔记]第一章 初始化 Direct3D
  15. 涅槃重生,力荐大型分布式手册,凤凰架构让你浴火成神,良心分享
  16. 达梦数据库导入dmp文件
  17. python中1到100怎么表示_python如何计算1到100的和(用for循环)
  18. VUE3中 v-for指令用法,列表循环
  19. 编译器优化故障的测试与定位
  20. 数学建模笔记(十一):统计模型(MATLAB计算,函数参数解释待补充)

热门文章

  1. 什么是声明式事务控制
  2. OAuth2.0授权码认证流程介绍
  3. 基于xml的方式配置AOP
  4. 数据库-事务并发操作问题及并发的控制
  5. 数据库-多条件查询-优先级
  6. 内核aio_今天来说说令人让人傻傻分不清的BIO,NIO,AIO
  7. mysql列偏移_MySQL:如何对待分布偏移的数据
  8. Activemq-In-action(二)
  9. 语音控制面板 通过linux_在Linux中,通常把设备作为( )来处理.
  10. 财政指标是什么意思_in the black是“在黑暗中”吗?那in the dark是什么意思?