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

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

逆向工程核心原理读书笔记-代码注入_第1张图片

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

逆向工程核心原理读书笔记-代码注入_第2张图片

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

逆向工程核心原理读书笔记-代码注入_第3张图片

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

逆向工程核心原理读书笔记-代码注入_第4张图片

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

[cpp]  view plain  copy
  1. int main(int argc, char *argv[])  
  2. {  
  3.     DWORD dwPID     = 0;  
  4.   
  5.     if( argc != 2 )  
  6.     {  
  7.         printf("\n USAGE  : %s \n", argv[0]);  
  8.         return 1;  
  9.     }  
  10.   
  11.     // change privilege  
  12.     if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )  
  13.         return 1;  
  14.   
  15.     // code injection  
  16.     dwPID = (DWORD)atol(argv[1]);  
  17.     InjectCode(dwPID);  
  18.   
  19.     return 0;  
  20. }  
分析InjectCode()函数之前,先看一下要注入的目标进程的代码。函数中并未直接调用相关API,也未直接定义使用字符串,它们都通过THREAD_PARAM结构体以线程参数的形式传递调用。
[cpp]  view plain  copy
  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.   
  7. typedef HMODULE (WINAPI *PFLOADLIBRARYA)  
  8. (  
  9.     LPCSTR lpLibFileName  
  10. );  
  11.   
  12. typedef FARPROC (WINAPI *PFGETPROCADDRESS)  
  13. (  
  14.     HMODULE hModule,  
  15.     LPCSTR lpProcName  
  16. );  
  17.   
  18. typedef int (WINAPI *PFMESSAGEBOXA)  
  19. (  
  20.     HWND hWnd,  
  21.     LPCSTR lpText,  
  22.     LPCSTR lpCaption,  
  23.     UINT uType  
  24. );  
  25.   
  26. DWORD WINAPI ThreadProc(LPVOID lParam)  
  27. {  
  28.     PTHREAD_PARAM   pParam      = (PTHREAD_PARAM)lParam;  
  29.     HMODULE         hMod        = NULL;  
  30.     FARPROC         pFunc       = NULL;  
  31.   
  32.     // LoadLibrary()  
  33.     hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);    // "user32.dll"  
  34.     if( !hMod )  
  35.         return 1;  
  36.   
  37.     // GetProcAddress()  
  38.     pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, pParam->szBuf[1]);  // "MessageBoxA"  
  39.     if( !pFunc )  
  40.         return 1;  
  41.   
  42.     // MessageBoxA()  
  43.     ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);  
  44.   
  45.     return 0;  
  46. }  

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

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

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

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

你可能感兴趣的:(数据逆向)