windows 如何访问用户模式内存?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6316880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 17:02:55  来源:igfitidea点击:

How to access user mode memory?

cwindowskernelwdk

提问by Unknown

I'm trying to read the PEB of notepad.exe Currently I'm trying to access the PEB by registering a ProcessCreation callback and then waiting until notepad.exe is created. When notepad is created I use it's PID to open the process and find the PEB with ZwQuerryProcess(PROCESS_BASIC_INFORMATION).

我正在尝试读取 notepad.exe 的 PEB 目前我正在尝试通过注册 ProcessCreation 回调然后等待直到创建 notepad.exe 来访问 PEB。创建记事本时,我使用它的 PID 打开进程并使用 ZwQuerryProcess(PROCESS_BASIC_INFORMATION) 找到 PEB。

But when I try to read beyond INFORMATION->PEB an exception is raised (I assume this is because I can't access the memory)

但是当我尝试阅读 INFORMATION->PEB 之外的内容时,会引发异常(我认为这是因为我无法访问内存)

When I first discovered this I remembered someone mentioning the KeStackAttachProcess and it's counterpart to access addresses inside another process context.

当我第一次发现这个时,我记得有人提到了 KeStackAttachProcess,它对应于访问另一个进程上下文中的地址。

The problem is that I don't know how to check if the context change was successful or not. And once I'm supposedly inside another context I still can't access the peb. Does anyone know how I can access the PEB of notepad?

问题是我不知道如何检查上下文更改是否成功。一旦我进入另一个上下文,我仍然无法访问 peb。有谁知道我如何访问记事本的PEB?

Here's the code I'm currently using to find and access the PEB:

这是我目前用于查找和访问 PEB 的代码:

Assume hgtPid = the PID of notepad

假设 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;
}

Does anyone spot any errors/faults?

有没有人发现任何错误/故障?

Thanks in advance

提前致谢

EDIT:

编辑:

I've changed a few things, and this is where it gets really bizarre. For the sake of being sure I changed the 'ep' of KeStackAttachProcess() to the by msdn designated PRKPROCESS type, when I call KeStackAttachProcess() now execution just disappears. Before the call everything is going fine, after the call there's just nothing. No errors no exceptions no BSOD's: Nothing. What's going on?!?

我改变了一些东西,这就是它变得非常奇怪的地方。为了确保我将 KeStackAttachProcess() 的“ep”更改为 msdn 指定的 PRKPROCESS 类型,当我调用 KeStackAttachProcess() 时,现在执行就消失了。通话前一切正常,通话后就什么都没有了。没有错误没有例外没有蓝屏:没有。这是怎么回事?!?

Changes:

变化:

    __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:

编辑2:

I have solved the problem. I still don't know what went wrong in the above code, however this code appears to be working:

我已经解决了这个问题。我仍然不知道上面的代码出了什么问题,但是这段代码似乎可以正常工作:

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;
}

回答by swatkat

You can use PPEB PsGetProcessPeb ( IN PEPROCESS Process ). You need to use MmGetSystemRoutineAddressto get this API's address. Take a look at GetDllByPebfunction in this file: http://code.google.com/p/arkitlib/source/browse/trunk/ARKitDrv/Ps.c

您可以使用PPEB PsGetProcessPeb ( IN PEPROCESS Process ). 您需要使用MmGetSystemRoutineAddress来获取此 API 的地址。看看GetDllByPeb这个文件中的函数:http: //code.google.com/p/arkitlib/source/browse/trunk/ARKitDrv/Ps.c

回答by Ogame Opensource admin

This is your PsGetProcessPeb :

这是你的 PsGetProcessPeb :

/base/ntos/ps/pshelper.c

/base/ntos/ps/pshelper.c

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

No need to do extra-work to extract PEBpointer from the EPROCESSstruct (which is pretty same for all Windows versions, except 32/64-bitdifference)

不需要做额外的工作来PEBEPROCESS结构中提取指针(这对于所有 Windows 版本都非常相同,除了32/64-bit不同)

And you can get EPROCESSby PsLookupProcessByProcessId, using ID=4(System Process).

你可以EPROCESS通过PsLookupProcessByProcessId,使用ID=4(系统进程)。