检测是否启用了TESTSIGNING

问题描述

我正在尝试翻译this C++ code,建议将其翻译为验证是否已启用 TESTSIGNING 解决方案。

我的代码几乎可以正常工作,但是在这一部分:

while (status = STATUS_BUFFER_OVERFLOW) or (status = STATUS_INFO_LENGTH_MISMATCH) do
begin
  n := Max(br,n * 2);
  Reallocmem(Buffer,n * SizeOf(TSystemCodeIntegrityinformation));
  Status := NtQuerySysteminformation({SystemCodeIntegrityinformation}103,Buffer,n * SizeOf(TSystemCodeIntegrityinformation),@br);
  Writeln('0x'+IntToHex(Status));
end;

我收到错误的地方:

内存不足

该如何解决

完整代码

program test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows,SysUtils,Math;

type
  NTSTATUS = DWORD;
  
  TSysteminformationClass = SYstem_informatION_CLASS;

  TNativeQuerySysteminformation = function(SysteminformationClass: TSysteminformationClass; Systeminformation: Pointer; SysteminformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;
  
  SYstem_CODEINTEGRITY_informatION = record
    Length: ULONG;
    CodeIntegrityOptions: ULONG;
  end;
  TSystemCodeIntegrityinformation = SYstem_CODEINTEGRITY_informatION;
  PSystemCodeIntegrityinformation = ^TSystemCodeIntegrityinformation;
  
const
  NTDLL_DLL = 'NTDLL.DLL';
  STATUS_SUCCESS = $00000000;
  STATUS_BUFFER_OVERFLOW = $80000005;
  STATUS_INFO_LENGTH_MISMATCH = $C0000004;
  
var
  NtQuerySysteminformation: TNativeQuerySysteminformation = nil;
  NTDLLHandle: THandle = 0;
  UnloadNTDLL: Boolean;
  Buffer: Pointer;
  Status: Cardinal;
  psci: PSystemCodeIntegrityinformation;
  n,br: Cardinal;
  
function InitNativeAPI: Boolean;
begin
  NTDLLHandle := GetModuleHandle(NTDLL_DLL);
  UnloadNTDLL := NTDLLHandle = 0;

  if NTDLLHandle = 0 then
    NTDLLHandle := LoadLibrary(NTDLL_DLL);

  if NTDLLHandle <> 0 then
  begin
    @NtQuerySysteminformation := GetProcAddress(NTDLLHandle,'NtQuerySysteminformation');
  end;

  Result := (NTDLLHandle <> 0) and Assigned(NtQuerySysteminformation);
end;

procedure FreeNativeAPI;
begin
  if (NTDLLHandle <> 0) and UnloadNTDLL then
  begin
    if not FreeLibrary(NTDLLHandle) then
      raise Exception.Create(Format('Unload Error: %s - 0x%x',[NTDLL_DLL,GetModuleHandle(NTDLL_DLL)]))
    else
      NTDLLHandle := 0;
  end;
end;

begin
  try
    Writeln(InitNativeAPI);

    Buffer := nil;
    n := $100;
    Buffer := Allocmem(n * SizeOf(TSystemCodeIntegrityinformation));
    Status := NtQuerySysteminformation(SystemCodeIntegrityinformation,@br);

    while (status = STATUS_BUFFER_OVERFLOW) or (status = STATUS_INFO_LENGTH_MISMATCH) do
    begin
      n := Max(br,n * 2);
      Reallocmem(Buffer,n * SizeOf(TSystemCodeIntegrityinformation));
      Status := NtQuerySysteminformation(SystemCodeIntegrityinformation,@br);
      Writeln('0x'+IntToHex(Status));
    end;

    try
      if Status = STATUS_SUCCESS then
      begin
        psci := PSystemCodeIntegrityinformation(Buffer);
        Writeln(IntToHex(psci.CodeIntegrityOptions));
      end;
    finally
      Reallocmem(Buffer,0);
      Buffer := nil;
    end;

    FreeNativeAPI;
    
    except
    on E: Exception do
      Writeln(E.ClassName,': ',E.Message);
  end;
  Readln;
end.

解决方法

您正在分配的内存超出了您的需要。 C ++代码仅分配1 SYSTEM_CODEINTEGRITY_INFORMATION,但您分配的数组很大。没必要。

但是,更重要的是,您不会像C ++代码那样在调用SYSTEM_CODEINTEGRITY_INFORMATION.Length之前初始化NtQuerySystemInformation()字段。

尝试以下方法:

program test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows,SysUtils,Math;

type
  NTSTATUS = DWORD;

  TSystemInformationClass = SYSTEM_INFORMATION_CLASS;

  TNativeQuerySystemInformation = function(SystemInformationClass: TSystemInformationClass; SystemInformation: Pointer; SystemInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;

  SYSTEM_CODEINTEGRITY_INFORMATION = record
    Length: ULONG;
    CodeIntegrityOptions: ULONG;
  end;
  TSystemCodeIntegrityInformation = SYSTEM_CODEINTEGRITY_INFORMATION;
  PSystemCodeIntegrityInformation = ^TSystemCodeIntegrityInformation;

const
  NTDLL_DLL = 'NTDLL.DLL';
  STATUS_SUCCESS = $00000000;

var
  NtQuerySystemInformation: TNativeQuerySystemInformation = nil;
  NTDLLHandle: THandle = 0;
  UnloadNTDLL: Boolean = False;
  Status: DWORD;
  sci: TSystemCodeIntegrityInformation;
  br: ULONG;

function InitNativeAPI: Boolean;
begin
  Result := False;

  NTDLLHandle := GetModuleHandle(NTDLL_DLL);

  if NTDLLHandle = 0 then
  begin
    NTDLLHandle := LoadLibrary(NTDLL_DLL);
    UnloadNTDLL := (NTDLLHandle <> 0);
  end;

  if NTDLLHandle <> 0 then
  begin
    @NtQuerySystemInformation := GetProcAddress(NTDLLHandle,'NtQuerySystemInformation');
    Result := Assigned(NtQuerySystemInformation);
  end;
end;

procedure FreeNativeAPI;
begin
  if (NTDLLHandle <> 0) and UnloadNTDLL then
  begin
    if not FreeLibrary(NTDLLHandle) then
      raise Exception.Create(Format('Unload Error: %s - 0x%x',[NTDLL_DLL,GetModuleHandle(NTDLL_DLL)]);
    NTDLLHandle := 0;
  end;
end;

begin
  try
    Writeln(InitNativeAPI);
    try
      sci.Length := sizeof(sci);

      Status := NtQuerySystemInformation(SystemCodeIntegrityInformation,@sci,SizeOf(sci),@br);
      Writeln('0x'+IntToHex(Status));

      if Status = STATUS_SUCCESS then
      begin
       Writeln(IntToHex(sci.CodeIntegrityOptions));
      end;
    finally
      FreeNativeAPI;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName,': ',E.Message);
  end;
  Readln;
end.

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...