如何访问用户态内存?
我正在尝试读取 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, 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;
}
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).
But when I try to read beyond INFORMATION->PEB an exception is raised (I assume this is because I can't access the memory)
When I first discovered this I remembered someone mentioning the KeStackAttachProcess and it's counterpart to access addresses inside another process context.
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?
Here's the code I'm currently using to find and access the PEB:
Assume hgtPid = the PID of notepad
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?!?
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:
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您可以使用
PPEB PsGetProcessPeb(IN PEPROCESS Process)
。您需要使用MmGetSystemRoutineAddress
来获取该API的地址。看一下此文件中的GetDllByPeb
函数:http://code.google.com/p/arkitlib /source/browse/trunk/ARKitDrv/Ps.c
You can use
PPEB PsGetProcessPeb ( IN PEPROCESS Process )
. You need to useMmGetSystemRoutineAddress
to get this API's address. Take a look atGetDllByPeb
function in this file:http://code.google.com/p/arkitlib/source/browse/trunk/ARKitDrv/Ps.c