PW Packet Sniffer

11/17/2011 06:37 asgborges#1
Hi there...

..long time i dont post here.. so its time for some update =]



I made a very simple plugin for Cheat Engine 5.5... as the Thread says.. it is for "Sniffing" the PW packets.. BUT.. it uses the real-time Decryption/Decompression.. so, its going to show you the real deal...

I can NOT garantee that is 100% accurate with the real packets but im sure about 99% of the encryption/compression proccess...

Im not sure if there is such a program around this forum or any others... but anyway.. give it a try and have fun =]

Instructions:

1. Decompress this plugin inside the \Plugin directory from the Cheat Engine...

2. Load the Cheat Engine 5.5... Click on Edit->Settings... move to the Plugin page... click on Add new... locate the "packeteditor.dll" inside the folder that you just installed.. and click on Open...

[Only registered and activated users can see links. Click Here To Register...]
3. Make sure the plugin is activated on the list... and then click on OK...
[Only registered and activated users can see links. Click Here To Register...]

4. Now you are almost good to go... Execute the game (PW) and get read to Login... just put your login and password... but dont click on Start YET...
[Only registered and activated users can see links. Click Here To Register...]

5. Go on the Cheat Engine... open the game process (elementclient.exe)...
[Only registered and activated users can see links. Click Here To Register...]

6. Now click on the menu Plugins->Attach packet Editor to process"...
[Only registered and activated users can see links. Click Here To Register...]

7. The plugin window will show up (maybe on the background)... find it and put the same Login as the game.. ps:the Login is necessary to handle the RC4 encryption..
[Only registered and activated users can see links. Click Here To Register...]

8. Go back to the game (PW)... now you are good to go... click on Start... and have fun on whatever you are doing that need to see the real packets *lol*
[Only registered and activated users can see links. Click Here To Register...]

* A log file will be created inside the "Perfect World Entertainment" folder (or whateverelse folder you installed your PW)... the log file name will be: Log(actual date+hour).txt... and will be saved only the decrypted/decompressed packet data...
* Also after long time (1hr+) using it can be showing inaccurate data maybe due to lack of a better "history" handling, wich i still learning...


Download:[Only registered and activated users can see links. Click Here To Register...] (updated 25/11/2011)

Update 25/11/2011:
* Added SendPacket function

Update 20/11/2011:
* Added color to Client->Server packets;
* Added Seach option in HEX format;
* Better packet history handler (internally);
* Moved the Login to the "Others" section;

TESTED ON:
Windows 7 64bits
PWI (last version at 25/11/2011)


Important Note: this is a very very simple utility and for now i dont have plans to extend it...but if your knowledge about the real PW packets are good and if something is not right.. pls tell me
11/17/2011 10:55 dumbfck#2
Oooh that looks pretty neat. I'll have a little play with this when I get home later.
Good work =]
11/17/2011 18:06 Smurfin#3
does anyone know the packet for selecting dialogue option with npc ? usually we can just use quest number without going through the dialogue first, but now it won't work.

for example I usually use this to exchange wraith's tag for rep
Code:
[i]acceptQuest(7010, $pid)[/i]
and repeat until the last one, now it wont work anymore.

the acceptQuest function looks like this, got it from [Only registered and activated users can see links. Click Here To Register...]
Code:
Func acceptQuest($questId, $pid)
	;Accept a new quest
	local $packet, $packetSize

	$packet = '2500'
	$packet &= '07000000'
	$packet &= '04000000'
	$packet &= _hex($questId)

	$packetSize = 14
	
	sendPacket($packet, $packetSize, $pid)
EndFunc
can this tool filter the packets ? maybe by displaying only specific packet which contains 7010 and possibly the npc id, or other method just to pinpoint the packet we're looking for.

I tried this just now but it crashed, maybe because I was afk in a crowded area and flooded by packets lol.
11/17/2011 18:28 asgborges#4
Quote:
Originally Posted by Smurfin View Post
does anyone know the packet for selecting dialogue option with npc ? usually we can just use quest number without going through the dialogue first, but now it won't work.

for example I usually use this to exchange wraith's tag for rep
Code:
[i]acceptQuest(7010, $pid)[/i]
and repeat until the last one, now it wont work anymore.

