I’m developing process monitoring idea and I would like to hook accesses to kernel32.dll (and some other dll’s as well), I hook the physical pages of the dll (from hypervisor) but unfortunately my process is not the only one who uses the dll so it causes a lot of overhead.
I want to use my own kernel32.dll instance, I use pssetloadimagenotifyroutine to see all the images that load to my process. I tried to do some tricks using the copy-on-write system so it will rallocate new memory to the pages but it didn’t really work since it blocked me from writing to the image (bsod).
Also I saw that I get image_info struct from the pssetloadimagenotifyroutine callback but after some research it seems it doesn’t effect anything in the system if I modify it.
Is there a way to do it without massivelly interfere with the system code?
You need to change the virtual address range protection from PAGE_EXECUTE_READ to PAGE_EXECUTE_WRITECOPY. NtProtectVirtualMemory/ZwProtectVirtualMemory does this. The bad news it is not exported by the kernel, though it can be located by some “disassembling” technique “embedded” in a driver.
if (KeGetCurrentIrql() == PASSIVE_LEVEL) {
DbgPrint(“Passive level”);
UNICODE_STRING pText;
// Obtain address to ZwProtectVirtualMemory
RtlInitUnicodeString(&pText, L"ZwProtectVirtualMemory");
auto NtProtect = MmGetSystemRoutineAddress(&pText);
DbgPrint(“ZwProtectVirtualMemory: %p”, NtProtect);
}
I will try this solution and will reply.
I know I can do this with filesystem filter driver (I’ve already done it in the past with dokan) but it’s a little of overhead to use new driver for this purpose only.
The following return on kernel32.dll (and all the other dll’s):
eStatus = c0000008 (STATUS_INVALID_HANDLE)
The handle I pass seems to be correct (- it’s the pid of the process - checked)
the base_address is right (double checked with windbg)
the page_size variable I correct (check in windbg) and from type ULONGLONG.
Now, I changed the page_size variable type from ULONG to ULONGLONG because I thought it might changed in 64bit. If I use the ULONG type it return the error: STATUS_INVALID_PARAMETER_3
It doesn’t seems like it should be failed in this error - unless it gets 0 (or another check) in the size -> which I thought it happens because of the wrong size of ULONG so I used ULONGLONG instead.
Any idea what type of size I need to use & what can cause this errors?
It should be a valid handle for a process object or NtCurrentProcess() not a PID.
If you have a process object use ObOpenObjectByPointer to get a handle.
If PAGE_EXECUTE_WRITECOPY failed try PAGE_EXECUTE_READWRITE. It might happen you are trying to modify a private portion of the address space which is not backed by a mapped file so COW is not supported for it.
Unfortunately it doesn’t seems to work, I noticed that if you iterate the header of the dll (pe header) it have access of 2 (PAGE_READONLY), the code have 20 (PAGE_EXECUTE_READ) access, also trying to set the exisiting protection failed - works only for the pe header. the code keeps returning the same error.
Why couldn’t you change the protection of memory pages within a mapped binary ?
The loader does this to resolve a binary dependencies.
My guess is that you are trying to change the protection of different regions of pages within the mapped binary. These are pages that have different protections. You must first query the size of the region a page belongs to before changing its protection. See VirtualQuery documentation.
I just refuse to believe my own eyes - this is already a second hooking-related thread in less than a week, but still I don’t see any reaction from “TELL US YOUR NAME AND COMPANY… (etc)” folks in so far.t If things keep on going this way I would not be too surprised if those who consider using Bo Branten’s Filedisk (or whatever it is called) are left unadvised about the possible legal ramifications of such a bold move…
If you’re going to hook kernel32.dll, why not hook from user mode? I’m assuming you have code in the memory space of the target process anyway since you need somewhere for those hooks to go.
VirtualProtect is definitely available in user mode and modifying kernel32 from the context of a user app will not negatively impact other processes.
> > I just refuse to believe my own eyes - this is already a second hooking-related thread in less than a week, but still I don’t see any reaction from “TELL US YOUR NAME AND COMPANY… (etc)” folks in so far.t If things keep on going this way I would not be too surprised if those who > consider using Bo Branten’s Filedisk (or whatever it is called) are left unadvised about the possible legal ramifications of such a bold move… > >
+1 for totally unnecessary provocative post of the week.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
> +1 for totally unnecessary provocative post of the week.
Sorry, guys,but I just could not resist the temptation this time - as you must have noticed it yourself, these days I try my best to behave However,in some cases the temptation is just too strong to resist.
Let’s face it - a thread like that without a “strong reaction” from certain posters is highly unusual,don’t you think…