What does AreThisProcessProtected() look like? If it's just checking the process ID that Windows shows you in Task Manager, Process Explorer etc. then your code can easily be bypassed, even by the higher level OpenProcess() API from kernel32. Many aren't aware of this however you can open *any* process with up to 4 different PIDs. Windows only lists the lowest value as the PID. For example, say Explorer.exe has a PID of 2800, if I called OpenProcess() on 2801, 2802, or 2803 I could still open the same process even if I had "protected" 2800, like in your code, and bypass your protection completely due to the logic flaw that most likely exists like other numerous examples of this online. If you're not already doing so you should be validating and sanitizing the PID like this within the callback, like any other parameter you work with inside a hook callback.
Code: Select all
function GetLowestPID(const PID: DWORD): DWORD;
result := PID - (PID mod 4);
if (ClientID <> nil) and AreThisProcessProtected(GetLowestPID(DWORD(ClientID.UniqueProcess))) then
Result := NTStatus(STATUS_ACCESS_DENIED);
You could also allow the real function to execute first and upon success then check the ProcessHandle with madRemote's ProcessHandleToProcessId(ProcessHandle^) which will also return the correct lowest PID that Windows displays to you. If it's a PID you want to protect you'd close the handle, zero out ProcessHandle^ and return STATUS_ACCESS_DENIED. Either of these methods would be less likely to be bypassed than just using the lowest PID to protect a process.
Also, in case you're running this code on x64, CLIENT_ID.UniqueProcess is a HANDLE (8 bytes) and not a DWORD (4 bytes) like it would be on x86. Just pointing this out. As far as being able to bypass this type of native API hook, it's actually rather easy. NTDLL can be remapped and executed (loaded from a different location), mapped as executable memory and executed directly, direct system call (INT 0x2E, SYSENTER, SYSCALL etc.), DuplicateHandle() of the protected process that may have already been opened by another process before your hook was installed etc. There's no telling what your target process is doing without uploading the binary for analysis. If a program wants to bypass your hooks badly enough it simply will =) This goes for all usermode hooking engines.