A brief on using createremoteThread

xiaoxiao2021-03-06  45

2004-12-14 GR1X (C)

In "Programming Applications for Microsoft Windows 4th", Jeffery Richter used Remote Threads to inject a dll into another process's address space He tansfered LoadLibrary's address into remote thread and let remote thread to load a dll we wrote (may be a trojan dll:. - )), As we create that thread ourselves, we cann't count on the compiler & linker has prepared the referenced functions' addresses well in the remote process's import section's thunk area (refer PE format specification), which means we have to get every function address we'll use in remote thread within the injected process address space, Jeffery told us to use GetProcAddress, howerver what GetProcAddress returns is just the address of function within our own process address space, how can we make sure that address will stay the same with REMOTE Process? Jeffery Said That "kernel32.dll is mapped to the limited and the remote processes' Address Spaces", Why Same? I think as for efficiench ration (relocation is a horrible process), Microsoft may has ran Rebase on all the operating system-supplied files before shipping Windows or has allocated a non-overlapped prefered address for these system-supplied fils so that none of the operating system modules overlap once .

To make this explaination simple, think that if we've wrote a dll, and we're sure the remote process and our own process all have loaded that dll in same memory location, surely we can play this magic trick. Luckily, nearly every process will load kernle32.dll and user32.dll, is not it a great relief :) Just think about the tedious work in virous for searching the base address of kernel32.dll and its export section for function GetProcAddress's address. A interesting question arises , why does virous have to do that awful work, why do not use the above talking attribute Personally, I think firstly Windows version varries so function memory location varies;? Second, Virus code are normally injected into EXE files and changes the entry point to point to itself so virus can start running before original EXE's code, it does not have the luxurios environment as we are now: tow running process in the same host, one for injecting and one being injected, as it does not know anything About the infec ted host. Anyway, some early virus just hardcoded the function address in code so they are not portable accross different platform. (Here, I must declare I know little about virus, just correct me if I'm wrong) .Sorry, just run Such Far Away from The Topic, FOLLOWING IS The Code Snippet Which Create A Remote Thread To Pop A MessageBox Periodlly:

// zombie.cpp: // Usage: Zombie (szMessage, szTitle); # include "zombie.h" #pragma comment (lib, "Psapi.lib") # define UNICODE # define _UNICODE # define _RemoteProcess typedef struct _remoteparameter {DWORD _OututDebugstring; DWORD _Sleep; DWORD _MessageBox; TCHAR szMessage [100]; TCHAR szTitle [20]; TCHAR szMessageBoxError [30]; TCHAR szDebugEnterRemote [30]; TCHAR szDebugExitRemote [30];} REMOTEPARAMETER, * PREMOTEPARAMETER; TCHAR szModuleName [MAX_PATH]; DWORD Process2ID (TCHAR *); DWORD WINAPI RemoteThread (LPVOID); BOOL Zombie (TCHAR * szMessage, TCHAR * szTitle) {MessageBox (NULL, szMessage, szTitle, MB_OK); GetModuleFileName (NULL, szModuleName, MAX_PATH); MessageBox (NULL, szModuleName, "Module", MB_OK); HANDLE RThread; HANDLE RemoteModuleHandle; TCHAR RemoteModuleName [2] [15]; TCHAR * RemotePageBaseAddr; TCHAR * RemoteParaBaseAddr; DWORD RemotePID; int nPageSize; in t signal; HINSTANCE hKernel32, hUser32; REMOTEPARAMETER remotepara; _tcscpy (RemoteModuleName [0], _ T ( "Explorer.exe")); _tcscpy (RemoteModuleName [1], _ T ( "Taskmgr.exe")); signal = 1; while (1) {remotePID = Process2Id (RemoteModulenAMe 2]); if (RemotePid == - 1) {Return Null;} else if (remotepid == 0) {IF (Signal% 2 == 0 ) {OutputDebugstring ("Remote Process Explorer isn't Running / N"));} else {OutputDebugstring (_T ("Remote Process Taskmgr Isn't Running / N"));} Sleep (1000); Continue;} RemoteModuleHandle =

OpenProcess (PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, RemotePID); if (RemoteModuleHandle == NULL) {Sleep (1000); continue;} else {break;}} nPageSize = sizeof (TCHAR) * 4 * 1024; RemotePageBaseAddr = (PTSTR ) VirtualAllocEx (RemoteModuleHandle, NULL, nPageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (RemotePageBaseAddr == NULL) {OutputDebugString (_T ( "VirtualAllocEx for Thread Error / n")); CloseHandle (RemoteModuleHandle); return NULL;} if (WriteProcessMemory ( RemoteModuleHandle, RemotePageBaseAddr, (LPVOID) RemoteThread, nPageSize, NULL) == FALSE) {OutputDebugString (_T ( "WriteProcessMemory for Thread Error / n")); CloseHandle (RemoteModuleHandle); return NULL;} memset (& remotepara, 0, sizeof ( remotepara)); _tcscpy (remotepara.szDebugEnterRemote, _T ( "Hello, Magic World / n!")); _tcscpy (remotepara.szMessageBoxError, _T ( "MessageBox () Error / n")); _tcscpy (remotepara.szDebugExitRemote, _T ("BYE, CRUEL World! / N")))); _TCSCPY (Remotepara.SzMessageBoxError, _T ("s leep () Error / n ")); _tcscpy (remotepara.szMessage, szMessage); _tcscpy (remotepara.szTitle, szTitle); hKernel32 = GetModuleHandle (_T (" kernel32.dll ")); hUser32 = GetModuleHandle (_T (" user32 .dll ")); remotepara._OututDebugstring = (DWORD) GetProcAddress (hKernel32," OutputDebugStringW "); remotepara._MessageBox = (DWORD) GetProcAddress (hUser32," MessageBoxExA "); remotepara._Sleep = (DWORD) GetProcAddress (hKernel32," Sleep "); nPageSize = sizeof (TCHAR) * sizeof (remotepara); RemoteParaBaseAddr = (PTSTR) VirtualAllocEx (RemoteModuleHandle, NULL, nPageSize, MEM_COMMIT, PAGE_READWRITE); if (RemoteParaBaseAddr ==

NULL) {OutputDebugString (_T ( "VirtualAllocEx for Parameter Error / n")); CloseHandle (RemoteModuleHandle); return NULL;} if (WriteProcessMemory (RemoteModuleHandle, RemoteParaBaseAddr, (LPVOID) & remotepara, nPageSize, NULL) == FALSE) {OutputDebugString ("WriteProcessMemory for parameter Error:")); char szbuf [80]; DWORD DW = getLastError (); Sprintf (SZBUF, "WriteProcessMemory Failed: getLastError Returned% U / N", DW); MessageBox (null, szbuf , "Error", MB_OK); CloseHandle (RemoteModuleHandle); return NULL;} RThread = CreateRemoteThread (RemoteModuleHandle, NULL, 0, (LPTHREAD_START_ROUTINE) RemotePageBaseAddr, (LPVOID) RemoteParaBaseAddr, 0, NULL); if (RThread == NULL) { OutputDebugString (_T ( "CreateRemoteThread Error / n")); CloseHandle (RemoteModuleHandle); return NULL;} return true;} DWORD Process2ID (TCHAR * processname) {DWORD lpidprocesses [1024], cbneeded, cprocesses; HANDLE hprocess; HMODULE hmodule; UINT I; TCHAR NORMALNAME [MAX_PATH] = _ T ("UnknownProcess"); if (! Enumprocesses (LPIDPROC) Esses, sizeof (lpidprocesses), & cbneeded) {OutputDebugstring (_t ("enumprocesses error / n")); return -1;} cprocesses = cbneeded / sizeof (dword); for (i = 0; i

转载请注明原文地址:https://www.9cbs.com/read-80694.html

New Post(0)