Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SendInput

Status
Not open for further replies.

m4tthew

Technical User
Jun 20, 2006
3
GB
I am trying to use SendInput while it has been hooked by another application. The hook seems to be made by placing a jump at the start of the entry to SendInput. I have been trying the following code to get around this:

Code:
function TForm3.SendInputTunnelUser(cInputs: dword; nInputs: PINPUT; cbSize: dword):cardinal; stdcall;
  asm
    push cbSize
    push nInputs
    push cInputs
    call @@Tunnel
    ret
  @@Tunnel:
    mov eax, $11F6
    mov edx, $7FFE0300
    call dword ptr [edx]
    ret $0C
  end;

procedure TForm3.Button1Click(Sender: TObject);
Var
  GInput: TINPUT; //GENERALINPUT;
  x:      integer;
  y:      boolean;
begin
  GInput.Itype          := INPUT_KEYBOARD;
  GInput.ki.wVk         := $5A;
  GInput.ki.wScan       := 0;
  GInput.ki.time        := 0;
  GInput.ki.dwExtraInfo := 0;

  GInput.ki.dwFlags     := 0;       //key down

  x:=SendInputTunnelUser( 1, @GInput, SizeOf(GInput) );
end

However, it does not work properly. The data seems to reach SendInput fine as I see a keystroke from the above code but immediately after I get an error "access violation at address 22f572, read of address f6" error. i'm not sure what is stored at 22f572 but 22f554 contains GInput. I have gone trough this with a debugger and the exception occurs when the return call is made. Oh the code is running in user mode by the way.

If anyone could suggest what the problem may be I would be grateful as this is driving me mad.
 
If you can explain it more, may be (and only may be) I'll be able to help you somewhat.

Actually I have a lot of doubts.

1) What exactly are you meaning with "hooked by another application"? How it is hooked? How the hooking app is related to your code?

2) How are you sure your hardwired call to $7FFE0300 is going to work everywhere, everytime? From where and how you got the address?

3) Why are you using a so convoluted way to call the $7FFE0300 subroutine (why not using a direct call inside the procedure instead of the nested call you are using?).

4) Are you aware about how the stack is when the $7FFE0300 sub is started? You have two ret addresses above the parameters frame ($7FFE0300 call ret addr, Tunnel ret addr, cInputs, bInputs, cbSize). Is that what you need to have?

5) In which ret is your code producing the violation: the first one (ret) or the second one (ret $0C)?

6) What is the $7FFE0300 sub? What do you knowa about it? Are you sure it is not cleaning the stack itself? It don't requires a formal stack framing (bp pushing)?

I'm not saying the code is structurally wrong, what I'm saying is that I don't understand it and I have no idea about what the $7FFE0300 sub is expecting or doing.

buho (A).

 
sending keys to another application/thread is not difficult, look here for more info : thread102-899078

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Thanks for your reply. I will try and clarify some things.

1) SendInput is hooked by overwriting the start of the entry (i.e. from the mov eax, 11F6 line) with a jump instruction. The application doing the hooking isn't related to my code other than it runs on my PC and it's hook interferes with my usage of SendInput. It hooks all the API's for sending input to processes so I can't get around it by using another API like keyboard_event, JournalPlayback etc.

2) I am not sure the $7FFE0300 call will work everywhere but I only want the code to work on my two home PC's so being robust and portable is not a concern to me.

3) I know from looking at the entry that SendInput expects the variables in the stack as I have put them and I wasn't sure what the Delphi compiler would do. I have played around removing the call to Tunnel but I still get an exception.

4) I have checked the stack and registers on entry into SendInputTunnelUser and before and after the system call. The stack is unaffected by calling $7FFE0300, and it is returned to the state just before reaching SendInputTunnelUser just before making the return (ret not ret $0C)

5)It is (ret) that gives the Exception, it passes (ret $0C) fine. If I change the code by removing this return then (ret $0C) gives the exception. For everything I have tried it is the last line of code executed before exiting the function which causes an exception.

6)Other than the entry I don't know much about what the function is doing and disassembling the kernel to find out is a bit beyond me at the moment.
 
I think your stack is misleading, as you are adding at least an extra return call before calling the hook (and may be your pushes are adding to the scenario).

Furthermore, after returning from the hook you are issuing a RET n in a routine which have pushed nothing onto the stack (@@Tunnel).

<<
The stack is unaffected by calling $7FFE0300, [...]
>>

I can't agree (or I can't understand). A CALL instruction will add a ret address on the stack.

Give me some time; I need to think a little and making some tests.

buho (A).
 
After some thinking I concluded that I can't do nothing without knowing how the hooking is made.

Sorry.

buho (A).
 
m4tthew,

can you explain us exactly what you're trying to do?
I'm sure there are several other ways (like the one I showed) to do this...

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
He have some program running which is globally hooking the system (kinda monitor or spy).

What he is trying to do is to "bypass" the hook.

Apparently, he is not bypassing the hook cleanly, but jumping into the hooker dispatcher. I think that is the reason why he is loading EAX before the call.

Very difficult to solve without having the hooker program installed to trace it. I can't guess neither how the frame needs to be inside the hooker dispatcher nor how to mannage the stack cleaning.

buho (A).

 
Thanks for the replies everyone, after doing a bit more research I have finally solved the access violation error and it functions properly. The problem was with the stack, when the code passes to my function various stuff is pushed onto the stack by the compiler (it pushes more onto the stack than I expect hence me pushing the variables on again to avoid doing some messy clean-up) and with me forcing a return after calling @@Tunnel there wasn't sufficient cleanup of the stack and hence the Violation.

By the way 7FFE0300 holds a few lines of code to make a system call and the EAX holds the identifier for the function I want to call (in this case SendInput)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top