PDA

View Full Version : UncleBen's sux program



UncleBen
11-15-2002, 11:35 AM
Below is my compilation of what I liked about all the code I found here. No, I didn't create the code, but was able to mix match it enough to run the way I want.


This technique will allow you to run the sniffer ONCE anytime you like, send the key using the UDP over to your linux box, then exit; Simply by hitting the enter key from a telnet window on you linux console.

I compiled this with MinGW (find the link in forum somehwere I'm sick of searching for the day).
You also need ActivePerl to run the perl script that enables a telnet connection on a port you pick, waits for the enter key, then executes your run once sniffer

get activeperl here: http://downloads.activestate.com/ActivePerl/Windows/5.6/ActivePerl-5.6.1.633-MSWin32-x86.msi

compile this code (I used MinGw) and link th32, ws2_32, and wsock32


CHANGE the location of the config file to where YOURS is (6 lines down in the code)



#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#include <tlhelp32.h>
#include <time.h>

#define CONF_FILE "C:/sniffer.conf" //LOCATION OF YOUR CONFIG FILE
#define CONF_SIZE 16

struct CONFIG
{
unsigned long long SessionKeyLocation;
unsigned int SendInterval;
char seq_ip[16];
int seq_port;
} config;

BOOL enable_debug_privs() /*This function makes it so you can run the program anytime without gettting the OpenProcess error 5 message */
{
HANDLE hToken; /* process token */
TOKEN_PRIVILEGES tp; /* token provileges */
TOKEN_PRIVILEGES oldtp; /* old token privileges */
DWORD dwSize = sizeof (TOKEN_PRIVILEGES);
LUID luid;

if (!OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
return TRUE;
printf ("OpenProcessToken() failed: %d\n", GetLastError());
return FALSE;
}

if (!LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid))
{
printf ("LookupPrivilege() failed: %d\n", GetLastError());
CloseHandle (hToken);
return FALSE;
}

ZeroMemory (&tp, sizeof (tp));
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

/* Adjust Token privileges */
if (!AdjustTokenPrivileges (hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize))
{
printf ("AdjustTokenPrivileges() failed: %d\n", GetLastError());
CloseHandle (hToken);
return FALSE;
}





return TRUE;
}

int SendSessionKey(unsigned long long SessionKey);

void readkey (HANDLE hProcess, int useConfig)
{


unsigned long addr;
unsigned long long key = 0xffffffffffffffff;
addr = config.SessionKeyLocation;

if (ReadProcessMemory (hProcess, (void *)addr, &key, 8, NULL) == 0)
{
printf ("ReadProcessMemory on 8 bytes at 0x%08x failed: %u\n", addr, GetLastError());
}
else
{

printf ("Session key:\t0x%016I64x\n", (unsigned long long) key);
beep (2500, 1000);



if (SendSessionKey(key) != SOCKET_ERROR)
printf("Sent the session key to %s:%d\n", config.seq_ip, config.seq_port);
else
printf("Failed to send the session key to %s:%d\n", config.seq_ip, config.seq_port);



}


fflush (stdin);
}

int scanproclist (int useConfig)
{
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};


hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hProcessSnap == INVALID_HANDLE_VALUE)
return 0;


pe32.dwSize = sizeof(PROCESSENTRY32);

if (Process32First(hProcessSnap, &pe32))
{
HANDLE hProcess;

do
{
LPSTR pCurChar;
char pName[512];

// strip path and leave exe filename
for (pCurChar = (pe32.szExeFile + strlen (pe32.szExeFile));
*pCurChar != '\\' && pCurChar != pe32.szExeFile - 1;
--pCurChar)

strcpy(pName, pCurChar);
strlwr(pName);

if ( (strncmp (pName, "testeqgame", 10) == 0) || (strncmp (pName, "eqgame", 6) == 0) )
{
printf ("found eqgame - pid = %u\n\n", pe32.th32ProcessID);
hProcess = OpenProcess (PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
if (hProcess == NULL)
{
DWORD dw;
dw = GetLastError();
printf ("OpenProcess failed, error: %u\n", dw);
return;
}
readkey (hProcess, useConfig);
}
}
while (Process32Next(hProcessSnap, &pe32));
}

CloseHandle (hProcessSnap);
return;
}


