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.