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
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.
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.