Page 1 of 23 12311 ... LastLast
Results 1 to 15 of 343

Thread: Maggotboy's Super Stealth Sniffer V2 (code)

  1. #1
    Registered User
    Join Date
    Nov 2002
    Posts
    115

    Post Maggotboy's Super Stealth Sniffer V2 (code)

    WARNING This code is experimental and currently seems to be crashing the game to the desktop. It's currently being discussed and debugged in this thread. If you're interested in the hard-core internals and want to experiment, then please read the entire thread before downloading and attempting to compile this code! This code was based on the 1.x code I posted at this thread: http://seq.sourceforge.net/showthrea...&threadid=2453

    This is version 2.0 of my super-stealth key sniffer.

    ** Code update to 2.05 **
    Please see eqsniffer.cpp for specific instructions on how to create a project file for the various compilers. Follow it to the letter!

    Revision 2.05
    - Fixed my call to GetTempFileName() to pass CORRECT parameters to the call. This should fix the RUNDLL32 not unloading bug.

    Revision 2.04
    - Changed the InjectCode() routine to inject the entire code section of the DLL rather
    than just the code for the InternalHookProc. This was done because many compilers use
    jump tables at the beginning of the code section, and the pointer to the InternalHookProc
    was actually at the beginning of the code section rather than at the end. Also, there
    were some cases where references were being made to code further up in memory, which did
    not exist when the code was injected.
    - Added the _SNIFFDEBUG #define to allow debug output to appear even in release builds.
    Commment the line out when you're done testing the sniffer and ready to use it for real.

    Revision 2.03
    - Added more debugging code to try and isolate why the DLL isn't being released properly
    - Added a safety variable gsh_bInjected to prevent multiple injections of the code into the game

    What's it do?
    This sniffer does what most sniffers do -- it retrieves the encryption key from the running EQGAME and sends it via UDP protocol to your SEQ box. Keep reading for the juicy bits.

    How's it different?
    This sniffer, unlike all others, lives inside the running EQGAME. It is injected into the game's address space by a DLL (dynamic link library), and all evidence of the DLL is removed immediately after the injection occurs.

    Is it a hack?
    No! It is completely benign and completely legal (meaning it uses normal Windows API functions and doesn't hack anything). When the game launches, the sniffer DLL is automatically loaded along with it, courtesy of the Windows OS. It's there legitimately! Not only that, but as part of the startup procedure for all DLL's, the DLL must tell the OS whether or not to load for any given program. The sniffer DLL detects when it is being loaded into the EQ game, injects its payload, and then tells the OS NOT TO LOAD IT! Before EQ even knows what hit it, Windows loaded the sniffer and the sniffer rejected the load request -- but in between being loaded and rejecting the load request, the sniffer injects its sniffing code into EQ's memory address space (see below for more details on this) and sets the sniffer to running.

    Whats this about injecting code? Do you alter EQ?
    Hell no! All processes take up a certain amount of room in memory when they're running. They're certainly allowed to allocate more memory if they need it, and indeed all programs allocate more memory for their variables, their windows, etc. The sniffer DLL merely allocates more memory when it loads, and drops the sniffer code into that new memory block!

    How does it work?
    Windows supports something called Hooking. The exact API call (if you want to look it up for yourself) is called SetWindowsHookEx(). This built-in mechanism is used by applications far and wide to tap into mouse messages, keyboard messages, etc. If you have a Logitech mouse for example, your mouse driver uses this API to intercept a middle mouse button click and turn it into something else, like a double-click or whatnot. Windows allows this, it is perfectly legal, and much to our benefit, is completely undetectable by a running program! That's the kicker of the hooking mechanism ... none of the applications are aware of it, and there's no way to detect if a hook has been installed!
    This sniffer utilizes the built-in Windows hooking mechanism to make the Windows OS automatically load the DLL into every process in the system.
    When the sniffer attaches to EQ, it allocates some memory, places some more hooking code into that memory, then creates a new hook JUST FOR EQ. Once finished, it then calls the UnhookWindowsHookEx() method to unhook the original system-wide hook from all the rest of the processes in the system.

    The end result is that the sniffer drops out of existance, leaving only a single hook in the EQ process, and that hook points to the sniffer procedure that was injected into legally-allocated memory in EQ's address space. It can then freely sniff the encryption key and send it to the SEQ box. EQ is unware of the hook, and no residual DLL's exist in memory.

    How sneaky is it?
    1. The sniffer allocates memory via VirtualAlloc(). Windows returns back with a pointer to that memory. It is entirely up to Windows to decide where to allocate the block, so it is never in the same place on any given computer or on any given run of the program.
    2. The sniffer DLL dislodges itself from the EQ game before the OS even finishes loading the DLL, so the EQ game never even knows there was a load attempt on the DLL. The DLL never lasts long enough for EQ to enumerate it and detect it.
    3. There's no published API calls to detect Windows hooks, disable them, or get information on them. They're ghosts in the machine, so to speak. The sniffer's hook on EQ exists only in the EQ process, and even then in a random location in memory assigned by Windows.
    4. The hook mechanism means that no additional threads are created (a process may have multiple threads of execution at any given time). Since no extra threads are created and the hook executes in the main program's thread, EQ can't do a thread count or examine the threadproc's to determine if any unknown threads are running in its address space.
    5. The sniffer generates no additional messages in EQ's
    message loop. No timer messages, not even a peep.
    6. No extra processes are running while EQ is running. The RUNDLL32 program only runs up until EQ gets loaded. When EQ loads, the RUNDLL32 program exits ... so EQ can't enumerate running programs and detect RUNDLL32. Even if they did, RUNDLL32 is a legitimate Windows program and has a right to be in the task list (and quite often IS!)

    What do I need to compile this?
    This is the tricky part. Due to the complexity of the injection code, I was forced to use about 3 lines of inline assembly. The Microsoft compilers can compile the inline assembly, but I have no idea if any other compilers are capable of it. I developed it using MS Visual C++ 6.0 and the latest platform SDK. It should compile on Visual C++ 6.0 and .NET with or without the platform SDK.

    If your compiler doesn't support inline assembly, I recommend using the code from V1 which can be found here:

    http://seq.sourceforge.net/showthrea...&threadid=2453

    Instructions for running the program are contained in the eqsniffer2.cpp file, along with revision information and other more detailed information.

    As always, use at your own risk!

    Maggotboy
    Attached Files Attached Files
    Last edited by maggotboy; 11-22-2002 at 01:40 AM.

  2. #2
    Registered User
    Join Date
    Sep 2002
    Posts
    18
    wow great util, and informitive post, thanks!

  3. #3
    Registered User
    Join Date
    Dec 2001
    Posts
    144
    Admit it, Maggotboy! You had fun writing this; didn't you?!

  4. #4
    Registered User
    Join Date
    Nov 2002
    Posts
    115
    Originally posted by guice
    Admit it, Maggotboy! You had fun writing this; didn't you?!
    Darn tootin! It's one of those "can I do it" projects that keep you up until 3am and occasionally give your computer a blue-screen

    Maggotboy

  5. #5
    Registered User fgay trader's Avatar
    Join Date
    Feb 2002
    Posts
    117
    You also like to use the word "legal" alot
    -FGay Trader er... GFay

  6. #6
    Registered User
    Join Date
    Dec 2001
    Posts
    10
    Off topic -

    Can anyone tell me how in the world to do this:

    #pragma comment(linker, "/section:.shared,rws")

    in Borland C++ Compiler?

    It doesn't like that, or:

    SECTIONS
    .shared READ WRITE SHARED

  7. #7
    Registered User
    Join Date
    Dec 2001
    Posts
    8
    I usually don't post on these boards much, except to help here and there when I can.

    I'm able to take what's on these boards, get it working, and am mostly the quiet guy around here.

    But a program like this deserves a "Well Done," from even the lurkers . This is nothing short of amazing.

    Props to you, maggotboy.

  8. #8
    Registered User
    Join Date
    Oct 2002
    Posts
    10
    refuses to run when compiled via .NET

    tried statically linking the MFC and it wont even compile.

  9. #9
    Registered User
    Join Date
    Sep 2002
    Posts
    14
    OK, after i compile with Microsoft Visual C6,0++ my "keyniffer" i get a directory with several files and folders in (Debug, Release).

    What do i have to start now ? There is no .exe file in this directory ?

    What is this "template command file " ? A Dos line ? From which directory do i have to run

    "RUNDLL32.EXE keysniffer.dll, InstallHook IP-Adress EQgame.exe Offset ??????

    ---> Is this a Dos command ?
    or a special command in the compiler ?

    Help a small noob please =)

  10. #10
    Registered User
    Join Date
    Nov 2002
    Posts
    115
    Originally posted by Hannibal
    Can anyone tell me how in the world to do this:
    #pragma comment(linker, "/section:.shared,rws")
    in Borland C++ Compiler?
    Requires a few tweaks ... I found this article on borland's website:

    http://community.borland.com/article...,20132,00.html

    In addition to marking the section shared as in their example at the site, you also have to make sure its marked READ WRITE.

    Maggotboy

  11. #11
    Registered User
    Join Date
    Oct 2002
    Posts
    5
    Compiled without errors on MSVS++ 6 but when I call the rundll32 thing, I get an error message (trying to translate from german):
    Error loading snif.dll
    A DLL initializing routine failed
    Any idea what could cause this?

  12. #12
    Registered User
    Join Date
    Dec 2001
    Posts
    10
    Originally posted by Talon
    There is no .exe file in this directory ?
    Talon - your are compiling a DLL file. There will be no exe.

  13. #13
    Registered User
    Join Date
    Nov 2002
    Posts
    115
    It's probably got to do with the DllMain routine. It returns FALSE when it should return TRUE at the end.

    It should return FALSE inside the if(dwReason == DLL_PROCESS_ATTACH) rather than outside as well.

    I'll have to test it some more.

    Maggotboy

  14. #14
    Registered User
    Join Date
    Dec 2001
    Posts
    10
    Maggotboy -

    Thanks. Sorta got that working, switched over to your new source - I don't believe Borland supports inline assembly. I could be wrong, I got frusterated - uninstalled Borland CBuilder 6, and will be installing Visual Studio .NET when I get home.

  15. #15
    Registered User
    Join Date
    Aug 2002
    Posts
    4
    Thanks again for your hard work Maggotboy, it's very much appreciated! Now to my problem =)

    First off, I'm running MS VC++ 6.0 standard (no service packs)
    Versions 1, 1.2 and 1.3 of your code compile and run without problem on my machine.

    Version 2.0 compiles fine, but when I go to run it I get the following error: "RUNDLL Error loading tcpcnt.dll A dynamic link library (dll) initialization routine failed"

    The syntax I use to run is: "rundll32.exe tcpcnt.dll,tcpcntstrt 192.168.1.101 12000 eqgame.exe 0x0078AAD"

    I've double checked the spelling in the .def and .cpp files to make sure there was no typo, but it all looks fine. Any suggestions?

Thread Information

Users Browsing this Thread

There are currently 2 users browsing this thread. (0 members and 2 guests)

Posting Permissions

You may post new threads
You may post replies
You may post attachments
You may edit your posts
HTML code is Off
vB code is On
Smilies are On
[IMG] code is Off