问题描述
|
我正在尝试阅读notepad.exe的PEB
当前,我正在尝试通过注册ProcessCreation回调访问PEB,然后等待创建notepad.exe。创建记事本后,我将使用其PID来打开进程并使用ZwQuerryProcess(PROCESS_BASIC_INFORMATION)查找PEB。
但是,当我尝试读取INFORMATION-> PEB以外的内容时,会引发异常(我认为这是因为我无法访问内存)
当我第一次发现这个问题时,我想起有人提到KeStackAttachProcess,它是在另一个进程上下文中访问地址的对应对象。
问题是我不知道如何检查上下文更改是否成功。而且,一旦我进入另一个环境,我仍然无法访问peb。有谁知道我如何访问记事本的PEB?
这是我当前用于查找和访问PEB的代码:
假设hgtPid =记事本的PID
void ModuleDumperThread(){
NTSTATUS Status = STATUS_SUCCESS;
HANDLE hProcessHandle = NULL;
PLIST_ENTRY Next;
PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
CLIENT_ID clientID;
ACCESS_MASK DesiredAccess = PROCESS_ALL_ACCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hProcessId = hgtPid;
PROCESS_BASIC_INFORMATION BasicInfoReal;
ULONG SizeReturned;
PEPROCESS ep;
KAPC_STATE *ka_state = NULL;
InitializeObjectAttributes (&ObjectAttributes,NULL,OBJ_KERNEL_HANDLE,NULL);
clientID.UniqueProcess = hProcessId;
clientID.UniqueThread = NULL;
__try{
Status = ZwOpenProcess(&hProcessHandle,DesiredAccess,&ObjectAttributes,&clientID);
if(Status != STATUS_SUCCESS){
DbgPrint(\"Failed to open process\\n\");
DbgPrint(\"NtStatus: 0x%x\",Status);
return;
}
Status = gZwQueryprocess(hProcessHandle,ProcessBasicInformation,(PVOID)&BasicInfoReal,sizeof(PROCESS_BASIC_INFORMATION),&SizeReturned);
if(Status != STATUS_SUCCESS){
DbgPrint(\"gZwQueryprocess failed\\n\");
DbgPrint(\"Size returned: 0x%x\\nNtStatus: 0x%x\\n\",SizeReturned,Status);
ZwClose(hProcessHandle);
return;
}
ZwClose(hProcessHandle);
Status = PsLookupProcessByProcessId(hProcessId,&ep);
if(Status != STATUS_SUCCESS){
DbgPrint(\"PsLookupProcessByProcessId failed\\n\");
DbgPrint(\"NtStatus: 0x%x\\n\",Status);
return;
}
ka_state = ExAllocatePoolWithTag(NonPagedPool,sizeof(KAPC_STATE),\'trak\');
KeStackAttachProcess(ep,ka_state);
__try{
if(BasicInfoReal.PebBaseAddress->Ldr){
Next = BasicInfoReal.PebBaseAddress->Ldr->InLoadOrderModuleList.Blink;
LdrDataTableEntry = CONTAINING_RECORD( Next,LDR_DATA_TABLE_ENTRY,LoadOrder
);
DbgPrint(\"Module base address: 0x%x\",LdrDataTableEntry->ModuleBaseAddress);
}
}__except( EXCEPTION_EXECUTE_HANDLER ) {
DbgPrint(\"Exception while trying to access the PEB\\n\");
}
KeUnstackDetachProcess(ka_state);
ExFreePool(ka_state);
}__except( EXCEPTION_EXECUTE_HANDLER ) {
DbgPrint(\"Exception in ModuleDumper\\n\");
}
if(ep){
ObDereferenceObject(ep);
}
return;
}
是否有人发现任何错误/故障?
提前致谢
编辑:
我已经更改了几件事,而这正是它变得奇怪的地方。为了确保我将KeStackAttachProcess()的'ep'更改为由msdn指定的PRKPROCESS类型,当我调用KeStackAttachProcess()时,执行消失了。通话之前一切正常,通话之后一切都没有。没有错误,没有例外,没有BSOD:没有。这是怎么回事?!?
变化:
__asm{
mov eax,ep
mov eax,[eax]
mov myPKPROCESS,eax // just dereferencing my pointer (I don\'t have the structs)
}
DbgPrint(\"Test print\\n\"); // gets printed just fine
KeStackAttachProcess(&myPKPROCESS,ka_state);
DbgPrint(\"Test print\\n\"); // nothing happens
编辑2:
我已经解决了问题。我仍然不知道上面的代码出了什么问题,但是这段代码似乎可以正常工作:
void ModuleDumperThread(){
NTSTATUS Status = STATUS_SUCCESS;
HANDLE hProcessHandle = NULL;
PLIST_ENTRY Next;
PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
CLIENT_ID clientID;
ACCESS_MASK DesiredAccess = PROCESS_ALL_ACCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hProcessId = hgtPid;
PROCESS_BASIC_INFORMATION BasicInfoReal;
ULONG SizeReturned;
PEPROCESS ep = NULL;
unsigned int Index = 0;
InitializeObjectAttributes (&ObjectAttributes,NULL);
clientID.UniqueProcess = hProcessId;
clientID.UniqueThread = NULL;
__try{
Status = ZwOpenProcess(&hProcessHandle,&SizeReturned);
if(Status != STATUS_SUCCESS){
DbgPrint(\"gZwQueryprocess failed\\n\");
DbgPrint(\"Size returned: 0x%x\\nNtStatus: 0x%x\\n\",Status);
ZwClose(hProcessHandle);
return;
}
//DbgPrint(\"Basic info: 0x%x\\n\",BasicInfoReal);
//DbgPrint(\"BasicInfoReal->PebBaseAddress: 0x%x\\n\",BasicInfoReal->PebBaseAddress);
//DbgPrint(\"RealPeb: 0x%x\\n\",RealPeb);
//DbgPrint(\"gZwReadVirtualMemory: 0x%x\\n\",gZwReadVirtualMemory);
Status = PsLookupProcessByProcessId(hProcessId,Status);
ZwClose(hProcessHandle);
return;
}
Timeout((INT64)0x1FFFFFF);
KeAttachProcess(ep);
__try{
DbgPrint(\"ImageBaseAddress of notepad.exe: 0x%x\\n\",BasicInfoReal.PebBaseAddress->ImageBaseAddress);
Next = BasicInfoReal.PebBaseAddress->Ldr->InLoadOrderModuleList.Blink;
LdrDataTableEntry = CONTAINING_RECORD( Next,LoadOrder);
for(Index = 0; Index != 17; Index++){
DbgPrint(\"%d: ImageBase of %wZ in Notepad.exe: 0x%x\\n\",Index,&(LdrDataTableEntry->ModuleName),LdrDataTableEntry->ModuleBaseAddress);
Next = Next->Blink;
LdrDataTableEntry = CONTAINING_RECORD(Next,LoadOrder);
}
}__except( EXCEPTION_EXECUTE_HANDLER ) {
DbgPrint(\"Exception while accessing the LDR\\n\");
}
KeDetachProcess();
}__except( EXCEPTION_EXECUTE_HANDLER ) {
DbgPrint(\"Exception in ModuleDumper\\n\");
}
ObDereferenceObject((PVOID)ep);
ZwClose(hProcessHandle);
return;
}
解决方法
您可以使用
PPEB PsGetProcessPeb ( IN PEPROCESS Process )
。您需要使用MmGetSystemRoutineAddress
来获取此API的地址。看一下此文件中的GetDllByPeb
函数:
http://code.google.com/p/arkitlib/source/browse/trunk/ARKitDrv/Ps.c
, 这是您的PsGetProcessPeb:
/base/ntos/ps/pshelper.c
PPEB
PsGetProcessPeb(
__in PEPROCESS Process
)
{
return Process->Peb;
}
无需做任何额外的工作即可从EPROCESS
结构中提取PEB
指针(除32/64-bit
差异外,所有Windows版本都相同)
使用ID=4
(系统进程),您可以将ѭ9减为PsLookupProcessByProcessId
。