• 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.
  • 相关阅读:
    二分图的部分关系
    二分图的部分关系
    日常训练赛 Problem C – Complete Naebbirac’s sequence
    日常训练赛 Problem C – Complete Naebbirac’s sequence
    J
    J
    Python strip()方法
    Python startswith()方法
    Python splitlines()方法
    Python split()方法
  • 原文地址:https://www.cnblogs.com/cfas/p/5124128.html
Copyright © 2020-2023  润新知