int ReadConfig (void)
{
int useConfig = 0;
char conf_buffer[CONF_SIZE];

GetPrivateProfileString("Client", "SessionKeyLocation", "0", conf_buffer, CONF_SIZE, CONF_FILE);
config.SessionKeyLocation = strtol(conf_buffer,NULL,16);

GetPrivateProfileString("Client", "SendInterval", "0", conf_buffer, CONF_SIZE, CONF_FILE);
config.SendInterval = atoi(conf_buffer);

GetPrivateProfileString("ShowEQ", "IP", "0", conf_buffer, CONF_SIZE, CONF_FILE);
strcpy(config.seq_ip, conf_buffer);

GetPrivateProfileString("ShowEQ", "Port", "0", conf_buffer, CONF_SIZE, CONF_FILE);
config.seq_port = atoi(conf_buffer);

if (config.SessionKeyLocation > 0)
useConfig = 1;

return useConfig;
}

int SendSessionKey(unsigned long long SessionKey)
{
int ret;
WSADATA wsd;
SOCKET ssocket;
SOCKADDR_IN seq;

if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return SOCKET_ERROR;
}

ssocket = socket(AF_INET, SOCK_DGRAM, 0);
if (ssocket == INVALID_SOCKET)
{
printf("socket() failed; %d\n", WSAGetLastError());
return SOCKET_ERROR;
}

seq.sin_family = AF_INET;
seq.sin_port = htons((short)config.seq_port);
seq.sin_addr.s_addr = inet_addr(config.seq_ip);

ret = sendto(ssocket, (char *) &SessionKey, sizeof(unsigned long long), 0, (SOCKADDR *)&seq, sizeof(seq));
if (ret == SOCKET_ERROR)
return SOCKET_ERROR;

closesocket(ssocket);
WSACleanup();

return 0;
}

int main(void)
{

if (enable_debug_privs() == FALSE)
printf ("Can't Enable Debuf Privs");
printf ("scanning for eqgame.exe\n");

if (ReadConfig() != 1)
printf ("Problem with your config file!\n");
else
scanproclist(0);


}



now you have the program that will execute when you hit enter from your telnet window on Linux; yay you

Now you need the config file for this program to use:


Create a new text tile, copy this into it, make changes for your system, and save it as the name/location you specified in your sniffer program


[Client]
SessionKeyLocation=0x00773b90
SendInterval=0

[ShowEQ]
IP=192.168.0.1
Port=666


SendInterval was used in a program to make a looping program sleep for x amount of time. I was too lazy and stupid to figure out how to get by without it being in the config file after I got rid of the looping part so I just left it there for simplicities sake. Just leave it there as I have np :)

set your IP to the IP of your linux box. and the port to a port which you are telling ShowEQ to sniff on for the key.


Now the sniffer program should be gtg so all you need now is to run this perl script so you can open a telnet connection to fire it off at your leisure



#!c:\perl\bin\perl.exe
use strict;
use IO::Socket;
my($MAXLEN, $PORTNO, $client, $server);
$MAXLEN = 1024;
$PORTNO = 10002;
$server = IO::Socket::INET->new(LocalPort => $PORTNO, Proto => 'tcp', Listen => 1) or die "socket: $@";
print "Awaiting TCP messages on port $PORTNO\n";
while ($client = $server->accept()) {
$client->autoflush(1);
while ( <$client>) {
my $runme = `c:\\ping.exe`;
$client->send($runme);
}
}
die "recv: $!";


save this to a text tile, and rename it with the .pl extention (pl is perl :))

also modifiy the port number if you wish, I set mine to open telnet on port 10002, but you can change to what you need/wish.

Change the runme line to point to your sniffer (my sniffer was named ping.exe and located in the root directory of C.

all should be good to go. So now you need to associate your perl script with the perl.exe. perl.exe should be in the /bin folder of where you installed activeperl. Make that association and you should be able to run the perl script by double clicking it np now

Fire off your perl script and launch EQ.

Now we gonna telnet to the port you specified with the script:


Open up a linux terminal and type:

telnet WindowsIP Port
in case you stupid, WindowsIP and Port need to be the actual numbers :)

