News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

IAT replacement

Started by Tripper, March 22, 2007, 02:36:24 AM

Previous topic - Next topic

Tripper

I've been working with DirectX to get an idea about how it works. Now that I have a basic idea about the COM interface and the pointers and all that, I'm gearing up to hook them so that I might be able to send keystrokes and mouse events to a couple of games. But I figured I better start small.

I wrote some code to change the IAT table of a program it launches so that a procedure call can be changed. My test program just launches a message box. The idea is to change the IAT table so that any calls to MessageBoxA in the usesr32.dll by that program are re-routed to a procedure inside the DLL my code injects. I know people here don't like talking about full-blown hooks, and I understand why. So I won't post the code that injects the DLL or the full DLL code. There is only one part I can't get working anyhow, so there is no need.

What I can't figure out for the life of me is why the folllowing code doesn't work. I've put in message boxes in every part of it to check returns from the API calls. I've checked that the user32.dll is found in the imports section, and that MessageBoxA is also found. Everything acts like it should be working. When I run it all, nothing changes. My NewMessageBox proc is supposed to pop up a message box of its own, then pass the original parameters to the original MessageBoxA proc. That never happens, but the message box from the hooked program does show up. I have it narrowed down to this proc, but I can't understand why it is failing. This is from the DLL, btw:

Set_Hook proc
         LOCAL lpflOldProtect    :DWORD
         LOCAL puLong            :DWORD

  push ebx
  push edx
 
    invoke  ImageDirectoryEntryToData, hModHandle, TRUE,\
                           IMAGE_DIRECTORY_ENTRY_IMPORT,\
                                            addr puLong
    cmp     eax, 0
      je    @done

    mov     ebx, eax
    assume  ebx:ptr IMAGE_IMPORT_DESCRIPTOR
    mov     edx, [hModHandle]

  @@:                                                          ;<== Begin looping imports
    cmp     [ebx].Name1, 0
      je    @done                                              ;<== No more imports, exit
    push    edx
    push    ebx
    add     edx, [ebx].Name1
    invoke  lstrcmpi, edx, addr User32                         ;<== Let the OS do this for now, while testing...
    cmp     eax, 0                                             ;<== Return is 0 for exact match
    pop     ebx
    pop     edx
      je    @F                                                 ;<== Import found, break
    add     ebx, sizeof IMAGE_IMPORT_DESCRIPTOR                ;<== No match, advance and continue
      jmp   @B

  @@:
    mov     ebx, [ebx].FirstThunk
    add     ebx, edx
    assume  ebx:ptr IMAGE_THUNK_DATA
    mov     edx, [CurrentProc]                                 ;<== Base of IMAGE_THUNK_DATA

  @@:                                                          ;<== Begin looping procs
    cmp     [ebx].u1.Function, 0
      je    @done                                              ;<== No more procs, exit
    cmp     [ebx].u1.Function, edx
      je    @F                                                 ;<== Proc found, break
    add     ebx, sizeof IMAGE_THUNK_DATA                       ;<== No match, advance and continue
      jmp   @B

  @@:
    lea     ebx, [ebx].u1.Function                             ;<== Load the address of the function
                                                               ;    within the process's IAT and prepare to
                                                               ;    over-write it with the address of NewMessageBox
                                                               ;    in this DLL

    invoke  VirtualProtect, ebx, 4h, PAGE_EXECUTE_READWRITE,\  ;<== Change protection to PAGE_EXECUTE_READWRITE
                                        addr lpflOldProtect    ;    to allow us to write to it
                         
    cmp     eax, 0
      je    @done                                              ;<== Error changing protection, so leave

    invoke  WriteProcessMemory,  hHandle, ebx,\                ;<== Now that we are allowed to write to memory,
                           addr NewMessageBox,\                ;    replace the old function
                                     4h, NULL

    invoke  VirtualProtect, ebx, 4h, lpflOldProtect,\          ;<== Set the memory protection back to what it was
                                addr lpflOldProtect            ;    before we messed with it

  @done:
    assume  ebx:nothing
   
  pop edx
  pop ebx

  ret
Set_Hook endp



I'm sure the DLL is getting injected and is getting called as I've set up numerous dummy tests to check.

If anyone could give me some insight as to what is wrong, I'd be grateful. I've been trying to get this to work for 3 days now :red

sluggy

I'm glad that you realise this topic is on shakey ground - we will help you to a certain degree with hooking Windows APIs, but we will not assist with game automation or game trainers or hooking third party APIs.

With regards to your problem: assuming you are correct in when you say the module is injected, have you determined the code path taken through your code? You should either attach a debugger to the process and step through it, or write to a log file. You should also check that you are writing the correct address to the new function to the IAT, and that your registers are not being munged during calls to the Win APIs.

BogdanOntanu

#2
It is not going to work with Directx esp because of it's COM interfaces that the author claims to understand well ...

The DirectX functions/methods will not appear in the IAT except for CoCreateInstance or the DirectDrawCreate older functions  probably... so no hooking is necessary or possible with ease.

The whole reasoning of this is debatable... I guess the author simply wants to bypass us with a phony reason for doing this :D

Edit after OP message:

I would like to know why you want to hook into commercial applications like games and why "send keys" to them?
Is this legal? Yes i know it can be done... but the question is if we can help you here and under the rules of this forum.

I suggest that  you write some big games / big usefull applications using ASM in order to get used with the language  and it's concepts. Then when your experience if much bigger you can grasp such a project with ease.

And then you can ask about concepts... but please do not ask for us to debug your code of debatable etics.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro