Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

A program that defeats AutoHotKey???


  • This topic is locked This topic is locked
133 replies to this topic
Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
Well, some good news and some bad news.

First, the good news. I ran the first script, then the second one. Then I ran a script called start.ahk, which was responsible for starting the third script after I ran the game.

When I ran the game, the tooltips kept getting pushed behind the game window. Then I started the third script and the tooltips were staying ontop nicely. This meant some sort of hooking was happening successfully there.

The downside, was that the simulated mouse movements no longer updated either overall OR physical, when it was updating both before opening and after closing the game. So, as you suggested, it must be something other than the injected bit being checked, because even the "overall" time kept climbing until I physically moved the mouse. Any ideas here?

Something else odd that happened, when I closed the game, it said that the third script could not hook the keyboard and some functionality would not work in the script. I had the exact error on the tip of my tongue but I just forgot, heh. That was more or less the gist of it though, the keyboard hook failed in the third script when it was run after the game was started.

Any thoughts?
Baby steps, heh. At least we have been able to force the tooltip ontop of the graphical display with something the third script is doing... It seems to cause the third script to gain video presidence despite the game hooking things like GetForegroundWindow I think. I would think the same would occur with the mouse/keyboard input, and it would get to strip it before any other hooks get it...

None the less, you might be right in that injected flag is not the data being compared for physical/virtual input. Any other ideas? I'm almost 100% certain they do not use a VxD as that would require installing the driver, and you don't have to reboot after you install the game, it works fine right away. At least that's my understanding of VxD's from researching them.

What I was thinking might be happening is game.exe is using HanDes.dll to globally hook the input, and when the hook is called from game.exe, HanDes.dll adds a flag or changes one on the mouse data which it checks for in the game further along. And then the game never handles events without the special bit on, this would explain why Overall never gets changed unless the physical mouse moves... The game ignores anything that doesn't get this bit set through HanDes.dll. But what I don't understand, is if AutoHotKey hooks first, strips the injected bit, passes on to HanDes.dll, then it should manipulate the data as it would a physically moved mouse. I'm lost, I don't know where they are comparing data between physical and generated events now that the injected bit is stripped.

Do you know of any other potential spots?

Closer, but no luck yet. Ready to test any other ideas you have.

Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
I just thought of something that might help track down the problem. We have identified that, while we strip injected bit, it's not affecting anything. However, by using those scripts, we could identify that now neither overall or physical is being updated, even though those events are occuring. By moving the mouse, we get the update to the tooltips. Again, showing us we're in the right ballpark here.

What I think MIGHT be of some help, is if you added a couple extra lines for logging some output to the AutoHotKey history window. If you log the flags of the mouse event before and after the strip occurs, then we should get the first script showing something like

BeforeGame
MouseClickFlagsWithBit: 123455
MouseClickFalgsWithoutBit: 123454

AfterGame
MouseClickFlags: 324568

What we're hoping to see here is after after we strip our injected bit off and it's passed into the game hook, we want to see what the flags are again after the game hook, and compare the flag values. If there is a difference, maybe they set a bit otherwise unused or something. If that is the case, then where we strip the event, we can ADD that bit value as well, and see if we're any closer... Does this seem to make sense? Another random thought sitting here... :)

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

I use the first script to start the second script after the game is running, will this work correctly to "start my script after the game"

There is a better way: The hook can be dynamically installed or removed indirectly by means of commands that load it conditionally. For example, in this script the hook is removed when hotkeys are suspended by put back when they are resumed:

$^!#s::return ; Hook hotkey that does nothing.
#z::suspend


I guess the question comes down to whether AutoHotKey is run once for each script, or once for all running scripts

Every script gets its own instance.

With this new AutoHotKey, my test script is simple. I'm going to call "MouseClick, RIGHT". My assumption is the new EXE is going to automatically strip the injected bit for me, right?

I only provided those three scripts for testing purposes. Beyond that simple test, they serve no purpose whatsoever. In other words, it is enough to run a single script with the modified EXE. As long as the mouse/keyboard hooks are installed by it, the bit will be changed.

Then I started the third script and the tooltips were staying ontop nicely. This meant some sort of hooking was happening successfully there.

I don't think the tooltips being on top has anything to do with the hooks. It's probably just a coincidence.

The downside, was that the simulated mouse movements no longer updated either overall OR physical, when it was updating both before opening and after closing the game. So, as you suggested, it must be something other than the injected bit being checked, because even the "overall" time kept climbing until I physically moved the mouse. Any ideas here?

That's interesting. The "overall" time is gathered directly from an API function called GetLastInputInfo(). It seems as though the game is intentionally or unintentionally blocking that function from reporting the correct time. Perhaps the game is using some form of BlockInput?

