Sending Packets

02/14/2012 20:44 dumbfck#286
Quote:
Originally Posted by atelarie View Post
wait. PWI as in PW International or PWI as in PW Indo? I'm a bit lost in the abbreviation used in this forum.
PWI normally means International, but I know Smurfin plays Indo, so I'm a little puzzled by this too :P

Quote:
Originally Posted by Smurfin View Post
tks Interest07, just about time before PWI gets upgraded to Descent tomorrow.
Make a copy of your current elementclient.exe today :P
When a new update comes out, I tend to make a backup of the client straight away. That way, any code offsets you've previously found, you can compare with the new client in ollydbg or something.
For example, this durability offset, load it into CE, see where it hits and make a regex that finds that exact piece of code. When the client updates, just run the regex on it and hey presto =]
Luckily though, most offsets don't change much so you can just take a peek in CE and look around the area that they previously were - or even better, do the same using ReClass. But it will be a big update so they might move a bit more than normal this time.

*Edit: This is especially useful for function offsets btw ;)
02/14/2012 21:15 Smurfin#287
thanks for the tips, dumbfck, I usually do that if there is a big update, not only elementclient.exe but the whole files in pw client folder :D
I still don't understand olly, regex and CE much, I usually use similar method using autoitscript and a range of numbers from the old offsets and search for the correct value from the game, it usually works unless the update is a big change to everything. I bet the offsets will have a big change today for you guys playing PWI for this Descent episode.

btw, I prefer to call PWI for International and PW Indo or PW-ID for Indonesian version, and everyone should stick to that so not to bring confusion to others ^^)
02/15/2012 04:00 atelarie#288
interest07
is there any way to send packet instead of skills, but button shortcut like f1-f8 and 1-9? Or do I just have to do dllcall? I'm using autoit and controlsend sometimes cause the ctrl/shift/alt keys to lock up indefinitely. Especially if you are running more than 5 clients.

I'm hoping to create a smurfit-like-commander-style tool to help me solo dungeon as TT 3-x and hopefully NV. sending packet skill id for 5 different player class seems to be too much for my small brain.

btw, smurfit commander is god :handsdown:. too bad smurfin is not updating it ::p
02/15/2012 10:29 dumbfck#289
Unfortunately you can't send your button / key mappings using packets. The cleanest way to do this is probably to inject into the guiCommand() function in the client. You can use something like this:
Code:
Func guiCommand($command, $guiObjPtr)
    ;//Declare local variables
    Local $pRemoteThread, $vBuffer, $loop, $result, $OPcode, $processHandle, $stringAddress, $stringSize

    $processHandle = memOpen($pid)

    ;//Allocate memory for the OpCode and retrieve address for this
    $functionAddress = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x46, 'int', 0x1000, 'int', 0x40)

    ;//Construct the OpCode for calling the 'guiCommand' function
    $OPcode &= '60'                         ; PUSHAD
    $OPcode &= 'A1' & _hex($guiObjPtr)         ; MOV EAX, guiObjPtr
    $OPcode &= '50'                         ; PUSH EAX
    $OPcode &= '68' & _hex($command)          ; PUSH commandString
    $OPcode &= 'B8' & _hex($guiCommandCall) ; MOV EAX, guiCommandCall
    $OPcode &= 'FFD0'                         ; CALL EAX
    $OPcode &= '61'                         ; POPAD
    $OPcode &= 'C3'                         ; RETN


    ;//Put the OpCode into a struct for later memory writing
    $vBuffer = DllStructCreate('byte[' & StringLen($OPcode) / 2 & ']')
    For $loop = 1 To DllStructGetSize($vBuffer)
        DllStructSetData($vBuffer, 1, Dec(StringMid($OPcode, ($loop - 1) * 2 + 1, 2)), $loop)
    Next

    ;//Write the OpCode to previously allocated memory
    DllCall($kernel32, 'int', 'WriteProcessMemory', 'int', $processHandle, 'int', $functionAddress[0], 'int', DllStructGetPtr($vBuffer), 'int', DllStructGetSize($vBuffer), 'int', 0)

    ;//Create a remote thread in order to run the OpCode
    $hRemoteThread = DllCall($kernel32, 'int', 'CreateRemoteThread', 'int', $processHandle, 'int', 0, 'int', 0, 'int', $functionAddress[0], 'ptr', 0, 'int', 0, 'int', 0)

    ;//Wait for the remote thread to finish
    Do
        $result = DllCall('kernel32.dll', 'int', 'WaitForSingleObject', 'int', $hRemoteThread[0], 'int', 50)
    Until $result[0] <> 258

    ;//Close the handle to the previously created remote thread
    DllCall($kernel32, 'int', 'CloseHandle', 'int', $hRemoteThread[0])

    ;//Free the previously allocated memory
    DllCall($kernel32, 'ptr', 'VirtualFreeEx', 'hwnd', $processHandle, 'int', $functionAddress[0], 'int', 0, 'int', 0x8000)

    memClose($processHandle)
    
    Return True

