<原創> 通過PEB獲得進程路徑 (附完整工程)


完整工程:http://files.cnblogs.com/files/Gotogoo/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86%E5%99%A8%28x86%26%26x64%29.zip

 

PEB(Process Environment Block,進程環境塊)存放進程信息,每個進程都有自己的PEB信息。位於用戶地址空間。

PEB地址可以通過函數PsGetProcessPeb(EPROCESS)來獲得,也可以通過EPROCESS基地址加偏移0x1b0(x86)來獲得。

 

PEB結構

 

  typedef struct _PEB { // Size: 0x1D8

  /*000*/ UCHAR InheritedAddressSpace;

  /*001*/ UCHAR ReadImageFileExecOptions;

  /*002*/ UCHAR BeingDebugged;

  /*003*/ UCHAR SpareBool;

  /*004*/ HANDLE Mutant;

  /*008*/ HINSTANCE ImageBaseAddress; 

  /*00C*/ VOID *DllList;

  /*010*/ PPROCESS_PARAMETERS *ProcessParameters;    //進程參數塊 
  /*014*/ ULONG SubSystemData;

  /*018*/ HANDLE DefaultHeap;

  /*01C*/ KSPIN_LOCK FastPebLock;

  /*020*/ ULONG FastPebLockRoutine;

  /*024*/ ULONG FastPebUnlockRoutine;

  /*028*/ ULONG EnvironmentUpdateCount;

  /*02C*/ ULONG KernelCallbackTable;

  /*030*/ LARGE_INTEGER SystemReserved;

  /*038*/ ULONG FreeList;

  /*03C*/ ULONG TlsExpansionCounter;

  /*040*/ ULONG TlsBitmap;

  /*044*/ LARGE_INTEGER TlsBitmapBits;

  /*04C*/ ULONG ReadOnlySharedMemoryBase;

  /*050*/ ULONG ReadOnlySharedMemoryHeap;

  /*054*/ ULONG ReadOnlyStaticServerData;

  /*058*/ ULONG AnsiCodePageData;

  /*05C*/ ULONG OemCodePageData;

  /*060*/ ULONG UnicodeCaseTableData;

  /*064*/ ULONG NumberOfProcessors;

  /*068*/ LARGE_INTEGER NtGlobalFlag; 

  /*070*/ LARGE_INTEGER CriticalSectionTimeout;

  /*078*/ ULONG HeapSegmentReserve;

  /*07C*/ ULONG HeapSegmentCommit;

  /*080*/ ULONG HeapDeCommitTotalFreeThreshold;

  /*084*/ ULONG HeapDeCommitFreeBlockThreshold;

  /*088*/ ULONG NumberOfHeaps;

  /*08C*/ ULONG MaximumNumberOfHeaps;

  /*090*/ ULONG ProcessHeaps;

  /*094*/ ULONG GdiSharedHandleTable;

  /*098*/ ULONG ProcessStarterHelper;

  /*09C*/ ULONG GdiDCAttributeList;

  /*0A0*/ KSPIN_LOCK LoaderLock;

  /*0A4*/ ULONG OSMajorVersion;

  /*0A8*/ ULONG OSMinorVersion;

  /*0AC*/ USHORT OSBuildNumber;

  /*0AE*/ USHORT OSCSDVersion;

  /*0B0*/ ULONG OSPlatformId;

  /*0B4*/ ULONG ImageSubsystem;

  /*0B8*/ ULONG ImageSubsystemMajorVersion;

  /*0BC*/ ULONG ImageSubsystemMinorVersion;

  /*0C0*/ ULONG ImageProcessAffinityMask;

  /*0C4*/ ULONG GdiHandleBuffer[0x22];

  /*14C*/ ULONG PostProcessInitRoutine;

  /*150*/ ULONG TlsExpansionBitmap;

  /*154*/ UCHAR TlsExpansionBitmapBits[0x80];

  /*1D4*/ ULONG SessionId;

  } PEB, *PPEB;

 

PEB偏移0x10處還有個指針ProcessParameters,指向一個進程參數塊PPB、即RTL_USER_PROCESS_PARAMETERS數據結構。

這PPB也是在用戶空間的,雖然是個獨立存在的數據結構,邏輯上卻可以看作是PEB的一部分。

 

進程參數塊RTL_USER_PROCESS_PARAMETERS結構

typedef struct _RTL_USER_PROCESS_PARAMETERS
{
     ULONG MaximumLength;
     ULONG Length;
     ULONG Flags;
     ULONG DebugFlags;
     PVOID ConsoleHandle;
     ULONG ConsoleFlags;
     PVOID StandardInput;
     PVOID StandardOutput;
     PVOID StandardError;
     CURDIR CurrentDirectory;
     UNICODE_STRING DllPath;
     UNICODE_STRING ImagePathName;     //進程完整路徑
     UNICODE_STRING CommandLine;
     PVOID Environment;
     ULONG StartingX;
     ULONG StartingY;
     ULONG CountX;
     ULONG CountY;
     ULONG CountCharsX;
     ULONG CountCharsY;
     ULONG FillAttribute;
     ULONG WindowFlags;
     ULONG ShowWindowFlags;
     UNICODE_STRING WindowTitle;
     UNICODE_STRING DesktopInfo;
     UNICODE_STRING ShellInfo;
     UNICODE_STRING RuntimeData;
     RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];
     ULONG EnvironmentSize;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

 

下面以x86為例,在Windbg中可以具體實驗感受一下:

1.先隨便找個進程

 

 

2.注意PEB是在用戶空間,從他的地址也可以看出來,因為7ffdf000<80000000,

所以在查看PEB時要先使用命令 .process 899ac958 切入我們我們所找的SogouExe.exe進程的地址空間中,這個很重要

然后我們查看進程SogouExe.exe的PEB

 

 

 

 

3.在偏移0x10處看到了結構體RTL_USER_PROCESS_PARAMETERS,從圖中可以看出,它位於地址0x20000處

繼續查看它

 

 

 

 

4,在偏移0x38處就存放着進程完整路徑。OK,成功找到,這樣就可以進入具體的代碼實現了

 

 1 BOOLEAN GetProcessPathByEProcess(PEPROCESS EProcess,WCHAR* wzProcessPath)
 2 {
 3     PPEB  Peb = NULL;
 4     KAPC_STATE ApcState;
 5     ULONG_PTR  ProcessParameters = NULL;
 6      
 7 
 8     if (EProcess==NULL||!MmIsAddressValid(EProcess))
 9     {
10         return FALSE;
11     }
12     Peb = PsGetProcessPeb(EProcess);
13     if (Peb==NULL)
14     {
15         return FALSE;
16     }
17     
18     KeStackAttachProcess(EProcess, &ApcState);   //切入進程地址空間,很重要
19 
20 
21     ProcessParameters = *(ULONG_PTR*)((ULONG_PTR)Peb+ProcessParametersOfPeb);
22 
23     memcpy(wzProcessPath,((PUNICODE_STRING)((ULONG_PTR)ProcessParameters+ImagePathNameOfProcessParameters))->Buffer,
24         ((PUNICODE_STRING)((ULONG_PTR)ProcessParameters+ImagePathNameOfProcessParameters))->Length);
25 
26 
27 
28     KeUnstackDetachProcess(&ApcState);      //切出進程,很重要 29 
30 
31 
32     return TRUE;
33 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM