Defining a Hook Function


Before proceeding into the hook logic, a limitation of process injection should be mentioned. This limitation has to do with function declarations. In kernel-level hooking, you can simply include ntddk.h to declare the original function, and then cut, paste, and modify the original function prototype from ntddk.h to create the declaration for the new hook function. However, where do you get prototype information without a header file? There is a fair possibility the function you wish to hook is undocumented, with no header file and no sample code that shows calls to the target function. There’s even the possibility that the function you wish to hook isn’t even exported.

These problems can be remedied with IDA. As mentioned in Chapter 1, IDA is a disassembler that parses machine code into assembly code. If you open the target DLL with IDA, you can use the menu option Navigate image from book Jump To image from book Function to get a list of the functions exported by the DLL. Then just begin typing the name of the desired target function; IDA will highlight the first function matching the letters you type until there is no longer a match. If there is a match, and you find the desired target function, just press Enter to jump to that function. You should see something similar to the information presented below. I have selected the function RtlGUIDFromString from ntdll.dll to demonstrate this process, but you can use any exported function from any DLL:

  .text:7C926B07               public RtlGUIDFromString .text:7C926B07 RtlGUIDFromString proc near .text:7C926B07 .text:7C926B07 var_14    = byte ptr –14h .text:7C926B07 var_12    = byte ptr –12h .text:7C926B07 var_10    = byte ptr –10h .text:7C926B07 var_E     = byte ptr –0Eh .text:7C926B07 var_C     = byte ptr –0Ch .text:7C926B07 var_A     = byte ptr –0Ah .text:7C926B07 var_8     = byte ptr –8 .text:7C926B07 var_6     = byte ptr –6 .text:7C926B07 var_4     = dword ptr -4 .text:7C926B07 arg_4     = dword ptr 8 .text:7C926B07 arg_8     = dword ptr 0Ch 

Though this might not be what you’re used to, it is a function prototype. Basically, this listing shows that RtlGUIDFromString receives two passed parameters, arg_4 and arg_8, and that both are 32-bit pointers. For reference, IDA classifies passed parameters as arg_x, and local stack variables as var_x.

Determining the return type can be a little more difficult. IDA displays

  .text:7C926B82               retn     8 

to indicate that the function is returning (and that 8 bytes must be popped from the stack to clean up after pushing the parameters arg_4 and arg_8). However, you need to look back to

  .text:7C926B76               xor     eax, eax 

just before the return to determine that the function probably returns NTSTATUS.

The other advantage to using IDA is the ability to see the actual machine code for the function. This is actually required when the function is not exported. Here’s the process.

After loading the target DLL and finding a location to hook, select Options image from book Text representation, and change Number of Opcode Bytes from 0 to 8. Then press Enter to return to the code. You will now see the machine code for the unexported function. Later, we will use some of these machine code “patterns” to hook unexported functions.

Even though RtlGUIDFromString is exported, it can serve as an example of how to retrieve a machine code pattern. Using the ntdll.dll from Windows XP SP2 Home Edition, you can see the pattern:

  55 8B EC 83 EC 14 56 8B 75 0C A1 34 C0 97 7C 8D 4D FA 51 8D 4D F8 51... 

Some knowledge of assembly language programming will be required to recognize when a machine code pattern can begin to vary with use, but it’s usually safe to use a pattern representing the initial moves and pushes of a function. What is really important is the uniqueness of the pattern within the DLL. The pattern must be long enough to be unique within all versions of the target DLL; otherwise, a pattern-matching algorithm could hook the wrong function. If you downloaded Microsoft Visual C++ 2005 Express, you can open files as binary and search a DLL for a specific pattern. If there is only one instance, you’re in luck!




Professional Rootkits
Professional Rootkits (Programmer to Programmer)
ISBN: 0470101547
EAN: 2147483647
Year: 2007
Pages: 229
Authors: Ric Vieler

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net