Something else odd that happened, when I closed the game, it said that the third script could not hook the keyboard and some functionality would not work in the script.

That could be a sign that the game is doing something to explicitly disable other programs or other hooks. If we could figure out how it does this, that might help our understanding.

It seems to cause the third script to gain video presidence despite the game hooking things like GetForegroundWindow I think.

I don't know if that's relevant or possible, but if it is, I know basically nothing about it.

None the less, you might be right in that injected flag is not the data being compared for physical/virtual input. Any other ideas?

No... perhaps there is some game designing trade secret that has not been publicized.

What I was thinking might be happening is game.exe is using HanDes.dll to globally hook the input, and when the hook is called from game.exe, HanDes.dll adds a flag or changes one on the mouse data which it checks for in the game further along.

Even if this were true, it doesn't explain how the game knows in the first place which events to call the hook with and which to ignore.

if AutoHotKey hooks first, strips the injected bit, passes on to HanDes.dll, then it should manipulate the data as it would a physically moved mouse. I'm lost, I don't know where they are comparing data between physical and generated events now that the injected bit is stripped.

Do you know of any other potential spots?

If the AHK hook cannot be installed after the game has started, that might explain it. It's also possible that the game is installing a hook sometime after it starts, which would give its hook precedence. But more likely, it's none of the above and the game is doing something else entirely.

If you log the flags of the mouse event before and after the strip occurs

Since the three test scripts were not intended for use with a game, I don't think this will help. But let me know if you want to pursue it.

What we're hoping to see here is after after we strip our injected bit off and it's passed into the game hook, we want to see what the flags are again after the game hook, and compare the flag values.

There would be no reason for the game to change the flags if it can already differentiate between artificial and physical input.

Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
The reason for a game to mangle those flags would be for deterring exactly what we're trying. Mangling the flags, would throw us off because we'd expect the inject bit to be used for this and it's not.

But alas, I am running out of ideas. The last idea I have as I said is to log the values of the flags before the game touches it and again after it's done, and see what changes occur if any. If nothing, then I am lost, and have no idea how it's securing physical input only.

I'm getting quite discouraged, this has been hell to figure out.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

The reason for a game to mangle those flags would be for deterring exactly what we're trying. Mangling the flags, would throw us off because we'd expect the inject bit to be used for this and it's not.

Even if it changed the flags, it wouldn't matter because the modified AutoHotkey.exe alters the flags unconditionally, regardless of what they were before. The only things that matter are:
1) Is the AutoHotkey hook topmost in the chain.
2) If so, does the game even check the injected bit?

I'm getting quite discouraged, this has been hell to figure out.

These game designers probably have way more experience with keyboard/mouse tricks than either you or I. Maybe if you could catch one on the Usenet and ask him? :)

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
On the off chance that you haven't completely given up on this, ealerner wrote the following in another topic. It might be applicable to your goal:

Chris, I wonder if you've seen the source code at sysinternals that discusses hooking directly into the keyboard driver to provide the most keyboard filtering stability? It's at:

http://www.sysintern.../ctrl2cap.shtml

I don't know if the filter could be applied to the mouse driver, and if so whether it would allow new events to be put into the input stream.

Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
Hmm, nice catch Chris.

I had pretty much given up on this, however my curiousity keeps me from giving up entirely. I have downloaded the source for the mentioned program, and if it does what it says, by converting control to caps or vice versa, then maybe I can inject additional events. Reading the article, I saw reference to kbfiltr as well or something like that, suggesting it allowed to inject input into the stream.

However, this reflects only keyboard, so I will be searching for similar mousefiltr type stuff first, as keyboard is a second priority for me.

Thanks for the heads up, let me know if you decide to play around with this at all, I'd be happy to test anything with the game in question for compatibility testing.

Ciao for now.

Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
Well, so far my research into this suggests the best approach for hooking to inject input is using kbfiltr and moufiltr, since my primary concern is now just Windows 2000.
Further research suggests I need the Windows DDK which doesn't appear to be a free download, go figure.

The article says that it would only be harder, but doesn't say impossible, to use that code at sysinternals to inject keys, so I'm going to poke around that code for a while and see where I end up.

Thanks again for the heads up, glad to see you are still looking into this, I am getting a bit lost trying to do it myself :)

WhiteCloud
  • Members
  • 68 posts
  • Last active: Feb 06 2005 05:55 PM
  • Joined: 19 Jun 2004
compared to game developers people who write bots for games seem to like attention more. They can't be all that hard to find either. You might ask some of them how they got low level control.
AHK = Hella fun

Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
As a natural course of action, I have already done this. In most cases, game developers opt to use DirectInput, or Win32API calls like GetKeyboardState and GetKeyState.