if the telnet connected you'll get a message saying so. Just hit enter once, after a sec you'll hear an annoying high-picted beep from windows letting you know a key was found (edit out the beep line in the C code if you don't like:)) then some output will be displayed on your telnet window also showing you what happend


Well, that's it. Hope it works for you.

PS, this was just ripped code from all over this board with slight changes I made. I take no credit for the thoughts and efforts put into the actual functions.

AMAZING what the search button can do here.

UncleBen
11-15-2002, 11:54 AM
this line:
*pCurChar != '\' && pCurChar != pe32.szExeFile - 1;

should read

*pCurChar != '\\' && pCurChar != pe32.szExeFile - 1;


lose the extra '\' with the code tags there :(

baelang
11-15-2002, 01:27 PM
Looks good.

i am going to snarf your "enable_debug_privs" code to merg into keyring.

UncleBen
11-15-2002, 10:14 PM
anyone use it or like it? *whine* whole point people share something is for a responce. If I don't get a hug in 1 day I'm deleting this; lol

baelang
11-15-2002, 11:26 PM
*HUG*

the code i promised to snarf has been added to keyring and will be part of my next release. with proper credit to you of course.

(uncleben.c and uncleben.o are now part of my code)

_I_ like it if no one else does.

fryfrog
11-16-2002, 09:07 AM
uncle, i'm using it. i like it because it runs, beeps and exits... just like i wanted it to do ;)

Puppit
11-16-2002, 04:29 PM
Thanks Uncle Ben - this works just like you describe. Nice job. Installation was a breeze and if I can do it, anyone can.

dbrust
11-17-2002, 10:10 AM
When compling with MinGW, I'm getting the following erros:

trial.cpp: In function `void readkey(void*, int)':
trial.cpp:79: `beep' undeclared (first use this function)
trial.cpp:79: (Each undeclared identifier is reported only once for each
function it appears in.)
trial.cpp: In function `int scanproclist(int)':
trial.cpp:136: return-statement with no value, in function declared with a
non-void return type
trial.cpp:145: return-statement with no value, in function declared with a
non-void return type


Any ideas? Thanks in advance

fryfrog
11-17-2002, 07:24 PM
it compiled fine for me, out of the box with MinGW you sure you are doing it right?



gcc -c file.c
gcc -o file.exe file.o -lth32 -lwsock32 -lws2_32

Loco
11-18-2002, 03:51 PM
Thanks Uncle, its just what I was looking for.

Nurseling
11-19-2002, 04:15 AM
On my network I have two showeq computers and two eq computers. I use the sniffer and the perl script posted here.
every time I request a code from the eq box the opposite showeq box gets a segmentation fault and the one that is supposed to get the key decodes normaly.

I really have no clue why it would do this, any theories floating around.

baelang
11-19-2002, 04:26 AM
Originally posted by Nurseling
On my network I have two showeq computers and two eq computers. I use the sniffer and the perl script posted here.
every time I request a code from the eq box the opposite showeq box gets a segmentation fault and the one that is supposed to get the key decodes normaly.

I really have no clue why it would do this, any theories floating around.

that's interesting.

are they sending/listening to different udp ports?

Nurseling
11-19-2002, 04:42 AM
Actually I have the other two machines set up using the bit of code that writes a file and is then read by hitting the f12 key.

lane
11-19-2002, 06:04 AM
:gives UncleBen a manly hug

It's all compiled etc., jsut waiting for the freaking servers to come back up now. Nice timing on this for me and was debating whether to use my "run all the time" key sniffer or not after the patch. Now I don't have to.

Quik question: Anyone scanning the EQ log file to kick things off? I could probably do this with perl just wanted to see if anyone had done it yet before I dust off the books.

-Lane

tgf
11-26-2002, 11:41 AM
Me love you long time !

Worked great once I put in the correct offset and added the extra "/". I used mingw without a hitch. I do not know Pearl so I just setup telnet on my EQ box and just run my exe manually. Hitting the up arrow replays last command so I have to hit up and then enter for each new decode (I know, I know, it's one extra key press, but didn't see the need to install and learn Pearl).

One thing tho,... I had to set the seq ip address to an address outside my network per lostinspace.

http://seq.sourceforge.net/showthread.php?s=&threadid=2412

That did the trick for my udp updates as well..

-TGF

PriestOfDiscord
12-06-2002, 02:29 PM
I really like the concept of this particular program. The only thing that worries me is the method for changing the privileges to allow the read.

Is there any type of cleanup done after the token has been altered? Couldn't soe just lookup the value of the token privileges and see that they had been altered? Wouldn't it make sense to 1) save the current values 2)change to be able to read and then 3) change back once key has been read.

seqmage
01-10-2003, 06:00 AM
I have been using this siffer since it first came out.

Other then changin the offset in my ini file and updating SEQ with the "patch > test.diff" will it still work or should i be looking to switch to Keyring or another one of the sniffers?

I really liked this one although the beep was a bit annoying.

Since it worked from the day i compiled with MingW.. i never got into one of the other sniffers..

If anybody is using this sniffer after the 1/9/03 patch and its working can you please post what you did to get it working?

lane
01-13-2003, 10:47 PM
I'm running it with minor changes that I did way back when (just to make it different). For the latest patch, I just changed the offset. :)

I've never bothered to get another one working either.

I also wraped it in a perl program so I keep a telnet session open to my EQ computer and just reach over and hit enter each time I zone and want it to decode. Can't remember where I got that bit of code.

-Lane

seqmage
02-19-2003, 07:46 AM
Happy to report, for the 16feb2003 fix. this program is still working, provided you change the offset in the conf file.