To achieve the thread must use a remote injection CreateRemoteThread functions provided by Windows to create a remote thread of the function prototype is as follows: HANDLE CreateRemoteThread (HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
Parameter Description: HPROCESS: Target Process Handle LPTHREADATTRIBUTES: Pointing the security description structure of the thread, typically set to null, indicating the use of the default security level DWSTACKSIZE: thread stack size, generally set to 0, indicating the use of the default size, general For 1mlpStartaddress: thread function, address LPParameter: thread parameter dwcreationFlags: thread creation method create_suspended thread Create LPTHREADID: Output Parameters, recorded ID Create Id
CreateremoteThread function is introduced, other details Refer to the Detailed description of this function in MSDN! Since I know this function to create a remote thread, let's define thread function, and the definition of the normal thread function, the thread function of the remote thread must define the static member function of the program, such as: DWORD __stdcall threadProc (LPVOID LPARAM) {// We first define this thread function as an empty function return 0;} Here we first define the thread function to be empty because the threaded thread is written as a remote injection thread. The way the normal thread function is slightly different.
The thread code is then copied to the target process address space (this address must be page attribute as page_execute_readwrite) or other host processes can perform local (eg shared memory mapping area). Here we choose the host process. At the copy line, we need to apply for a storage area in the host process in the host process, then write the thread code into the host process through the WriteProcessMemory function.
To obtain the ID of the host process, there are many ways to use the functions in psapi.h, or you can use the TOOLHELP function, which provides a function that uses the TOOLHELP implementation, the function is as follows
// The process name of the process ID obtained, if there are multiple instances running at the same time, then only return to the first enumeration process IDDWORD processNameToId (LPCTSTR lpszProcessName) {HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; Pe.dwsize = sizeof (Processentry32);
if (! Process32First (hSnapshot, & pe)) {MessageBox (NULL, "The frist entry of the process list has not been copyied to the buffer", "Notice", MB_ICONINFORMATION | MB_OK); return 0;} while (Process32Next (hSnapshot , & PE) {if (! strcmp (lpszprocessname, pe.szexefile) {return pe.th32processid;}} Return 0;}
You can create a remote thread using CreateRemoteThread after completion of the steps! The sample code is as follows
#include
// To insert the thread function dword __stdcall threadproc (lpvoid lparam) {return 0;}
INT Main (int Argc, char * argv []) {const dword dwthreadsize = 4096; dword dwwritebytes;
Std :: cout << "please input the name of target process" << std :: end1; char szexename [max_path] = {0}; // Wait for the input host process name std :: cin >> szexename; // get process ID Specifies the name of the process, if there is more than one process instance, a process to obtain the first ID DWORD dwProcessId = processNameToId (szExeName); HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, dwProcessId) void * pRemoteThread = VirtualAllocEx (hTargetProcess, 0, dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); // write the thread body hosting process if (WriteProcessMemory (hTargetProcess, pRemoteThread, & threadProc, dwThreadSize, 0!)) {MessageBox (NULL, "write data to target process failed!", "Notice", MB_ICONINFORMATION | MB_OK); return 0;} // create a thread HANDLE hRemoteThread in the host process = CreateRemoteThread (hTargetProcess, NULL, 0, (DWORD (__stdcall *) (void *)) pRemoteThread, NULL, 0, & dwWriteBytes ); If (! Hremothetread) {MessageBox (Null, "Create Remote Thread Failed!", "Notice", MB_ICONSTOP); RETURN-1;} Re TURN 0;} When the above code is run, create a thread-defined thread in the host process, but now this thread correspondence is empty. Let's write the contents of the specific thread correspondence, here we just display a message dialog box messageBox modification thread function as follows: DWORD __STDCALL ThreadProc (lpvoid lparam) {MessageBox (Null, "Hello", "Hello ", MB_OK); return 0;}
After the thread is modified, we run the program and inject the thread into the host process. However, an illegal access error is generated. The reason is that the messagebox (NULL, "Hello", "Hello", MB_OK) in the thread body; the string pointed to by the second and third parameters of the function is existing in the address space of the current process, the thread in the host process. Accessing the string "Hello" will have an illegal error that accesses the memory. The method is to copy the contents of the string to the address space of the host process, and together with the address of the MessageBox function in user32.dll to the host process. To copy the entry address of the string and the Messagebox function to the host process we first define the following RemoteParam structure, used to store the entry address of the MessageBox function and the contents of the MessageBox displayed, the definition of this structure is as follows: // Thread parameter typedef struct _RemoteParam {char szMsg [12]; // DWORD dwMessageBox MessageBox function string displayed; // MessageBox function entry address} RemoteParam, * PRemoteParam; RemoteParam remoteData; ZeroMemory (& remoteData, sizeof (RemoteParam)); HINSTANCE hUser32 = LoadLibrary ("User32.dll"); RemoteData.dwMessageBox = (DWORD) GetProcaddress (HUSER32, "MessageBoxa); strcat (RemoteData.szmsg," Hello / 0 ");
// allocate memory space in the host process RemoteParam * pRemoteParam = (RemoteParam *) VirtualAllocEx (hTargetProcess, 0, sizeof (RemoteParam), MEM_COMMIT, PAGE_READWRITE); if (! PRemoteParam) {MessageBox (NULL, "Alloc memory failed!", "Notice", MB_ICONITION | MB_OK); RETURN 0;}
// Write the entry address of the string and the MessageBox function into the host process if (! WriteProcessMemory (HtargetProcess, PremoteParam, & RemoteData, Sizeof (RemoteData), 0) {MessageBox (Null, "Write Data To Target Process Failed!", " Notice ", MB_ICONINFORMATION | MB_OK); return 0;} // create a remote thread HANDLE hRemoteThread = CreateRemoteThread (hTargetProcess, NULL, 0, (DWORD (__stdcall *) (void *)) pRemoteThread, pRemoteParam, 0, & dwWriteBytes);
It is also important to note that some system processes are unable to open with the openprocess function when opening the process. At this time, it is necessary to enhance the access to the process, and the purpose of accessing the system process is to provide an improvement here. The function enabledeBugPriv () of the process access rights, the function is as follows:
// upgrade process access to bool enableDebugPriv () {HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; (! OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, & hToken)) if {return false;} if (LookupPrivilegeValue (NULL, SE_DEBUG_NAME,! & sedebugnamevalue)) {CloseHandle (HTOKEN); RETURN FALSE;}
Tkp.privilegegount = 1; tkp.privileges [0] .luid = sedebugnameValue; tkp.privileges [0] .attributes = se_privilege_enable
IF (! AdjustTokenPrivilegeg (HToken, False, & Tkp, Sizeof (TKP), NULL, NULL) {CloseHandle (HTOKEN); RETURN FALSE;}
Return True;}
At this time, the work of creating a remote thread is over, and the complete code is given below:
#pragma overce # include "stdafx.h" #include
// Thread Parameter Structure Definition TypeDef Struct _RemoteParam {char SZMSG [12]; // MessageBox function displayed in the character prompt dword dwmessagebox; // messagebox function entry address} RemoteParam, * PremoteParam;
/ / Define the function pointer of the MessageBox type TypedEf int (__stdcall * pfn_messagebox) (HWND, LPCTSTSTSTSTSTSTR, DWORD);
// thread function definition DWORD __stdcall threadProc (LPVOID lParam) {RemoteParam * pRP = (RemoteParam *) lParam; PFN_MESSAGEBOX pfnMessageBox; pfnMessageBox = (PFN_MESSAGEBOX) pRP-> dwMessageBox; pfnMessageBox (NULL, pRP-> szMsg, pRP-> szMsg, 0);
Return 0;}
// upgrade process access to bool enableDebugPriv () {HANDLE hToken; LUID sedebugnameValue; TOKEN_PRIVILEGES tkp; (! OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, & hToken)) if {return false;}
IF (! Lookupprivilerage (NULL, SE_DEBUG_NAME, & SEDEBUGNAMEVALUE) {CloseHandle (HTOKEN); RETURN FALSE;}
tkp.PrivilegeCount = 1; tkp.Privileges [0] .Luid = sedebugnameValue; tkp.Privileges [0] .Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges (hToken, FALSE, & tkp, sizeof (tkp), NULL, NULL)!) { CloseHandle (HTOKEN); RETURN FALSE;
Return True;}
// get the process ID from the process name, if there are multiple instances running, then returns to the first enumerated IDDWORD processNameToId processes (LPCTSTR lpszProcessName) {HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; pe.dwSize = SIZEOF (Processentry32);
IF (! Process32First (& PE) {MessageBox (Null, "The Frist Entry of The Process List Has Not Been Copyied to The Buffer," Notice ", MB_ICONITIONFORMATION | MB_OK; RETURN 0;}
While (Process32Next (Hsnapshot, & PE) {if (! strcmp (lpszprocessname, pe.szexefile) {return pe.th32processid;}} returnography
INT Main (int Argc, char * argv []) {// Defines the size of the line console const dword dwthreadsize = 4096; DWORD dwWriteBytes; // Lifting Process Access EnabledEbugPriv ();
// Waiting for the input process name, pay attention to case match match std :: cout << "please input the name of target process! << std :: endl; char szexename [max_path] = {0}; std :: cin >> Szexename;
DWORD dwprocessid = processnametoid (szexename);
IF (dwprocessid == 0) {MessageBox (Null, "Target Process Have Not Been Found!", "Notice", MB_ICONIONFORMATION | MB_OK; RETURN-1;}
// The process ID obtained process handle HANDLE hTargetProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, dwProcessId); if (! HTargetProcess) {MessageBox (NULL, "! Open target process failed", "Notice", MB_ICONINFORMATION | MB_OK); return 0; } // Open a storage area for the thread in the host process // Note that MEM_COMMIT | MEM_RESERVE memory non-match type and page_execute_readwrite memory protection Type // It is referred to in the MSDN for the VirtualaLalkEx function. void * pRemoteThread = VirtualAllocEx (hTargetProcess, 0, dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (! pRemoteThread) {MessageBox (NULL, "! Alloc memory in target process failed", "notice", MB_ICONINFORMATION | MB_OK); return 0 ;} // the thread body copied to the host process if {MessageBox (NULL, "Write data to target process failed!", "Notice", MB_ICONINFORMATION | MB_OK (WriteProcessMemory (hTargetProcess, pRemoteThread, & threadProc, dwThreadSize, 0)!) RETURN 0;} // Define thread parameter structural variable RemoteParam RemoteData; ZeromeMory (& RemoteData); // Fill member hinstance huser32 = loadLibrary ("user32.dll") in the structural variable; RemoteData. dwMessageBox = (DWORD) GetProcAddress (hUser32, "MessageBoxA"); strcat (remoteData.szMsg, "Hello / 0"); // open thread parameter storage area in the host process RemoteParam * pRemoteParam = (RemoteParam *) VirtualAllocEx (hTargetProcess , 0, SizeOf (RemoteParam), MEM_COMMIT, PAGE_READWRITE, IF (! PR EmoteParam) {MessageBox (NULL, "Alloc Memory Failed!", "Notice", MB_ICONITIONFORMATION | MB_OK); RETURN 0;
/ / Copy the thread parameters to the host process address space if (! WriteProcessMemory (HtargetProcess, PremoteParam, & RemoteData, Sizeof (RemoteData)) {MessageBox (Null, "Write Data to Target Process Failed!", "Notice", MB_ICONINFORMATION | MB_OK); return 0;} // create a thread HANDLE hRemoteThread in the host process = CreateRemoteThread (hTargetProcess, NULL, 0, (DWORD (__stdcall *) (void *)) pRemoteThread, pRemoteParam, 0, & dwWriteBytes); if ( ! hremotethread) {MessageBox (Null, "Create Remote Thread Failed!", "Notice", MB_ICONITIONFORMATION | MB_OK); RETURN 0;}
CloseHandle (HREMOTETHREAD);
Return 0;}