Home > database >  Passing variables to a function with CreateRemoteThread
Passing variables to a function with CreateRemoteThread

Time:09-23

HANDLE CreateRemoteThread(
  HANDLE                 hProcess,
  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  SIZE_T                 dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID                 lpParameter,
  DWORD                  dwCreationFlags,
  LPDWORD                lpThreadId
);

lpParameter

A pointer to a variable to be passed to the thread function.

int x = 0;
LPCWSTR foo = L"Hello World";

CreateRemoteThread(hProcess, 0, 0, pFunction, &x, 0, 0);

Suppose i need to pass more than one variable, like x and foo, to a function that requires two parameters, example:

LPCWSTR Test(int x, LPCWSTR foo) 
{
  //....
}

How would it be?

CodePudding user response:

As its name implies, CreateRemoteThread() creates a new thread in an external process. As such, the lpStartAddress parameter must point to the memory address of a function in the target process, and the lpParameter parameter must point to a memory address that exists in the target process (unless it is a pointer-casted integer). You can't pass a pointer to memory that exists locally in the process that is calling CreateRemoteThread(). You can use VirtualAllocEx() to allocate memory in another process, eg:

DWORD WINAPI MyThreadProc(LPVOID lpParameter)
{
    INT *x = (INT*) lpParameter;
    // use *x as needed...
    VirtualFree(x, 0, MEM_RELEASE);
    return 0;
}

...

LPTHREAD_START_ROUTINE pFunction = ...; // point to MyThreadProc() in hProcess

INT x = 0;

LPVOID param = VirtualAllocEx(hProcess, NULL, sizeof(x), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!param) ...

SIZE_T numWritten;
if (!WriteProcessMemory(hProcess, param, &x, sizeof(x), &numWritten)) ...

if (!CreateRemoteThread(hProcess, 0, 0, pFunction, param, 0, 0)) ...

Alternatively, you can use a pointer-casted integer instead, in which case you don't need to allocate anything:

DWORD WINAPI MyThreadProc(LPVOID lpParameter)
{
    INT x = INT(reinterpret_cast<INT_PTR>(lpParameter));
    // use x as needed...
    return 0;
}

...

LPTHREAD_START_ROUTINE pFunction = ...; // point to MyThreadProc() in hProcess

int x = 0;
LPVOID param = reinterpret_cast<LPVOID>(INT_PTR(x));

if (!CreateRemoteThread(hProcess, 0, 0, pFunction, param, 0, 0)) ...

If you need to pass multiple values to the function, you will have to allocate a struct in the target process to hold them, eg:

#pragma pack(push, 1)
struct MyThreadData
{
    INT x;
    LPCWSTR foo; // points to fooData...
    //WCHAR fooData[]...
}; 
#pragma pack(pop)

...

DWORD WINAPI MyThreadProc(LPVOID lpParameter)
{
    MyThreadData *params = static_cast<MyThreadData*>(lpParameter);
    // use params->x and params->foo as needed...
    VirtualFree(params, 0, MEM_RELEASE);
    return 0;
}

...

LPTHREAD_START_ROUTINE pFunction = ...; // point to MyThreadProc() in hProcess

INT x = 0;
LPCWSTR foo = L"Hello World";
int foo_numBytes = (lstrlenW(foo)   1) * sizeof(WCHAR);

MyThreadData *params = static_cast<MyThreadData*>(VirtualAllocEx(hProcess, NULL, sizeof(MyThreadData)   fooNumBytes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
if (!params) ...

SIZE_T numWritten;
if (!WriteProcessMemory(hProcess, &(params->x), &x, sizeof(x), &numWritten)) ...

LPWSTR foo_data = reinterpret_cast<LPWSTR>(params   1);
if (!WriteProcessMemory(hProcess, &(params->foo), &foo_data, sizeof(foo_data), &numWritten)) ...

if (!WriteProcessMemory(hProcess, fooDataPtr, foo, foo_numBytes, &numWritten)) ...

CreateRemoteThread(hProcess, 0, 0, pFunction, params, 0, 0);
  • Related