the acceptQuest function looks like this, got it from [Only registered and activated users can see links. Click Here To Register...]
Code:
Func acceptQuest($questId, $pid)
	;Accept a new quest
	local $packet, $packetSize

	$packet = '2500'
	$packet &= '07000000'
	$packet &= '04000000'
	$packet &= _hex($questId)

	$packetSize = 14
	
	sendPacket($packet, $packetSize, $pid)
EndFunc
can this tool filter the packets ? maybe by displaying only specific packet which contains 7010 and possibly the npc id, or other method just to pinpoint the packet we're looking for.

I tried this just now but it crashed, maybe because I was afk in a crowded area and flooded by packets lol.
Hey...
im already making a "filter" option for the plugin... thx


about your function not working.. what is happening?... also i guess there was an update of the elementclient past week (not sure tho).. the function address could be changed a lil or the function itself (i havent checked this)..

or maybe they fixed it on the server side now forcing using the NPC properly

edit: also dont use the plugin at same time your trying to use your "sendpacket" function..
11/17/2011 19:48 Smurfin#5
I want to check a specific packet, possibly looking like this, but it's hard to find with the constant packets coming x_x
[0066EFB3] Packet: 25 00 07 00 00 00 04 00 00 00 62 1B

hex("7010") is 1B62, is it reversed in pw's packet, so it'll look like above 62 1B, or is it 1B 62 in the packet? I tried to find it in the log file but couldn't find it

Code:
Func acceptQuest($questId, $pid)
	;Accept a new quest
	local $packet, $packetSize

	$packet = '2500'
	$packet &= '07000000'
	$packet &= '04000000'
	$packet &= _hex($questId)

	$packetSize = 14
	
	sendPacket($packet, $packetSize, $pid)
EndFunc


-edit-
aha, found it ! seems like I didn't follow the step by step instructions and used the plugin with my char already logged in, now the packet is found and looks like this
[Only registered and activated users can see links. Click Here To Register...]

now how should I put that correctly into the function ? how packetsize is calculated ?
11/17/2011 20:11 Sᴡoosh#6
Smurfin, they changed packet struct for that.

procedure TPWPackets.Getquest(ID: Cardinal);
var
lPacket: TPWPacket;
pckHead: word;
zero: cardinal;
begin
lPacket.len := 22;
lPacket.buf[0] := $25;
lPacket.buf[1] := $00;
lPacket.buf[2] := $07;
lPacket.buf[3] := $00;
lPacket.buf[4] := $00;
lPacket.buf[5] := $00;
lPacket.buf[6] := $0C;
lPacket.buf[7] := $00;
lPacket.buf[8] := $00;
lPacket.buf[9] := $00;
_copymemory(@lPacket.buf[10], @ID, SizeOf(Cardinal));
zero := $00;
_Fillmemory(@lPacket.buf[14], @zero, 8);

HelpFuncs.InjectFunc(PWIHandle, @SendCallfunc, @lPacket, SizeOf(lPacket));
end;
11/17/2011 20:43 Smurfin#7
ahhhhhhhhhh thanks, changed the packetsize to 22 and now it's working, I've been experimenting with this function since yesterday and now finally it's working, thanks to you all :handsdown:
11/17/2011 20:51 asgborges#8
Quote:
Originally Posted by Smurfin View Post
-edit-
aha, found it ! seems like I didn't follow the step by step instructions and used the plugin with my char already logged in, now the packet is found and looks like this
[Only registered and activated users can see links. Click Here To Register...]

now how should I put that correctly into the function ? how packetsize is calculated ?
Yep you found =]
as Swoosh just said looks like some things have been changed (maybe for the future big update "Underground" coming?!).. but heres an simple explanation os the packets should looks like:

Taking base of a Crazy Stone quest for lvl76 ([Only registered and activated users can see links. Click Here To Register...])
FULL packet:
2217162500070000000C000000191D00000000000000000000
22 =opcode (GamedataSend)
17 =cmdlen starting fron the next byte
16 = type or subtype of the request (maybe a new thing?!) OR maybe just the lenght of the data of whats going to proccess before send, in this case, ignore the codes bellow
the rest as you know:
2500
07000000
0C000000
191D0000 (7449 ->quest number in reversed Hex or knowed as Octal for some ppl)
0000000000000000 <-extra (not sure if it is necessary)