EndFunc   ;==>guiCommand
where $guiCommandCall is the function call address in the client.

And you would call it like this:
Code:
guiCommand($command, $control)
Where $command and $control are both strings... unfortunately, I can't remember what those string are for the skillbar keys. I'll have to take a look when I get home this evening, unless someone else would be kind enough to take a look :P (if you breakpoint at the function call in OllyDbg and take a few steps in, I think you can find the strings fairly easily).

Oh... and to find the function call, assuming it hasn't changed in the PWI update (has that happened yet?) you can use this utility - just stick it in your element folder and run it in AutoIt. It will spit the function call address out in the console. For the PWI client as of yesterday, the address was at 0x616CB0
Code:
getGuiCommandOffset()

Func getGuiCommandOffset()

    $path = "elementclient.exe"
    $file = FileOpen($path, 16)
    $data = FileRead($file, FileGetSize($path))
    FileClose($file)
    $search = StringRegExp($data,    '53' & _            ; PUSH EBX                                ; guiCommand()
                                    '8B5C24.{2}' & _    ; MOV EBX,DWORD PTR SS:[ARG.1]
                                    '56' & _            ; PUSH ESI
                                    '8B7424.{2}' & _    ; MOV ESI,DWORD PTR SS:[ARG.2]
                                    '57' & _            ; PUSH EDI
                                    '56' & _            ; PUSH ESI                                 ; /Arg2 => [ARG.2]
                                    '53' & _            ; PUSH EBX                                 ; |Arg1 => [ARG.1]
                                    'E8.{8}' & _        ; CALL 007E6E30                            ; \ElementClient.007E6E30
                                    '84C0' & _            ; TEST AL,AL
                                    '74.{2}' & _        ; JE SHORT 00604B6A
                                    '85F6' & _            ; TEST ESI,ESI
                                    '74.{2}' & _        ; JE SHORT 00604B62
                                    '8BCE' & _            ; MOV ECX,ESI
                                    'E8.{8}' & _        ; CALL 007F4940                            ; [ElementClient.007F4940
                                    '84C0' & _            ; TEST AL,AL
                                    '74.{2}' & _        ; JE SHORT 00604B62
                                    '8B06' & _            ; MOV EAX,DWORD PTR DS:[ESI]
                                    '6A.{2}' & _        ; PUSH 1
                                    '6A.{2}' & _        ; PUSH 0
                                    '6A.{2}' & _        ; PUSH 0
                                    '8BCE' & _            ; MOV ECX,ESI
                                    'FF50.{2}' & _        ; CALL DWORD PTR DS:[EAX+1C]
                                    '5F' & _            ; POP EDI
                                    '5E' & _            ; POP ESI
                                    'B0.{2}' & _        ; MOV AL,1
                                    '5B' & _            ; POP EBX
                                    'C2.{4}' & _        ; RETN 8
                                    '68.{8}', 2)           ; PUSH OFFSET 00AB4C8C

    $call_pos = StringInStr($data, $search[0])/2 + 0x3FFFFF
    ConsoleWrite('guiCommand() call address: 0x' & Hex($call_pos) & @CRLF)
EndFunc


Func rev($string)
    Local $all
    For $i = StringLen($string) + 1 To 1 Step -2
        $all = $all & StringMid($string, $i, 2)
    Next
    While StringLeft($all, 1) = '0'
        $all = StringTrimLeft($all, 1)
    WEnd
    Return $all
EndFunc
02/15/2012 14:10 Smurfin#290
dumbfck, is that what the game is using for sending keystroke into the game for casting skills ?
02/15/2012 14:28 dumbfck#291
Not exactly... That's the in-game function that handles mouse clicks within the GUI, including clicking buttons on your skill bar. However, clicking buttons on your skill bar does then go to the same function that is used for handling hotkeys for casting skills.
The advantage to using this method is that you can use all of your extended skills in the expanded skill bars :)

