| View previous topic :: View next topic |
| Author |
Message |
iPromise Grandmaster Cheater
Reputation: -1
Joined: 27 Jun 2009 Posts: 529 Location: Canada
|
Posted: Fri Nov 09, 2012 9:44 pm Post subject: Bypassing OpenProcess |
|
|
Does the NtCurrentProcess macro return the same result as OpenProcess would? A valid handle that can be used with a usermode application?
Also, in the case where OpenProcess was under a Ring0 hook how do I plan on bypassing it?
|
|
| Back to top |
|
 |
SteveAndrew Master Cheater
Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Sat Nov 10, 2012 3:34 am Post subject: Re: Bypassing OpenProcess |
|
|
| iPromise wrote: | Does the NtCurrentProcess macro return the same result as OpenProcess would? A valid handle that can be used with a usermode application?
Also, in the case where OpenProcess was under a Ring0 hook how do I plan on bypassing it? |
Yes I'm pretty sure! The Nt instead of Zw is for usermode... You aren't actually calling the kernel mode version unless you're calling the Zw Kernel API's! Remember you can still execute usermode code like normally from the kernel.
For openprocess the way I used was just doing a 'KeAttachProcess' or 'KeStackAttachProcess' then 'KeDetachProcess' or 'KeStackDetachProcess' when detaching.
If those are hooked just do a hook hop or trampoline to regain the ability to KeAttachProcess...
Once attached in this way, you can access the memory of the attached application just as if you were inside of it! Actually you are operating from inside the attached application running from a thread which is actually inside the process! Careful though! If the address you access is invalid you will BSOD.
Alright let me see if I can remember correctly:
| Code: |
PEPROCESS TargetProcess;
ULONG TargetProcessId = 0x1234;
ULONG SomeValidAddressInTarget = 0x400000;
unsigned short MZHeader = 0;
PsLookupProcessByProcessId((HANDLE)TargetProcessId, &TargetProcess);
KeAttachProcess(TargetProcess);
MZHeader = *(unsigned short*)SomeValidAddressInTarget; //read
if(MZHeader == 'MZ')
{
DbgPrint("MZ Header Found! Lets Reverse it for fun!");
}
*(unsigned short*)SomeValidAddressInTarget = 'ZM'; //write
KeDetachProcess();
|
If you do that you should see the 'MZ' at the imagebase of your application your testing on change to 'ZM'(well I hardcoded it to 0x400000 here so test it on an exe that has the usual 0x400000 image base)
Yes the process id from user mode is the same thing as in the kernel. The same as if you look at the task manager for the PID! Pass the target process id in from your usermode application, yes its probably possible to get a process id from a process name from inside the kernel, but its much easier just to get it the normal easy way in usermode and pass it into the kernel using IO (calling DeviceIoControl from usermode, and defining IOCTLS in kernel mode and setting up the basic way to pass data in from usermode [implementing create/close {just return STATUS_SUCCESS) and a function in IRP_MJ_xx to implement using the IrpStack to read data passed in from usermode and optionally write data back out to usermode.
Oh and the documentation says not to use KeAttachProcess anymore in favor of KeStackAttachProcess so I guess we'll do that:
| Code: |
PEPROCESS TargetProcess;
KAPC_STATE *kapc_state = 0;
ULONG TargetProcessId = 0x1234;
ULONG SomeValidAddressInTarget = 0x12345678;
PsLookupProcessByProcessId((HANDLE)TargetProcessId, &TargetProcess);
KeStackAttachProcess(TargetProcess, kapc_state);
ULONG ReadTheValue = *(ULONG*)SomeValidAddressInTarget; //read
*(ULONG*)SomeValidAddressInTarget = 0x539; //write
KeUnstackDetachProcess(kapc_state);
|
Hope you get it working! Make sure you're getting the correct process id though! Test it by manually putting the correct process id if your process id isn't getting passed in from usermode correctly (Then that would be your issue, if KeAttach/KeStackAttach doesn't get the right eprocess to attach to of course it isn't going to be right)
And if you really want to actually use ZwOpenProcess I think you can like this:
| Code: |
NTSTATUS Status = STATUS_SUCCESS;
HANDLE hProcess = 0;
CLIENT_ID client_id;
ACCESS_MASK DesiredAccess = PROCESS_ALL_ACCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG TargetProcessId = 0;
InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0);
client_id.UniqueProcess = (HANDLE) TargetProcessId;
client_id.UniqueThread = 0;
Status = ZwOpenProcess(&hProcess, DesiredAccess, &ObjectAttributes, &client_id);
if (!NT_SUCCESS(Status))
{
DbgPrint("cannot get process handle, ERROR CODE = %08X\n", Status);
IoStatus->Status = STATUS_UNSUCCESSFUL;
return IoStatus->Status;
}
DbgPrint("process handle = %08X\n", hProcess);
|
It would be a kernel handle (since we used a Zw) So you would have to use ZwWriteVirtualMemory or ZwReadVirtualMemory with the kernel mode handle from ZwOpenProcess to write/read memory to your target process!
And don't forget to use ZwClose(ProcessHandle); to close the kernel mode handle after you're done with it! (the kernel mode CloseHandle API)
_________________
|
|
| Back to top |
|
 |
iPromise Grandmaster Cheater
Reputation: -1
Joined: 27 Jun 2009 Posts: 529 Location: Canada
|
Posted: Sat Nov 10, 2012 12:49 pm Post subject: |
|
|
Sorry for the misunderstanding I already have a driver which has attached to a usermode application.
The problem is that when I try to set a hook on a usermode function with my driver, the usermode fnction is protected with PAGE_EXECUTE_READ. I need to change that into PAGE_EXECUTE_READWRITE in order to set my hook successfully.
If I use OpenProcess / VirtualProtectEx from the usermode application before hand and then set the hook with my driver it won't work because OpenProcess is under a hook. So I thought that maybe Zw/NtCurrentProcess was equivlant to OpenProcess and that I can use instead of OpenProcess.
The problem with ZwProtectVirtualMemory is that it hasn't been documented and therefore I have to grab the kernel address myself which is a pain in the ass because I haven't done that before. MmGetRoutineSystemAddress keeps returning 0 for functions that Microsoft doesn't really want others using such as ZwProtectVirtualMemory.
So if I can get ZwProtectVirtualMemory or if I can bypass OpenProcess I can set my hook.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25837 Location: The netherlands
|
Posted: Sat Nov 10, 2012 2:14 pm Post subject: |
|
|
Another way of obtaining a functional processhandle is by using ObOpenObjectByPointer and pass it the EProcess of the target process and request a handle of type PsProcessType
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
|