2011-06-11 82 views
5

我想读notepad.exe的PEB 目前我试图通过注册ProcessCreation回调来访问PEB,然后等到创建notepad.exe。当创建记事本时,我使用它的PID打开进程并使用ZwQuerryProcess(PROCESS_BASIC_INFORMATION)查找PEB。如何访问用户模式内存?

但是当我尝试读取超出信息 - > 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, 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 

EDIT2:

我已经解决了这个问题。我仍然不知道哪里出了问题在上面的代码,但是这个代码似乎工作:

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, OBJ_KERNEL_HANDLE, NULL, 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; 
        } 

    //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, &ep); 

        if(Status != STATUS_SUCCESS){ 
           DbgPrint("PsLookupProcessByProcessId failed\n"); 
           DbgPrint("NtStatus: 0x%x\n", 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, LDR_DATA_TABLE_ENTRY, 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, LDR_DATA_TABLE_ENTRY, 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; 
} 

回答

0

这是您的PsGetProcessPeb:

/base/ntos/ps/pshelper.c

PPEB 
PsGetProcessPeb(
    __in PEPROCESS Process 
    ) 
{ 
    return Process->Peb; 
} 

不需要做额外的工作,从EPROCESS结构提取PEB指针(其除了32/64-bit区别外,其他所有版本都很相似)

而且你可以得到EPROCESSPsLookupProcessByProcessId,使用ID=4(系统过程)。