Edit: I've been poking around - Seems that this stuff is for all gui based clicks EXCEPT for skills lol - I coulda sworn it used to handle the skillbar stuff too. I'm closing in on the function that handles the skillbar stuff but it's getting late here now so I'll try again tomorrow :/

Btw, the new SendPacket function address is 0x63AA80
02/18/2012 00:44 olivarra1#292
Thank you very much for your code

i'm trying to use this to farm ballista [PQ3 glitch, yup], and sniffing, decrypting and uncompressing packets i found out that what's being sent is:
0x2213123600551710C0000000000000000054510000 each time i gather it.

However, i checked the operation codes, and it seems that gather should be 7E, so i think it might be the tool i'm using is outdated and is not decrypting/uncompressing properly

Using your function to send all that stuff just makes nothing in-game, [and if i put wrong packetSize i get kicked out from server :D (not ban, just disconected from server)]

Do you know what am i missing?

Thank you very much :3
02/18/2012 10:13 Interest07#293
My gather resource packet isn't exactly correct, it has a hard coded position for the gathering tool and its id in there. I should update it some time, but I didn't think anybody would use it over the gather resource action struct.
02/18/2012 10:41 Sᴡoosh#294
I inject the function, but you are right - using actionstruct is better, I should change that some day :D
02/18/2012 13:53 atelarie#295
Quote:
Originally Posted by Interest07 View Post
Just in case you don't have the action structs...


Follow:
Code:
        public void follow(int playerId)
        {
            int actionStruct = values.actionStructPointer;
            int actionList = MemFunctions.MemReadInt(pr_processHandle, actionStruct + 0x30);
            int followAction = MemFunctions.MemReadInt(pr_processHandle, actionList + 0x1C);

            MemFunctions.MemWriteInt(pr_processHandle, followAction + 0x8, 0);          //Set error = 0
            MemFunctions.MemWriteInt(pr_processHandle, followAction + 0x20, playerId);  //Set playerId to follow
            //MemFunctions.MemWriteInt(pr_processHandle, followAction + 0x48, 0);       //Set stopped following = 0

            MemFunctions.MemWriteInt(pr_processHandle, actionStruct + 0xC, followAction);   //Set new action at position 1
            MemFunctions.MemWriteInt(pr_processHandle, actionStruct + 0x18, 1);             //Set next action position to 1
            MemFunctions.MemWriteInt(pr_processHandle, actionStruct + 0x14, followAction);  //Set new action type follow as next action
 
        }

Interest07
I'm trying to make my char follow another char using your actionstruct but doesn't work. I am positive that I understand the actionstruct incorrectly, could you please help out here?
I posted my code here, somebody could help point out where i were wrong?
I'm fairly new to this just a few weeks, so I apologize if my questions are very basic.

many thanks

Code:
$vBaseAdress = 11702660
$vstructaddress = 28
$vplayeraddress = 32
$vactionstruct = 4084
$vOpen = _MemoryOpen(WinGetProcess($elementclient))

