Code: Select all
library ntcp;
{$IMAGEBASE $5FFFFFFF}
uses
Windows,
madCodeHook,
JwaWinType in 'JwaWinType.pas',
madStrings,
messages;
var
ZwCreateSectionNext: function(var SectionHandle: Cardinal;
DesiredAccess: ACCESS_MASK;
ObjectAttributes: POBJECT_ATTRIBUTES;
SectionSize: PLARGE_INTEGER;
Protect: DWORD;
Attributes: DWORD;
FileHandle: DWORD): NTSTATUS; stdcall;
type
TZwQueryObject = function(ObjectHandle: Integer;
ObjectInformationClass: Integer;
ObjectInformation: Pointer;
Length: Integer;
var ResultLength: Integer): NTSTATUS; stdcall;
const
FILE_EXECUTE = $00000020;
NTDLL = 'ntdll.dll';
function IsNT: Boolean; stdcall;
begin
result := ((GetVersion() and $80000000)= 0);
end;
function NT_SUCCESS(const Status: Integer): WordBool;
begin
result := status >= 0;
end;
function ExtractFileName(FileName: string): string;
begin
result := FileName;
while Pos('\', result) <> 0 do
Delete(result, 1, Pos('\', result));
while Pos('/', result) <> 0 do
Delete(result, 1, Pos('/', result));
end;
function FileNameFromFileHandle(const hF: HFILE): string; stdcall;
type
UNICODE_STRING = packed record
len: Word;
maxlen: Word;
buf: PWideChar;
end;
OBJECT_NAME_INFORMATION = record
name: UNICODE_STRING;
end;
const
ONI = 1;
UNICODE_MAX_PATH = MAX_PATH *sizeof(WCHAR);
var
ret: Integer;
status: Integer;
pONI: ^OBJECT_NAME_INFORMATION;
ZwQueryObject: TZwQueryObject;
begin
result := '';
@ZwQueryObject := GetProcAddress(GetModuleHandleW('ntdll.dll'), 'ZwQueryObject');
if @ZwQueryObject = nil then
Exit;
GetMem(pONI, UNICODE_MAX_PATH);
ZeroMemory(pOni, sizeof(OBJECT_NAME_INFORMATION));
status := ZwQueryObject(hF, ONI, @pONI^, UNICODE_MAX_PATH, ret);
if NT_SUCCESS(status) then
result := WideToAnsiEx(@pONI^.name.buf^);
FreeMem(pONI);
end;
function ZwCreateSectionCb(var SectionHandle: Cardinal;
DesiredAccess: ACCESS_MASK;
ObjectAttributes: POBJECT_ATTRIBUTES;
SectionSize: PLARGE_INTEGER;
Protect: DWORD;
Attributes: DWORD;
FileHandle: DWORD): NTSTATUS; stdcall;
begin //* Todo:+ check protection against FILE_EXECUTE ?
if not (AmSystemProcess) and //..
(FileHandle <> INVALID_HANDLE_VALUE)and // validate FileHandle
(Attributes = SEC_IMAGE) and // executable image file
(FileHandle > 0) then // == 0 backed up by paging file ?
begin
if lstrcmpi(PChar(ExtractFileName(FileNameFromFileHandle(FileHandle))), 'calc.exe') <> 0 then
result := ZwCreateSectionNext(
SectionHandle,
DesiredAccess,
ObjectAttributes,
SectionSize,
Protect,
Attributes,
FileHandle
)
else
result := NTSTATUS($C0000022); //* Access Denied
end
else
result := ZwCreateSectionNext(
SectionHandle,
DesiredAccess,
ObjectAttributes,
SectionSize,
Protect,
Attributes,
FileHandle
);
end;
Procedure DLLMain(Code: Integer);
begin
case Code of
DLL_PROCESS_DETACH: {};
DLL_PROCESS_ATTACH:
begin
if IsNT() then
HookAPI(NTDLL, 'ZwCreateSection', @ZwCreateSectionCb, @ZwCreateSectionNext, SAFE_HOOKING);
end;
end;
end;
begin
DLLProc := @DLLMain;
DLLMain(DLL_PROCESS_ATTACH);
end.