Valhalla Legends Forums Archive | Battle.net Bot Development | Re: [PHP] Fixing Flappy Webbot

AuthorMessageTime
Smarter
As many of you know, Fapiko created a php based Battle.Net Webbot, which can be easily modified into numerous things, and also uses BNLS, and is open source, and available on his website (fapiko.com), however, it was written before lockdown, and uses BNLS_VERSIONCHECK (0x09), which i'm not personally sure if 0x09 supports lockdown, or only BNLS_VERSIONCHECKEX2, nevertheless, the modification nessscary is located in the packets.php file:

[code]function Parse0x50($data) {
global $bnls, $pbuffer, $sToken;
$sToken = $pbuffer->GetDWORD(substr($data, 8, 4));
$mpqVer = substr($data, 31, 1); // Needs to be changed for lockdown-IX86-00.dll
$checksumFormula = substr($data, 37, strlen($data) - 38);

$pbuffer->InsertDWORD(3);
$pbuffer->InsertDWORD($mpqVer);
$pbuffer->InsertString($checksumFormula);
$pbuffer->SendPacket(9, $bnls);
}
[/code]

However... I have no idea of the makeup of $data, so I can't modify the substr(), of mpqVer so it can grab the right version, anyone have any ideas, also is 0x09 Lockdown Able?
September 26, 2007, 11:50 AM
LockesRabb
First off, I suggest downloading and installing Notepad++. It's quite useful for coding.