If your are using delphi, just do as Swoosh said but change the code as bellow:
Code:
  lPacket.len := 23; 
  lPacket.buf[1] := $16;
  lPacket.buf[1] := $25;
  ...
If you are using Auto-It:
Code:
Func acceptQuest($questId, $pid)
	;Accept a new quest
	local $packet, $packetSize

	$packet = '162500'
	$packet &= '07000000'
	$packet &= '04000000'
	$packet &= _hex($questId)
        $packet &= '0000000000000000';

	$packetSize = 23
	
	sendPacket($packet, $packetSize, $pid)
EndFunc
11/17/2011 21:57 dumbfck#9
Just had a little play with it - Looks like you did a nice job =]
Definitely looking forward to the filters though, even if only to filter only sent / received packets.
What would also be cool is if the packets of which we know what they are for, we could add descriptions for them, i.e., StartMeditating or SelectTarget etc. Perhaps add them via the actual program interface, or even if just in an ini file. That would be uber :D

Oh... I left it running while I typed this post and I'm now getting access violations... First was:
Access violation at address 1F997709 in module 'cepe.dll'. Read of address E1000000

Then a whole bunch of:
Access violation at address 00000001. Read of address 00000001

I'm running Win7 32 bit if that's of any help.

But still, very nice job =]

Edit: I should probably have mentioned I'm using CE 6.1 too, although you specified it's built for v5.5 - My bad :P
11/17/2011 23:22 Smurfin#10
yea if it can be filtered like chat messages it'd be great, and can be set to only display packets which are already identified as for doing what, like accepting quest above, and others like in interest07's packet collection, but it'd be time consuming.

I also experienced the same crash just now while afk in crowded area, but so far it's been running great. I'm using ce 5.6.1 coz my previously installed 6.0 won't work and can't find 5.5 anywhere, 6.0 gave me error message like missing something I forgot.

@asgborges, I just tried the autoit code above but it didn't work, even if 04000000 was changed to 0C000000, maybe you forgot to change this one after copy-pasted it, but it still didn't work.

the one I use looks like this :
Code:
Func acceptQuest($questId, $pid)
	;Accept a new quest
	local $packet, $packetSize

	$packet = '2500'
	$packet &= '07000000'
	$packet &= '0C000000'
	$packet &= _hex($questId)

	$packetSize = 22
	
	sendPacket($packet, $packetSize, $pid)
EndFunc
I'm curious how to write the function correctly from just looking at the sniffed packet.
11/20/2011 23:25 asgborges#11
Quote:
Originally Posted by dumbfck View Post
Edit: I should probably have mentioned I'm using CE 6.1 too, although you specified it's built for v5.5 - My bad :P
You can download the 5.5 here: [Only registered and activated users can see links. Click Here To Register...]

the plugin is based on version 5.5 units.. i cant garantee it would work on other version that this..

Quote:
Originally Posted by dumbfck View Post
What would also be cool is if the packets of which we know what they are for, we could add descriptions for them, i.e., StartMeditating or SelectTarget etc. Perhaps add them via the actual program interface, or even if just in an ini file. That would be uber :D
Quote:
Originally Posted by Smurfin View Post
I'm curious how to write the function correctly from just looking at the sniffed packet.
Well.. handling the packets is not hard.. but also not that easy.. all you have to do is have a good knowledge of the packets (wich one is for what)...
this plugin will capture packet by packet.. and EACH packet can contain alot of game commands, and that is what you guys talking about... and for that i will have to implement an "split" function to give access a Command by Command, and then you can have a better visualization and name them... BUT.. i have to have a very very good knowledge about ALL the packets in order to split them correctly.. and since ive been out of PW schene since 2009 i have to catch up with the new things... and looks like the game have alot more diferent structure if i compare with the time im used to see...

