问题描述
我正在尝试使用控制流保护 api 将内存区域设置为有效执行。
我用这些例子作为崇敬材料:
https://github.com/BreakingMalwareResearch/CFGExceptions/blob/master/CFGExceptions/main.cpp
https://github.com/trailofbits/cfg-showcase/blob/master/cfg_valid_targets.cpp#L111
这是我的代码:
#include <stdio.h>
#include <Windows.h>
#include <psapi.h>
#include "cfgTest.h"
BOOL GetMemoryAllocationBaseAndRegionSize(PVOID,PVOID*,PSIZE_T);
INT main() {
HANDLE hProcess;
NTSTATUS ntStatus = ERROR_SUCCESS;
STARTUPINFOA startupInfo;
PROCESS_informatION processinformation = { 0 };
CFG_CALL_TARGET_INFO cfgCallTargetInfoList[1];
DWORD dwPid = 0;
SIZE_T stRegionSize = NULL;
PVOID pvAllocationBase = NULL;
// Function pointers
SETPROCESSVALIDCALLTARGETS pSetProcessValidCallTargets = NULL;
PVOID pvAddresstoAddCfgExceptionTo = NULL;
//
// Get address of SetProcessValidCallTargets
//
CONST HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
CONST HMODULE hKernelbase = LoadLibraryW(L"Kernelbase.dll");
if (hKernelbase && hNtdll) {
pSetProcessValidCallTargets = (SETPROCESSVALIDCALLTARGETS)GetProcAddress(hKernelbase,"SetProcessValidCallTargets");
pvAddresstoAddCfgExceptionTo = GetProcAddress(hNtdll,"NtSetContextThread");
}
else {
return ERROR_MOD_NOT_FOUND;
}
FreeLibrary(hNtdll);
FreeLibrary(hKernelbase);
// Get memory allocation base and region size by calling VirtualProtect.
if (GetMemoryAllocationBaseAndRegionSize(pvAddresstoAddCfgExceptionTo,&pvAllocationBase,&stRegionSize) == FALSE) {
ntStatus = ERROR_UNHANDLED_ERROR;
goto lblCleanup;
}
//
// Add cfg exception
//
cfgCallTargetInfoList[0].Flags = CFG_CALL_TARGET_VALID;
cfgCallTargetInfoList[0].Offset = (ULONG_PTR)pvAddresstoAddCfgExceptionTo - (ULONG_PTR)pvAllocationBase;;
if (pSetProcessValidCallTargets(GetCurrentProcess(),pvAllocationBase,stRegionSize,1,cfgCallTargetInfoList) == FALSE) {
printf("%d",GetLastError());
ntStatus = ERROR_UNHANDLED_ERROR;
goto lblCleanup;
}
lblCleanup:
if (processinformation.hProcess) {
CloseHandle(processinformation.hProcess);
}
if (processinformation.hThread) {
CloseHandle(processinformation.hThread);
}
return ntStatus;
}
BOOL GetMemoryAllocationBaseAndRegionSize(PVOID pvAddress,PVOID* ppvAllocationBase,PSIZE_T pstRegionSize) {
SIZE_T stErr = 0;
MEMORY_BASIC_informatION tMemoryBasicinformation = { 0 };
stErr = VirtualQuery(pvAddress,&tMemoryBasicinformation,sizeof(tMemoryBasicinformation));
if (0 == stErr) {
return FALSE;
}
*ppvAllocationBase = tMemoryBasicinformation.AllocationBase;
*pstRegionSize = tMemoryBasicinformation.RegionSize;
return TRUE;
}
#pragma once
typedef enum _VIRTUAL_MEMORY_informatION_CLASS
{
VmPrefetchinformation,VmPagePriorityinformation,VmCfgCallTargetinformation
} VIRTUAL_MEMORY_informatION_CLASS;
typedef struct _MEMORY_RANGE_ENTRY
{
PVOID VirtualAddress;
SIZE_T NumberOfBytes;
} MEMORY_RANGE_ENTRY,* PMEMORY_RANGE_ENTRY;
typedef struct _VM_informatION
{
DWORD dwNumberOfOffsets;
DWORD dwMustBeZero;
PDWORD pdwOutput;
PCFG_CALL_TARGET_INFO ptOffsets;
} VM_informatION,* PVM_informatION;
typedef NTSTATUS(NTAPI* NTSETinformatIONVIRTUALMEMORY)(
HANDLE hProcess,VIRTUAL_MEMORY_informatION_CLASS VminformationClass,ULONG_PTR NumberOfEntries,PMEMORY_RANGE_ENTRY VirtualAddresses,PVOID Vminformation,ULONG VminformationLength
);
typedef BOOL(WINAPI* SETPROCESSVALIDCALLTARGETS)(
HANDLE hProcess,PVOID VirtualAddress,SIZE_T RegionSize,ULONG NumberOfOffsets,PCFG_CALL_TARGET_INFO Offsetinformation
);
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
我的问题是 SetProcessValidCallTargets 返回 FALSE 并且 GetLastError() 告诉我它的 87 这意味着传递了一个无效参数。但我不知道出了什么问题。谁能看到发生了什么?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)