This commit is contained in:
2022-09-06 00:08:26 +08:00
parent e17ffc3965
commit 91d57c13f0
232 changed files with 191628 additions and 250 deletions

View 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.

View 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;
}
}

View 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;

View 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);
}