Second off, if you're using Notepad++, just hit CTRL and F. This will bring up the 'Find' dialog box. Click the 'Find in files' tab. Browse to where the main directory of the php files for Flappy is. Then put in the string you'd like it to search the files. In our case, Parse0x50(. Without the ending dot, of course. Click 'Find them all'. It'll begin searching the files for any subsequent references to the function. Once it finds the references, it shouldn't be too hard for you to figure out the structure from there on, and update it.

If you're not using Notepad, hopefully, based on the above instructions, you'll be able to search those files. Perhaps use Windows' search feature? I know Windows is able to search inside files.
September 26, 2007, 1:22 PM
Smarter
No no no, $data, is the data being recieved, and since it's in php, I can only speculate at it's content, I need to know the data being recieved, to parse the mpqFilename out...
September 26, 2007, 1:46 PM
LockesRabb
First off, I'd make a hex dump function and have a die() command in the function. Then I'd pass $data along to the dump function from the Parse0x50 function.

That should give you a general idea of where to work with the data.
September 26, 2007, 2:13 PM
Smarter
Looks like I don't need too, thx to bnet they reverted it back to ver-IX86-#.dll.
September 26, 2007, 2:39 PM
LockesRabb
Dump function in VB:

[code]'DumpPacket function coded by Grok
'----------------------------------
Public Sub DumpPacket(ByVal sIn As String)
    RaiseEvent DebugOutput("Dumping packet...")
    Dim x1 As Long, y1 As Long
    Dim iLen As Long, iPos As Long
    Dim sB As String, sT As String
    Dim sOut As String
    Dim Offset As Long, sOffset As String
   
    iLen = Len(sIn)
    If iLen = 0 Then Exit Sub
    sOut = ""
    Offset = 0
    For x1 = 0 To ((iLen - 1) \ 16)
        sOffset = Right$("0000" & Hex(Offset), 4)
        sB = String(48, " ")
        sT = "................"
        For y1 = 1 To 16
            iPos = 16 * x1 + y1
            If iPos > iLen Then Exit For
            Mid(sB, 3 * (y1 - 1) + 1, 2) = Right("00" & Hex(Asc(Mid(sIn, iPos, 1))), 2) & " "
            Select Case Asc(Mid(sIn, iPos, 1))
                Case 0, 9, 10, 13
                Case Else
                    Mid(sT, y1, 1) = Mid(sIn, iPos, 1)
            End Select
        Next y1
        If Len(sOut) > 0 Then sOut = sOut & vbCrLf
        sOut = sOut & sOffset & ": "
        sOut = sOut & sB & " " & sT
        Offset = Offset + 16
    Next x1
    RaiseEvent DebugOutput(sOut)
End Sub[/code]

Ported to PHP would be:
[code]#DumpPacket function coded by Grok, ported to PHP By Don Cullen
#----------------------------------
function DumpPacket($sIn){
$iLen = strlen($sIn);
if(iLen = 0) return;
$sOut = '';
$Offset = 0;
$x1 = 0;
while($x1 <= ($iLen - 1) \ 16){
$sOffset = substr("0000".dechex(Offset),-4);
$sB = str_pad('', 48, ' ');
$sT = '................';
for($y1 = 0; $y1 <= 16; $y1++;){
$iPos = 16 * $x1 + $y1;
if($iPos > $ilen) break;
substr($sB, 3 * ($y1 - 1) + 1, 2) = substr("00" & dechex(ord(substr($sIn, $iPos, 1))), -2);
if(ord(substr($sIn, $iPos, 1)) == 0 || ord(substr($sIn, $iPos, 1)) == 9 || ord(substr($sIn, $iPos, 1)) == 10 || ord(substr($sIn, $iPos, 1)) == 13){
# Do nothing
} else {
substr($sT, $y1, 1) = substr($sIn, $iPos, 1);
}
}
if(strlen($sOut) > 0) $sOut .= '<br>';
$sOut .= $sOffset.': ';
$sOut .= $sB.' '.$sT;
$Offset = $Offset + 16;
}
return $sOut;
}[/code]

Keep in mind, I haven't tested the ported code. You might have to make a few adjustments. If you do end up making a few adjustments to make it work, we'd appreciate it if you posted the working code here.
September 26, 2007, 3:20 PM
BreW
Smarter: The BNLS 0x09 function does support lockdown checkrevision.
And you're refering to exactly what client when you say, "reverted it back to ver-IX86-##.dll"? They did not change anything at all recently that concerns CheckRevision. I tested just a moment ago to verify. Keep in mind, however, that the version of the CheckRevision used is directly dependant on the Verbyte you report in your 0x50 packet. If you send an invalid value, like say 0x00, you will indeed be sent the older CR mpq, along with a null checksum formula.
September 26, 2007, 4:04 PM
Leaky
[code]
function debugOutput($buffer) {
$i = 0;
$j = 0;
$returnString = "";
for($i = 0; $i < strlen($buffer); $i++) {
if(($i != 0) && ($i % 16 == 0)) {
$returnString = $returnString . "\t";
for($j = $i - 16; $j < $i; $j++) {
if(ord($buffer[$j]) < 0x20 || ord($buffer[$j]) > 0x7F)
$returnString = $returnString . '.';
else
$returnString = $returnString . $buffer[$j];
}
// Add a linefeed after the string
$returnString = $returnString . "\n";
}
$returnString = $returnString . bin2hex($buffer[$i]) . " ";
}
if($i != 0 && $i % 16 != 0) {
for($j = 0; $j < ((16 - ($i % 16)) * 3); $j++) {
$returnString = $returnString . " ";
}
}
$returnString = $returnString . "\t";
if($i > 0 && ($i % 16) == 0) {
$j = $i - 16;
}
else {
$j = ($i - ($i % 16));
}
for(; $i >= 0 && $j < $i; $j++) {
if(ord($buffer[$j]) < 0x20 || ord($buffer[$j]) > 0x7F) {
$returnString = $returnString . ".";
}
else {
$returnString = $returnString . $buffer[$j];
}
}
$returnString = $returnString . "\n";
$returnString = $returnString . "Length: " . strlen($buffer) . "\n";
return $returnString;
}
[/code]

there is a 100% working hex dumper...
return is a string but meh you can modify that if you want...
September 26, 2007, 7:28 PM
Leaky
why fix fapico's bot? it wasn't all that usefull to begin with... I would suggest creating your own like I did.. a nice framework can go a LONG way! and fapico's is a nice refrence tool... also i've converted someone's (i dont remember who.. somewhere on these boards) packet class from vb to php and it's open to the public just send me a PM if you'd like it.. it's pritty handy but you need to know how to use classes inorder to use it.
September 26, 2007, 7:40 PM
Barabajagal
Just wondering... I've never quite understood this. First off, how does php send raw packets? Secondly, how does it refresh data on a webpage? Does it use AJAX or some other system of that type?
September 26, 2007, 7:42 PM
Leaky
php doesn't refresh data on a webpage and ajax isn't part of php it's just javascript that gets xml from somewhere else

if your interested in making a phpbot you can aim me for info and help (i dont give handouts but i will help you learn it)

animepages11  (if you dont need help and think your cool cause you can spam people's aim's dont worry i can auto block your spam...)
September 26, 2007, 7:45 PM
Barabajagal
I have no interest in making one, I just wondered how it worked. I know AJAX isn't part of PHP, but I've seen some webapps that use AJAX to show fresh data instantly.
September 26, 2007, 7:47 PM
LockesRabb
The options for that vary. One could use AJAX, or one could use buffering (ob_start, flush, etc), or one could use recurring page refreshes.

Edit: As for how to send raw data via php's sockets...

http://us3.php.net/pack
http://us.php.net/sockets

That should answer your questions. :-)
September 26, 2007, 8:25 PM
Leaky
I could never figure pack out so i did it a different way...
September 26, 2007, 8:31 PM
Smarter
[quote author=Leaky link=topic=17054.msg173273#msg173273 date=1190835611]
why fix fapico's bot? it wasn't all that usefull to begin with... I would suggest creating your own like I did.. a nice framework can go a LONG way! and fapico's is a nice refrence tool... also i've converted someone's (i dont remember who.. somewhere on these boards) packet class from vb to php and it's open to the public just send me a PM if you'd like it.. it's pritty handy but you need to know how to use classes inorder to use it.
[/quote]

Well, any PHP bot would be great, but I didn't know of any others, is your public/open source, also I don't know enough php to write my own bot, just enough to read it, and modify it, and write simple things, so couple that with knowledge of BNCS and I can fix his bot.
September 26, 2007, 9:08 PM
Leaky
what I'm trying to encourage you to do is create your own bot... I would be happy to help you and it's a good opportunity to learn some of the more advanced things of programming (atleast the way i did it.. you learn things that apply to all languages) anyways aim me if your interested in learning more or would like some of the tools i've created for making a php bot
September 26, 2007, 9:17 PM
Smarter
I would love to, sadly I don't know enough php for that, I can read/edit PHP, and write simple scripts, that's it, and have no real desire to learn it, as I program in C#, which doubles As ASP.NET, so if I was to make a web based bot, i'd simply make it in ASP.NET, however I haven't began my programming in the web side of C#, so for now i'd just like a simply bot in PHP, that I can run some bots on, and modify for my own personal usage, and fappys is the only open source one I can get my hands on ? Although I would love to learn exactly how it is all done in PHP.
September 26, 2007, 11:28 PM
Leaky
o.O last i saw asp it looked more like visual basic than c#..... and asp sucks anyways.. you should learn php
September 26, 2007, 11:33 PM
idiat
Isn't the Debug function inside the PBuffer class the "hex dumper" you guys are talking about?

Is there any reason fapiko doesn't use pack/unpack? The PacketBuffer seems incomplete.

I could fix this up a bit if fapiko's okay with that and if no one else has a "framework" which they feel would better suit Smarter's needs and if Smarter hasn't decided to do it on his own. I really don't feel like starting another PHP bot right now (I'm not even properly working on my Python bot), but I'm interested to see what others have come up with.
September 27, 2007, 1:20 AM
Fapiko
I made that bot ages ago just to prove you could make a bot in PHP that could keep the connection alive for a substantial amount of time and not have the script timeout.  The bot uses both AJAX and live PHP output.  The AJAX kicks in when you type and hit enter which thus sends the text to a script that puts it in a queue to go to bnet.  When you load the webbot view script it creates a socket which connects to the backend script and echo's then flushes text as it comes in.  A more efficient way would be to set the PHP INI setting that turns on flushing after every output, can't think of it off the top of my head, but I didn't know about this setting when I coded the bot.  Also, I think my debugging code should still be built in which creates a hex and string representation of all the packets as they go in and out.  Just uncomment the debugging lines.
September 27, 2007, 2:19 AM
Leaky
OH SNAP!! FAPIKO IS ALIVE!!.. i thought he didn't really exist.. you know? like the tooth fairy?


anyways...

fapiko's bot is kinda messy and stuff but

here's a packet buffer that i made based off of someone elses vb / c++ packet buffer if ound on these boards


[code]
<?php

/* class packet module */


error_reporting(E_ALL);

class Packet {

Private $buffer = "";
Private $RawData = "";
var $PacketFormat = array("pBnet" => 1, "pBNLS" => 2, "pMCP" => 3, "pNone" => 4, "pMatrix" => 5, "pCLS" => 6);
Private $PacketType = array("pIncoming" => 1, "pOutgoing" => 2, "pNull" => 3);
Private $mode = 3;
var $pType = 1;
var $PacketID = NULL;
var $Position = 0;
var $RaiseOverflowErrors = false;
var $packetLength = 0;

function debugOutput($buffer) {
$i = 0;
$j = 0;
$returnString = "";
for($i = 0; $i < strlen($buffer); $i++) {
if(($i != 0) && ($i % 16 == 0)) {
$returnString = $returnString . "\t";
for($j = $i - 16; $j < $i; $j++) {
if(ord($buffer[$j]) < 0x20 || ord($buffer[$j]) > 0x7F)
$returnString = $returnString . '.';
else
$returnString = $returnString . $buffer[$j];
}
// Add a linefeed after the string
$returnString = $returnString . "\n";
}
$returnString = $returnString . bin2hex($buffer[$i]) . " ";
}
if($i != 0 && $i % 16 != 0) {
for($j = 0; $j < ((16 - ($i % 16)) * 3); $j++) {
$returnString = $returnString . " ";
}
}
$returnString = $returnString . "\t";
if($i > 0 && ($i % 16) == 0) {
$j = $i - 16;
}
else {
$j = ($i - ($i % 16));
}
for(; $i >= 0 && $j < $i; $j++) {
if(ord($buffer[$j]) < 0x20 || ord($buffer[$j]) > 0x7F) {
$returnString = $returnString . ".";
}
else {
$returnString = $returnString . $buffer[$j];
}
}
$returnString = $returnString . "\n";
$returnString = $returnString . "Length: " . strlen($buffer) . "\n";
return $returnString;
}

function Packet($type = 1) {
$this->pType = $type;
}

function Reset() {
$this->mode = NULL;
$this->RawData = "";
$this->Position = 0;
}

function SetData($data, $process = false) {
$log = fopen("log.txt", "a");
//echo $this->debugOutput($data) . "\n\n";
flush();
if(is_string($data)) {
$this->RawData = $data;
$this->mode = $this->PacketType["pIncoming"];
if($process) {
if($this->pType == $this->PacketFormat["pBnet"]) {
//printf("[BNET] -> [BOT]\n%s\n\n", $this->debugOutput($data));
fprintf($log, "[BNET] -> [BOT]\n%s\n\n", $this->debugOutput($data));
$this->GetBYTE();
$this->PacketID = $this->GetBYTE();
$this->packetLength = $this->GetWORD();
}
elseif(($this->pType == $this->PacketFormat["pBNLS"]) || ($this->PType == $this->PacketFormat["pMCP"])) {
//printf("[BNLS] -> [BOT]\n%s\n\n", $this->debugOutput($data));
fprintf($log, "[BNLS] -> [BOT]\n%s\n\n", $this->debugOutput($data));
$this->GetWORD();
$this->PacketID = $this->GetBYTE();
}
elseif($this->pType == $this->PacketFormat["pMatrix"]) {
$this->PacketID = $this->GetBYTE();
$this->GetBYTE();
}
}
}
$this->mode = $this->PacketType["pIncoming"];
fclose($log);
}

function getData() {
$tmp = $this->RawData;
$this->Reset();
return $tmp;
}

function Skip($bytes) {
if(is_float($bytes) || is_int($bytes)) {
$this->Position = $this->Position + $bytes;
}
}

function GetString() {
$NTPos = $strTemp = NULL;
$NTPos = strpos($this->RawData, "\x0", $this->Position);
if($NTPos === FALSE) {
if($this->RaiseOverflowErrors) {
trigger_error("Trying to read past end of packet.", E_WARNING);
}
return;
}
$strTemp = substr($this->RawData, $this->Position, $NTPos - $this->Position);
$this->Position = $NTPos+1;
return $strTemp;
}

function GetStringList() {
$strTemp = NULL;
$strTemp = explode("\x0", substr($this->RawData, $this->Position, strpos($this->RawData, "\x0\x0", $this->Position) - $this->Position));
return $strTemp;
}

function GetFixedString($length) {
$rVal = NULL;
if(is_int($length) || is_float($length)) {
if($this->LenData() - $this->Position + 1 >= $length) {
$rVal = substr($this->RawData, $this->Position, $length);
$this->Position = $this->Position + $length;
return $rVal;
}
else {
if($this->RaiseOverflowErrors) {
trigger_error("Trying to read past end of packet.", E_WARNING);
}
return;
}
}
}

function GetBoolean($bytes = 4) {
$rVal = NULL;
if($this->LenData() - $this->Position + 1 >= $bytes) {
$rVal = (int)intval(substr($this->RawData, $this->Position, $bytes));
$this->Position = $this->Position + $bytes;
}
else {
if($this->RaiseOverflowErrors) {
trigger_error("Trying to read past end of packet.", E_WARNING);
}
return;
}
if($rVal == 0) {
return false;
}
else {
return true;
}
}

function DWORD($data, $start = 0) {
$a = $b = $c = $d = NULL;
/*
$a = strrev(str_pad(dechex((substr($data, $start, 1))), 2, '0', STR_PAD_LEFT));
$b = strrev(str_pad(dechex((substr($data, $start + 1, 1))), 2, '0', STR_PAD_LEFT));
$c = strrev(str_pad(dechex((substr($data, $start + 2, 1))), 2, '0', STR_PAD_LEFT));
$d = strrev(str_pad(dechex((substr($data, $start + 3, 1))), 2, '0', STR_PAD_LEFT));
return hexdec(strrev($a . $b . $c . $d));
*/
$data = substr($data, $start, 4);
$a = (((int)$data & 0x000000FF) >> 0);
$b = (((int)$data & 0x0000FF00) >> 8);
$c = (((int)$data & 0x00FF0000) >> 16);
$d = (((int)$data & 0xFF000000) >> 24);
return chr($a) . chr($b) . chr($c) . chr($d);
/*$dcom = new COM("CopyMemoryCom.CopyMemory");
$ret = $dcom->makeDWORD(substr($data, $start, 4));
return $ret;
*/
}

function DWORD2($data, $start = 0) {
$a = $b = $c = $d = NULL;
$a = strrev(str_pad(dechex(ord(substr($data, $start, 1))), 2, '0', STR_PAD_LEFT));
$b = strrev(str_pad(dechex(ord(substr($data, $start + 1, 1))), 2, '0', STR_PAD_LEFT));
$c = strrev(str_pad(dechex(ord(substr($data, $start + 2, 1))), 2, '0', STR_PAD_LEFT));
$d = strrev(str_pad(dechex(ord(substr($data, $start + 3, 1))), 2, '0', STR_PAD_LEFT));
return hexdec(strrev($a . $b . $c . $d));
}

function GetDWORD() {
$rVal = NULL;
if($this->LenData() - $this->Position + 3 >= 4) {
$rVal = $this->DWORD2($this->RawData, $this->Position);
$this->Position = $this->Position + 4;
return $rVal;
}
else {
if($this->RaiseOverflowErrors) {
trigger_error("Trying to read past end of packet.", E_WARNING);
}
return;
}
}

/**
* Add an array of DWORD's to the packet buffer
*
* @param int $length
* @return array
*/
function GetDWORDArray($length) {
$oS = array();
$i = NULL;
if($length > 0 && (is_float($length) || is_int($length))) {
for($i = 0; $i <= $length - 1; $i++) {
$oS[$i] = $this->GetDWORD();
}
return $oS;
}
}

function WORD($data, $start = 0) {
$a = $b = NULL;
/*
$a = strrev(str_pad(dechex(ord(substr($data, $start, 1))), 2, '0', STR_PAD_LEFT));
$b = strrev(str_pad(dechex(ord(substr($data, $start + 1, 1))) , 2, '0', STR_PAD_LEFT));
return hexdec(strrev($a . $b));
*/
$len = 2;
if(strlen($data) == 3 && intval($data) > 99) {
$len = 3;
}
$data = substr($data, $start, $len);
$a = (((int)$data & 0x00FF) >> 0);
$b = (((int)$data & 0xFF00) >> 8);
return chr($a) . chr($b);
}

function WORD2($data, $start = 0) {
$a = $b = NULL;
$a = strrev(str_pad(dechex(ord(substr($data, $start, 1))), 2, '0', STR_PAD_LEFT));
$b = strrev(str_pad(dechex(ord(substr($data, $start + 1, 1))) , 2, '0', STR_PAD_LEFT));
return hexdec(strrev($a . $b));
}

function GetWORD() {
$rVal = $a = $b = NULL;
if($this->LenData() - $this->Position + 1 >= 4) {
$rVal = $this->WORD2($this->RawData, $this->Position);
$this->Position = $this->Position + 2;
return $rVal;
}
else {
if($this->RaiseOverflowErrors) {
trigger_error("Trying to read past end of packet.", E_WARNING);
}
return;
}
}

function GetWORDArray($length) {
$oS = array();
$i = NULL;
if($length > 0 && (is_float($length) || is_int($length))) {
for($i = 0; $i <= $length - 1; $i++) {
$oS[$i] = $this->GetWORD();
}
return $oS;
}
}

function GetBYTE() {
$return = NULL;
if($this->LenData() - $this->Position >= 1) {
//$return = (int)substr($this->RawData, $this->Position, 1);
$return = ord(substr($this->RawData, $this->Position, 1));
$this->Position = $this->Position + 1;
return $return;
}
else {
if($this->RaiseOverflowErrors) {
trigger_error("Trying to read past end of packet.", E_WARNING);
}
}
}

function GetStringArray($length) {
$oS = array();
$i = NULL;
if($length > 0 && (is_float($length) || is_int($length))) {
for($i = 0; $i <= $length - 1; $i++) {
$oS[$i] = GetString();
}
return $oS;
}
}

function LenData() {
return strlen($this->RawData);
}

function buildUDPHeader($header = array()) {
switch($header["class"]) {
case 0:
$this->RawData = $this->WORD($header["sent"]) . $this->WORD($header["recv"]) . "\x0" . $this->BYTE($header['packetid']) . $this->BYTE($header['playerid']) . $this->BYTE($header['resend']) . $this->RawData;
$this->RawData = $this->WORD(strlen($this->RawData) + 4) . $this->RawData;
$this->RawData = ($this->DWORD(0x00) . $this->UDPCheckSum($this->WORD(0x00) . $this->RawData) . $this->RawData);
break;

}
}

function Send(&$socket, $PacketID = NULL, $Format = 1, $host = "", $port = 6112) {
$log = fopen("log.txt", "a");
switch($Format) {
case $this->PacketFormat["pBnet"]:
//printf("[BOT] -> [BNET]\n%s\n\n", $this->debugOutput(chr(0xFF) . chr($PacketID) . $this->WORD(strlen($this->RawData) + 4) . $this->RawData));
fprintf($log, "[BOT] -> [BNET]\n%s\n\n", $this->debugOutput(chr(0xFF) . chr($PacketID) . $this->WORD(strlen($this->RawData) + 4) . $this->RawData));
$socket->sendData(chr(0xFF) . chr($PacketID) . $this->WORD(strlen($this->RawData) + 4) . $this->RawData);
break;
case $this->PacketFormat["pBNLS"]:
case $this->PacketFormat["pMCP"]:
//printf("[BOT] -> [BNLS]\n%s\n\n", $this->debugOutput($this->WORD(strlen($this->RawData) + 3) . chr($PacketID) . $this->RawData));
fprintf($log, "[BOT] -> [BNLS]\n%s\n\n", $this->debugOutput($this->WORD(strlen($this->RawData) + 3) . chr($PacketID) . $this->RawData));
$socket->sendData($this->WORD(strlen($this->RawData) + 3) . chr($PacketID) . $this->RawData);
break;
case $this->PacketFormat["pMatrix"]:
$socket->sendData($this->BYTE($PacketID) . chr(strlen($this->RawData) + 3) . $this->RawData);
break;
case $this->PacketFormat["pCLS"]:
printf("[BOT] -> [%s:%d]\n%s\n\n", $host, $port, $this->debugOutput($this->RawData));
fprintf($log, "[BOT] -> [%s:%d]\n%s\n\n", $host, $port, $this->debugOutput($this->RawData));
socket_sendto($socket, $this->RawData, strlen($this->RawData), 0, $host, $port);
break;
default:
fprintf($log, "[BOT] -> [BNET]\n%s\n\n", $this->debugOutput($this->RawData));
$socket->sendData($this->RawData);
}
$this->Reset();
}

function InsertString($Data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$this->RawData = $this->RawData . $Data . chr(0);
}

function InsertStringList($Data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$i = NULL;
if(is_array($Data)) {
for($i = 0; $i < count($Data); $i++) {
$this->RawData = $this->RawData . $Data[$i] . chr(0);
}
$this->RawData = $this->RawData . chr(0);
}
}

function InsertStringArray($Data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$i = NULL;
if(is_array($Data)) {
for($i = 0; $i < count($Data); $i++) {
$this->RawData = $this->RawData . $Data[$i] . chr(0);
}
}
}

function InsertNTString($Data) {
$this->InsertString($Data);
}

function InsertNonNTString($Data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$this->RawData = $this->RawData . $Data;
}

function InsertByte($Data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$this->RawData = $this->RawData . $this->BYTE($Data);
}

function InsertWORD($data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$this->RawData = $this->RawData . $this->WORD($data);
}

/**
* Add a DWORD to the packet buffer
*
* @param string $data
*/
function InsertDWORD($data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$this->RawData = $this->RawData . $this->DWORD($data);
}

/**
* Add an array of DWORD's to the packet buffer
*
* @param array $data
*/
function InsertDWORDArray($data) {
if($this->mode == $this->PacketType["pIncoming"]) {
return;
}
$this->mode = $this->PacketType["pOutgoing"];
$i = NULL;
if(is_array($data)) {
for($i = 0; $i < count($data); $i++) {
$this->RawData = $this->RawData . $this->DWORD($data[$i]);
}
}
}

function BYTE($data) {
//return (int)substr($data, 0, 1);
return chr($data);
}

/* function SubSum() {
$length = strlen($this->DWORD(0x00) . $this->RawData) - 2;
$tmpData = $this->DWORD(0x00) . $this->RawData;
$sum1 = $sum2 = 0;
for($iY = 0; $iY <= $length - 1; $iY++) {
printf("L %d\n", $sum2);
$i = $length - $iY;
$sum2 = $sum2 + ord(substr($tmpData, $i, 1));
if( $sum2 > 0xFF ) {
$sum2 = $sum2 - 0xFF;
}
$sum1 = $sum1 + $sum2;
}
return (($sum2 & 0xFF)<<8) | (($sum1 % 0xFF) & 0xFF);
}

function UDPChecksum() {
$subsum = $this->SubSum();
printf("subsum\n%s\n", $this->debugOutput($subsum));
$a = 0xFF - (($subsum AND 0xFF) + ($subsum >> 8)) % 0xFF;
$b = (int)(((0xFF - ($a + ($subsum << 8)) % 0xFF) AND 0xFF) OR ($a >> 8));
printf("%s\n\n", $this->debugOutput($b));
$ret = $this->WORD($b);
return $ret;
}
*/
function SubCheckSum($buff, $length) {
$sum1 = $sum2 = "";
$i = $iY = 0;
for($iY = 0; $iY <= $length; $iY++) {
$i = $length - $iY;
$sum2 = $sum2 + ord(substr($buff, $i, 1));
if($sum2 > 0xFF) {
$sum2 = $sum2 - 0xFF;
}
$sum1 = $sum1 + $sum2;
}
return ((($sum2 & 0xFF) << 8) | (($sum1 % 0xFF) & 0XFF));
}

function UDPCheckSum($buff) {
$tmpData = $buff;
$length = $this->WORD2(substr($tmpData, 2, 2)) - 2;
$subsum = $this->SubCheckSum(substr($tmpData, 2), $length);
$a = 0xFF - (($subsum & 0xFF) + ($subsum >> 8)) % 0XFF;
$b = ((((0xFF - ($a + ($subsum >> 8)) % 0xFF) & 0xFF) | ($a << 8)));
eval('$b = "\x' . substr(dechex($b), 2, 2) . '\x' . substr(dechex($b), 0, 2) . '";');
$ret = $b;
return $ret;
}

}
?>
[/code]




it's been modified a bit tho my packet buffer supports sc udp packets (BuildUDPHeader and UDPCheckSum) also



if anyone thinks they can improve upon my packet buffer feel free to

:P i release the packet buffer under the Creative Commons license
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

:P because i like open source and i like forcing people to share
September 27, 2007, 2:54 AM
Camel
[quote author=Leaky link=topic=17054.msg173284#msg173284 date=1190838688]
I could never figure pack out so i did it a different way...
[/quote]

Pack is pretty cryptic, but it's probably the best option.
September 27, 2007, 8:44 PM
Leaky
can pack make DWORD and WORD's? o.O if it can :P would you be so kind as to example?
September 27, 2007, 9:00 PM
idiat
I can't find the source code to my old PHP bot, but I have a PacketBuffer I wrote in Python which uses pack/unpack:

[code] def InsertWORD(self, txt):
self.Buffer = self.Buffer + struct.pack("<H", txt)

def InsertDWORD(self, txt):
self.Buffer = self.Buffer + struct.pack("<L", txt)[/code]

unpack to extract DWORDs, WORDs, bytes, etc:

[code]header = struct.unpack("<2cH", packet)[/code]

("packet" has the BNCS packet header only)
header[0] = 0xff
header[1] = ID
header[2] = packet length
September 28, 2007, 12:16 AM
Leaky
that looks alot simpler and prolly more reliable than my current method..

i'll prolly use pack when i make my bncs server in php
September 28, 2007, 12:22 AM
Yegg
idiat: You don't need the '<' in your first argument to pack().

Leaky: Perl's pack function does the same thing as Python's only the arguments are different (same method Ruby uses).

http://www.perl.com/doc/manual/html/pod/perlfunc/pack.html
http://us3.php.net/pack

Since PHP borrows from Perl, I decided to check a manual on both. Both pack functions are the same. Should be easy to figure out from there.
September 28, 2007, 2:03 AM
Leaky
why think you kind sir
September 28, 2007, 2:20 AM
Smarter
[quote author=idiat link=topic=17054.msg173301#msg173301 date=1190856043]
Isn't the Debug function inside the PBuffer class the "hex dumper" you guys are talking about?

Is there any reason fapiko doesn't use pack/unpack? The PacketBuffer seems incomplete.

I could fix this up a bit if fapiko's okay with that and if no one else has a "framework" which they feel would better suit Smarter's needs and if Smarter hasn't decided to do it on his own. I really don't feel like starting another PHP bot right now (I'm not even properly working on my Python bot), but I'm interested to see what others have come up with.
[/quote]

Fappys bot is open source just for that exact reason, you can do as you wish to it, if you do modify it, into a better working bot, could you be so kind as to provide me with a copy? :-D
October 2, 2007, 12:44 PM

Search