<原创> 通过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结构
PEB偏移0x10处还有个指针ProcessParameters,指向一个进程参数块PPB、即RTL_USER_PROCESS_PARAMETERS数据结构。
这PPB也是在用户空间的,虽然是个独立存在的数据结构,逻辑上却可以看作是PEB的一部分。
进程参数块RTL_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,成功找到,这样就可以进入具体的代码实现了
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; }
相关文章推荐
- 2016蓝桥杯假期任务之《核桃的数量 》
- 在eclipse中配置opencv开发环境
- ActiveMQ学习心得之ActiveMQ四种存储器分析
- ScaleType简单属性介绍
- 我的Node.js处女作
- FastReport.Net 常用功能总汇
- 自定义UITableViewCell(registerNib: 与 registerClass: 的区别)
- iOS UIScrollView使用Autolayout
- 【ntp】centos7下ntp服务器设置
- Codeforces--630F--Selection of Personnel(组合数)
- 流媒体开发之--HLS--M3U8解析(2): HLS草案
- 研发流程图
- javaScript系列:js中获取时间new Date()详细介绍
- 管理域计算机
- Animation动画详解(十)——联合动画的XML实现与使用示例
- Docker网络详解及pipework源码解读与实践
- QML动画使用总结
- 杭电1276士兵队列训练问题
- Uncaught TypeError: boolean is not a function
- ECMAScript5之Array