1211
This commit is contained in:
59
test/Detours/samples/payload/Makefile
Normal file
59
test/Detours/samples/payload/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
##############################################################################
|
||||
##
|
||||
## Makefile for Detours Test Programs.
|
||||
##
|
||||
## Microsoft Research Detours Package
|
||||
##
|
||||
## Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
##
|
||||
|
||||
!include ..\common.mak
|
||||
|
||||
LIBS=$(LIBS) kernel32.lib
|
||||
CFLAGS=$(CFLAGS) /EHsc
|
||||
|
||||
all: dirs \
|
||||
$(BIND)\payload.exe \
|
||||
$(BIND)\payloadtarget.exe
|
||||
|
||||
clean:
|
||||
-del *~ 2>nul
|
||||
-del $(BIND)\payload.* 2>nul
|
||||
-del $(BIND)\payloadtarget.* 2>nul
|
||||
-rmdir /q /s $(OBJD) 2>nul
|
||||
|
||||
realclean: clean
|
||||
-rmdir /q /s $(OBJDS) 2>nul
|
||||
|
||||
dirs:
|
||||
@if not exist $(BIND) mkdir $(BIND) && echo. Created $(BIND)
|
||||
@if not exist $(OBJD) mkdir $(OBJD) && echo. Created $(OBJD)
|
||||
|
||||
$(OBJD)\payload.obj : payload.cpp
|
||||
|
||||
$(BIND)\payload.exe : $(OBJD)\payload.obj $(DEPS)
|
||||
link\
|
||||
/SUBSYSTEM:CONSOLE\
|
||||
$(LINKFLAGS)\
|
||||
$(LIBS)\
|
||||
/PDB:"$(@R).pdb"\
|
||||
/OUT:"$@"\
|
||||
$**\
|
||||
|
||||
$(OBJD)\payloadtarget.obj : payloadtarget.cpp
|
||||
|
||||
$(BIND)\payloadtarget.exe : $(OBJD)\payloadtarget.obj $(DEPS)
|
||||
link\
|
||||
/SUBSYSTEM:CONSOLE\
|
||||
$(LINKFLAGS)\
|
||||
$(LIBS)\
|
||||
/PDB:"$(@R).pdb"\
|
||||
/OUT:"$@"\
|
||||
$**\
|
||||
|
||||
##############################################################################
|
||||
|
||||
test: $(BIND)\payload.exe $(BIND)\payloadtarget.exe
|
||||
$(BIND)\payload.exe
|
||||
|
||||
################################################################# End of File.
|
||||
131
test/Detours/samples/payload/payload.cpp
Normal file
131
test/Detours/samples/payload/payload.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
#include "payloadguid.hpp"
|
||||
|
||||
HANDLE hChildProcess = NULL;
|
||||
HANDLE hChildThread = NULL;
|
||||
|
||||
__declspec(noreturn) void HandleApiFailure(const char* api)
|
||||
{
|
||||
DWORD lastErr = GetLastError();
|
||||
std::cout << "payload.exe: " << api << " failed (" << lastErr << ')' << std::endl;
|
||||
|
||||
if (hChildThread != NULL)
|
||||
{
|
||||
CloseHandle(hChildThread);
|
||||
}
|
||||
|
||||
if (hChildProcess != NULL)
|
||||
{
|
||||
TerminateProcess(hChildProcess, 1);
|
||||
CloseHandle(hChildProcess);
|
||||
}
|
||||
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
std::wstring GetProcessFileName(HANDLE process)
|
||||
{
|
||||
DWORD exeLocation_size = MAX_PATH + 1;
|
||||
|
||||
std::wstring exeLocation;
|
||||
exeLocation.resize(exeLocation_size);
|
||||
|
||||
if (!QueryFullProcessImageNameW(process, 0, &exeLocation[0], &exeLocation_size))
|
||||
{
|
||||
HandleApiFailure("QueryFullProcessImageNameW");
|
||||
}
|
||||
|
||||
exeLocation.resize(exeLocation_size);
|
||||
return exeLocation;
|
||||
}
|
||||
|
||||
void StartChild()
|
||||
{
|
||||
std::wstring target = GetProcessFileName(GetCurrentProcess());
|
||||
target.erase(target.rfind(L'\\') + 1);
|
||||
target += L"payloadtarget.exe";
|
||||
|
||||
STARTUPINFOW si = { sizeof(si) };
|
||||
PROCESS_INFORMATION pi;
|
||||
if (!CreateProcessW(target.c_str(), NULL, NULL, NULL, false,
|
||||
CREATE_SUSPENDED, NULL, NULL, &si, &pi))
|
||||
{
|
||||
HandleApiFailure("CreateProcessW");
|
||||
}
|
||||
|
||||
hChildProcess = pi.hProcess;
|
||||
hChildThread = pi.hThread;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
volatile T* InjectPayload(HANDLE hProcess, T payload, REFGUID guid)
|
||||
{
|
||||
return static_cast<volatile T*>(
|
||||
DetourCopyPayloadToProcessEx(hProcess,guid, &payload, sizeof(payload)));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
StartChild();
|
||||
|
||||
// give the child a handle to ourself
|
||||
HANDLE targetHandleToParent;
|
||||
if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
|
||||
hChildProcess, &targetHandleToParent, 0, false, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
HandleApiFailure("DuplicateHandle");
|
||||
}
|
||||
|
||||
if (!InjectPayload(hChildProcess, targetHandleToParent, PARENT_HANDLE_PAYLOAD))
|
||||
{
|
||||
HandleApiFailure("DetourCopyPayloadToProcessEx");
|
||||
}
|
||||
|
||||
// inject a payload in ourself containing zero data
|
||||
// the goal is for the child process to find this payload
|
||||
// and fill it with random data, to test DetourFindRemotePayload
|
||||
volatile random_payload_t* payloadAddr =
|
||||
InjectPayload<random_payload_t>(GetCurrentProcess(), 0, RANDOM_DATA_PAYLOAD);
|
||||
if (!payloadAddr)
|
||||
{
|
||||
HandleApiFailure("DetourCopyPayloadToProcessEx");
|
||||
}
|
||||
|
||||
if (!ResumeThread(hChildThread))
|
||||
{
|
||||
HandleApiFailure("ResumeThread");
|
||||
}
|
||||
|
||||
CloseHandle(hChildThread);
|
||||
hChildThread = NULL;
|
||||
|
||||
if (WaitForSingleObject(hChildProcess, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
HandleApiFailure("WaitForSingleObject");
|
||||
}
|
||||
|
||||
DWORD exitCode;
|
||||
if (!GetExitCodeProcess(hChildProcess, &exitCode))
|
||||
{
|
||||
HandleApiFailure("GetExitCodeProcess");
|
||||
}
|
||||
|
||||
// the exit code should match the random data the child process gave us
|
||||
random_payload_t payload = *payloadAddr;
|
||||
if (exitCode == payload)
|
||||
{
|
||||
std::cout << "Success, exit code (0x" << std::uppercase << std::hex << exitCode
|
||||
<< ") matches payload content (0x" << payload << ')' << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error, exit code (0x" << std::uppercase << std::hex << exitCode
|
||||
<< ") does not matches payload content (0x" << payload << ')' << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
12
test/Detours/samples/payload/payloadguid.hpp
Normal file
12
test/Detours/samples/payload/payloadguid.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <guiddef.h>
|
||||
|
||||
// {C2569A74-12FE-4E06-8F02-8DF13E39A266}
|
||||
const GUID PARENT_HANDLE_PAYLOAD =
|
||||
{ 0xc2569a74, 0x12fe, 0x4e06, { 0x8f, 0x2, 0x8d, 0xf1, 0x3e, 0x39, 0xa2, 0x66 } };
|
||||
|
||||
// {CB5230ED-04FA-4C47-B606-AC09B2777601}
|
||||
const GUID RANDOM_DATA_PAYLOAD =
|
||||
{ 0xcb5230ed, 0x4fa, 0x4c47, { 0xb6, 0x6, 0xac, 0x9, 0xb2, 0x77, 0x76, 0x1 } };
|
||||
|
||||
typedef unsigned int random_payload_t;
|
||||
60
test/Detours/samples/payload/payloadtarget.cpp
Normal file
60
test/Detours/samples/payload/payloadtarget.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#define _CRT_RAND_S
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
|
||||
#include "payloadguid.hpp"
|
||||
|
||||
HANDLE hParent = NULL;
|
||||
|
||||
__declspec(noreturn) void HandleApiFailure(const char* api)
|
||||
{
|
||||
DWORD lastErr = GetLastError();
|
||||
std::cout << "payloadtarget.exe: " << api << " failed (" << lastErr << ')' << std::endl;
|
||||
|
||||
if (hParent)
|
||||
{
|
||||
CloseHandle(hParent);
|
||||
}
|
||||
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
DWORD payloadSize;
|
||||
void* payloadAddr = DetourFindPayloadEx(PARENT_HANDLE_PAYLOAD, &payloadSize);
|
||||
if (!payloadAddr || payloadSize != sizeof(HANDLE))
|
||||
{
|
||||
HandleApiFailure("DetourFindPayloadEx");
|
||||
}
|
||||
|
||||
hParent = *static_cast<HANDLE*>(payloadAddr);
|
||||
|
||||
DWORD randomPayloadSize;
|
||||
void* randomPayload = DetourFindRemotePayload(hParent, RANDOM_DATA_PAYLOAD, &randomPayloadSize);
|
||||
if (!randomPayload || randomPayloadSize != sizeof(random_payload_t))
|
||||
{
|
||||
HandleApiFailure("DetourFindRemotePayload");
|
||||
}
|
||||
|
||||
random_payload_t randomData;
|
||||
if (rand_s(&randomData) != 0)
|
||||
{
|
||||
HandleApiFailure("rand_s");
|
||||
}
|
||||
|
||||
|
||||
if (!WriteProcessMemory(hParent, randomPayload, &randomData, sizeof(randomData), NULL))
|
||||
{
|
||||
HandleApiFailure("WriteProcessMemory");
|
||||
}
|
||||
|
||||
CloseHandle(hParent);
|
||||
hParent = NULL;
|
||||
|
||||
// conversion to int return type is potentially undefined
|
||||
ExitProcess(randomData);
|
||||
}
|
||||
Reference in New Issue
Block a user