4

I am attempting to make a simple botting program for a game. I want this to be functional even when the game is out of focus or minimized. Because of this, I cannot use SendInput() as it simulates global events. I figured out that, to make this work, I must use the PostMessage() function. I made a test program that simulates input in Notepad:

#include <Windows.h>
HWND handle = FindWindow(NULL,CStringW("Untitled - Notepad"));
HWND edit = FindWindowEx(handle, NULL, CStringW("Edit"), NULL);
PostMessage(edit, WM_CHAR, 'a', 0 );

This example successfully simulates the clicking of "a" in notepad even if notepad is out of focus or minimized. I similarly got mouse events to work as well.

When I try this same thing for my game, however, I am unable to Post the click commands. After investigation, I found that the original handle is obtained but permission is denied when I call FindWindowEx(), and no handle is returned.

Is there a way to obtain 'edit' access to another process if it blocks this function?

Reed B
  • 636
  • 1
  • 8
  • 19
  • What do you get if you call GetLastError after your call to FindWindowEx? – anthonyvd Nov 08 '12 at 01:28
  • Also, if your game's window doesn't have a subwindow called "Edit", it'll return null. you should PostMessage to the handle obtained when calling FindWindow to find your game's window handle. – anthonyvd Nov 08 '12 at 01:30
  • Please edit your question. It seems that you are trying to get a handle to a window that doesn't exist in your application. – Sebastian Cabot Nov 10 '12 at 12:29

2 Answers2

1

Of course Windows never let you do that, what if you try to steal password of the user?? you are not allowed to receive input while you don't have the focus!!

But you may do some tricks here: you should write a hook function for mouse or keyboard and this function should implemented in a DLL(not your EXE) use SetWindowsHookEx to install it and then use an IPC mechanism in your DLL to send mouse and/or keyboard messages to your main EXE.

But beside that: while it usually work the line

HWND handle = FindWindow(NULL,CStringW("Untitled - Notepad"));

foes not make any sense, windows have to version of most of functions that get at least one string argument: one for ANSI that its name terminated with A and one for wide(UTF-16) characters that terminated with W. MSVC have an extra layer over this design called TCHAR and by using define map all such functions to eith ANSI or Wide, so if you are using that version of API it is not wise to directly use CStringW that generate wide strings. And since Windows API work with char* and wchar_t* why you convert your string literal to CString and then pass it to the function? you should use one of this:

// This also work with CStringA
HWND handleA = FindWindowA(NULL, "Untitled - Notepad");
// This also work with CStringW
HWND handleW = FindWindowW(NULL, L"Untitled - Notepad");
// This also work with CString
HWND handleT = FindWindow(NULL, _T("Untitled - Notepad") );
BigBoss
  • 6,904
  • 2
  • 23
  • 38
  • "Of course Windows never let you do that, what if you try to steal password of the user?? you are not allowed to receive input while you don't have the focus!!" This isn't part of the question, but yes, GetAsyncKeyState() allows a program to monitor the keyboard even if it is not in focus. The code snippet that I provided allows input to Notepad while Notepad and/or the program is out of focus. Do you have an example of how to hook Notepad in the manner that you suggested to simulate input? – Reed B Nov 08 '12 at 00:23
  • @ReedB You didn't read my sample carefully, note L"", `L` at start of a literal make it a wide string literal, and also since you are not using TCHAR version you should use _T("") and it certainly work! – BigBoss Nov 08 '12 at 00:34
  • Ah, I see, thank you. I have never injected a DLL before. Do you have any advice if I choose to attempt this? – Reed B Nov 08 '12 at 00:39
  • See documentation of `SetWindowsHookEx` and you shall get it, there is also dozen of samples out there – BigBoss Nov 08 '12 at 01:05
  • Thanks. Is there no way to simply get the permission to edit? Like I said, I got this to work in notepad but it won't work in my game. Anything to do with tokens? http://msdn.microsoft.com/en-us/library/aa379295(VS.85).aspx – Reed B Nov 08 '12 at 01:09
  • what do you want to do? if you want to post a message to a window it is simple, use `PostMessage` the technique that I describe is to receive input from the background. – BigBoss Nov 08 '12 at 01:21
  • oh. I am interested in using PostMessage. The handle that you provide postmessage needs to have edit capabilities, like in my example. When I attempt to request edit capabilites using "FindWindowEx(handle, NULL, CStringW("Edit"), NULL);", NULL is returned when I attempt to do this with the game (it works fine for notepad). This is the source of error and reason for the post. – Reed B Nov 08 '12 at 01:25
  • You are not getting a handle with `edit` capabilities, you search for a window that its class is named `EDIT`. in your program you don't have such a class. Please read documentation of `FindWindow` and `FindWindowEx` in `MSDN` – BigBoss Nov 08 '12 at 02:13
  • Thanks for all the help! Is there any way to still use PostMessage() for what I'm trying to do that you can think of? – Reed B Nov 08 '12 at 04:39
  • There are no subwindows inside of the original handle object for my game; however, posting the message to the handle object does not actually click the button in-game. Do you think that this has to do with the game using directX and thus utilizing directInput? – Reed B Nov 08 '12 at 05:43
  • button is actually a window with class "BUTTON" – BigBoss Nov 08 '12 at 08:25
  • The buttons that are in this game are not standard .Net Windows buttons. They are on a custom UI which doesn't allow access to the buttons via findwindowex. – Reed B Nov 08 '12 at 13:31
  • OK, that custom UI, have an accessor for that button?? you should handle posted message in parent window and call a function to simulate some action on the button, so `PostMessage` will be used to post a message to your main window!! If that button is not an standard windows button, how you want to send a message to it and expect it to do something?? Or how you want to send a message to something that does not have an `HWND`?? – BigBoss Nov 08 '12 at 13:50
  • I want to simulate a mouse click at specific coordinates in addition to keystrokes. I could issue a mouse event within the coordinates of the button and it will be as if the user clicked it. – Reed B Nov 08 '12 at 16:29
0

Are you sure the game you are trying to send text to owns a Windows Edit control which can be enumerated from the children of the client? It may very well be that the Edit control you are referring to is an entity of the Client's graphics container. If that's the case you might have to send WM_KEYDOWN and WM_KEYUP messages to the client window itself to achieve the desired functionality.

Hope that helps.

cfi
  • 10,915
  • 8
  • 57
  • 103
  • Thanks for the answer! There are two different ways that a program can handle user input. One is taking input from the operating system. This is successfully simulated with my example. The other method is to constantly check the state of the given key or button. This, to my knowledge, cannot be easily replicated. The only way to make a botting program that simulates this type of input is by injecting a dll which executes the code that would normally run on a change in button state. – Reed B Jun 28 '13 at 11:52
  • It appeared to me you were trying to send characters to the program from outside of the process memory, so I replied accordingly. Of course running from within the process memory makes things more accessible but the functionality you had described in your question was doable from outside of the process itself. Anyways, thanks for the reply. –  Jun 28 '13 at 19:33