Buying from network with packet injecting?

06/04/2011 19:58 jremy#1
What i'm trying to do is simple AutoIt script using nuConnector that automatically buys elixirs from stallnetwork, but client crash everytime it buys one. After reloggin i can see it have bought one, sometimes more. Here is the code:

Code:
#NoTrayIcon
#include <String.au3>

Global $buying = false, $currentPage = 1
Global $weapon_id = "00000E5F"
Global $shield_id = "00000E60"
Global $protector_id = "00000E61"
Global $accessory_id = "00000E62"

GUICreate("GUI", 171, 176, 192, 114)
$typeCombo = GUICtrlCreateCombo("Weapon Elixir", 16, 16, 137, 25)
GUICtrlSetData(-1, "Protector Elixir|Accessory Elixir|Shield Elixir")
GUICtrlCreateLabel("Max price:", 16, 56, 53, 17)
$maxPrice = GUICtrlCreateInput("500000", 16, 88, 137, 21)
$buy = GUICtrlCreateButton("Check and Buy!", 16, 136, 139, 25)
GUISetState(@SW_SHOW)

TCPStartUp()
$socket = TCPConnect("127.0.0.1", 22580)
If @Error Then Exit

While 1
	Switch GUIGetMsg()
		Case -3
			Exit
		Case $buy
			InjectPacket("7461", "01002100000000") ;reguest 1st page of elixirs
			$buying = true

	EndSwitch

	$recv = ReadPacket()
	$size = Dec(StringMid($recv, 3, 2) & StringMid($recv, 1, 2))
	$opcode = StringMid($recv, 7, 2) & StringMid($recv, 5, 2)
	$data = StringMid($recv, 13)

	If $opcode = "B461" AND $buying = true Then
		BeginParse($data, $size)
		ParseByte()
		$amount = Dec(ParseByte())
		$pages = Dec(ParseByte())

		For $i = 1 To $amount
			$model = ParseDword()
			ParseWord()
			$id = ParseDword()
			$length = Dec(ParseWord())
			$nick = ParseAscii($length)
			$numByte = ParseByte()
			ParseWord()
			ParseByte()
			$price = ParseQword()
			$dunno = ParseQword()

			If $model = $weapon_id AND GUICtrlRead($typeCombo) = "Weapon Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($id, $numByte, $price, $dunno)
			ElseIf $model = $shield_id AND GUICtrlRead($typeCombo) = "Shield Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($id, $numByte, $price, $dunno)
			ElseIf $model = $protector_id AND GUICtrlRead($typeCombo) = "Protector Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($id, $numByte, $price, $dunno)
			ElseIf $model = $accessory_id AND GUICtrlRead($typeCombo) = "Accessory Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($id, $numByte, $price, $dunno)
			EndIf
		Next

		If $currentPage = $pages Then
			$buying = false
			InjectPacket("7462", "") ;close network
			$currentPage = 1
		Else
			InjectPacket("7461", "03" & Hex($currentPage, 2) & "2100000000") ;next page please!
			$currentPage += 1
		EndIf
	EndIf

	If $buying = true Then
		ToolTip("Buying = ON! please wait...", 0, 0)
	Else
		ToolTip("Buying = OFF!", 0, 0)
	EndIf
WEnd

Func ReadPacket()
	$recv = Hex(Binary(TCPRecv($socket, 2)))
	If $recv = "" Then
		Return ""
	Else
		$size = Dec(StringMid($recv, 3, 2) & StringMid($recv, 1, 2))
		$recv &= Hex(Binary(TCPRecv($socket, $size+4)))
		Return $recv
	EndIf
EndFunc

Func InjectPacket($opcode, $data, $security = "0100")
	$size = Hex(StringLen($data) / 2, 4)
	$size = StringMid($size, 3, 2) & StringMid($size, 1, 2)
	$opcode = StringMid($opcode, 3, 2) & StringMid($opcode, 1, 2)
	$packet = _HexToString($size & $opcode & $security & $data)
	TCPSend($socket, $packet)
