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

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

delphi R3下 跨进程获取DLL信息 NtQueryInformationProcess的相关文章

.net环境下跨进程、高频率读写数据

原文:.net环境下跨进程.高频率读写数据 一.需求背景 1.最近项目要求高频次地读写数据,数据量也不是很大,多表总共加起来在百万条上下. 单表最大的也在25万左右,历史数据表因为不涉及所以不用考虑, 难点在于这个规模的热点数据,变化非常频繁. 数据来源于一些检测设备的采集数据,一些大表,有可能在极短时间内(如几秒钟)可能大部分都会变化, 而且主程序也有一些后台服务需要不断轮询.读写某种类型的设备,所以要求信息交互时间尽可能短. 2.之前的解决方案是把所有热点数据,统一加载到共享内存里边,到也能

ajax跨域获取cookie信息

js脚本ajax请求 news.xxx.com 请求www.xxx.com获取登录状态信息 $.ajax({             type: "GET",             url: 'http://www.xxx.com/index.php?m=member&'+Math.random(),             data: {},             dataType: "Html",             xhrFields: {  

Linux下查看进程和端口信息

1.根据进程名查看进程信息,以查看tomcat进程名为例,查看所对应的进程id为1095(或者使用: ps -aux | grep tomcat 查看占用内存等信息) ps -ef | grep tomcat 2.根据进程id查看进程占用端口,查看对应端口为8080(如果没有netstat命令,使用 yum  -y  install  net-tools安装) netstat -nap | grep 1095 3.根据端口查看对应进程,查看占用8080端口的进程id,为1095 netstat

Wayland中的跨进程过程调用浅析

原文地址:http://blog.csdn.net/jinzhuojun/article/details/40264449 Wayland协议主要提供了Client端应用与Server端Compositor的通信机制,Weston是Server端Compositor的一个参考实现.Wayland协议中最基础的是提供了一种面向对象的跨进程过程调用的功能,在作用上类似于Android中的Binder.与Binder不同的是,在Wayland中Client和Server底层通过domain socke

Wayland (三) Wayland中的跨进程过程调用浅析 [FW]

原文地址:http://blog.csdn.net/jinzhuojun/article/details/40264449 Wayland协议主要提供了Client端应用与Server端Compositor的通信机制,Weston是Server端Compositor的一个參考实现.Wayland协议中最基础的是提供了一种面向对象的跨进程过程调用的功能,在作用上类似于Android中的Binder.与Binder不同的是,在Wayland中Client和Server底层通过domain socke

微信快速开发框架V2.3--增加语音识别及网页获取用户信息(八),代码已更新至Github

不知不觉,版本以每周更新一次的脚步进行着,接下来应该是重构我的代码及框架的结构,有朋友反应代码有点乱,确实如此,当时写的时候只是按照订阅号来写的,后来才慢慢增加到支持API接口.目前还在开发第三方微信平台,旨在使用户能够无需自己开发就能简易搭建微信平台. 更新内容 1.增加支持语音识别 2.增加"网页授权获取用户基本信息" 语音识别其实是对Voice信息的一个扩展,您必须启用语音识别功能,启用后会在VoiceMessage中增加一个Recongnition字段,我们可以判断这个字段的内

win/linux 下使用 psutil 获取进程 CPU / memory / IO 占用信息

psutil - A cross-platform process and system utilities module for Python 1. 安装 pip 安装即可. windows 下需要安装 vs2008,否则报错: Unable to find vcvarsall.bat 如果已经安装 vs2010 / vs2012 则需要设置环境变量,VS90COMNTOOLS 指向已有的 vs 变量. vs2010 设置如下: VS90COMNTOOLS = %VS100COMNTOOLS%

获取系统进程信息和进程依赖的dll信息

body { font-family: Bitstream Vera Sans Mono; font-size: 11pt; line-height: 1.5; } html, body { color: #000000; background-color: #C2E7C7; } h1 { font-size:1.5em; font-weight:bold; } h2 { font-size:1.4em; font-weight:bold; } h3 { font-size:1.3em; fon

手把手教你R0下通过EPROCESS获取进程加载模块

在R3下获取一个进程加载的相关模块儿还是比较简单的,直接通过ToolHelp32库API就能够获取到进程关联的模块儿了,但是既然已经在R0下混了再去使用R3层的东西就没什么意义了,所以这里小悠在这里将会一部一部的介绍如何在R0下通过EPROCESS结构获取到进程加载的模块. 首先这里我们先介绍一下我们通过EPROCESS查询的大概思路 ①  通过EPROCESS 获取到对应的PEB 结构 ②  通过PEB找到 _PEB_LDR_DATA这货 ③  在_PEB_LDR_DATA内部有3个LIST_