Files
e-fin-ADWS-BOF/ADWS-BOF/base/mock.cpp
T
2026-06-05 16:58:34 -04:00

725 lines
27 KiB
C++

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <cstring>
#include <map>
#include <tuple>
#include <cassert>
#include <windows.h>
extern "C" {
#ifdef _DEBUG
#undef DECLSPEC_IMPORT
#define DECLSPEC_IMPORT
#endif
#include "..\beacon.h"
}
#include "mock.h"
namespace bof {
namespace utils {
template <typename T>
T swapEndianness(T value) {
char *ptr = reinterpret_cast<char *>(&value);
std::reverse(ptr, ptr + sizeof(T));
return value;
}
template <typename T>
std::vector<char> toBytes(T input) {
char *ptr = reinterpret_cast<char *>(&input);
return std::vector<char>(ptr, ptr + sizeof(T));
}
const char* typeToStr(int callbackType) {
switch (callbackType) {
case CALLBACK_OUTPUT: return "CALLBACK_OUTPUT";
case CALLBACK_OUTPUT_OEM: return "CALLBACK_OUTPUT_OEM";
case CALLBACK_ERROR: return "CALLBACK_ERROR";
case CALLBACK_OUTPUT_UTF8: return "CALLBACK_OUTPUT_UTF8";
default: return "CALLBACK_UNKOWN";
}
}
}
namespace mock {
static BEACON_INFO beaconInfo = { 0 };
char *BofData::get() {
return size() > 0 ? reinterpret_cast<char *>(&data[0]) : nullptr;
}
int BofData::size() {
return data.size();
}
void BofData::addData(const char *buf, std::size_t len) {
std::vector<char> bytes;
bytes.assign(buf, buf + len);
insert(static_cast<int>(len));
append(bytes);
}
void BofData::append(const std::vector<char> &data) {
this->data.insert(std::end(this->data), std::begin(data), std::end(data));
}
void BofData::insert(int v) {
append(bof::utils::toBytes(bof::utils::swapEndianness(v)));
}
void BofData::insert(short v) {
append(bof::utils::toBytes(bof::utils::swapEndianness(v)));
}
void BofData::insert(unsigned int v) {
insert(static_cast<int>(v));
}
void BofData::insert(unsigned short v) {
insert(static_cast<short>(v));
}
void BofData::insert(const char *v) {
addData(v, std::strlen(v) + 1);
}
void BofData::insert(const wchar_t *v) {
addData((const char *)v, (std::wcslen(v) + 1) * sizeof(wchar_t));
}
void BofData::insert(const std::vector<char>& data) {
pack<int32_t>(data.size());
append(data);
}
void setBeaconInfo(BEACON_INFO& info) {
std::memcpy(&bof::mock::beaconInfo, &info, sizeof(BEACON_INFO));
}
void setSection(PALLOCATED_MEMORY_SECTION info, PVOID baseAddress, SIZE_T size, DWORD finalProtection, DWORD allocationType, ALLOCATED_MEMORY_LABEL label) {
info->BaseAddress = baseAddress;
info->VirtualSize = size;
info->PreviousProtect = finalProtection;
info->CurrentProtect = finalProtection;
info->MaskSection = TRUE;
info->Label = label;
}
ALLOCATED_MEMORY_REGION allocateBeaconMemory(const bof::profile::Stage& stage, size_t size, DWORD* initialPermission) {
ALLOCATED_MEMORY_REGION info;
std::memset(&info, 0, sizeof(info));
/* Allocate the base memory for Beacon. The following .stage options affect how the memory is allocated:
* - .stage.allocator: Set how Beacon's Reflective Loader allocates memory for the agent. Options are: HeapAlloc, MapViewOfFile, and VirtualAlloc.
* - .stage.module_x64/x86: Ask the ReflectiveLoader to load the specified library and overwrite its space instead of allocating memory with the .stage.allocator.
*/
*initialPermission = stage.useRWX == bof::profile::UseRWX::True ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
if (stage.module.empty()) {
HANDLE hHeap = INVALID_HANDLE_VALUE;
HANDLE hFile = INVALID_HANDLE_VALUE;
switch (stage.allocator) {
case bof::profile::Allocator::HeapAlloc: {
// For heap allocator we don't honor the .stage.userwx flag
*initialPermission = PAGE_EXECUTE_READWRITE;
hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
assert(hHeap != NULL && "Could not create the heap");
info.AllocationBase = HeapAlloc(hHeap, 0, size);
info.Type = MEM_PRIVATE;
info.CleanupInformation.AllocationMethod = METHOD_HEAPALLOC;
info.CleanupInformation.AdditionalCleanupInformation.HeapAllocInfo.HeapHandle = hHeap;
info.CleanupInformation.AdditionalCleanupInformation.HeapAllocInfo.DestroyHeap = TRUE;
break;
}
case bof::profile::Allocator::MapViewOfFile: {
hFile = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, size, NULL);
assert(hFile != NULL && "Could not create file mapping");
info.AllocationBase = MapViewOfFile(hFile, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
info.Type = MEM_MAPPED;
info.CleanupInformation.AllocationMethod = METHOD_NTMAPVIEW;
CloseHandle(hFile);
DWORD old = 0;
if (!VirtualProtect(info.AllocationBase, size, *initialPermission, &old)) {
assert(false && "Could not set the initial memory permission for the Beacon memory");
}
break;
}
case bof::profile::Allocator::VirtualAlloc: {
info.AllocationBase = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, *initialPermission);
info.Type = MEM_PRIVATE;
info.CleanupInformation.AllocationMethod = METHOD_VIRTUALALLOC;
break;
}
}
}
else {
// For simplicity we use module base here instead of resolving a function
info.AllocationBase = (PVOID)LoadLibraryExA(stage.module.c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES);
info.Type = MEM_IMAGE;
info.CleanupInformation.AllocationMethod = METHOD_MODULESTOMP;
DWORD old = 0;
if (!VirtualProtect(info.AllocationBase, size, *initialPermission, &old)) {
assert(false && "Could not set the initial memory permission for the Beacon memory");
}
}
assert(info.AllocationBase != NULL && "Could not allocate the base memory for Beacon");
// Set the necessary fields for the Beacon memory
info.Purpose = PURPOSE_BEACON_MEMORY;
info.RegionSize = size;
info.CleanupInformation.Cleanup = TRUE;
return info;
}
BEACON_INFO setupMockBeacon(const bof::profile::Stage& stage) {
const std::vector<std::tuple<ALLOCATED_MEMORY_LABEL, std::string>> sections{
{ LABEL_PEHEADER, "PE" },
{ LABEL_TEXT, ".text" },
{ LABEL_RDATA, ".rdata" },
{ LABEL_DATA, ".data" },
#ifdef _M_X64
{ LABEL_PDATA, ".pdata" },
#endif
{ LABEL_RELOC, ".reloc" },
};
const size_t sectionSize = 0x1000;
BEACON_INFO info = { 0 };
info.version = bof::CsVersion;
// Set the static mask key
for (size_t i = 0; i < MASK_SIZE; ++i) {
info.mask[i] = 0xAB;
}
// Allocate the memory for Beacon
DWORD initialProtection = 0;
ALLOCATED_MEMORY_REGION beaconMemory = allocateBeaconMemory(stage, sections.size() * sectionSize, &initialProtection);
info.allocatedMemory.AllocatedMemoryRegions[0] = beaconMemory;
info.beacon_ptr = stage.obfuscate == bof::profile::Obfuscate::False
? reinterpret_cast<char*>(beaconMemory.AllocationBase)
: reinterpret_cast<char*>(beaconMemory.AllocationBase) - 0x1000;
// Build the section list
PALLOCATED_MEMORY_SECTION nextSection = info.allocatedMemory.AllocatedMemoryRegions[0].Sections;
char* sectionBase = reinterpret_cast<char*>(beaconMemory.AllocationBase);
for (auto [section, name] : sections) {
// Skip the PE header if .stage.obfuscate = true
if (stage.obfuscate == bof::profile::Obfuscate::True && section == LABEL_PEHEADER) {
continue;
}
// Fill the memory
for (size_t i = 0; i < sectionSize; ++i) {
sectionBase[i] = name[i % name.length()];
}
DWORD finalProtection = initialProtection;
// Fix the .code section permission if the allocator is not heap alloc and .stage.userwx is false
if (stage.allocator != bof::profile::Allocator::HeapAlloc || !stage.module.empty()) {
if (section == LABEL_TEXT && stage.useRWX == bof::profile::UseRWX::False) {
finalProtection = PAGE_EXECUTE_READ;
// Fix the permissions
DWORD old = 0;
if (!VirtualProtect(sectionBase, sectionSize, finalProtection, &old)) {
assert(false && "Could not set the final memory protection");
}
}
}
// Set the section memory information
setSection(nextSection, sectionBase, sectionSize, finalProtection, beaconMemory.Type, section);
// Next section
++nextSection;
sectionBase += sectionSize;
}
// Add few mock heap records
const size_t numberOfHeapRecords = 2;
info.heap_records = new HEAP_RECORD[numberOfHeapRecords + 1];
assert(info.heap_records != nullptr && "Could not the allocate heap records array");
for (size_t i = 0; i < numberOfHeapRecords; ++i) {
info.heap_records[i].ptr = new char[512];
info.heap_records[i].size = 512;
assert(info.heap_records[i].ptr != nullptr && "Could not allocate a heap record");
}
info.heap_records[numberOfHeapRecords].ptr = NULL;
info.heap_records[numberOfHeapRecords].size = 0;
return info;
}
void resolveMockUpSleepmaskLocation(BEACON_INFO& info) {
// Get the base address of the debug exe
char* exeBase = (char*)GetModuleHandleA(NULL);
// Find the start of the section headers
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)exeBase;
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)(exeBase + dosHeader->e_lfanew);
PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)(reinterpret_cast<char*>(&ntHeader->OptionalHeader) + ntHeader->FileHeader.SizeOfOptionalHeader);
// Find the .text section which will be our "mock" sleepmask code
DWORD numberOfSections = ntHeader->FileHeader.NumberOfSections;
while (numberOfSections--) {
if (strcmp(reinterpret_cast<char*>(sectionHeader->Name), ".text") == 0) {
info.sleep_mask_ptr = exeBase + sectionHeader->VirtualAddress;
info.sleep_mask_text_size = sectionHeader->Misc.VirtualSize;
// In theory, the total size would contains also the data part, but we cannot guarantee the section order.
info.sleep_mask_total_size = sectionHeader->Misc.VirtualSize;
return;
}
++sectionHeader;
}
assert(false && "Could not find the text section of the debug image");
}
FUNCTION_CALL createFunctionCallStructure(PVOID targetFunction, WinApi targetFunctionName, BOOL bMask, int numOfArgs, ...) {
FUNCTION_CALL functionCall = { 0 };
va_list valist = NULL;
/* Set basic info for encapsulated function call */
functionCall.functionPtr = targetFunction;
functionCall.function = targetFunctionName;
functionCall.bMask = bMask;
functionCall.numOfArgs = numOfArgs;
/* Start parsing valist and copy over variadic arguments. */
va_start(valist, numOfArgs);
for (int i = 0; i < numOfArgs; i++)
{
functionCall.args[i] = va_arg(valist, ULONG_PTR);
}
va_end(valist);
return functionCall;
}
}
namespace output {
std::vector<OutputEntry> outputs;
void addEntry(int type, const char* data, int len) {
OutputEntry output = {
type,
std::string(data, data + len)
};
outputs.push_back(output);
}
const std::vector<OutputEntry>& getOutputs() {
return outputs;
}
void reset() {
outputs.clear();
}
void PrintTo(const OutputEntry& o, std::ostream* os) {
*os << "{ callbackType: " << bof::utils::typeToStr(o.callbackType) << ", output: " << o.output << " }";
}
}
namespace valuestore {
std::map<std::string, void*> values;
void reset() {
values.clear();
}
}
namespace bud {
char custom[BEACON_USER_DATA_CUSTOM_SIZE] = { 0 };
void reset() {
std::memset(custom, 0, BEACON_USER_DATA_CUSTOM_SIZE);
}
void set(const char* data) {
if (data) {
std::memcpy(custom, data, BEACON_USER_DATA_CUSTOM_SIZE);
}
}
}
std::vector<bof::output::OutputEntry> runMockedSleepMask(SLEEPMASK_FUNC sleepMaskFunc, PBEACON_INFO beaconInfo, PFUNCTION_CALL functionCall) {
// Reset the global output container
bof::output::reset();
// Execute the entrypoint
sleepMaskFunc(beaconInfo, functionCall);
// Return the stored outputs
return bof::output::getOutputs();
}
std::vector<bof::output::OutputEntry> runMockedSleepMask(SLEEPMASK_FUNC sleepMaskFunc, const bof::profile::Stage& stage, const bof::mock::MockSleepMaskConfig& config) {
BEACON_INFO beaconInfo = bof::mock::setupMockBeacon(stage);
FUNCTION_CALL functionCall = bof::mock::createFunctionCallStructure(Sleep, SLEEP, TRUE, 1, config.sleepTimeMs);
bof::mock::resolveMockUpSleepmaskLocation(beaconInfo);
bof::mock::setBeaconInfo(beaconInfo);
std::vector<bof::output::OutputEntry> output;
do {
output = runMockedSleepMask(sleepMaskFunc, &beaconInfo, &functionCall);
} while (config.runForever);
return output;
}
std::vector<bof::output::OutputEntry> runMockedSleepMask(SLEEPMASK_FUNC sleepMaskFunc, const bof::profile::Stage& stage) {
// Set the default config for the mock sleepmask runner
const bof::mock::MockSleepMaskConfig config = {
.sleepTimeMs = 5000,
.runForever = false,
};
return runMockedSleepMask(sleepMaskFunc, stage, config);
}
std::vector<bof::output::OutputEntry> runMockedSleepMask(SLEEPMASK_FUNC sleepMaskFunc) {
return runMockedSleepMask(sleepMaskFunc, bof::profile::defaultStage);
}
std::vector<bof::output::OutputEntry> runMockedBeaconGate(SLEEPMASK_FUNC sleepMaskFunc, PFUNCTION_CALL functionCall, const bof::profile::Stage& stage) {
BEACON_INFO beaconInfo = bof::mock::setupMockBeacon(stage);
bof::mock::resolveMockUpSleepmaskLocation(beaconInfo);
bof::mock::setBeaconInfo(beaconInfo);
return runMockedSleepMask(sleepMaskFunc, &beaconInfo, functionCall);
}
std::vector<bof::output::OutputEntry> runMockedBeaconGate(SLEEPMASK_FUNC sleepMaskFunc, PFUNCTION_CALL functionCall) {
return runMockedBeaconGate(sleepMaskFunc, functionCall, bof::profile::defaultStage);
}
}
#include "mock_syscalls.cpp"
extern "C"
{
// Print API
void BeaconPrintf(int type, const char *fmt, ...) {
printf("[Output Callback: %s (0x%X)]\n", bof::utils::typeToStr(type), type);
va_list args;
va_start(args, fmt);
int size = vsnprintf(nullptr, 0, fmt, args);
if (size >= 0) {
char* buffer = new char[size + 1];
vsnprintf(buffer, size + 1, fmt, args);
bof::output::addEntry(type, buffer, size);
delete[] buffer;
}
vprintf(fmt, args);
printf("\n");
va_end(args);
}
BOOL BeaconDownload(const char* filename, const char* buffer, unsigned int length) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
return FALSE;
}
void BeaconOutput(int type, const char *data, int len) {
bof::output::addEntry(type, data, len);
printf("[Output Callback: %s (0x%X)]\n%.*s", bof::utils::typeToStr(type), type, len, data);
}
// Parser API
void BeaconDataParse(datap *parser, char *buffer, int size) {
parser->buffer = buffer;
parser->original = buffer;
parser->size = size;
parser->length = size;
}
char* BeaconDataPtr(datap* parser, int size) {
if (parser->length < size) {
return NULL;
}
char* data = parser->buffer;
parser->buffer += size;
parser->length -= size;
return data;
}
int BeaconDataInt(datap *parser) {
int value = *(int *)(parser->buffer);
parser->buffer += sizeof(int);
parser->length -= sizeof(int);
return bof::utils::swapEndianness(value);
}
short BeaconDataShort(datap *parser) {
short value = *(short *)(parser->buffer);
parser->buffer += sizeof(short);
parser->length -= sizeof(short);
return bof::utils::swapEndianness(value);
}
int BeaconDataLength(datap *parser) {
return parser->length;
}
char *BeaconDataExtract(datap *parser, int *size) {
int size_im = BeaconDataInt(parser);
char *buff = parser->buffer;
parser->buffer += size_im;
if (size)
{
*size = size_im;
}
return buff;
}
// Format API
void BeaconFormatAlloc(formatp *format, int maxsz) {
format->original = new char[maxsz];
format->buffer = format->original;
format->length = maxsz;
format->size = maxsz;
}
void BeaconFormatReset(formatp *format) {
format->buffer = format->original;
format->length = format->size;
}
void BeaconFormatFree(formatp *format) {
delete[] format->original;
}
void BeaconFormatAppend(formatp *format, const char *text, int len) {
memcpy(format->buffer, text, len);
format->buffer += len;
format->length -= len;
}
void BeaconFormatPrintf(formatp *format, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int len = vsprintf_s(format->buffer, format->length, fmt, args);
format->buffer += len;
format->length -= len;
va_end(args);
}
char *BeaconFormatToString(formatp *format, int *size) {
if (size)
{
*size = format->size - format->length;
}
return format->original;
}
void BeaconFormatInt(formatp *format, int value) {
value = bof::utils::swapEndianness(value);
BeaconFormatAppend(format, (char *)&value, 4);
}
// Internal API
BOOL BeaconUseToken(HANDLE token) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
return TRUE;
}
void BeaconRevertToken() {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
BOOL BeaconIsAdmin() {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
return FALSE;
}
void BeaconGetSpawnTo(BOOL x86, char *buffer, int length) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
void BeaconInjectProcess(HANDLE hProc, int pid, char *payload,
int p_len, int p_offset, char *arg,
int a_len)
{
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
void BeaconInjectTemporaryProcess(PROCESS_INFORMATION *pInfo,
char *payload, int p_len,
int p_offset, char *arg,
int a_len)
{
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO* si, PROCESS_INFORMATION* pInfo) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
return false;
}
void BeaconCleanupProcess(PROCESS_INFORMATION *pInfo) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
BOOL toWideChar(char *src, wchar_t *dst, int max) {
std::string str = src;
std::wstring wstr(str.begin(), str.end());
size_t bytes = min(wstr.length() * sizeof(wchar_t), max);
std::memcpy(dst, wstr.c_str(), bytes);
return TRUE;
}
BOOL BeaconInformation(PBEACON_INFO info) {
std::memcpy(info, &bof::mock::beaconInfo, sizeof(BEACON_INFO));
return TRUE;
}
BOOL BeaconAddValue(const char* key, void* ptr) {
auto item = bof::valuestore::values.find(std::string(key));
if (ptr && item == bof::valuestore::values.end()) {
bof::valuestore::values[std::string(key)] = ptr;
return TRUE;
}
return FALSE;
}
void* BeaconGetValue(const char* key) {
auto item = bof::valuestore::values.find(std::string(key));
if (item != bof::valuestore::values.end()) {
return item->second;
}
return NULL;
}
BOOL BeaconRemoveValue(const char* key) {
auto item = bof::valuestore::values.find(std::string(key));
if (item != bof::valuestore::values.end()) {
bof::valuestore::values.erase(item);
return TRUE;
}
return FALSE;
}
PDATA_STORE_OBJECT BeaconDataStoreGetItem(size_t index) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
return NULL;
}
void BeaconDataStoreProtectItem(size_t index) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
void BeaconDataStoreUnprotectItem(size_t index) {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
size_t BeaconDataStoreMaxEntries() {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
return 0;
}
char* BeaconGetCustomUserData() {
return bof::bud::custom;
}
BOOL BeaconGetSyscallInformation(PBEACON_SYSCALLS info, SIZE_T infoSize, BOOL resolveIfNotInitialized) {
if (infoSize != sizeof(BEACON_SYSCALLS)) {
return FALSE;
}
if (info) {
bof::mock::syscall::ResolveSyscalls(&info->syscalls);
bof::mock::syscall::ResolveRtls(&info->rtls);
return TRUE;
}
return FALSE;
}
// Beacon System Call API
LPVOID BeaconVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) {
return VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect);
}
LPVOID BeaconVirtualAllocEx(HANDLE processHandle, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) {
return VirtualAllocEx(processHandle, lpAddress, dwSize, flAllocationType, flProtect);
}
BOOL BeaconVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) {
return VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
}
BOOL BeaconVirtualProtectEx(HANDLE processHandle, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) {
return VirtualProtectEx(processHandle, lpAddress, dwSize, flNewProtect, lpflOldProtect);
}
BOOL BeaconVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {
return VirtualFree(lpAddress, dwSize, dwFreeType);
}
BOOL BeaconGetThreadContext(HANDLE threadHandle, PCONTEXT threadContext) {
return GetThreadContext(threadHandle, threadContext);
}
BOOL BeaconSetThreadContext(HANDLE threadHandle, PCONTEXT threadContext) {
return SetThreadContext(threadHandle, threadContext);
}
DWORD BeaconResumeThread(HANDLE threadHandle) {
return ResumeThread(threadHandle);
}
HANDLE BeaconOpenProcess(DWORD desiredAccess, BOOL inheritHandle, DWORD processId) {
return OpenProcess(desiredAccess, inheritHandle, processId);
}
HANDLE BeaconOpenThread(DWORD desiredAccess, BOOL inheritHandle, DWORD threadId) {
return OpenThread(desiredAccess, inheritHandle, threadId);
}
BOOL BeaconCloseHandle(HANDLE object) {
return CloseHandle(object);
}
BOOL BeaconUnmapViewOfFile(LPCVOID baseAddress) {
return UnmapViewOfFile(baseAddress);
}
SIZE_T BeaconVirtualQuery(LPCVOID address, PMEMORY_BASIC_INFORMATION buffer, SIZE_T length) {
return VirtualQuery(address, buffer, length);
}
BOOL BeaconDuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions) {
return DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
}
BOOL BeaconReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead) {
return ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}
BOOL BeaconWriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten) {
return WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten);
}
VOID BeaconDisableBeaconGate() {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
VOID BeaconEnableBeaconGate() {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
VOID BeaconDisableBeaconGateMasking() {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
VOID BeaconEnableBeaconGateMasking() {
std::cerr << "Not implemented: " << __FUNCTION__ << std::endl;
}
}