EndFunc

Func Rev($val)
	$result = ""
	For $i = 1 To StringLen($val) / 2
		$byte = StringRight($val, 2)
		$val = StringTrimRight($val, 2)
		$result &= $byte
	Next
	Return $result
EndFunc

Func _Dec($hex) ;for Qwords
	$number = 0
	For $i = StringLen($hex) To 1 Step -1
		$number += Dec(StringMid($hex, $i, 1)) *16^ (StringLen($hex) - $i)
	Next
	Return $number
EndFunc

Func BuyElixir($id, $numByte, $price, $dunno)
	InjectPacket("7463", Rev($id) & $numByte & Rev($price) & "010000" & Rev($dunno))
	Sleep(300)
EndFunc

;-----------Packet parsing functions by pushedx!----------------------------------------------------

Func BeginParse($buffer, $size)
	Global $globalParseIndex = 1
	Global $globalParseSize = $size
	Global $globalParseBuffer = $buffer
EndFunc

Func ParseByte()
	$result = StringMid($globalParseBuffer, $globalParseIndex, 2)
	$globalParseIndex = $globalParseIndex + 2
	return $result
EndFunc

Func ParseWord()
	$low = ParseByte()
	$hi = ParseByte()
	return $hi & $low
EndFunc

Func ParseDword()
	$low = ParseWord()
	$hi = ParseWord()
	return $hi & $low
EndFunc

Func ParseQWord()
	$low = ParseDword()
	$hi = ParseDword()
	return $hi & $low
EndFunc

Func ParseAscii($length)
	$result = StringMid($globalParseBuffer, $globalParseIndex, $length * 2)
	$globalParseIndex = $globalParseIndex + ($length * 2)
	$len = StringLen($result)
	$strResult = ""
	For $i = 1 to $len Step 2
		$strResult = $strResult & Chr(Dec(StringMid($result, $i, 2)))
	Next
	return $strResult
EndFunc
What might be causing the crash? I appreciate any help or suggestions, thanks!

edit: in rsro btw :)
06/05/2011 00:04 Keyeight#2
i didnt playe rsro befor and i dont know about autoit or like LastThief call it autoshit but mybe this server have game hack shild or somthing like that !!! try to byBass it :)

i hope i can help you
06/05/2011 03:05 bootdisk#3
It doesn't have HS.
Check the packets, perhaps this is like when you buy things from a npc, preventing them from being sent to the client might be the key.
06/05/2011 08:44 vorosmihaly#4
well,I think you simply inject the packets too fast..you should put a Sleep before the end of the while :)
06/05/2011 11:32 Shadowz75#5
You cant just simply inject the buy/network buy packet. It acually works , but if the client receives the packet from the server(that you sucessfully bought the item) it crashes, because the client isnt prepared for it. You could just block the packet from the server and fake the item pickup packet
06/05/2011 14:56 jremy#6
I see, B034 is the response when i buy item from NPC or pick one. But when i buy from network the response is B463 with only 1 byte of data (always 0x01). Should i fake the B034 anyway? Sameway than picking elixir?

Code:
[S -> C][B034]
01
06
0D	    //slot
60 0E 00 00 //id
01 00       //quantity
e: B463 must be telling it succesfully bought it so gotta inject B034 packet before it.
06/05/2011 22:14 jremy#7
I got it working now, thanks for help! I used phConnector v2 to block the B463 packet. Now that i had to parse inventory i could also make alchemy bot and other small tools for a lazy man (me) ^^

Code:
#NoTrayIcon
#include <Array.au3>
#include <String.au3>
#include "equipData.au3"

Global $buying = false, $currentPage = 1
Global $weapon_id = "00000E5F"
Global $shield_id = "00000E60"
Global $protector_id = "00000E61"
Global $accessory_id = "00000E62"

