问题描述
我正在尝试翻译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.