SetProcessValidCallTargets 引发错误 87

问题描述

我正在尝试使用控制流保护 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 (将#修改为@)