GUICreate("GUI", 171, 176, 192, 114)
$typeCombo = GUICtrlCreateCombo("Weapon Elixir", 16, 16, 137, 25)
GUICtrlSetData(-1, "Protector Elixir|Accessory Elixir|Shield Elixir")
GUICtrlCreateLabel("Max price:", 16, 56, 53, 17)
$maxPrice = GUICtrlCreateInput("500000", 16, 88, 137, 21)
$buy = GUICtrlCreateButton("Check and Buy!", 16, 136, 139, 25)
GUISetState(@SW_SHOW)

TCPStartUp()
$socket = TCPConnect("127.0.0.1", 22580)
If @Error Then Exit

While 1
	Switch GUIGetMsg()
		Case -3
			Exit
		Case $buy
			InjectPacket("7461", "01002100000000") ;reguest 1st page of elixirs
			$buying = true

	EndSwitch

	$recv = ReadPacket()
	$size = Dec(StringMid($recv, 3, 2) & StringMid($recv, 1, 2))
	$opcode = StringMid($recv, 7, 2) & StringMid($recv, 5, 2)
	$data = StringMid($recv, 13)

	If $opcode = "3013" Then
		BeginParse($data, $size)
		$globalParseIndex += 118 ;skip 59 bytes

		$maxSlot = Dec(ParseByte())
		$itemCount = Dec(ParseByte())

		Global $usedSlot[$maxSlot]

		ToolTip("Loading inventory please wait...", 0, 0)

		For $i = 1 To $itemCount
			$slot = Dec(ParseByte())
			$model = ParseDword()
			If IsEquip($model) = true Then
				$plus = Dec(ParseByte())
				ParseQword()
				ParseDword()
				ParseDword()
				ParseByte()
			Else
				ParseWord()
			Endif
			$usedSlot[$slot] = "used"
		Next
	EndIf

	If $opcode = "7034" Then
		BeginParse($data, $size)
		$flag = ParseByte()
		If $flag = "09" Then ;item sold to npc
			$slot = Dec(ParseByte())
			$usedSlot[$slot] = ""
			ParseWord()
			ParseDword()
		ElseIf $flag = "02" Then ;item stored
			$slot = Dec(ParseByte())
			$usedSlot[$slot] = ""
			ParseByte()
			ParseDword()
		ElseIf $flag = "00" Then ;item moved
			$slot = Dec(ParseByte())
			$usedSlot[$slot] = ""
			$newSlot = Dec(ParseByte())
			$usedSlot[$newSlot] = "used"
			ParseWord()
		EndIf
	EndIf

	If $opcode = "B461" AND $buying = true Then
		BeginParse($data, $size)
		ParseByte()
		$amount = Dec(ParseByte())
		$pages = Dec(ParseByte())

		For $i = 1 To $amount
			$model = ParseDword()
			ParseWord()
			$id = ParseDword()
			$length = Dec(ParseWord())
			$nick = ParseAscii($length)
			$numByte = ParseByte()
			ParseWord()
			ParseByte()
			$price = ParseQword()
			$dunno = ParseQword()

			If $model = $weapon_id AND GUICtrlRead($typeCombo) = "Weapon Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($model, $id, $numByte, $price, $dunno)
			ElseIf $model = $shield_id AND GUICtrlRead($typeCombo) = "Shield Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($model, $id, $numByte, $price, $dunno)
			ElseIf $model = $protector_id AND GUICtrlRead($typeCombo) = "Protector Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($model, $id, $numByte, $price, $dunno)
			ElseIf $model = $accessory_id AND GUICtrlRead($typeCombo) = "Accessory Elixir" AND _Dec($price) <= GUICtrlRead($maxPrice) Then
				BuyElixir($model, $id, $numByte, $price, $dunno)
			EndIf
		Next

		If $currentPage = $pages Then
			$buying = false
			InjectPacket("7462", "") ;close network
			$currentPage = 1
		Else
			InjectPacket("7461", "03" & Hex($currentPage, 2) & "2100000000") ;next page please!
			$currentPage += 1
		EndIf
	EndIf

	If $buying = true Then
		ToolTip("Buying ON! please wait...", 0, 0)
	Else
		ToolTip("Buying OFF!", 0, 0)
	EndIf