Func follow($playerid)
	local $readstructaddress
	local $readplayeraddress
	local $readactionstructaddress
	local $actionpointer
	local $actionlist
	local $followaction
	$readstructaddress = _MemoryRead($vBaseAdress, $vOpen, "dword") + $vstructaddress
	$readplayeraddress = _MemoryRead($readstructaddress, $vOpen, "dword") + $vplayeraddress
	$readactionstructaddress = _MemoryRead($readplayeraddress, $vOpen, "dword") + $vactionstruct
	$actionpointer = _MemoryRead($readactionstructaddress, $vOpen, "dword")
	$actionlist = _MemoryRead($actionpointer + 48, $vOpen, "dword")
	$followaction = _MemoryRead($actionlist + 28, $vOpen, "dword")

	_MemoryWrite($followaction + 8, $vOpen, 0, "dword")
	_MemoryWrite($followaction + 32, $vOpen, $playerid, "dword")
	;_MemoryWrite($followaction + 72, $vOpen, 0, "dword") ; stop following

	_MemoryWrite($actionpointer + 12, $vOpen, $followaction, "dword")
	_MemoryWrite($actionpointer + 24, $vOpen, 1, "dword")
	_MemoryWrite($actionpointer + 20, $vOpen, $followaction, "dword")

EndFunc
02/19/2012 01:35 amineurin#296
Quote:
Originally Posted by atelarie View Post
Interest07
I'm trying to make my char follow another char using your actionstruct but doesn't work. I am positive that I understand the actionstruct incorrectly, could you please help out here?
I posted my code here, somebody could help point out where i were wrong?
I'm fairly new to this just a few weeks, so I apologize if my questions are very basic.

many thanks

Code:
$vBaseAdress = 11702660
$vstructaddress = 28
$vplayeraddress = 32
$vactionstruct = 4084
$vOpen = _MemoryOpen(WinGetProcess($elementclient))

Func follow($playerid)
	local $readstructaddress
	local $readplayeraddress
	local $readactionstructaddress
	local $actionpointer
	local $actionlist
	local $followaction
	$readstructaddress = _MemoryRead($vBaseAdress, $vOpen, "dword") + $vstructaddress
	$readplayeraddress = _MemoryRead($readstructaddress, $vOpen, "dword") + $vplayeraddress
	$readactionstructaddress = _MemoryRead($readplayeraddress, $vOpen, "dword") + $vactionstruct
	$actionpointer = _MemoryRead($readactionstructaddress, $vOpen, "dword")
	$actionlist = _MemoryRead($actionpointer + 48, $vOpen, "dword")
	$followaction = _MemoryRead($actionlist + 28, $vOpen, "dword")

	_MemoryWrite($followaction + 8, $vOpen, 0, "dword")
	_MemoryWrite($followaction + 32, $vOpen, $playerid, "dword")
	;_MemoryWrite($followaction + 72, $vOpen, 0, "dword") ; stop following

	_MemoryWrite($actionpointer + 12, $vOpen, $followaction, "dword")
	_MemoryWrite($actionpointer + 24, $vOpen, 1, "dword")
	_MemoryWrite($actionpointer + 20, $vOpen, $followaction, "dword")

EndFunc

im not interest07, but try this for follow:
Quote:
Global $OFFSET_ACTIONFOLLOW[6], $CFG_OFFSET_ACTIONOBJECT = "ActionObject_Offset"
$OFFSET_ACTIONFOLLOW[1] = 52
$OFFSET_ACTIONFOLLOW[2] = $ActionBaseOffset
$OFFSET_ACTIONFOLLOW[3] = 48
$OFFSET_ACTIONFOLLOW[4] = 28
$OFFSET_ACTIONFOLLOW[5] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_ACTIONOBJECT, "32")

Global $OFFSET_ACTIONREAD3[5], $CFG_OFFSET_ACTIONREAD3 = "ActionRead3_Offset"
$OFFSET_ACTIONREAD3[1] = 52 ;0x30
$OFFSET_ACTIONREAD3[2] = $ActionBaseOffset
$OFFSET_ACTIONREAD3[3] = 48 ;030
$OFFSET_ACTIONREAD3[4] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_ACTIONREAD3, "28") ; 1c

Global $OFFSET_ACTIONSETERROR[6], $CFG_OFFSET_ACTIONSETERROR = "ActionSetError_Offset"
$OFFSET_ACTIONSETERROR[1] = 52 ;0x30
$OFFSET_ACTIONSETERROR[2] = $ActionBaseOffset
$OFFSET_ACTIONSETERROR[3] = 48 ;0x30
$OFFSET_ACTIONSETERROR[4] = 8 ;0x8
$OFFSET_ACTIONSETERROR[5] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_ACTIONSETERROR, "52")

