View Full Version : A different approach (code)
maggotboy
11-16-2002, 12:33 AM
[Updated code to 1.4 -- see the comments below in the source for details]
Attached is a ZIP file containing
eqsniffer.cpp
eqsniffer.def
The source is too long to post, so here's just the topmost info:
/* eqsniffer.cpp written by Maggotboy
HOW IT WORKS
This DLL takes advantage of the built-in hooking mechanism of Windows 9x/NT. The DLL hooks into
keyboard processing messages on all processes in the system using a global keyboard hook. This
allows the DLL to sit in the address space of all processes that handle keyboard events.
When the DLL detects that it has latched onto EQGAME.EXE, it does several things ... First, it
de-hooks itself from the global keyboard hook chain. Then it hooks into the main message pump
of EQ's main thread. As messages get processed by the game through the normal mechanisms, the
DLL will be checking the game's memory and sending the encryption key to SEQ when it changes.
This method is completely unobtrusive. No changes are made to the running program, no extra
threads are created, no extra messages get pumped to the application. The datablocks it uses
are scrambled using a random number, and the more you rearrange the code and global variables,
before compiling this, the safer you are from being detected.
There are no API calls to detect whether or not any hooks have been installed, and no way to
shut down a hook without knowing the hook's unique hook handle. The ways of detecting this
program's presence are incredibly complex, and by changing the program around before you
compile it, you pretty-much eliminate most feasible detection methods.
COMPILING THE PROGRAM
Before you compile this program, you need to take several steps:
For VC++ 6.0 users:
1. Create a new WIN32 DLL Project. Select "Empty DLL Project" for the type, and give
the project an obscure name like TCPEXT or somesuch thing. The final DLL will compile
as <projectname>.DLL ... So if you chose TCPEXT, the DLL will compile as TCPEXT.DLL.
For VS.NET users:
1. Create a WIN32 Project. Make the project a DLL Project, and make sure its an
"empty" project. You want to end up with a blank DLL project that has no files.
Make sure you name the project something obscure as mentioned in the VC++ 6.0 step.
Common steps:
2. Add the eqsniffer.cpp and eqsniffer.def files to the project.
3. Edit the eqsniffer.def file, and at the top where it says "LIBRARY eqsniffer" change
the name to the name of your project (no DLL extension).
***** The following steps are optional, but highly recommended in order to make your
***** build unique and deter Verant from being able to detect the program. The program is
***** quite stealthy on its own, but the steps below will give you some added security.
4. Rename HookProc, InstallProc and ReleaseProc to something obscure in the DEF file while
you're there.
5. Open the eqsniffer.cpp file and find where the "#define EQHOOKPROC" statement is down below.
Rename the functions to the same names you gave in the .DEF file in step 4.
For example ... if you renamed HookProc to TCPNotify, the #define statement would
read:
#define EQHOOKPROC TcpNotify
Do this for all 3 functions, making sure they match the names in the .DEF file.
RUNNING EQ WITH THE HOOK
First, you have to get this program up and running.
To install the hook, use this command line as a template:
RUNDLL32.EXE mysniffer.dll,InstallHook <ipaddr> <port> <filename> <memaddr>
Replace "mysniffer.dll" with whatever name you gave the DLL
Replace "InstallHook" with whatever name you gave to the InstallHook procedure from
steps 4-5 above.
<ipaddr> The IP Address of your SEQ box
<port> The port to send UDP packets to the SEQ box on
<filename> Either EQGAME.EXE or TESTEQGAME.EXE or any partial derivitive of.
The code uses strstr() to see if this sequence is in the actual
filename of the process being attached (case-insensitive)
<memaddr> The memory address to read the key from ... 0x00773b90
Example:
RUNDLL32.EXE mysniffer.dll,InstallHook 192.168.1.10 666 eqgame.exe 0x00773b90
Once you've installed the DLL, run EQ normally. There's no timeout or time limit ... whenever you're ready, run the game.
REMOVING THE HOOK:
Removing the hook is only necessary if you installed it, but never ran a program that
matched the search criteria (in our case, "eqgame.exe"). If you ran that program, the
hook auto-terminates, so there's no need for manual removal.
RUNDLL32.EXE mysniffer.dll,ReleaseHook
Again, rename "mysniffer.dll" to the name of your DLL, and rename "ReleaseHook" to
whatever name you called it from steps 4-5 above.
Revision 1.4
- Fixed the call to GetTempFileName() to pass CORRECT information. This should fix the RUNDLL32 not unloading bug.
Revision 1.3
- The DLL automatically releases itself from the global hook chain when it successfully hooks
to the matching process. When it hooks into the target process, it uses a local-only hook.
- Changed the way the hooking mechanism works. The global hook is triggered by a keypress
rather then a mouse move.
- Removed the Timer from the sniffer. The DLL now uses a WH_GETMESSAGE hook local to the target
process, which hooks into the main thread's message queue. No timer is necessary, and the
sniffer has improved invisibility :)
- Got rid of rand() and srand() for lighter code. Uses GetTickCount() now to get the XOR seed.
Revision 1.2
- Removed the try/catch and replaced it with the easier IsBadReadPtr() API call to determine
whether or not the mem addr is readible.
- Modified the DoEQProcessing() loop to only open a socket if the key changes. Oops!
Revision 1.1
- Added _MSC_VER checks around the __try and __catch exception handlers to avoid non-MS compiler problems
- Added function prototypes to avoid problems when the code is rearranged.
- Added #define's to define the name of the HookProc, InstallHook and ReleaseHook methods for easy renaming.
- Added a #define for the update interval, defaulting to 500ms (half a second). Since this DLL lives
in the same address space as the game, it doesn't have the overhead of out-of-process methods and therefore
doesn't require as much time and effort and API calls to get the key. Therefore 500ms is quite acceptable.
*/
/*
TODO:
- Change the name of the InstallHook, ReleaseHook and HookProc functions.
- Edit the EQSNIFFER.DEF file and update it to reflect the above changes.
- Rearrange the items in the shared data segment, add some filler nonsense
variables, etc.
*/
maggotboy
11-16-2002, 12:46 AM
For you NT users, you can make a UNICODE build of this DLL. You have to do a couple things ...
1. Add an uppercase W to the end of your InstallHook function and in the corresponding .DEF file. Do not refer to it with the W when calling RUNDLL32.DLL ...
For example, rename InstallHook to InstallHookW in the .cpp file and in the .def file, but your original RUNDLL32.EXE command-line will remain the same.
2. Reconfigure your compiler options for a UNICODE build -- this usually involves #define'ing _UNICODE and UNICODE
3. Line 197, which reads:
gsh_SEQAddr.sin_addr.s_addr = inet_addr(pszTok);
Needs some changes, since pszTok will now be a UNICODE string, and inet_addr() doesn't accept UNICODE strings. You'll have to call the WideCharToMultiByte() function to convert it prior to giving it to this winsock function.
I haven't tried compiling it for UNICODE, so I'm not sure if I missed anything else in the code.
Maggotboy
RavenCT
11-16-2002, 08:04 AM
/clap Maggotboy
Forgive me what is probably a stupid (or simple) question. I'm an MCSE and I've been working in this field for around 10 years now, so I know networking but not development... (Although I did just get the Visual C++ for dummies book last night and I'm starting to read it...)
Would you mind answering, Why would someone want to make this for UNICODE ??
Is it any different that in its normal form and what does it accomplish? Does it (in the end) make it harder to detect?
Thanks!
(Flame on)
RavenCT
11-16-2002, 08:49 AM
So, I created a new empty DLL project and added the two files. Change some names, moved some stuff around, etc, etc, etc
When I go to compile it I get:
Compiling...
SnifMe.cpp
D:\Program Files\Microsoft Visual Studio\MyProjects\SniffMe\SnifMe.cpp(154) : error C2664: 'SetTimer' : cannot convert parameter 4 from 'void (struct HWND__ *,unsigned int,unsigned long,unsigned long)' to 'void (__stdcall *)(struct HWND__ *,unsigned
int,unsigned int,unsigned long)'
None of the functions with this name in scope match the target type
Error executing cl.exe.
Any ideas? I'm looking around to see if I can figure this out, but a little help would be greatly appreciated :)
fryfrog
11-16-2002, 09:13 AM
is there any chance you think this might compile with gcc in MinGW some how?
C:\Temp\dll>gcc -c eqsniffer.cpp
eqsniffer.cpp: In function `void DoEQProcessing()':
eqsniffer.cpp:99: `__try' undeclared (first use this function)
eqsniffer.cpp:99: (Each undeclared identifier is reported only once for each
function it appears in.)
eqsniffer.cpp:99: parse error before `{' token
eqsniffer.cpp: At global scope:
eqsniffer.cpp:118: ISO C++ forbids declaration of `__except' with no type
eqsniffer.cpp:118: syntax error before `{' token
eqsniffer.cpp:121: `s' was not declared in this scope
eqsniffer.cpp:121: ISO C++ forbids declaration of `closesocket' with no type
eqsniffer.cpp:121: `int closesocket' redeclared as different kind of symbol
c:/MinGW/include/winsock.h:429: previous declaration of `int
closesocket(unsigned int)'
eqsniffer.cpp:122: parse error before `}' token
Seqsy
11-16-2002, 09:23 AM
RavenCT,
I had the same problem. Figured out that I had to typecast that TimerProc parameter. Try this:
SetTimer(NULL, 0, 500, (TIMERPROC) TimerProc);
BTW I'll have Unicode version posted shortly - it's compiling with VC6 now, but not working yet for whatever reason...
Seqsy
11-16-2002, 10:50 AM
Bah not working with XP, not sure why. Will argue with it more later... Sorry no Unicode version yet
MisterSpock
11-16-2002, 10:53 AM
I have an error free compile, but have not yet gotten it to cooperate on Win2k. Looking at it further, too.
maggotboy
11-16-2002, 10:54 AM
First, the TimerProc ...
If you rearrange any of the functions, you'll need to prototype them at the top of the .cpp file. I'll post an update later today with the modified code with the prototypes in place.
If you modify the TimerProc, make sure it remains VOID CALLBACK. CALLBACK evaluates to the __stdcall calling convention, and all function callbacks have to use the __stdcall calling convention.
As for the __try/__except handler, just // comment those lines out if your compiler doesn't support them.
maggotboy
11-16-2002, 11:00 AM
I wrote the code and tested it in WinXP ... I had some trouble when first entering the game -- SEQ would be all grey dots ... but after I zoned the first time, it would be fine. I wasn't sure if it was my fault or not.
OH, as for UNICODE ...
UNICODE is the native environment of Windows NT-based OS's. The only real reason to compile it in UNICODE on NT is to further obfuscate the resulting binary.
Maggotboy
MisterSpock
11-16-2002, 12:20 PM
Maggotboy --
I should be able to point this toward any process, correct? What I normally do to check the operation of a keysnarfer is as follows:
Launch Calc.exe
Launch a version of keysnarfer pointed to 0x01000000
Set the keysnarfer to send to my SEQ box, but don't launch SEQ
use tcpdump on the linux box set to listen only to the port in question.
Test
This way, I can test and fine-tune the operation of the code w/o launching eq more than necessary.
Is there any reason this code wouldn't work when pointed to calc? The dll's function seems to launch correctly, but does not hook, and then doesn't release the hook. As such, rundll32 must be terminated manually. Just to see if I was doing everything correctly, I added some additional functions (that don't do much of anything but beep, etc) and set them as exports. They work fine when launched with rundll32.exe, so my project settings, etc, are probably okay.
On an unrelated note, with a few minor adjustments, mainly in handling the exports, this also compiles in lcc-win32 :)
maggotboy
11-16-2002, 12:49 PM
The hook is a global hook which hooks all processes and remains in memory until terminated with the RUNDLL32.EXE snarf.dll,ReleaseHook
If you compile for debug build you should see "attach" debug messages as it attaches it to every process that handles mouse events.
It will remain attached to all the processes until you release the hook with a 2nd call to RUNDLL32 ...
When you run EQ, you'll see attach messages first to EVERQUEST.EXE and then to EQGAME.EXE when the license agreement pops up.
The only way to see the debug output is to either run it under the debugger, or to get the DBMON.EXE which comes with the Microsoft Platform SDK and run that (NT-based OS's only).
heythere
11-16-2002, 12:50 PM
Great work! I'm getting one error when compiling in lcc. "Missing Exports: Aborting " Being new to this (after looking in the lcc help text) I have come back here for any suggestions.
Thanks,
HeyThere
MisterSpock
11-16-2002, 12:55 PM
Yep -- the ReleaseHook export runs, but does not remove the hook, nor does it cause rundll32.exe to exit....
One way to get the functions to export in lcc-win32 is to declare them as such in the code.
For example:
int __declspec(dllexport) MyFunction(int f)
{
// some code here
return(1);
}
This will cause an export called
_MyFunction
which could be launched by :
rundll32 whatever_you_name_your_dll.dll,_MyFunction
Hope this helps!
maggotboy
11-16-2002, 01:15 PM
Well ... like I said, I've only ever used MSVC++ ... and it compiles and works great on XP using VC++ 6.0 (latest service packs and latest platform sdk)...
Maggotboy
MisterSpock
11-16-2002, 01:18 PM
I'm compiling with both MSVC++ (6) and lcc.
Behavior of both is the same when attempting to test using calc.exe as the process...
Going to run it with the debugger...
heythere
11-16-2002, 01:25 PM
Mr. Spock,
Thank you for your last reply, I have been trying to figure out what to change-- then fixing the errors that came up when i changed stuff. Seems I don't know enough about this to dable and I don't have a version of MS VC++ to use. Could you post your LCC could for me please.
Heythere
Elifino
11-16-2002, 01:29 PM
Using MSVC++
Created a new win32 project ... selected DLL, empty project
Added existing files...eqsniffer.cpp and eqsniffer.def (it placed them under Source Files)
Made the suggested changes and changed the three defines EQHOOKPROC, INSTALLHOOK, RELEASEHOOK to TcpNotify, StartSend, FinishSend (for now at least) and changed the three lines in eqsniffer.def to match.
Then did a build, one warning about a type cast no errors...
When running
rundll32.exe myproject.dll,StartSend 192.168.0.2 8061 eqgame.exe 0x00773b90
it appears to run fine...after a few seconds the error:
Error in myproject.dll
Missing entry:StartSend
Any idea as to what I am doing wrong? Thanks in advance for any help.
Morannon
11-16-2002, 01:52 PM
Attempting to build it in VS.NET under WinXP -
Fatal error C1010: unexpected end of file while looking for precompiled header directive.
Any ideas ?
maggotboy
11-16-2002, 01:56 PM
Morannon -- make sure your project isn't using any precompiled headers ... or if you did make a DLL project with a stdafx.h and stdafx.cpp, make sure you add #include "stdafx.h" to the top of the eqsniffer.cpp file.
The error occurs when the project is configured for precompiled headers, and the specified .cpp file doesn't reference them.
Maggotboy
maggotboy
11-16-2002, 02:00 PM
Elifino -- not sure what could be wrong.
If you have the MS Platform SDK, you can use DEPENDS.EXE or DUMPBIN.EXE to view the DLL's exports...
Using DUMPBIN, type
DUMPBIN mydll.dll /exports
It'll show you the exported functions out of your DLL as they appear in the DLL ... so if there's any mismatches, you'll catch it here.
DEPENDS.EXE is a nice GUI version which shows you DLL dependencies and exported symbols.
Maggotboy
Morannon
11-16-2002, 02:50 PM
Ahh... I had selected the wrong type of DLL, tried again and its working perfectly ! Thanks !
Spook
11-16-2002, 02:59 PM
Elifinio:
Go to project properties
Open Linker settings
Find the INPUT setting options
add eqsniffer.def to the module definition file section
cheeze69
11-16-2002, 03:44 PM
Hi,
I only have VS.net (and yeah, it's legal :) thanks to MS employee discount!) and I'm running into a problem trying to compile this code.
I created a new VC++ Project, of type MFC DLL. I overwrote the .cpp and .def with the ones from your .zip file and restarted so your code/etc. is there.
When I try to build the solution, or even just the .cpp file, I get this error:
c:\build\eqsniffer\eqsniffer.cpp(301): fatal error C1010: unexpected end of file while looking for precompiled header directive
Any idea why this is happening? I'm afraid that I'm not at all proficient with this Visual Studio -- I bought it hoping to learn some new languages, but so far, I have not had an excuse to write anything in it :(
Thanks!
maggotboy
11-16-2002, 03:48 PM
Yeah ... look up about 3 messages above yours for the answer.
cheeze69
11-16-2002, 03:52 PM
Doh! Just saw the post regarding the precompiled lib error from someone else.
I added the #include <stdafx.h> to the source, but now I get a dozen other errors about "missing ;", undeclared identifiers, and other goodies.
Is MFC DLL the right type of project for me to choose? There is also an ISAPI DLL project type, but I have no idea what that is.
Thanks!
maggotboy
11-16-2002, 03:59 PM
Choose a standard Win32 DLL, not MFC, ISAPI or any other "helpers"...you want to end up with an empty DLL project with no files whatsoever.
cheeze69
11-16-2002, 04:08 PM
Ahhh.... thanks maggotboy! I had the wrong project type selected. VS.net defaults to a large icon view which was obscuring the 3rd DLL option (which worked).
Thanks for the help!!!
Elifino
11-16-2002, 04:31 PM
Thanks Spook
seq appears to crash every now and then ... believe it occurs after zoning or right before zoning -- does how frequently you scan and update have anything to do with that or is that another problem?
cheeze69
11-16-2002, 04:47 PM
Well, after finally getting the dll built, I issue the rundll32 command like this:
rundll32.exe mjseqdll.dll,InstallHook 192.168.1.2 1069 eqgame.exe 0x00773b90
(Yeah, I need to change the InstallHook to a different name to obscure, but for now, I just want to get it running for now).
This pops a dialog about not being able to find "opends60.dll" and then errors out.
Any idea why this opends60 is getting requested and where the heck I can get it or make it not required?
Thanks!
Mr. Suspicious
11-16-2002, 04:59 PM
Any idea why this opends60 is getting requested and where the heck I can get it or make it not required?
http://www.google.com -> Searchword: opends60.dill result:
opends60.dll (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odssql/ods_6_con_00_6p9v.asp)
maggotboy
11-16-2002, 05:02 PM
opends60.dll is a SQL Server open database services library. I have *NO* idea how in the world you ended up having a dependency on this library!
Make sure the lib doesn't appear in your linker settings ...
Maggotboy
cheeze69
11-16-2002, 05:31 PM
Ahh, this must be because I selected the VS.net "Extended stored procedure DLL".
VS.net does not have a "plain" DLL project template, only the following:
ATL Project
ATL Server Project
ATL Server Web Service
Custom Wizard
Extended Stored Procedure DLL
Makefile Project
Managed C++ Application
Managed C++ Class Library
Managed C++ Empty Project
Managed C++ Web Service
MFC ActiveX Control
MFC Application
MFC DLL
MFC ISAPI Extension DLL
Win32 Project
So far, I've tried all 3 DLL options, and the Extended Stored DLL has been the only one to compile but it is obviously intended to work the MS-SQL server or something, hence the dependancy on the opensd60.dll.
I guess I'll keep messing around trying to figure-out how to work around this.
maggotboy
11-16-2002, 05:33 PM
You want WIN32 Project. From there you can select EXE or DLL, etc.
It's been a while since I used VS.NET :)
cheeze69
11-16-2002, 06:04 PM
Thanks again, maggotboy! The Win32->DLL template did not have any extra crap or dependancies. I'm really feeling like a n00b at this Windows/VS.net stuff :D
So, I'm now building without errors (finally -- sorry about my lack of knowledge!) but when I run the dll:
rundll32.exe eqsniff.dll,InstallHook 192.168.1.2 1069 eqgame.exe 0x00773b90
I get an "Error in eqsniff.dll. Missing entry:InstallHook".
I did notice that VS.net was not interested in the eqsniffer.def file -- it did not even know what to do with that type of file. Would that explain why InstallHook is not getting exposed? BTW, I did not change the source code at all yet, so all of the function names should still match-up...
I guess this is why I was trying to figure-out how to make a Perl version of the sniffer -- I'm too n00b at Windows development!
Thanks again!
Morannon
11-16-2002, 06:15 PM
Mine compiled using the 3rd option of the MFC DLL.
I pasted the CPP file after the
static AFX_EXTENSION line in the project.cpp file
and the DEF file I posted after the LIBRARY line, and deleted the empty EXPORTS line.
cheeze69
11-16-2002, 06:56 PM
OK, here's a rundown on what I did for others who may be having trouble with VS.net:
1) Create a new project using the MFC DLL template. In the wizard, select Application Settings (NOT Finish) and then "MFC Extension DLL". I also enabled the Sockets support, but I don't know if it's required.
2) Close VS.net.
3) Unpack the .cpp and .def from the zip into your project's directory. Overwrite the .cpp and .def from VS.net with these two files.
4) Open VS.net and open your project.
5) You should now see maggotboy's code in the project.cpp. Scroll down to the INCLUDE statements.
6) Add #INCLUDE "stdafx.h" before all of the other INCLUDES.
7) Perform any other edits you may want and follow directions in .cpp file.
8) Mash "Build Project."
Hopefully, that will do it for you.
Again, thanks to all who helped me in figuring this out!
Mike
Spook
11-16-2002, 07:43 PM
Compiles and all but doesn't appear to work with how I am running it. How are *you* running it ?
I have a little app to load eq wait 70 secs then it.... ?
Morannon
11-16-2002, 08:38 PM
Do the rundll32 xxx.dll,InstallHook blah blah blah
Then run eq.
UncleBen
11-16-2002, 09:27 PM
Thanx for sharing this MaggotBoy. downloading a copy of msvc++ standard, updating, and having a go at it tonight; woot
ManOnTheMoon
11-16-2002, 11:25 PM
This is a nice bit of code!
I thank you for skills and time on this.
falkore
11-16-2002, 11:55 PM
Downloaded, 11:50pm
Compiled with M$VS.NET, 11:55
Up and Sniffing, 11:59
Simply amazing.
Undectable via the process list, damn near 100% silent, no waste of resource, just amazing..
Thank you.
///EDIT: I cannot type ///
UncleBen
11-17-2002, 02:31 AM
WOOT. downloaded MSVC++ 6.0 standard and changed to this line as posted on first page (SetTimer(NULL, 0, 500, (TIMERPROC) TimerProc); ) after getting compile error. and it works!
Frickin marvelous; muahah.
PS, doing the rundll32.exe sniffer.dll,remove. It gives no errors but doesn't seem to unload caus i can see rundll32 when I ctl+alt+del.
no biggy, cause I just shut it down from there np.
thanx again
love it love it
maggotboy
11-17-2002, 02:33 AM
I'll have to test it on Win9x platforms to make sure I didn't miss something silly. The differences between 9x and NT are boggling sometimes.
Maggotboy
Kimbler
11-17-2002, 05:28 AM
UncleBen,
WOOT. downloaded MSVC++ 6.0 standard
I searched MS site and was not able to find MSVC++ 6.0 standard to download only All that appear are .Net versions. Searching Google resulted in lots of add-ins but not MSVC++ 6.0 standard itself. Could you point me towards where you got MSVC++ 6.0 standard itself. Thank you.
MisterSpock
11-17-2002, 05:54 AM
I have not gotten this code to work yet using lcc-win32 as the compiler. I can get it to compile without error, but not to correctly attach and send keys. A slightly modified version on MS compiles and runs perfectly.
But, for starters, the .def file needs to change for lcc. Something like:
LIBRARY eqsniffer
EXPORTS
InstallHook
ReleaseHook
HookProc
will work. Add it to the linker options, and your exports will be properly defined. FYI -- in the first line, whatever follows the keyword LIBRARY must match the name of the dll you're going to make. So, for example, if you're naming your dll sniffthis.dll, the first line would be:
LIBRARY sniffthis
Note -- do NOT add '.dll' to this, or it will expect sniffthis.dll.dll...
The 1.1 zip file, when these changes are made, compiles without issue, but I've not had luck getting it to work. I'll keep plugging away at it.
this might be a platfrom issue, but i have it to compile fine with no errors (msvc++ 6)
start the hook no errors
nothing happens after that
running windows ME
the design is great, would like to get this one working for me.
if anyone else is using ME and have this working can you let me know what needed to be done if anything
LordCrush
11-17-2002, 08:50 AM
I try to get it working using Borland.
Thank you for giving us the code and let us participate in your knowledge :) /bow
If i'll get it it working, i'll post possible changes. /cheer
well im tryin to compile this in cbuilder and i got an error i seen here earlier in the thread so i typecasted like it suggested and now i got these 2 errors any help or a point in the right direction would be awsome :)
C++ Error] xxx.cpp(188): E2034 Cannot convert 'long (__stdcall *)(int,unsigned int,long)' to 'int (__stdcall *)()'
[C++ Error] xxx.cpp(188): E2342 Type mismatch in parameter 'lpfn' (wanted 'int (__stdcall *)()', got 'long (__stdcall *)(int,unsigned int,long)')
[C++ Warning] xxx.cpp(280): W8004 'n' is assigned a value that is never used
Edit: FYI runnin under winxp
guice
11-17-2002, 09:58 AM
nm
Seqsy
11-17-2002, 10:16 AM
Just wanted to follow up on my post yesterday about why some people get the parameter conversion error on the SetTimer call that can be resolved by typecasting the TimerProc function pointer paramter.
SetTimer(NULL, 0, 500, (TIMERPROC) TimerProc);
The Windows API has that TIMERPROC function prototype in a typedef in winuser.h. No code there, just tells the compiler that the function pointer is of the correct type.
The box that I'm building this on is Win2k not WinXP so I'm guessing that's why Maggotboy didn't run into this.
maggotboy
11-17-2002, 10:27 AM
I can test under the following circumstances -- all with only the MSVC++ compiler:
Win XP
Win 2K
Win Me
Win 98se
When I get some time (hope this afternoon) I will do the tests.
Maggotboy
UncleBen
11-17-2002, 10:50 AM
Originally posted by Kimbler
UncleBen,
I searched MS site and was not able to find MSVC++ 6.0 standard to download only All that appear are .Net versions. Searching Google resulted in lots of add-ins but not MSVC++ 6.0 standard itself. Could you point me towards where you got MSVC++ 6.0 standard itself. Thank you.
it's copy I got off direct connect (place where I get all my software; hehe)
http://www.neo-modus.com
LordCrush
11-17-2002, 11:43 AM
Hmmm looks like warez ... in certain point ...
its one thing to work around SoE´s EULA with seq, but i prefer to pay for the software i am using ...
only my 2cp
UncleBen
11-17-2002, 07:03 PM
me too lord, sorry about that :( . I'm flat broke atm and just wanted the .dll compiled so I figured 'what the hell' :)
I don't keep warez, only borrow it when needed; lol. yeah, that's still bad . Don't hate me too much
Pokesfan
11-17-2002, 10:22 PM
OK, I'm normally able to figure out the nuances of this kind of stuff, but after reading through this about 10 times, I have a few things that are coming to mind.
1. I assume that since this is DLL oriented and runs in the background it doesn't have the same issues as the sniffer progs that use the ReadProcessMemory commands. Is this a correct assessment?
2. I don't quite understand what you were referencing with your 500 ms comment. Lets see if I'm correct on this: It runs and is able to check every half second for new key and only have a negligable impact on system performance?
I'm sure I'll have more questions after I get a grasp on this part.
Thanks for sharing,
Pokesfan
maggotboy
11-17-2002, 10:35 PM
Yes, it checks every 500ms for a new key. The 1.1 code needs to be modified to only open and close the socket if the key changes (bug) but other than that small change, checking the key every 500ms (half a second) involves no more than reading memory, comparing it, and exiting if they are identical. This sort of operation *could* be done every 5ms (1/200th of a second) or less, and still not impact the system. Of course, the SetTimer() function doesn't have that kind of resolution, though.
For comparison ... take a game that operates at 100 fps ... 100 frames per second is 1 frame every 10ms (1/100th of a second) ....and 1 frame every 10ms means evaluating, translating, lighting and rendering the entire screen EVERY 10ms!
All my program is doing is reading and comparing a measly 8 bytes every 500ms...which is a tiny TINY fraction of what it takes to render a full 3D frame.
Pokesfan
11-17-2002, 11:14 PM
OK, that I understand. Now what about the difference between this approach and the ReadProcessMemory hook used in most of the other sniffers?
Is this one "safer?" I guess what I am asking is to fill in a hole or two here for me. What makes this approach better than the other one. Does it make there be less (if any) fingerprints on the memory reads?
Sorry for the questions, I'm just trying to learn.
Pokesfan
heythere
11-17-2002, 11:39 PM
Although I have notced no lag due to checking ever .5 seconds, I was wondering if there is any benefit to slowing the timer down to say .. once every second or once every 5 seconds.
Or better yet time your average zone time and check once every 0.75xzonetime seconds.
maggotboy
11-18-2002, 12:38 AM
The problem with the ReadProcessMemory() method in use right now is threefold...
1. It requires another EXE to be running while EQ is running. One must cleverly disguise it to prevent it from being overly obvious during a task enumeration.
2. If VI modifies its security and/or elevates its security, it can potentially disable this method on NT-based OS's
3. Correct me if I'm wrong, but I think it requires a keypress to send the key onto the SEQ box. This is something else VI can be on the look-out for.
Aside from those limits, it is also uneconomical to have the ReadProcessMemory() method run on a short-timer because of the overhead it must incur by reading the address space of another process.
The DLL method is superior (aside from the implementation problems some people have had -- those bugs will be worked out soon enough) for several reasons ...
1. It lives in the same address space as the game, and cannot be squished by elevating priviledges or any other NT-based security measure.
2. It doesn't have any overhead in reading the memory, since it doesn't require a cross-process memory read. Reading the memory is literally an 8-byte read, no more than saying X = Y.
3. Even if VI enumerates the processes in memory, at most it'll only find RUNDLL32.EXE, which is quite often present anyway depending on the platform you're on. RUNDLL32 has legitimate reasons for being present and one cannot raise an eyebrow if it appears in the task list.
maggotboy
11-18-2002, 12:41 AM
As for the 500ms thing ... I need to make a change to the code to only open and close a socket if the key changes. Once I do that, I personally am going to switch to a 250ms timer. Even at that rate, I doubt anyone would see any performance degredation.
Maggotboy
maggotboy
11-18-2002, 02:27 AM
Code updated to 1.2 ... the original page 1 has been updated to reflect the new stuff.
Maggotboy
LordCrush
11-18-2002, 03:02 AM
Hi all ,
I am trying to compile with Borland C++ Builder and i receive the following error:
[C++ Error] eqsniffer.cpp(191): E2034 Converting from 'long (__stdcall *)(int,unsigned int,long)' to 'int (__stdcall *)()' not possible
[C++ Error] eqsniffer.cpp(191): E2342 The type at parameter 'lpfn' was expected to be 'int (__stdcall *)()', it is 'long (__stdcall *)(int,unsigned int,long)'
I have it now compiling with the following changes:
typedef int (CALLBACK* EQHOOKPROCType)();
...
gsh_hHook = SetWindowsHookEx(WH_MOUSE, (EQHOOKPROCType) EQHOOKPROC, g_hMod, 0);
I have not tested it now... if i can use that :confused:
Has anybody an idea ? - Thnx :)
MisterSpock
11-18-2002, 06:57 AM
Maggotboy --
Again, I like your code! This method is promising, indeed.
A couple of notes on the current method (ReadProcessMemory).
1) It *does* require an executable to be in memory. This can either be the code itself, or a service program that launches the code. It does need to be cleverly named (in case of tasklist scans), and people should do things to make their versions different.
2) ReadProcessMemory does not require a keypress. It will read upon execution. The only keypress that might be required is if someone has implemented the reader in such a way as to be interactive.
3) There *are* several things that tend to be common among the versions here. There is only one thing that really bothers me at all, after extensive reading and looking at the way these programs work. I won't say precisely what it is, since I don't want to give them any ideas. But, for those of you interested, consider implementing the sniffer with ToolHelp32ReadProcessMemory instead of ReadProcessMemory. There is a step in the RPM process that is unnecessary when using the toolhelp function. I'm not seriously worried about the detectability of this because of what must be done to detect it. However, if one is particularily worried about it, consider the tip above.
4) One final note -- we must consider what the resulting executable looks like in the file system. Most compilers/linkers tend to default leaving debug symbols on. I suggest turning off all debug-related output and optimizing the code at compile time. Other than for debugging purposes, I don't like the code to print anything -- remark out all the printf's. This reduces the size of the code in many cases. Additionally, careful handling of string constants is in order. When I open the executable in ultraedit32 (or even with a debugger), I don't like to see anything recognizable.
maggotboy
11-18-2002, 11:42 AM
LordCrush -- looks to me like a problem with the headers or with your declare. LRESULT is defined as a LONG, and matches the API requirements for a hook procedure. You've typedef'd with an INT return value, which technically doesn't match the LONG return value it is supposed to have ...
Maggotboy
LordCrush
11-18-2002, 01:41 PM
maggotboy,
i tried to match the error message
eqsniffer.cpp(191): E2342 The type at parameter 'lpfn' was expected to be 'int (__stdcall *)()', it is 'long (__stdcall *)(int,unsigned int,long)
it states that it wantes an itn return value, and no arguments ... wired behavior of borland
Samefudge
11-18-2002, 01:54 PM
Compiling as-is results in:
gcc -o keysniff.exe keysniff.c -lth32 -lwsock32
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp/ccWMdaaa.o(.text+0x1084):keysniff.c: undefined reference to `enable_debug_privs'
Edit:
Comment out the following and the script will compile under MinGW, but you lose the run-anytime functionality (I assume, un-tested yet).
Line 13:
// extern unsigned short int enable_debug_privs();
Line(s) 386, 387, 388:
//if (enable_debug_privs() == FALSE) {
// printf("unable to set debug privlidges. you may see the dreaded error 5.\n");
// }
I'd like it to work WITH debug_priv as well however, if anyone finds the fix for MinGW before I do.
cllnsj
11-18-2002, 01:56 PM
Could somebody please (that has sucessfully done this with lcc) be so kind to post step-by-step (layman terms) instructions on how to do this procedure? LCC seems to be the easiest to operate, and it doesn't require us to download any warez. Thank you in advance for assisting us with this project :).
Pokesfan
11-18-2002, 04:22 PM
Originally posted by MisterSpock
Maggotboy --
4) One final note -- we must consider what the resulting executable looks like in the file system. Most compilers/linkers tend to default leaving debug symbols on. I suggest turning off all debug-related output and optimizing the code at compile time. Other than for debugging purposes, I don't like the code to print anything -- remark out all the printf's. This reduces the size of the code in many cases. Additionally, careful handling of string constants is in order. When I open the executable in ultraedit32 (or even with a debugger), I don't like to see anything recognizable.
MisterSpock (or MaggotBoy),
While I'm working through this (I'm still trying to get a grip on the syntax of C++), you make the above comments. I have a couple questions for you regarding the code that Maggotboy has posted...
1. What modifications would need to be made to turn off all debug-related output? I see that almost every single output line appears to be debug
And here is a generalized question: I've performed webferret and google searches for a basic answer, but all I'm coming up with is gibberish: What is the main differences between printf and wsprintf? I've looked up both and as near as I can tell, printf is for output and wsprintf is for storing into a buffer. Is this the short of it?
I'm sure I'm showing how green I am right now. Please ignore me if I'm too much of a pain. :)
Pokesfan
maggotboy
11-18-2002, 04:47 PM
Originally posted by Pokesfan
1. What modifications would need to be made to turn off all debug-related output? I see that almost every single output line appears to be debug
What is the main differences between printf and wsprintf?
The first question is a little difficult to answer. It depends on your compiler. If you create an empty DLL project in MSVC++ 6.0 or on VS.NET, you need merely change the build from "debug" to "release" to get a release build without any debug info.
The reason all the debug lines are marked with #ifdef _DEBUG is because those wsprintf's and OutputDebugString's contain fixed text strings that Verant could use to sniff us out. I don't want that debug output or those strings in the final release build because I don't want Verant to be able to search for them in memory.
wsprintf() differs from sprintf() in that wsprintf() is a KERNEL32 API call, and sprintf() is a standard C runtime call. When you're trying to make lightweight code that has a little C runtime in it as possible, you can use wsprintf() instead of sprintf. That way the C runtime code for the sprintf() command doesn't have to live inside your code ...
I do that a lot...functions such as strcmp(), strlen(), strupr(), etc all have Windows API equivilents -- so you can avoid the added length of having those C runtime functions in your code by using the Windows API versions, lstrcmp(), lstrlen(), CharUpper(), etc.
Maggotboy
Spook
11-18-2002, 05:06 PM
The issue I had was not a problem with the code it was server related.
noacess
11-18-2002, 05:12 PM
Linking...
c:\eqsniffer.def : fatal error LNK1136: invalid or corrupt file
Error executing link.exe.
I'm using the same .def fil included in the zip, any ideas what wrong? Am I including the .def file wrong? please help
thanks
maggotboy
11-18-2002, 05:19 PM
Originally posted by noacess
Linking...
c:\eqsniffer.def : fatal error LNK1136: invalid or corrupt file
Error executing link.exe.
I'm using the same .def fil included in the zip, any ideas what wrong? Am I including the .def file wrong? please help
What compiler are you using? If MS, do you have all the latest service packs?
Maggotboy
maggotboy
11-18-2002, 05:30 PM
Code revved to 1.3 ... see the topmost post for details.
Maggotboy
noacess
11-18-2002, 06:26 PM
I just updated my MSVC++ 6 to the latest service pack and I am still getting
Linking...
LINK : fatal error LNK1104: cannot open file "eqsniffer.def"
Error executing link.exe.
I am going into Project>Settings>Link Tab>Category=INPUT>
and place eqsniffer.def in the Output/Lib modules.
Is this correct? And if so what folder do I have to copy the .def file to? Thanks
-noacess
Pokesfan
11-18-2002, 07:03 PM
Maggotboy,
Using MS Visual C++ 6.0
Linking...
Creating library Release/funstuff.lib and object Release/myprog.exp
myprog.exp : warning LNK4070: /OUT:eqsniffer.dll directive in .EXP differs from output filename "Release/myprog.dll"; ignoring directive
myprog.dll - 0 error(s), 1 warning(s)
Then when I try to execute the code, I get a RUNDLL exception. This is under Windows XP.
Not certain what is going on, I didn't have this issue on my Win2K box (at work). But it seems to give me the exception on version 1.2 and 1.3.
Pokesfan
maggotboy
11-18-2002, 07:29 PM
Originally posted by Pokesfan
myprog.exp : warning LNK4070: /OUT:eqsniffer.dll directive in .EXP differs from output filename "Release/myprog.dll"; ignoring directive
You need to edit the eqsniffer.def file and change
LIBRARY eqsniffer
to
LIBRARY myprog
That will solve the warning above.
What's the exact error you're getting in RUNDLL32?
Maggotboy
maggotboy
11-18-2002, 07:33 PM
Originally posted by noacess
I just updated my MSVC++ 6 to the latest service pack and I am still getting
Linking...
LINK : fatal error LNK1104: cannot open file "eqsniffer.def"
Error executing link.exe.
I am going into Project>Settings>Link Tab>Category=INPUT>
and place eqsniffer.def in the Output/Lib modules.
Is this correct? And if so what folder do I have to copy the .def file to? Thanks
No, this isn't correct ... not sure where you came up with this step :)
Undo this step. Just make sure the .def file and .cpp file are in the project. There's no additional steps required in the project setup.
Maggotboy
Pokesfan
11-18-2002, 07:43 PM
RUNDLL
An exception has occurred while trying to run "myprog.dll,HookProc 192.168.0.2 15000 eqgame.exe 0x00773b90"
Any ideas? And thanks for the friendly reminder on the DEF file. I have done this about 10 times and am getting sloppy I think.
Pokesfan
::edit - typed "will" instead of "while" in the error message
EQDoze
11-18-2002, 07:44 PM
I've successfully gotten this to build with Dev-Cpp, building it as a C language DLL project. However, if I try to build it as a C++ DLL project, I get linker errors. For Dev-Cpp, you simply create a new project, add the eqsniffer.cpp to the project, and create a .DEF file as so:
--- eqsniffer.def ---
EXPORTS
InstallHook
HookProc
ReleaseHook
--- end ---
You add this to Project->Project Options->Linker Options as:
--def eqsniffer.def
The caveat, of course, is that you need to build it as a C project. If you try it as C++, it fails with:
Undefined reference to InstallHook ...
(one of those errors for each export)
As I said, this results in a dll that can be loaded, but it does nothing... i.e. it never contacts the SEQ machine. I'll work on it some more to get it working. But, for now, that's the extent of my success with a "free" compiler/IDE.
maggotboy
11-18-2002, 08:03 PM
Originally posted by EQDoze
I've successfully gotten this to build with Dev-Cpp, building it as a C language DLL project. However, if I try to build it as a C++ DLL project, I get linker errors.
As I said, this results in a dll that can be loaded, but it does nothing... i.e. it never contacts the SEQ machine. I'll work on it some more to get it working. But, for now, that's the extent of my success with a "free" compiler/IDE.
2 things ...
#1 The .DEF file contains a SECTIONS entry. This MUST BE THERE for the program to work -- either that, or your compiler must have some other way of marking the ".shared" segment as "read write shared". If the special segment can't be marked as shared, the program won't work at all.
#2 For cpp compiles, in the function prototypes and in the actual functions that are exported, add the EXTERN_C macro ... like this:
EXTERN_C void CALLBACK HOOKPROC( ... )
This will keep the function names from being mangled. MSVC doesn't have issues, but other compilers apparently do.
Maggotboy
maggotboy
11-18-2002, 08:06 PM
Originally posted by Pokesfan
RUNDLL
An exception has occurred while trying to run "myprog.dll,HookProc 192.168.0.2 15000 eqgame.exe 0x00773b90"
Any ideas? And thanks for the friendly reminder on the DEF file. I have done this about 10 times and am getting sloppy I think.
Yap. You call RUNDLL32.EXE myprog.dll,InstallHook
not myprog.dll,HookProc !!!
Maggotboy
Pokesfan
11-18-2002, 08:14 PM
Originally posted by maggotboy
Yap. You call RUNDLL32.EXE myprog.dll,InstallHook
not myprog.dll,HookProc !!!
Maggotboy
OK, so I'm blind too. lol. Time for testing. Thanks a ton!
Pokesfan
MisterSpock
11-18-2002, 09:30 PM
Okay -- for those of you running lcc-win32 and want to use this code. Unfortunately, there is one minor code modification needed to get this running under lcc.
1) Create a folder for your new project. On the first screen, select the path, name, etc. Select Dynamic Link Library
2) Copy the source code and the .def file to the directory selected for this project. Edit: Change the extension of the file from .cpp to .c (lcc doesn't care for the .cpp extension).
3) Edit the eqsniffer.def file to look like the following (rename the exports accordingly):
Library MyDllName
SECTION
.shared READ WRITE SHARED
EXPORTS
InstallHook
ReleaseHook
HookProc
4) Create a new project in lcc. On the first screen, select the path, name, etc. Select Dynamic Link Library
5) Select create. Answer NO to the Application Skeleton question
6) Add the v.1.3 Sniffer.cpp code (or whatever you want to name it) to your project.
7) On the compiler settings screen, uncheck Generate Debug. Check Optimize and Use Pentium Pro.
8) For the linker settings:
a)select do not include underscores.
b) add wsock32.lib to the text box titled Additional files to be included in the link.
c) change the entry point name from LibMain to DllMain (case sensitive)
edit: Note -- lcc has a nasty habit of not remembering the dll entry point name. After you close lcc, if you come back in, you may have to change this back to DllMain again.
d) In the additional arguments text box, pass the name of your .def file, making sure to include the entire path.
e.g. c:\lcc\projects\mydll\eqsniffer.def
9) In the debugger screen, click finish. Your editor window should be open.
10) In the source code, find the line that reads (around line 193):
MoveMemory(szCmp, gsh_szFileName, MAX_PATH);
change to
CopyMemory(szCmp, gsh_szFileName, MAX_PATH);
(For some reason, my version of lcc will not properly link MoveMemory. You can try it with MoveMemory, and if you get a linker error, change to CopyMemory. MoveMemory is the preferred operation here, so I'll research this some more).
11) Select Compiler - Make from the menu and build your dll.
12) Close lcc and test.
13) Alter the export names, re-arrange the globals and add some, etc. Just make it different :)
Good luck -- hope this helps!
maggotboy
11-18-2002, 09:43 PM
Originally posted by MisterSpock
10) In the source code, find the line that reads (around line 193):
MoveMemory(szCmp, gsh_szFileName, MAX_PATH);
change to
CopyMemory(szCmp, gsh_szFileName, MAX_PATH);
(For some reason, my version of lcc will not properly link MoveMemory. You can try it with MoveMemory, and if you get a linker error, change to CopyMemory. MoveMemory is the preferred operation here, so I'll research this some more).
CopyMemory is just fine. I was experimenting with eliminating the C runtime library entirely ... forgot to revert this code back to CopyMemory.
Maggotboy
o0shadow0o
11-19-2002, 01:52 AM
Thanx for putting in the effort and writing up the walk through for LCC MisterSpock. I followed your instructions but there is one point I'm not too sure on and one spot I'm getting stuck.
First the point I'm not clear on is the changes to eqsniffer.def:
Original file
SECTIONS
Your modification
SECTION
is that right?
And the point where I'm getting stuck is at step 9.
After I click finish the editor window does open but I get a prompt saying "I do not know how to handle EQSNIFFER.CPP Please define how it should be handled in the makefile"
I click ok
I get a File processor window with 2 fields
Command line for this file
Output file produced
It won't let me leave the fields blank.
I asume output file would be something like eqsniffer.dll
but I have no idea what it's looking for in the Command line for this file.
Any sugestions?
Thanx
MisterSpock
11-19-2002, 06:55 AM
Shadow...
Yes, you must change SECTIONS to SECTION for use with LCC.
The keyword is different, and LCC will flip out if you don't change it.
Rename eqsniffer.cpp to eqsniffer.c
Lcc seems to not care for the cpp extension.
I'll fix the instructions for the latter problem. Good luck!
LordCrush
11-19-2002, 07:00 AM
Hi all,
I have found ther reolution to this wired Borland compiler issue:
eqsniffer.cpp(191): E2342 The type at parameter 'lpfn' was expected
to be 'int (__stdcall *)()', it is 'long (__stdcall *)(int,unsigned int,long)
(6) Attempt: Tried to use SetWindowsHookEx. The second parameter to this
function is of type HOOKPROC, which, according to the Borland documentation
(as well as MSDN) is a pointer to a function like so:
long func_one(int,unsigned int,long);
(7) Problem: For some strange reason, my compiler expects HOOKPROC to be a
pointer to a function of this type:
int func_two();
As a result, the compiler barfs saying parameter 2 in my SetWindowsHookEx
call is of wrong type.
I realize that this is because the winuser.h file in Borland/Include defines
HOOKPROC differently based on a macro called "STRICT". If STRICT is defined,
HOOKPROC typedefs to (6), otherwise it typedefs to (7).
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define STRICT
#include <windows.h>
Pokesfan
11-19-2002, 08:12 AM
Used this last evening and I have to say that I am really happy with this sniffer. Made a few personalized changes just so I'm not using sniffer_copy_832613.
Thanks for the code and the assistance. It is very much appreciated.
Pokesfan
goldmund
11-19-2002, 09:10 AM
First off - thanks for the excellent work Maggotboy. Yours is the only solution that I've been willing to try, and it works great.
Now to my question, it's my understanding that running the ReleaseHook command is only necessary if you never start eqgame.exe after running InstallHook. To actually remove the sniffer from memory after it's begun you need to kill rundll32.exe correct?
Is there a way to kill rundll32.exe without going in through task manager? I use EQW in Win2k, and bringing up task manager instantly kills that program.
o0shadow0o
11-19-2002, 09:14 AM
I made the changes you sugested and it complied flawlessly. Thank you MisterSpock.
Now I just have to wait for the servers to come back up to test it.
monster69
11-19-2002, 09:16 AM
Ran into a snag that I am having trouble with.
I grabed the 1.3 this morning and tried to compile it using MS VS6 but I am getting the following:
c:\program files\microsoft visual studio\myprojects\project1\eqsniffer.cpp(124) : error C2664: 'SetTimer' : cannot convert parameter 4 from 'void (struct HWND__ *,unsigned int,unsigned long,unsigned long)' to 'void (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,unsigned long)'
None of the functions with this name in scope match the target type
Error executing cl.exe.
Any clues on how to proceed?
Monster
Fletch
11-19-2002, 09:47 AM
Originally posted by monster69
Ran into a snag that I am having trouble with.
I grabed the 1.3 this morning and tried to compile it using MS VS6 but I am getting the following:
c:\program files\microsoft visual studio\myprojects\project1\eqsniffer.cpp(124) : error C2664: 'SetTimer' : cannot convert parameter 4 from 'void (struct HWND__ *,unsigned int,unsigned long,unsigned long)' to 'void (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,unsigned long)'
None of the functions with this name in scope match the target type
Error executing cl.exe.
Any clues on how to proceed?
Monster
Check the first page of this thread, Seqsy shows how to fix this.
monster69
11-19-2002, 09:51 AM
Damn! I hate it when I do that.
Thanks Fletch!
maggotboy
11-19-2002, 10:39 AM
Originally posted by goldmund
Now to my question, it's my understanding that running the ReleaseHook command is only necessary if you never start eqgame.exe after running InstallHook. To actually remove the sniffer from memory after it's begun you need to kill rundll32.exe correct?
Is there a way to kill rundll32.exe without going in through task manager? I use EQW in Win2k, and bringing up task manager instantly kills that program.
Here's what happens ...
RUNDLL32 (...), InstallHook -- this installs the hook procedure, and causes RUNDLL32 to remain resident in memory while the hook is in place.
When the DLL realizes that it has connected to the game, it automatically triggers the resident RUNDLL32 to release the hook, which causes RUNDLL32 to automatically exit.
At this point, the sniffer has been removed from memory for all processes *except* EQ. When EQ exits, the sniffer will die as well.
If you never run the game and need to shut the hook down manually, you need to run another RUNDLL32 command:
RUNDLL32 (yourdllname),ReleaseHook
This causes another RUNDLL32 to start, calls the DLL's ReleaseHook function, which triggers the first RUNDLL32 to exit, and then this instance exits as well.
What I did is I created 2 shortcuts on my desktop. One called Install Hook, and the other called Release Hook.
Both shortcuts call RUNDLL32. The first one calls my InstallHook procedure with all the parameters ... and the second shortcut calls RUNDLL32 with my ReleaseHook procedure. Since I made the change to make the hook automatically release itself once it latches onto EQ, I never need to run the Release Hook shortcut ... but I keep it there just in case.
Maggotboy
Alwayslost
11-19-2002, 11:34 AM
Kudos to Maggotboy!
This is the first sniffer I have been willing to try, and I'm a TOTAL noob when it comes to programming.
I did a compile on a W2k box (0 errors, 0 warnings) and am chomping at the bit to get home and try it out on my XP box at home.
I hope this works for me... :)
I am, however, VERY intrigued by your post on V 2... Looking forward to seeing that one. :cool:
This does work with windows ME...
After many hours of staring and flipping through books and comparing to other programs...
I found the problem using the old ancient method of looking at the code with crossed eyes...
/em tells himself that it's
eqgame.exe not everquest.exe to search memory for
It works like a charm /congrats
Side note:
I've noticed now each zone has an oddball player spawned using this method. This is not a real player or has ever been displayed before, nor displayed using one of the other sniffers...
One for example is in SH Player named "Wave of Prexus" (not the same in each zone, but each zone it is constant) also does have a guild tag, for the life me at this moment i don't remember that tag... Also when there isn't anything targeted, seq defaults the target to this unkown named spawn... (meaning if there isn't anything in my target window in eq, on seq this weird spawn is targeted)
Anyone else seeing this?
maggotboy
11-19-2002, 12:16 PM
h3x -
Aye, I've seen this as well, but figured it was a side-effect of the new manual decoding on SEQ's side.
Not sure how this happens or what to do about it.
Maggotboy
guice
11-19-2002, 12:28 PM
Same here .. actually, to be more spacific; they always have the guild tag <The Untrusted>
Manaweaver
11-19-2002, 12:35 PM
Thats fun =). I am using this code...not seeing those player spawns in each zone though. Kind of an oddity.
guice
11-19-2002, 12:39 PM
Not each zone, but a number of them. ToV comes to mind right off hand. /shrug
On with the show .......
Manaweaver
11-19-2002, 12:45 PM
Odd...now I'm getting something ....its a player that is grayed out...at lvl 0, race, class....both 0...has the tag of one of the guilds on my server. Heh. Just....weird...
I see the same guild tag on an unknown player in a few zones. PoD around the middle of the zone (near goos) is the one I remember the most but have seen the same "person" in other zones as well.
-Lane
nino2469
11-19-2002, 03:37 PM
Ok I am totally new at this so please bear with me on this question. I wanted to know if I need to edit this in VS.net "RUNDLL32.EXE mysniffer.dll,InstallHook <ipaddr> <port> <filename> <memaddr>" with my information or do I leave it as is and only use that line when I open up a cmd window? Also so I need the .dll that I created in the same directory as the rundll32?
maggotboy
11-19-2002, 03:43 PM
Lets say you compile the program as MYSNIFFER.DLL ...
Furthermore, lets say the IP address of your SEQ box is 192.168.1.40 and is listening on port 666.
You could then go to a DOS prompt, change to the directory where MYSNIFFER.DLL is, and type ...
RUNDLL32 MYSNIFFER.DLL,InstallHook 192.168.1.40 666 eqgame.exe 0x0078AAD0
You have to substitute each item in the command-line with your information, each item being separated by a space. First the ipaddr, then the port, then the name of the program to hook, followed by the memory address to look in for the key.
RUNDLL32.EXE is in the Windows\System or Windows\System32 directory. If that directory is in your PATH, then you don't have to worry about where RUNDLL32.EXE is. If its not in your path and you get "invalid command or filename" , then you'll have to type:
C:\Windows\System\RUNDLL32 MYSNIFFER.DLL,InstallHook 192.168.1.40 666 eqgame.exe 0x0078AAD0
Maggotboy
nino2469
11-19-2002, 03:45 PM
thanks maggotboy!
Simon
11-19-2002, 05:09 PM
Started using maggots great program for the first time today. My findings were that the suggested port 666 didn't work for me. Everything seemed to work, including tcpdump, but SEQ just didn't decode.
Restarted using port 32421 and voila...nice coloured dots. Strange, and I haven't had the time yet to figure out what is causing this, but others who may have the same problem might try changing the udp port number as well.
IamGman
11-19-2002, 07:00 PM
I was able to get the sniffer working, but I have no clue how to get the key that is sent into ShowEQ. Any help on finding where the key is sent to on the linux box would be greatly appreciated.
flobee
11-19-2002, 08:09 PM
I am running win XP, and compiled with MSVC++ 6
When running:
c:\windows\system32\rundll32.exe mydll.dll,InstallHook 192.168.1.104 10000 eqgame.exe 0x0078ADD0
I receive a popup that states:
RUNDLL
Error loading mydll.dll
A dynamic link library (DLL) initialization routine failed.
and an OK button.
When I compiled the dll I get 0 errors 0 warnings, anyone know what I am doing wrong? Been messing with this for about 3 hours now and i'm getting frustrated.
Thanks in advance.
maggotboy
11-19-2002, 08:21 PM
flobee -- are you using the 1.3 codebase or the 2.0 codebase? What does the .cpp file say its revision is?
Maggotboy
flobee
11-19-2002, 08:38 PM
maggotboy, 2.0 sorry, forgot to mention that.
maggotboy
11-19-2002, 08:41 PM
K. Take this to the V2 thread then ... if your code revision says 2.0, then you need to download it again. The most recent update has been 2.01 and addresses just the problem you're describing.
Maggotboy
cllnsj
11-20-2002, 12:26 AM
I am having a similar problem to IamGman. I followed directions to the letter regarding the compile & changes associated with using lcc (using Misterspock's guide- Including the changes within the DFF file). The compile worked great, zero errors. I direct my prompt to the folder than the new dll file is located, type rundll32.exe eqsniffer.dll, InstallHook IPaddress 10000 eqgame.exe 0x0078AAD0
(Yes I plan on changing the names if I get it working:D). After entering that information there is about a 4 second pause & I am able to open EQ. I get no decoding once it comes up. I have tried changing the port settings, zoning, saving the preferences then zoning, nothing seems to work. Am I missing something overly obvious? I am running mandrake 8.2 on the linux box, XP on my EQ puter', 4.3.3 version seq with the newest libEQ.a, version 1.3 of this sniffer program. Any advise is greatly appreciated. Thank you in advance.
maggotboy
11-20-2002, 01:28 AM
Unfortunately I'm not familiar at all with the LCC compiler. If I've got some extra time, I'll take a look at it and see what the deal is ...
Maggotboy
MisterSpock
11-20-2002, 06:19 AM
What version of lcc are you running?
Also, it worries me that it pauses for 4 seconds at the cmd prompt. It should return almost instantly.
Lcc is *very* twitchy about certain things. One of the things you really have to watch for is that it likes to reset the dll entry point to libmain. In fact, I got so frustrated with it that I changed the DllMain function to LibMain (and the associated prototype) so I wouldn't forget. Another thing is it doesn't want to stop the compiler from including debug symbols, so this needs to be verified every time (you want it off). The thing is -- when either of these two things happens, the compile will still work, but the dll won't (Dll Main will never get called).
I'll look into it and see if I can duplicate the problem you described.
Talon
11-20-2002, 06:26 AM
Maggotboy : 1) You are really, really good ! :-=)
2nd ) I have the same problem as flohbee, where can i download 2,01 ?
(You mentioned 2,0 not functioning)
Thx in advance !
cllnsj
11-20-2002, 10:17 AM
Misterspock: Version 3.3 lcc. By the way, the file name next to library within the dff file is "keysniffer". I renamed the new dll file to match it (keysniffer.dll) immediatly after the compiler produced it. Just incase one was wondering if I had done that correctly, I neglected to mention that earlier; it seems to be a common error that people are making. In addition, I was careful to make the appropriate changes that you described that lcc was sensitive to. Unless it changed them after I progressed to the next step of the compile process, they should be correct.
Edit: I attempted to run it from both windows and a dos prompt with no success.
Edit again: According to your guide, I could not exactly find a place for step #1:
1) Create a folder for your new project. On the first screen, select the path, name, etc. Select Dynamic Link Library.
I created just a regular folder through windows to place it in, but the only place that I saw the option of selecting the path, name, dynamic link library was when I begun with step 4 of your guide while opening the project. I doubt that this has anything to do with it since it compiled fine, but thought I should mention it just in case :).
Adeon
11-20-2002, 04:58 PM
Any reason why this wouldnt compile under VC++ 5.0 ?
Getting this on the build..
Compiling...
code.cpp
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(163) : error C2501: 'ULONGLONG' : missing decl-specifiers
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(163) : error C2239: unexpected token 'identifier' following declaration of 'ULONGLONG'
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(163) : error C2061: syntax error : identifier 'g_ullLastKey'
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(169) : error C2061: syntax error : identifier 'UINT_PTR'
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(200) : error C2664: 'SetWindowsHookExA' : cannot convert parameter 2 from 'long (int,unsigned int,long)' to 'int (__stdcall *)(void)'
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(268) : error C2664: 'SetWindowsHookExA' : cannot convert parameter 2 from 'long (int,unsigned int,long)' to 'int (__stdcall *)(void)'
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(320) : error C2146: syntax error : missing ';' before identifier 'ullKey'
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(320) : error C2065: 'ullKey' : undeclared identifier
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(329) : error C2059: syntax error : ')'
C:\Program Files\DevStudio\MyProjects\nopop\code.cpp(331) : error C2065: 'g_ullLastKey' : undeclared identifier
Error executing cl.exe.
IamGman
11-20-2002, 05:57 PM
OK. I ran tcpdump and I know that it is sending the packets to my linux box. My problem is that I am a complete newbie to using UDP. How do I use the info sent to my ShowEQ machine? Thanks in advance for the help.
bonkersbobcat
11-20-2002, 06:11 PM
I could not find in the code where the key obtained from EQ and used to see if the key has changed gets XORed? Does this happen?
If it is not, then could EQ scan memory for copies of the key that shouldn't be there?
Edit:
// Record the XOR'd key for future reference.
pinj->ullLastKey = ullKey;The comment says "the XOR'd" key, but where is it actually XOR'd?
MisterSpock
11-20-2002, 06:42 PM
GMan -- if you can see the upd traffic on your linux box using tcpdump, you're essentially done. Just make sure you have the latest SEQ (4.3.3) compiled with the proper libEQ.a file, and you should be ready to rock.
cllnsj -- The line
Library mydll
in the .def file needs to be changed so that the 'mydll' portion matches the name of your project. It is used in the compile/link process, not in the execution of the dll. So, if your project is named bluebell (for example), it will produce bluebell.dll. Your .def file should be changed to read:
Library bluebell
*before* you compile the code. Lcc is so goofy, it probably isn't really exporting the functions properly.
---
Also -- step 1 may have been a bit vague. When creating a new project, it asks you for the path. Within there, you can create the folder. Likewise, you can create a blank .c file. I just cut/paste the code from notepad into the blank .c file I create while starting the initial project. If the end result was a folder, a .c source file, a .def file, and a .prj project file, you're good to go.
As an alternative to changing the DLL Entry Point in the Compiler Options page, you can leave it at LibMain and change the code accordingly:
BOOL APIENTRY DllMain (HANDLE, DWORD, LPVOID);
becomes
BOOL APIENTRY LibMain (HANDLE, DWORD, LPVOID);
and
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
becomes
BOOL APIENTRY LibMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
This prevents lcc from that annoying flip-back problem...
cllnsj
11-20-2002, 10:45 PM
I changed the code & left LibMain in place, it worked perfectly. Thank you so much for taking the time to assist. A big thank you to all that have contributed in this project :D
Monchichi
11-21-2002, 09:08 AM
I can get this to compile, no problem, no errors vs .net on winxp. problem is the only time I see any packets on the linux box are when i zone (once) and when i log to char select (once)... it doesnt do anything while running around a zone and I never seem to get a key.
Help?
somguy
11-21-2002, 09:54 AM
Compiled using LCC, as per mister spocks instructions. It compiles no errors. I start up by doing 'run' => 'RUNDLL32.EXE <mydll>.dll,<myhookname> <seq box IP> 23674 eqgame.exe 0x0078AAD0
It seems to start running, all I get is a little hourglass on my cursor for about 5 seconds. I start up EQ log in and get into game. Set the keyport to the same that I set it as above in SEQ, then nothing. No decryption at all, still GPS mode. That isn't the biggest problem though
After playing for about 15 min EQ will crash to desktop. Can't log back in without rebooting, EQ will throw up all kinds of errors if I try. I've tried the code (v1.3) un-edited and my edited version, both produce same results.
Oh and one more thing, when I start the sniffer and start EQ, if I do exit EQ before it crashes I still have the rundll32.exe in the process list, 2 times even. I thought this was supposed to automatically die after eq exits?
I do have the latest CVS update, and eqlib.a
P.S. wondering if there would be any intrest in a perl version of this code, would remove the complexity of having to have XXX compiler or special instructions per a myriad of different compilers... and perl is free :)
I'm a perl programmer but have zero experiance dong window's apps
Thanks for the help in advance, great peice of code maggotboy.
maggotboy
11-21-2002, 10:14 AM
somguy ... having this issue hashed out in the V2 thread ... read my post
http://seq.sourceforge.net/showthread.php?s=&postid=16616#post16616
for more info ...
Scotty
11-21-2002, 02:19 PM
I just wanted to say thanks Maggot and all the others contributing. My knowledge on programming really sucks so please feel free to laugh at me if I'm doing something totally wrong.
I compiled Version 1.3 without any problems and installed it using this command. I'm running windows ME Visual Studio 6 with SP5 to compile it on, but my EQ box that I run it on is Windows XP with SP1.
I run the command from a dos command prompt, and the dll is in the EQ directory:
RUNDLL32.exe windump.dll,InstallHook 192.168.1.1 13400 eqgame.exe 0x00773b90
I downloaded the latest eqlib file and did a cvs to update to the latest showeq as well. I get no errors launching the DLL and everything appears to be smooth with that. The only problem I have is that I barely get a decode. On the showeq box I set the default port to 13400 as well. Although the first time running the latest showeq,(previous one was running didn't have the drop down box of All,corpses, NPC's, ect) i was using your DLL I notice that I'm getting a semi decode or something. In the ALL catagory is the only place where I can see stuff. I'm decoding Forges, Looms, and some doors, but the rest which isn't the whole zone worth of stuff are unknowns. After a while i start to see on the unknowns that their equipment start to appear slowly, but by no means are the let's say 40 unknowns that are showing up are all the PC's and NPC's in the bazaar.
I tried to look through all the other posts but I didn't really see anyone having a problem like me. Since this is the first time that I'm running the latest EQ with your DLL will showeq see some things again and decode some PC's equipment while still showing them as unknowns, or will that only occur if the dll is sending the decode key and my Showeq box is just being really slow or something. The show eq box is and the DLL are set to the right IP address and ports corrispond. Also the show eq box is running a P3 600mhz proccessor.
Also I just wanted to state one other thing. In the instructions you say the mem address is 0x00773b90 while on another post you say to type in: "RUNDLL32 MYSNIFFER.DLL,InstallHook 192.168.1.40 666 eqgame.exe 0x0078AAD0". Sorry for being so noob with this stuff, but is everyones memory address going to be the same or different?
Thanks and appreciate any help or advice you can give me :)
Scotty
11-21-2002, 02:22 PM
ack after reading more I saw that 0x0078AAD0 is the new offset. I think that will fix my problem :)
Monchichi
11-21-2002, 04:14 PM
I compile, fine, no errors.. run it, fine.. no errors, launch EQ.. fine, doesnt crash.
Load tcpdump on the linux box and watch, this is what happens:
Every time I load the game, get to char select and zone this happens:
12:01:08.330000 sending.name.withheld.1161 > seqbox.name.withheld.32421: udp 8
But never while actually in the zone does it come up, and I never have gotten the despawn to work.
I'm on .NET compiler Win XP.
v2.04 still causes EQ to crash to desktop.
I'll get my hands on a debugger tonight, but I thought I'd put this up.
maggotboy
11-22-2002, 01:44 AM
Revved the code to 1.4 to fix a bug in my call to GetTempFileName() which is more than likely (I am sure) causing the RUNDLL32 not unloading problem.
Maggotboy
IamGman
11-22-2002, 10:48 PM
I downloaded what I thought was going to be 1.4, but it only lists revisions to 1.2. Also, When I compile with lcc 3.3 I get the following error:
Line 3: Keyword expectedCannot load winsock32.lib
I was using Spocks instructions (which worked perfectly fine the first time I compiled the "real" 1.2 btw). Any ideas?
Dedpoet
11-23-2002, 08:20 AM
I downloaded what I thought was going to be 1.4, but it only lists revisions to 1.2. Also, When I compile with lcc 3.3 I get the following error:
There are some other posts like this in this same thread, IamGman. Most likely your browser or download manager cached the download. Try downloading to a different directory or clearing the cache in your browser/download manager and try again.
Admatha
11-23-2002, 11:48 AM
sorry if you read my post b4, was being a moron LoL, in any event, i compiled using MSVC++ 6.0 in winxp, built, compiled, and debugged no errors or warnings, moved the dll (and all other files in the release directory) to the windows\system32 directory, and used
c:\windows\system32\rundll32 ntxt.dll,pcpnote 192.168.254.99 666 eqgame.exe 0x0078AAD0
in a command window to recieve the following error
An exception has occurred while trying to run "ntxt.dll,pcpnote 192.168.254.99 666 eqgame.exe 0x0078AAD0"
any ideas why it might be doing that?
Originally posted by Admatha
An exception has occurred while trying to run "ntxt.dll,pcpnote 192.168.254.99 666 eqgame.exe 0x0078AAD0"
any ideas why it might be doing that?
Does your shortcut really have a comma between "ntxt.dll" and pcpnote? Maybe thats the problem? I'd start there.
maggotboy
11-25-2002, 10:52 AM
Originally posted by Admatha
c:\windows\system32\rundll32 ntxt.dll,pcpnote 192.168.254.99 666 eqgame.exe 0x0078AAD0
An exception has occurred while trying to run "ntxt.dll,pcpnote 192.168.254.99 666 eqgame.exe 0x0078AAD0"
When you renamed the InstallHook, HookProc and ReleaseHook functions, did you call HookProc "pcpnote" ? If so, this would cause your crash -- you must use InstallHook in the RUNDLL32 cmdline (or the renamed function, whatever it may be).
Maggotboy
sudden_thought
11-25-2002, 12:54 PM
Ok, just bought VC++ 6 from a friend and complied your examples Maggotboy. Version 2 doesn't work for me at all, the same crash to desktop when I hit a key as many others.
Version 1 works well, most of the time but there seems to be a glitch. I noticed this before when we were all using EQW and background key sniffers. Sometimes I see to get a 'bad key'
The output from the debugger looks like this;
00000000 0.00000000 [2696] Attaching to process C:\WINDOWS\SYSTEM32\RUNDLL32.EXE
00000001 8.06196514 [2748] time()-cpuSpeed:1533053
00000002 9.06681603 [2748] TimeGetTime-cpuSpeed: 1537546
00000003 32.89173093 [2748] Found EQ Process!
00000004 32.89186531 [2748] Attaching to process C:\EVERQUEST\EQGAME.EXE
00000005 32.91095544 [2748] Addr 0x0078AAD0 contains key: 0x0000000000000000
00000006 137.04820976 [2748] Addr 0x0078AAD0 contains key: 0xFFFFFFFFB83384AE
00000007 145.00068361 [2748] 0 Removed
00000008 191.98335934 [2748] 0 Removed
00000009 400.33782422 [2748] Addr 0x0078AAD0 contains key: 0xC1593B595689873E
00000010 409.42820917 [2748] 0 Removed
00000011 494.34010049 [2748] Addr 0x0078AAD0 contains key: 0x829A8E60356FAABA
00000012 503.53697970 [2748] 0 Removed
00000013 671.53595666 [2748] Addr 0x0078AAD0 contains key: 0xFC911E45367FAC1A
00000014 679.93141810 [2748] 0 Removed
The first time I loaded up the 'key' was displayed as 0xFFFFFFFFB83384AE, these bad keys usually start with 8 F's, after that (I zoned) the keys were correct and I got my skittles. Sometimes though the keys remain incorrect and I can't get any decodes at all.
Any idea what's causing these glitches and is it just me?
somguy
11-26-2002, 09:02 AM
Code compiles fine, runs, doesn't crash anything now... but stilll nothing decoding on my seq box. I did a tcpdump on that machine and didn't see any lines where udp = the port number I gave the sniffer. So I am assuming the key never makes it.
Is there something I need to set up, or do on my linux machine to ensure it will let these packets in? If that is even my problem.
stump
01-28-2003, 07:10 AM
Hello,
Every time I log out, the rundll that called this sniffer hangs. I assume it is because of this particular line:
WaitForSingleObject(hEvent, INFINITE);
While the InstallHook is on infinite hold the "Terminate" msg is not processed.
Does anybody have any idea how to avoid that? Is there a windows event that gets trigered on log-out or shut down that I can check for with WaitForMultipleObjects() or are there any other ways to handle this situation?
Thank you for you help.
Powered by vBulletin® Version 4.1.9 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.