WEnd

Func ReadPacket()
	$recv = Hex(Binary(TCPRecv($socket, 2)))
	If $recv = "" Then
		Return ""
	Else
		$size = Dec(StringMid($recv, 3, 2) & StringMid($recv, 1, 2))
		$recv &= Hex(Binary(TCPRecv($socket, $size+4)))
		Return $recv
	EndIf
EndFunc

Func InjectPacket($opcode, $data, $security = "0100")
	$size = Hex(StringLen($data) / 2, 4)
	$size = StringMid($size, 3, 2) & StringMid($size, 1, 2)
	$opcode = StringMid($opcode, 3, 2) & StringMid($opcode, 1, 2)
	$packet = _HexToString($size & $opcode & $security & $data)
	TCPSend($socket, $packet)
EndFunc

Func Rev($val)
	$result = ""
	For $i = 1 To StringLen($val) / 2
		$byte = StringRight($val, 2)
		$val = StringTrimRight($val, 2)
		$result &= $byte
	Next
	Return $result
EndFunc

Func _Dec($hex) ;for Qwords
	$number = 0
	For $i = StringLen($hex) To 1 Step -1
		$number += Dec(StringMid($hex, $i, 1)) *16^ (StringLen($hex) - $i)
	Next
	Return $number
EndFunc

Func BuyElixir($model, $id, $numByte, $price, $dunno)
	$slot = GetSlot()
	If $slot <> -1 Then
		$usedSlot[Dec($slot)] = "used"
		InjectPacket("7463", Rev($id) & $numByte & Rev($price) & "010000" & Rev($dunno))
		InjectPacket("B034", "0106" & $slot & Rev($model) & "0100", "0200")
		Sleep(300)
	Else
		$buying = false
		InjectPacket("7462", "") ;close network
		MsgBox(16, "Error", "Inventory full")
	EndIf
EndFunc

Func IsEquip($id)
	$search = _ArraySearch($item_id, $id)
	If $search <> -1 Then
		Return true
	Else
		Return false
	EndIf
EndFunc

Func GetSlot()
	For $i = 0 To UBound($usedSlot) - 1
		If $usedSlot[$i] = "" AND $i > 12 Then
			Return Hex($i, 2)
		EndIf
	Next
	Return -1
EndFunc

;-----------Packet parsing functions by pushedx!----------------------------------------------------

Func BeginParse($buffer, $size)
	Global $globalParseIndex = 1
	Global $globalParseSize = $size
	Global $globalParseBuffer = $buffer
EndFunc

Func ParseByte()
	$result = StringMid($globalParseBuffer, $globalParseIndex, 2)
	$globalParseIndex = $globalParseIndex + 2
	return $result
EndFunc

Func ParseWord()
	$low = ParseByte()
	$hi = ParseByte()
	return $hi & $low
EndFunc

Func ParseDword()
	$low = ParseWord()
	$hi = ParseWord()
	return $hi & $low
EndFunc

Func ParseQWord()
	$low = ParseDword()
	$hi = ParseDword()
	return $hi & $low
EndFunc

Func ParseAscii($length)
	$result = StringMid($globalParseBuffer, $globalParseIndex, $length * 2)
	$globalParseIndex = $globalParseIndex + ($length * 2)
	$len = StringLen($result)
	$strResult = ""
	For $i = 1 to $len Step 2
		$strResult = $strResult & Chr(Dec(StringMid($result, $i, 2)))
	Next
	return $strResult
EndFunc
And a snippet which creates "equipData.au3" from media.pk2's itemdata files:

Code:
#include <File.au3>

$a = 0

$new = FileOpen("equipData.au3", 1)

LoadItems("itemdata_5000.txt", $new)
LoadItems("itemdata_10000.txt", $new)
LoadItems("itemdata_15000.txt", $new)
LoadItems("itemdata_20000.txt", $new)
LoadItems("itemdata_25000.txt", $new)
LoadItems("itemdata_30000.txt", $new)
LoadItems("itemdata_35000.txt", $new)