Global $OFFSET_ACTIONWRITE[4], $CFG_OFFSET_ACTIONWRITE = "ActionWrite_Offset"
$OFFSET_ACTIONWRITE[1] = 52 ;0x30
$OFFSET_ACTIONWRITE[2] = $ActionBaseOffset
$OFFSET_ACTIONWRITE[3] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_ACTIONWRITE, "12") ;0xC

Global $OFFSET_ACTIONVALUE[6], $CFG_OFFSET_ACTIONVALUE = "ActionValue_OffSet"
$OFFSET_ACTIONVALUE[1] = 52 ;0x30
$OFFSET_ACTIONVALUE[2] = $ActionBaseOffset
$OFFSET_ACTIONVALUE[3] = 48 ;030
$OFFSET_ACTIONVALUE[4] = 4 ;0x4
$OFFSET_ACTIONVALUE[5] = IniRead($SOFTWARE_OFFSET_CONFIG, $CFG_OFFSET_ROOT_KEY, $CFG_OFFSET_ACTIONVALUE, "44")
;################################################# #######
;### Follow Leader
;################################################# #######
Func EPFOLLOWLEADER()
$LEADERID=$PlayerArray[0][0] ;player id to follow
Local $Read = _MemoryPointerRead($APP_BASE_ADDRESS, $PROCESS_INFORMATION, $OFFSET_ACTIONREAD3)
_MemoryPointerWrite($APP_BASE_ADDRESS, $PROCESS_INFORMATION, $OFFSET_ACTIONSETERROR, 0)
_MemoryPointerWrite($APP_BASE_ADDRESS, $PROCESS_INFORMATION, $OFFSET_ACTIONFOLLOW, $LEADERID)
_MemoryPointerWrite($APP_BASE_ADDRESS, $PROCESS_INFORMATION, $OFFSET_ACTIONWRITE, $Read[1])
_MemoryPointerWrite($APP_BASE_ADDRESS, $PROCESS_INFORMATION, $OFFSET_ACTIONFLAG, 1)
_MemoryPointerWrite($APP_BASE_ADDRESS, $PROCESS_INFORMATION, $OFFSET_ACTIONWRITE2, $Read[1])
EndFunc
have fun :)
02/19/2012 01:49 atelarie#297
Quote:
Originally Posted by amineurin View Post
im not interest07, but try this for follow:

have fun :)
Thanks amineurin. I'm getting there.
MemoryPointerWrite is a user function isn't it? I don't think its a part of nomadmemory.au3.
Could you please break down the function if you don't mind?
I've never actually write anything in my bot. Mostly just read datas and then using controlsend and clicks - but this method is ancient and unreliable.
So i'm a bit clueless on how to and where to write on memory.

many thanks
02/19/2012 02:07 amineurin#298
_MemoryPointerWrite is inside nomadmemory.au3

you need a player id to get this working.
i use names for my squad, lets say a player named: amineurin
then i list all players on first start next to my bot, if name is found get the player id.

after that you can anytime say your bot to follow this player by using the id.
maybe u code a healer....the healer follow a player.
check player hp and if under 50% he heal the player.
after healing you start follow function again....so healer follow again playername.

or u plan to make a bot hunting in a squad.
follow a leader, make assist target and hunt with a full squad or more bots :)

you can look in prophet bot, from there i have the action structs.
i ad the follow function and some others to the bot.
if u plan to make anything in autoit, most is allready inside the prophet bot.
02/19/2012 02:43 dumbfck#299
Welcome back ami ^^
02/19/2012 03:16 amineurin#300
thanks a lot dumbfck :-)
finally my city movement, renovating, find a new job and build up a new pc has an end :cool:

today i start again a bit of coding and found out....windows 7 64 bit is no god for autoit :mad:
so i now set up another pc with god old xp :D

do you or interest7 know how to stop this packet ?
so the char stop running to a mob ;)

Quote:
Func regularAttack($afterSkill)
;Start with regular attacks. $afterskill is 1 if you
;start attacking after using a skill.
local $packet, $packetSize

$packet = '0300'
$packet &= _hex($afterSkill, 2)
$packetSize = 3

sendPacket($packet, $packetSize, $PROCESS_ID)
EndFunc ;==>