您的位置:首页 > 编程语言 > Delphi

delphi R3下 跨进程获取DLL信息 NtQueryInformationProcess

2016-01-12 13:47 741 查看
unit APIUnit;
{
GetProcessModuleHandle API Unit

Ring3调用NtQueryInformationProcess实现跨进程获取DLL句柄

}
interface
USES
Winapi.Windows,System.SysUtils;
type
USHORT = Word;
UNICODE_STRING = packed Record
Length : USHORT;
MaximumLength: USHORT;
Buffer : PWideString;
end;
RTL_USER_PROCESS_PARAMETERS = packed record
Reserved1 : array[0..15] of Byte;
Reserved2 : array[0..9] of Pointer;
ImagePathName: UNICODE_STRING;
CommandLine : UNICODE_STRING;
end;
PRTL_USER_PROCESS_PARAMETERS = ^RTL_USER_PROCESS_PARAMETERS;

_PEB_LDR_DATA = record
Length: ULONG;
Initialized: BOOLEAN;
SsHandle: pointer;//PVOID;
InLoadOrderModuleList: LIST_ENTRY;
InMemoryOrderModuleList: LIST_ENTRY;
InInitializationOrderModuleList: LIST_ENTRY;
end {_PEB_LDR_DATA};
PEB_LDR_DATA = _PEB_LDR_DATA;
PPEB_LDR_DATA = ^_PEB_LDR_DATA;

_LDR_MODULE = record
InLoadOrderModuleList: LIST_ENTRY;
InMemoryOrderModuleList: LIST_ENTRY;
InInitializationOrderModuleList: LIST_ENTRY;
BaseAddress: pointer;
EntryPoint:  pointer;
SizeOfImage: ULONG;
FullDllName: UNICODE_STRING;
BaseDllName: UNICODE_STRING;
Flags: ULONG;
LoadCount: SmallInt;
TlsIndex: SmallInt;
HashTableEntry: LIST_ENTRY;
TimeDateStamp: ULONG;
end {_LDR_MODULE};
LDR_MODULE = _LDR_MODULE;
PLDR_MODULE = ^_LDR_MODULE;

_PEB_FREE_BLOCK = record
Next:Pointer;
Size:ULONG;
end;
PPEB_FREE_BLOCK = ^_PEB_FREE_BLOCK;

PEB = packed record
InheritedAddressSpace:Boolean;// 00h
ReadImageFileExecOptions:Boolean; // 01h
BeingDebugged:Boolean; //02H
Spare:Boolean;
Mutant:THandle;
ImageBaseAddress:Pointer;
LoaderData:Pointer;  //0C
ProcessParameters:Pointer;
SubSystemData:Pointer;
ProcessHeap:Pointer;
FastPebLock:Pointer;
FastPebLockRoutine:PPointer;
FastPebUnlockRoutine:PPointer;
EnvironmentUpdateCount:ULONG;
KernelCallbackTable:^Pointer;
EventLogSection:Pointer;
EventLog:Pointer;
FreeList:PPEB_FREE_BLOCK;
TlsExpansionCounter:ULONG;
TlsBitmap:Pointer;
TlsBitmapBits:array [0..$2] of ULONG;
ReadOnlySharedMemoryBase:Pointer;
ReadOnlySharedMemoryHeap:Pointer;
ReadOnlyStaticServerData:^Pointer;
AnsiCodePageData:Pointer;
OemCodePageData:Pointer;
UnicodeCaseTableData:Pointer;
NumberOfProcessors:ULONG;
NtGlobalFlag:ULONG;
Spare2:array [0..$4] of Byte;
CriticalSectionTimeout:LARGE_INTEGER;
HeapSegmentReserve:ULONG;
HeapSegmentCommit:ULONG;
HeapDeCommitTotalFreeThreshold:ULONG;
HeapDeCommitFreeBlockThreshold:Ulong;
NumberOfHeaps:ULONG;
MaximumNumberOfHeaps:ULONG;
ProcessHeaps:PPointer;
GdiSharedHandleTable:Pointer;
ProcessStarterHelper:Pointer;
GdiDCAttributeList:Pointer;
LoaderLock:Pointer;
OSMajorVersion:ULONG;
OSMinorVersion:ULONG;
OSBuildNumber:ULONG;
OSPlatformId:ULONG;
ImageSubSystem:ULONG;
ImageSubSystemMajorVersion:ULONG;
ImageSubSystemMinorVersion:ULONG;
GdiHandleBuffer:array [0..$22] of ULONG;
PostProcessInitRoutine:ULONG;
TlsExpansionBitmap:ULONG;
TlsExpansionBitmapBits: array [0..$80] of Byte;
SessionId:ULONG;
end;
PPEB = ^PEB;