for example.. a packet "normally" starts with the OpCode and the PckLen (packetlen).. but the commands inside this packet can vary alot:
cmd1: 0xXXXXXX...
cmd2: 0xXXXX00...
cmd3: 0xXX0000...
cmd4: 0x0000XX...
cmd5: 0x000000...
............
@Smurfin... for the packets that you are used to see would be the cmd3 scheme...


im already working on a spliting function.. but im facing some problems due the lack of my knowledge about the packets.. and such information is quite limited to a few knowed things...
would be good to have some help.. thats why this Packet Sniffer can help you and other guys identify the packets and make a database of the knowed things in future maybe
:)
11/21/2011 19:10 Smurfin#12
thanks for the explanation.

I think using packet for doing stuffs in pw is very cpu friendly and uses much2 less cpu resources, unlike doing stuffs by memory writing or send key macro which now has to be unfreezed and use more cpu/gfx resources.

does every single one of whatever we do in pw have packet ? such as jumping, fly up/fly down, using hp pot/mp pot etc, maybe similar to casting skills which have packets and utilizing skill id in the packet function for casting different skill for different class.

it'd help ease the cpu much if bot utilizes sendpacket instead of memory read/write/macro, though memory read prolly will still be needed to check some values like hp mp and filtering mobs.

btw if you are going to identify some of the packets, please post some of them here when you found like jumping packet, fly up fly down packet, using hp pot/mp pot, and add them to Interest07's already made sendpacket script, it's good to have a lot of packets collection for doing stuffs :D
11/22/2011 01:14 dumbfck#13
Quote:
Originally Posted by Smurfin View Post
does every single one of whatever we do in pw have packet ? such as jumping, fly up/fly down, using hp pot/mp pot etc, maybe similar to casting skills which have packets and utilizing skill id in the packet function for casting different skill for different class.
Not everything, but most things. Basically anything that you could see from another client will use packets - plus some other things that only the user would see, i.e., 'invisible' skills such as a Venomancer's Summer Sprint buff or interaction with an NPC.
For example, I don't think jumping actually sends a physical 'jump' packet (correct me if I'm wrong) but you'd see another player 'rising' because their height has been updated via a packet. Doing a flip in the air sends a packet though.

As for building a collection of packet data, Interest's thread is a great starting point. Every packet starts with a unique 2 byte signature, so it shouldn't be too tricky to parse those first two bytes to determine what sort of packet is being sent - Even just a simple switch statement would suffice as the frequency of packets is not so great as to cause any performance impact if purely just interpreting packets and nothing else. Unless you wanted to interpret packets within an actual bot (again, would there be any actual reason to do this on-the-fly?) it's not a problem.

As for received packets... Well I've not investigated those at all (as I've not needed to thus far) so I have no idea what they represent :P
Until I have a need to interpret received packets I probably wouldn't go to the effort of figuring them out.
11/22/2011 07:40 Smurfin#14
I want to replace any action that uses send key macro in my bot with sendpacket, so I don't have to use unfreeze, running a lot of clients with unfreeze hogged down cpu resources. Interest07's sendpacket script has a function for skill casting, only need to figure out skill ids, the one thing missing is how to use pots with sendpacket instead of sending shortcut key, or maybe there is also packet for using whatever is put in shortcut slot (f1-f8 / 1 - 9)

just a thought, with packets coming and going, if another players, for example assassins, are in stealth nearby, will it cause packet exchange ? if yes, will it be possible some of them can be used for detecting the presence of stealthing assassins ?
11/22/2011 08:14 Interest07#15
Quote:
Originally Posted by Smurfin View Post
I want to replace any action that uses send key macro in my bot with sendpacket, so I don't have to use unfreeze, running a lot of clients with unfreeze hogged down cpu resources. Interest07's sendpacket script has a function for skill casting, only need to figure out skill ids, the one thing missing is how to use pots with sendpacket instead of sending shortcut key, or maybe there is also packet for using whatever is put in shortcut slot (f1-f8 / 1 - 9)

just a thought, with packets coming and going, if another players, for example assassins, are in stealth nearby, will it cause packet exchange ? if yes, will it be possible some of them can be used for detecting the presence of stealthing assassins ?
To use potions, send a "useItem" packet, or whatever I named it lol

There is no way to send a useFkey packet, as that's all just GUI sugar wrapping for the user.