The worst nightmare of every botter is a hidden keylogger in his/her brand new bot because we don't want to lose our char we have invested so much time and work into. So how do we detect such filthy little bastards
in our software?
This is the tutorial's topic so go on reading.
Some theory
A keylogger is a tool that logs the user's input. Most of them save the input in a file and forward it to the bad guy so he can skim through it and look for suspicious looking data such as passwords and accounts. So we need to know how they work in order to defeat them.
There are several common techniques for writting a keylogger:
The Newbie Method
There will be a time more or less every newbie wants to write a keylogger. And the most basic method for writing one is simply checking the key state of the keyboard a lot of times per second.
The great thing is that this method is dead easy as it gets us a system-wide keylogger without much effort. The downside is that there will be an infinite loop (such as while(1) { }) in order to keep the keylogger alive and checking. The used functions here would be:
SHORT GetKeyState(int nVirtKey);
MSDN says: The GetKeyState function retrieves the status of the specified virtual key. The status specifies whether the key is up, down, or toggled (on, off?alternating each time the key is pressed).
Sounds great, doesn't it?
SHORT GetAsyncKeyState(int vKey);
MSDN says: The GetAsyncKeyState function determines whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call to GetAsyncKeyState.
Even better.
BOOL GetKeyboardState(PBYTE lpKeyState);
MSDN says: The GetKeyboardState function copies the status of the 256 virtual keys to the specified buffer.
Woah, pretty easy as well!
All of these three functions would be called in an infinite loop gathering information about the key states.
Dead easy and working.
Hooking The System
The previous method asked the system for the current state of each key but why can't the system simply tell us whenever a key is pressed? Well, it can.
This is achieved but setting up a Windows hook on the keyboard using the following function:
HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
MSDN says: The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.
Yahtzee!
So basically we apply a hook on the keyboard (idHook = WH_KEYBOARD or WH_KEYBOARD_LL if needed) and Windows tells us whenever a key is pressed. That's great but realization is rather complicated as there's one little detail: Global hooking is only possible using a DLL which will be loaded into each process' memory.
And we would be the ones to write this DLL. And if we think further we notice that now we would be given a .exe file as well as a .dll file which should make us curious. I think though, there are even tricks to hide the DLL somewhere inside the .exe or some other filthy tricks but basically there should be a .dll if it's a global hook.
This method is usually the preferred one and there should be a shit load of good (and even a bigger shit load of non-working) examples on how to implement the method but what WE need to know is just the used function.
Subclassing The Window
Wait. We want the system to tell us when a key is pressed. Isn't that what every window does?
Right. Every focused window will get a WM_KEYDOWN (or WM_CHAR) whenever a key is pressed inside it.
And there's a way to perform a, well, man-in-the-middle attack on this one.
We just modify each visible window (enumerate all the windows, filter with IsWindowVisible) and change the adress of its callback function. Now, when a key is pressed WE are the ones to get the WM_KEYDOWN or WM_CHAR message. And after we've processed this information we just pass it along to the original window proc.
The used function here would be:
LONG SetWindowLong(
HWND hWnd,
int nIndex,
LONG dwNewLong
);
MSDN says: The SetWindowLong function changes an attribute of the specified window. [...]
Notice that the SetWindowsLong function can be used to modify a lot of different things. We're only interested in SetWindowLong calls with nIndex = GWL_WNDPROC (used to modify a windows's window proc).
Other Methods
As I was searching the net for keylogging methods I came across a site (
)with the great title "How to write a HOOKLESS keylogger for Windows". As the title says no Windows hooks are used and of course none of the newbie methods mentioned above but some other function does the trick here:
BOOL WINAPI AttachThreadInput(
DWORD idAttach,
DWORD idAttachTo,
BOOL fAttach
);
I can't tell you much about the function, if you're interested read the article above. Again, what WE need is the function name, nothing more.
How To Detect A Keylogger
Finally the interesting part. We now know of the mechanisms (and especially the used functions) of each keylogger.
And there is a pretty easy way to find out wether an .exe file uses these functions or not.
The .exe file is a PE file (PE = portable executable) with a special format. Go ahead and ask Wikipedia or the net for details if you're interested. In a PE file there are several sections. One of them is of special interested for us: the section rdata. Inside of this section is the so-called IAT, the import adress table containing every single function imported into the .exe file. And if you're not plain stupid you now should have guessed that we simply have to look through this table to spot one of the functions above.
And now let's see how this knowledge works applied to a real example:
1) First of all we need a keylogger as we want to find a postive case and not a negative one.
Download Tiny Keylogger (
)2) Extract it, don't run it (you don't run any suspicious program at all, do you?).
3) This step is not necessary here but you should still get used to it.
Get PEiD (
), launch it and check the TinyKL.exe for known modifications such as .exe packers.PEiD gives green light ans says "Nothing found *". All clear.
If we would've stumbled across some .exe packer such as UPX (only packer, not crypter) go and get a depacker.
If it is some nasty shit like ASProtect (as they tend to modify the IAT as far as I know) you'll have to visit the unpacking gods (google it).
4) Now grab a PE viewer such as PEview (
) and open TinyKL.exe.5) On the left side you see the sections, open "SECTION .rdata" and click on "IMPORT address table"
6) On the right side we now can see each imported function. What we have to do now is to look through all of them and spot one of the ones above. If you do so, you'll see one bad boy: "SetWindowLongA". Bingo.
What this keylogger does is modify each window's window proc, set it to a middle-man window proc and log WM_KEYDOWN/WM_CHAR to a file. And that's it.
Final Words
Now you've learned how keyloggers work and how to spot these suspicious functions in executables.
Remember: SetWindowsHookEx and SetWindowLong can be used for quite a lot of things so if you spot them you'd better fire up a disassembler and search for the particular calls to see if they really hook the keyboard and if they really modify the window proc.
I'm not omniscient and there might be methods I didn't explain here so don't feel on the safe side if you find none of the above although I'd say a big percentage of publicly available keyloggers use them.
The last note: .dll files are nothing but PE files with a slight difference - they need to be loaded. From then on they are as deadly as .exe files. If you come across a distribution with an .exe file and several .dll files then check all of them (even the .dll files!) as the coder could have hidden the keylogging code inside them as well.
Some more basic stuff to look for are file routines such as CreateFileA, LoadLibraryA, FindWindowA (used to find a specific window - the target probably).
Note that these methods here are used to collect input in an abstract method. If the target is a single application (and not a game) there are quite a few other (complicated) methods to grab keyboard input.
You all probably know these password-box-star-remover tools - they work using CreateRemoteThread and some other rather evil methods and exactely the same method can be used to modify that editbox' window proc
to catch input.
EOF.