FileClose($new)

$read = FileReadLine("equipData.au3", 1)
$replace = "#include-once" & @CRLF & "Global $item_id[" & $a & "]" & @CRLF & @CRLF & $read
_ReplaceStringInFile("equipData.au3", $read, $replace, 0, 0)

MsgBox(0, "", "Done!")

Func LoadItems($filename, $new)
	$file = FileOpen($filename, 0)
	While 1
		$read = FileReadLine($file)
		If @error = -1 Then ExitLoop

		$array = StringSplit($read, "	", 2)

		$id = Hex($array[1], 8)

		If StringInStr($read, "ITEM_CH_") OR StringInStr($read, "ITEM_EU_") Then
			FileWrite($new, "$item_id[" & $a & "] = " & '"' & $id & '"' & @CRLF)
			$a += 1
		EndIf
	Wend
	FileClose($file)
EndFunc
06/05/2011 22:53 Keyeight#8
good work
08/03/2011 14:59 sarkoplata#9
@jremy
Can you explain what you did to stop crashing? i am also doing something like this , so i get crash. The thing is not with stall network btw, buying items from npc.
08/03/2011 17:00 GoneUp#10
Quote:
Originally Posted by sarkoplata View Post
@jremy
Can you explain what you did to stop crashing? i am also doing something like this , so i get crash. The thing is not with stall network btw, buying items from npc.
Like Shadow Said He faked a pickup Packet and Blocked the Stall Network response packet.
08/03/2011 18:15 sarkoplata#11
Quote:
Originally Posted by GoneUp View Post
Like Shadow Said He faked a pickup Packet and Blocked the Stall Network response packet.
Ok well , i blocked the packet when server sends when i buy item from npc. And so i didnt crash but i wasnt able to see the item in my inventory , of course.

So to see the item i did (faked pickup packet)

Code:
Dim FakeSuccess As New Packet(&HB074)
                            FakeSuccess.WriteUInt8(1)
                            FakeSuccess.WriteUInt8(1)
                            Proxy.ag_local_context.Security.Send(FakeSuccess)
Code:
Dim FakePickUp As New Packet(&HB034)
                            FakePickUp.WriteUInt8(1)
                            FakePickUp.WriteUInt8(6)
                            FakePickUp.WriteUInt8(Slot)
                            FakePickUp.WriteUInt32(ItemId)
                            FakePickUp.WriteUInt8(Amount)
                            Proxy.ag_local_context.Security.Send(FakePickUp)
Code:
Dim FakeOK As New Packet(&HB074)
                            FakeOK.WriteUInt8(2)
                            FakeOK.WriteUInt8(0)
                            Proxy.ag_local_context.Security.Send(FakeOK)
Although i was sure that would not work , i just tried. And it made my client crash.So should i send the pickpacket also ? well , since it does not have any uniqueid as a drop...
08/04/2011 10:01 lesderid#12
Quote:
Originally Posted by sarkoplata View Post
Ok well , i blocked the packet when server sends when i buy item from npc. And so i didnt crash but i wasnt able to see the item in my inventory , of course.

So to see the item i did (faked pickup packet)

*Code*

Although i was sure that would not work , i just tried. And it made my client crash.So should i send the pickpacket also ? well , since it does not have any uniqueid as a drop...
Try to send as less responses as possible to client when it doesn't send a request.
08/04/2011 12:09 zeteris#13
Quote:
Originally Posted by sarkoplata View Post
Although i was sure that would not work , i just tried. And it made my client crash.So should i send the pickpacket also ? well , since it does not have any uniqueid as a drop...
It's simple, just block buying response packet, and imitate item pickup packet.
08/04/2011 19:55 sarkoplata#14
Quote:
Originally Posted by zeteris View Post
It's simple, just block buying response packet, and imitate item pickup packet.
I already did it , problem was i needed to write word for amount but i wrote byte , my bad.