PROCESS_BASIC_INFORMATION = packed record
ExitStatus : DWORD;
PebBaseAddress: PPEB;
AffinityMask : DWORD;
BasePriority : DWORD;
uUniqueProcessId: ULong;
uInheritedFromUniqueProcessId: ULong;
end;
TProcessBasicInformation = PROCESS_BASIC_INFORMATION;

function NtQueryInformationProcess(
ProcessHandle: THandle; {进程句柄}
ProcessInformationClass: Byte; {信息类型}
ProcessInformation: Pointer;   {缓冲指针}
ProcessInformationLength: ULONG; {以字节为单位的缓冲大小}
ReturnLength: PULONG  {写入缓冲的字节数}
): DWORD; stdcall; external 'ntdll.dll';
function GetProcessModuleHandle(dwProcessID:DWORD;DllName:PChar):DWORD;
implementation
function EnablePrivilege(hToken: Cardinal; PrivName: string; bEnable: Boolean):Boolean;
var
TP: TOKEN_PRIVILEGES;
Dummy: Cardinal;
begin
try
TP.PrivilegeCount := 1;
LookupPrivilegeValue(nil, pchar(PrivName), TP.Privileges[0].Luid);
if bEnable then
TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else TP.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(hToken, False, TP, SizeOf(TP), nil, Dummy);
except
end;
Result :=True;
end;
function EnableDebugPrivilege: Boolean;
var
hToken: THandle;
begin
Result := False;
try
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
EnablePrivilege(hToken, 'SeDebugPrivilege', True);
CloseHandle(hToken);
Result :=True;
except
end;
end;
function GetProcessModuleHandle(dwProcessID:DWORD;DllName:PChar):DWORD;
var
hProcess:DWORD;
PBI:TProcessBasicInformation;
r,ret:DWORD;
readByte: SIZE_T;
PEBType:PPEB;
PLD :PPEB_LDR_DATA;
PME :PLDR_MODULE;
PEBDLLName:PChar;
const
Size:DWORD = 255;
begin
Result := 0;
GetMem(PEBType,SizeOf(PEB));
ZeroMemory(PEBType,SizeOf(PEB));
GetMem(PLD,SizeOf(PEB_LDR_DATA));
ZeroMemory(PLD,SizeOf(PEB_LDR_DATA));
GetMem(PME,SizeOf(LDR_MODULE));
ZeroMemory(PME,SizeOf(LDR_MODULE));
GetMem(PEBDLLName,Size);
try
//提升进程权限
if not EnableDebugPrivilege then
begin
OutputDebugStringW('Do not have Debug privilege');   //无法提升调试权限
end;
//如果PID为0则获取自身的伪句柄,如果不是则获取指定PID的句柄
if dwProcessID <> 0 then
//打开进程,需要PROCESS_QUERY_INFORMATION和PROCESS_VM_READ权限
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE,dwProcessID)
else
hProcess := GetCurrentProcess;
//调用NtQueryInformationProcess获取结构信息
ret := NtQueryInformationProcess(hProcess,0,@PBI,SizeOf(PBI),@r);
//正常情况下ret是0,如果不是则认为错误
if ret = 0 then
begin
//获取PEB结构
ReadProcessMemory(hProcess,PBI.PebBaseAddress,PEBType,SizeOf(PEB),readByte);
//获取PLD结构
ReadProcessMemory(hProcess,PEBType.LoaderData,PLD,SizeOf(PEB_LDR_DATA),readByte);
//获取第一个PME
ReadProcessMemory(hProcess,PLD.InLoadOrderModuleList.Flink,PME,SizeOf(LDR_MODULE),readByte);
//循环
while True do
begin
//清零缓冲区
ZeroMemory(PEBDLLName,Size);
//读取buff到内存中,获取当前结构的DLL名
if not ReadProcessMemory(hProcess,PME.BaseDllName.Buffer,PEBDLLName,PME.BaseDllName.Length,readByte) then Break;
//对比DLL名称,不区分大小写
if LowerCase(AnsiString(PEBDLLName)) = LowerCase(AnsiString(DllName)) then
begin
//调试信息
OutputDebugStringW(PEBDLLName);
//返回DLL的句柄
Result := dword(pme.BaseAddress);
//退出循环
Break;
end;
//调试信息
OutputDebugStringW(PEBDLLName);
//如果下一个结构为开始的结构,则认为链表已经枚举完了
if PME.InLoadOrderModuleList.Flink = PLD.InLoadOrderModuleList.Flink then Break;
//读取下一个结构
if not ReadProcessMemory(hProcess,PME.InLoadOrderModuleList.Flink,PME,SizeOf(LDR_MODULE),readByte) then Break;
end;
end
else
begin
//返回错误信息
OutputDebugStringW('Error!NtQueryInformationProcess Error!');
end;
finally
//释放使用的内存
FreeMem(PEBDLLName,Size);
FreeMem(PME,SizeOf(LDR_MODULE));
FreeMem(PLD,SizeOf(PEB_LDR_DATA));
FreeMem(PEBType,SizeOf(PEB));
end;
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: