我正在尝试翻译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, Buffer, n * SizeOf(TSystemCodeIntegrityInformation), @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, Buffer, n * SizeOf(TSystemCodeIntegrityInformation), @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.
答案 0 :(得分:1)
您正在分配的内存超出了您的需要。 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.