Does anyone know of a good way to prevent a process from being hooked by another, or at least by detecting the hook?

Recommended Answers

All 7 Replies

i have no idea what u r talkin about.. care to elaborate? 'hooked'?

a hook is a prorgam that attaches to another process by

1) Inserting its code into the program's memory
2) Accesses known resources (usually edits) that the program will require usage of

a hook is very general, so It's hard to give a better definition, look around on msdn.com they support hooks in various forms (DirectX hook, Mouse Hook, Keyboard Hook, etc).

A hook is genrally used by hackers to attack a program (usually games so they can cheat, most aimbots [a program that aims for the user] uses some sort of hook)

I need to prevent this, but honestly I don't know how, but I know theres a solution, PunkBuster has it.

ohh ok i see what you r talking about now. my windows knowledge is rather limited so i have nothin constructive 2 add, sorry. i can tell u in linux how tho, the method of 'attaching' to a process's address space is by using the ptrace() system call. if a process sets the PTRACE_NO_TRACE flag (or something to that effect), then other process's cannot attach themselves to it. i'd imagine windows has slightly similar thing.

thats very helpful, i can detect the API call thnx :D

Fuck. I wrote a big essay on how to do it only to be confronted by a screen asking me to logon, then I lost it all.:evil:
Here I go again..

API hooking is usually done by placing a jmp opcode at the start of the function the programmer wants to hook. This jmp would push the flow of code over to a function of his own, where he could check the arguments of the call, etc, then could either carry on executing the API, or return back to the callee function without having done such.

There are two basic ways to prevent this that I can think of from the top of my mind at the moment. The first being this, using the api function GetProcAddress as an example:

_asm {
  	 mov eax, GetProcAddress
  	 cmp dword ptr ds:[eax], 0xE9 // 0xE9 is the jmp opcode
  	 je badboy
  }

Unfortunatly, this one would probably be easily detectable by crackers. The alternative to that would be to do this, using GetProcAddress as an example again:

DWORD FirstParam = (DWORD)LoadLibrary("kernel32.dll");
  char* SecondParam = "GetModuleHandleA";
  
  DWORD Result;
  
  _asm {
  	 mov eax, GetProcAddress
  	 add eax, 5
  	 push SecondParam
  	 push FirstParam
  	 push OFFSET returnhere
  	 push ebp
  	 mov ebp, esp
  	 push ecx
  	 push ecx
  	 jmp eax
  	 returnhere:
  	 mov Result, eax
  }
  
  // result contains the location of GetModuleHandleA()

If you're wondering why I have

push ebp
   	 mov ebp, esp
   	 push ecx
   	 push ecx

in the middle of that code snippet, this is why.

If you look at the GetProcAddress export in kernel32.dll with a disassembler, it'll present you with something similar to the following code:

77E7B332 >  55			  push	ebp
  77E7B333    8BEC		    mov	 ebp, esp
  77E7B335    51			  push	ecx
  77E7B336    51			  push	ecx
  77E7B337    53			  push	ebx
  77E7B338    57			  push	edi

Now, since the jmp opcode takes up 5 bytes (hence add eax, 5), and you're going to want to jump over it, you're going to need to make up for the opcodes that you have skipped. i.e the first five bytes worth.

There is fundamental flaw with this technique, though. The opcodes that you jump over could vary according to the version of the dll that you're working with. This would severely limit the compatability scope of your application.

If you wanted to fix this, you'd have to dynamically read the opcodes from the dll with ReadProcessMemory for example, and parse the bytes read with a reiterating select() (not all opcodes are the same size, you'd have to account for this). You could then append a jmp command to the opcodes which were read, and simply call the function. For example:

class FunctionStub
  {
  public:
  	 FunctionStub(char* FunctionName, char* LibraryName)
  	 {
 		 DWORD FunctionAddress = (DWORD)GetProcAddress(LoadLibrary(LibraryName), FunctionName);
  		  CodeCave = new BYTE[128];
  
  		  ReadProcessMemory(...); // Read the required bytes into the codecave
  
 		 ParseData();
  		  AppendJump();
  	}
  
  	 ~FunctionStub() { delete [] CodeCave; }
  
  	 DWORD ExecuteFunction(...);
  private:
 	 ParseData();
  	 AppendJump();
  	 BYTE* CodeCave;
  }
  
  void Example()
  {
  	 FunctionStub GetProcStub("GetProcAddress", "kernel32.dll");
  
  	 GetProcStub->ExecuteFunction(LoadLibrary("kernel32.dll"), "GetModuleHandleA");
  }

I hope this helped.

hell yeah that helped :D

np~ :]

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.