dev65
dev65

Reputation: 1605

How to prevent memory editing to prevent hooking

I recently learned inline hooking x32 and x64 which is based on overwriting the first bytes of the function with a jmp to the hooking function or by pushing the 64 address to rax then jmp rax to perform a far jmp on x64 architecture I also learned iat hooking and delay imports hooking which requires editing an offest holding function address in the import table to point to my hook function Also hooking by exceptions requires editing at least the first byte to an unknown byte so an exception will be thrown and you will catch it with your already installed handler and redirect to your trampoline

All these types of hooking requires editing memory and the memory usually is PAGE_EXECUTEREAD for functions or read only for the import table

So the attacker will use VirtualProtect or NtVirtualProtect to be able to edit the bytes

One more hooking method is via guard exceptions which almost doesn't require any editing to the bytes but to the memory protection so an exception will be raised on accessing the function and you will handle them and do whatever you want

So these methods all require changing the protection of the memory so i think of hooking VirtualProtect and NtVirtualProtect to prevent any edit for particular addresses but the hooker can unhook the functions and bypass this

I heard about new mitigations such dynamic code generation preventing but I need to allocate some executable code so I can't use this and it won't protect against iat hooking and guard exceptions hooking

Is there really a method to full defend against hooking or at least make it very hard ?

Upvotes: 2

Views: 4480

Answers (3)

Jason
Jason

Reputation: 150

To prevent memory editing which in turn may prevent hooking, proper configurations for the process must be in place. Attackers will modify code through calls to WriteProcessMemory/NtWriteVirtualMemory when the specified memory is passed into the call. Attackers will use these routines regardless of if they are executing within the context of the process they are modifying. There are various other ways to write memory within the process as well that attackers may use which I will go over how to protect from.

Do note that you cannot prevent WriteProcessMemory/NtWriteVirtualMemory calls from modifying code from user-mode without proper attributes being configured for the pages containing the addresses being modified. When NtWriteVirtualMemory initiates a system service request, the kernel handles the rest.

From a kernel-mode standpoint, the API provided for Windows drivers does provide a routine that registers callbacks for operations on certain types of handles such as process and thread handles. This routine is called ObRegisterCallbacks. Some software uses this routine to prevent certain operations on their handle(s) from being complete.

ObRegisterCallbacks can register callbacks for the following types of handle operations

  • Process handles
  • Thread handles
  • Desktop handles

Preventing specific operations on a designated process handle can prevent system service requests such as NtWriteVirtualMemory (WriteProcessMemory) and NtProtectVirtualMemory (VirtualProtect/Ex) from being complete. Doing so prevents the attacker from writing memory to your process through a service request and it prevents them from changing the protections of virtual pages in your process.

From a user-mode standpoint, you are much more limited in terms of being able to read the kernel data structures for objects such as processes and threads and you are much more limited in what types of routines you can call. WriteProcessMemory cannot be prevented if the attacker just decides to call VirtualProtectEx and change the page from read-only/execute to read/write/execute.

A strong configuration for the code and data sections of your process will still go a long way though. In fact, it's important to make sure any and all security descriptors, DACLs, etc., in your process are properly configured. First and foremost, make sure that your code pages are read-only/execute. Each process contains a VAD (virtual address descriptor) tree (implemented as an AVL tree) to the kernel. A VAD contains the attributes and flags for a range of virtual addresses in your process. Such attributes and flags include the various types of protections such as read/write/execute, copy on write, whether memory is committed/reserved, etc...

There is a flag used in VAD flags called SecNoChange. If you remap the code section in your process using NtCreateSection then pass SecNoChange in the AllocationAttributes and then call NtMapViewOfSection to map the memory back into the process, then it will make calls such as NtProtectVirtualMemory fail. This will prevent attackers from modifying the page attributes for your code so that they can't cause arbitrary exceptions and handle them to redirect code, nor can they change the protections if they are read-only/execute to write to that memory. Writing to read-only memory will of course fail. This is where it would be important for the code pages to be marked as read-only/execute instead of read/write/execute, so that the attacker cannot change the protection nor write to the address range.

Even with your sections configured with SecNoChange, it also does not hurt to have additional mitigation techniques such as memory integrity checks. At the basic level, memory integrity checks generally work by hashing the contents of the memory of a group of pages and verifying the integrity of the next cycle with the first hash generated, if the hashes differ, then memory has been modified and the program may terminate its current activity.

Windows provides many types of mitigation techniques and policies. I'd also look into process mitigation policies provided by Windows.

Upvotes: 0

dev65
dev65

Reputation: 1605

I had a good solution If I want to not be affected by hooking simply don't use the hooked functions directly but from a trampoline so the attacker must know the address of your trampoline

Upvotes: -2

V. Kravchenko
V. Kravchenko

Reputation: 1904

I think that you can't protect from hooking entirely. Still hacker can modify you executable file on disk in such a way that it won't install hooks. Or he just can install hooks inside your executable himself.

To prevent this actually there are a lot of techniques. For example, you can do a lot of checks for modification of your program. You can do hidden checks for modification of particular sections of code in program and you can obfuscate your code. There are many other techniques, that are usually combined to make an efficient software protection system. But none of the ways can make your code fully protected from hacker's modifications. If there was such a protection, no software/game would be pirated. Now pirating software which is distributed to clients is only a matter of difficulty. The more complicated protection system is, the more time it takes to hack it. But it's never impossible.

Upvotes: 2

Related Questions