The game in question, however, does not. If you have followed this thread from the start, it originated with finding a way to hook into DirectInput, which I was able to do, only to find out the game doesn't utilize DirectInput like I thought. Further investigation lead me to believe that whatever this game is doing in specific, it's outside the scope of "most games", because most games cooperate with AutoHotKey already, like Everquest. This specific game has been written a bit more ingeniously. I believe they utilize WH_LL hooks, I'm just not sure how... The reason I think this is because of the exported SetWindowsHookExA in a DLL that comes with the game. Knowing this, I tried endlessly to hook overtop of them. Chris even kindly enough wrote a modified AutoHotKey that converted virtual input into what we thought was physical input, but the game could still detect the difference.

As Chris has now suggested, moving back towards miniport filter drivers for the mouse and keyboard based on kbfiltr and moufiltr may be the answer. I looked into something similar sometime between when I started and now, but wasn't as successful in my initial research. These 2 methods have rendered some useful searches, and when I get a couple hours I'm going to sit down and try to write an upper level filter for the mouse to inject right clicks and see where that gets me.

Anyway, gotta go, will be in touch.

Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
Well, after locating CD's from an MSDN subscription, I have the Windows DDK available to me.

I've installed and looked at some of the examples, but nothing so far has lead me to any ideas on how injecting input works. None the less, this task is quite daunting and I'd appreciate any help towards it's end.

Everything I've read suggests moufiltr and kbfiltr can inject input into the streams. However, after reading the documentation I have not yet found exactly how this is achieved. I read over the source briefly for the cap2ctrl driver that is similar, and I have written the author of that driver, still waiting for a response.

When I get a bit more motivation, I'm going to write a simple framework driver that does nothing more than hook in and pass on with no changes. Once I can confirm I've got it loading correctly, I can start playing with some more useful code in it. I'm not sure if loading and unloading can be done on the fly like in cap2ctrl with using moufiltr or not, so we'll see how it goes. If anyone wants to help, please email or post here, I've come to check this forum more frequently now :)

Thanks again, any advice and thoughts on this would be appreciated, I'm really new to this.

And to Chris, sorry this has really gotten off topic from an AutoHotKey problem, but perhaps you can help with writing these filter drivers in such a way that they can be used by AutoHotKey once we have a proof of concept to work from. The first eureka will be when I can have it constantly input a right click every 5 seconds and it works in the game :)

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

None the less, this task is quite daunting and I'd appreciate any help towards it's end.

Although I hope you find someone to help, among the readership of this forum you may be a pioneer in this field.

sorry this has really gotten off topic from an AutoHotKey problem

No problem, I'll move it into the Wish List forum.

perhaps you can help with writing these filter drivers in such a way that they can be used by AutoHotKey once we have a proof of concept to work from.

Yes. I regret not being able to participate more in the research. That decision was only due to timing: I did not want to put all the other planned features on hold.

I have a high interest in this topic -- as do some others I suspect -- so thanks for your continued tenacity.

Astaelan
  • Members
  • 34 posts
  • Last active: Dec 13 2007 03:39 AM
  • Joined: 23 Sep 2004
It's been a rough ride so far, and I doubt it'll get any smoother along the way.

Device drivers are pretty much the last line before things get into assembly and really too complicated to be worth the effort. In fact, right now, with my current state of mind, I'd love to have it working, but the effort involved has been extensive and the primarily solo effort has had me running in circles with no progress.
As I said before, I'll attempt to use this cap2ctrl to try and write a mock driver, but once that works, I am kinda at a hurdle to figure out how to inject data into the stream, as opposed to just capturing physical keys and transforming them into other keys. Everything I've found says it's possible, but no information pointing as to how. IRP_MJ_READ does not have a parallel IRP_MJ_WRITE as one might expect.

Anyway, I appreciate all the other features going into AutoHotKey, and if it takes a few more weeks before they are done, then I can respect that, and hope once you hit your target you will bash brains with me to solve this specific problem and be able to incorporate it into AutoHotKey. For now, I am stepping down for a while, the lack of success has been depressing and working on it solo has proven to be frustrating. I look forward to the next releases of AutoHotKey and the potential to move forward on this problem then.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Ok. I've made a note to contact you again (perhaps by posting here) when some of the higher priority items on the wish list get finished. Although I don't think I'll be any immediate help to you then or now because of the lack of documentation and my lack of knowledge on the subject, feel free to send me related links or docs if you think there's any chance I will spot something you missed.

savage
  • Members
  • 207 posts
  • Last active: Jul 03 2008 03:12 AM
  • Joined: 02 Jul 2004
Heheh, I forgot I'd posted in here. Chris, I was just using SendInput. It's not nearly low level enough for what you're talking about here.

I just checked and AHK can automate Doomsday which my program, using just SendInput, couldn't.