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.
时间: 2024-10-13 08:40:48