您的位置:首页 > 其它

<原创> 通过PEB获得进程路径 (附完整工程)

2016-03-09 18:10 405 查看
完整工程: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,成功找到,这样就可以进入具体的代码实现了

BOOLEAN GetProcessPathByEProcess(PEPROCESS EProcess,WCHAR* wzProcessPath)
{
PPEB  Peb = NULL;
KAPC_STATE ApcState;
ULONG_PTR  ProcessParameters = NULL;

if (EProcess==NULL||!MmIsAddressValid(EProcess))
{
return FALSE;
}
Peb = PsGetProcessPeb(EProcess);
if (Peb==NULL)
{
return FALSE;
}

KeStackAttachProcess(EProcess, &ApcState);   //切入进程地址空间,很重要

ProcessParameters = *(ULONG_PTR*)((ULONG_PTR)Peb+ProcessParametersOfPeb);

memcpy(wzProcessPath,((PUNICODE_STRING)((ULONG_PTR)ProcessParameters+ImagePathNameOfProcessParameters))->Buffer,
((PUNICODE_STRING)((ULONG_PTR)ProcessParameters+ImagePathNameOfProcessParameters))->Length);

KeUnstackDetachProcess(&ApcState);      //切出进程,很重要

return TRUE;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: