关于CFG(Control Flow Guard)的几个函数

·

// 查看当前进程是否启用了CFG
BOOL EnabledCFG() {
  PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY cfg_policy;
  if (GetProcessMitigationPolicy(GetCurrentProcess(),
                                 ProcessControlFlowGuardPolicy, &cfg_policy,
                                 sizeof(cfg_policy))) {
    printf("EnableControlFlowGuard: %d\nEnableExportSuppression: %d\n",
           cfg_policy.EnableControlFlowGuard,
           cfg_policy.EnableExportSuppression);
    return TRUE;
  }
  return FALSE;
}
// 模拟的CFG地址校验函数
// My Map Offset is 0x19B3C8
void MyLdrpDispatchUserCallTarget(size_t BitMapAddress, size_t TargetAddress) {
  // unsigned __int64 qword_18019B3C8;//这是BitMap地址
  // unsigned __int64 v0;  // rax
  unsigned __int64 v2; // r10
  __int64 v1;          //      r11

  // size_t *p = (size_t*)(BitMapAddress + 8 * (TargetAddress >> 9));
  v1 = *(size_t *)(BitMapAddress + 8 * (TargetAddress >> 9));
  v2 = TargetAddress >> 3;
  if ((TargetAddress & 0xF) != 0) {
    v2 &= 0xFFFFFFFFFFFFFFFEui64;
    if (!_bittest64(&v1, v2 % 64)) {
      printf("%llx Is Not Valid\n", TargetAddress);
      return;
    }
  } else if (_bittest64(&v1, v2 % 64)) {
    printf("%llx Is Valid\n", TargetAddress);
    return;
  }
  if (_bittest64(&v1, (v2 | 1) % 64)) {
    printf("%llx Is Valid\n", TargetAddress);
    return;
  }
  printf("%llx Is Not Valid\n", TargetAddress);
  return;
}
// 查看模块是否支持CFG,并获取CFG校验函数的地址
BOOL IsCFGEnabledForModule(HMODULE hModule,
                           PBYTE *GuardCFDispatchFunctionPointer) {
  // 获取模块基地址
  PBYTE baseAddress = (PBYTE)hModule;
  if (GuardCFDispatchFunctionPointer)
    *GuardCFDispatchFunctionPointer = NULL;
  // 获取DOS头
  PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)baseAddress;
  if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
    return FALSE;
  }

  // 获取NT头
  PIMAGE_NT_HEADERS ntHeaders =
      (PIMAGE_NT_HEADERS)(baseAddress + dosHeader->e_lfanew);
  if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
    return FALSE;
  }
  if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG]
          .Size == 0) {
    return FALSE;
  }
  // 获取加载配置目录
  PIMAGE_LOAD_CONFIG_DIRECTORY loadConfigDir =
      (PIMAGE_LOAD_CONFIG_DIRECTORY)(baseAddress +
                                     ntHeaders->OptionalHeader
                                         .DataDirectory
                                             [IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG]
                                         .VirtualAddress);

  // 检查GuardFlags字段
  if (loadConfigDir->GuardFlags & IMAGE_GUARD_CF_INSTRUMENTED) {
    PBYTE *pp = (PBYTE *)loadConfigDir->GuardCFDispatchFunctionPointer;
    printf("%p\t%p\n", pp, *pp);
    if (GuardCFDispatchFunctionPointer)
      *GuardCFDispatchFunctionPointer = *pp;
    return TRUE;
  }
  return FALSE;
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注