• Welcome to Valhalla Legends Archive.
 

Good place to start

Started by RyanIdium, December 07, 2003, 05:14 PM

Previous topic - Next topic

RyanIdium

Hello.  Im sure you get alot of these, but now you get another!
Im begining to see how some of these bots work (without cleanslatebot).  Im just wondering what a good way to send these packets to a server in Delphi.  I am currently using TClientSocket and its SendText function, adding what i need with chr($47) or whatnot.
Thanks in advance.

Arta

Have some free code (aren't I nice). gogo Delphi programmers!

This is a multipurpose packet buffer I wrote a long time ago. I have no idea what weird strange things might be in there. The GetPacket() function returns a string you can pass to SendText(). I'd suggest removing the things specific to botnet or MCP until you need them.


unit TPacketBufferUnit;

interface

uses windows, dialogs, sysutils;

type
 TPacketBuffer = class
   public
     procedure AddByte(Data: byte);
     procedure AddWord(Data: word);
     procedure AddDword(Data: int64);
     procedure AddString(Data: string; nullterm: boolean = true);
     procedure ClearBuffer;
     procedure Print;
     function GetPacket(ID: byte; magicbyte: byte=1): string;

     constructor create(usebotnet: boolean=false; bnProtocol: byte=0; inagame: boolean=false; Realm: boolean=false);
       
   private
     Buffer: string;
     protocol: byte;
     onbotnet, OnRealm, ingame: boolean;
 end;

implementation
uses MainUnit, TBotnetUnit;


constructor TPacketBuffer.create(usebotnet: boolean=false; bnProtocol: byte=0; inagame: boolean=false; Realm: boolean=false);
begin
 Buffer:='';
 protocol:=bnProtocol;
 onbotnet:=usebotnet;
 ingame:=inagame;
 OnRealm:=realm;
end;

procedure TPacketBuffer.Print;
var i: integer;
   bytestream: string;
begin
 bytestream:=#9;
 for i:=1 to length(buffer) do
 begin
   bytestream:=bytestream+inttohex(byte(buffer[i]), 2)+#32;
   if (i mod 16)=0 then bytestream:=bytestream+#13#10#9;
 end;

 main.Display(SENDER_BNET, 'Displaying Current Packet: '#13#10+bytestream, bnWhite);
end;

procedure TPacketBuffer.AddByte(Data: byte);
begin
 Buffer:=Buffer+char(Data);
end;

procedure TPacketBuffer.AddWord(Data: word);
var tmp: string[2];
begin
 tmp:=char( Data and $00FF ) + char((Data and $FF00) shr 8);
//  showmessage(inttohex(byte(tmp[1]), 2)+' '+inttohex(byte(tmp[2]), 2));
 Buffer:=Buffer+Tmp;
end;

procedure TPacketBuffer.AddDword(Data: int64);
var tmp: string[4];
begin
 tmp:=char( Data and $FF ) + char((Data and $FF00) shr 8) + char( (Data and $FF0000) shr 16) + char( (Data and $FF000000) shr 24);
 Buffer:=Buffer+Tmp;
end;

procedure TPacketBuffer.AddString(Data: string; nullterm: boolean = true);
begin
 Buffer:=Buffer+Data;
 if nullterm then Buffer:=Buffer+#0;
end;

procedure TPacketBuffer.ClearBuffer;
begin
 Buffer:='';
end;

function TPacketBuffer.GetPacket(ID: byte; magicbyte: byte=1): string;
var PacketLen: word;
   tmp: string[2];
begin

 if ingame then
 begin
   PacketLen:=length(Buffer)+2;
   tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);
   result:=tmp+Buffer
 end
 else if onbotnet then
 begin
   PacketLen:=length(Buffer)+4;
   tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);

   result:=char(magicbyte)+char(ID)+tmp+Buffer
 end
 else if OnRealm then
 begin
   PacketLen:=length(Buffer)+3;
   tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);
   result:=tmp+char(ID)+Buffer
 end
 else
 begin
   PacketLen:=length(Buffer)+4;
   tmp:=char( PacketLen and $FF ) + char((PacketLen and $FF00) shl 8);
   result:=#$FF+char(ID)+tmp+Buffer;
 end;

// BotNet.DisplayPacketStr(result);

 ClearBuffer;
end;

end.


You'll probably run into problems when you need functions such as HashData and CheckRevision. To my knowledge, no one has translated these to Delphi except me, and if they have, I'm fairly sure they haven't been publicly released. Assuming you're not a total beginner and that you know some C, it shouldn't be too hard to translate code that is available.

Arta

...and this is a receive buffer. When you get data on your socket, call AddData. CheckPacket returns true when a complete packet is available. GetPacket can be used to remove it from the buffer for processing. Again, this is multipurpose - you might want to remove the non-BNCS stuff.


unit TRecieveBufferUnit;

interface

uses SysUtils, Dialogs, MiscFuncs;

type



 TRecieveBuffer = class
   public
     Buffer, RealmBuffer: string;
     
     procedure AddData(Data: string);
     function CheckBuffer: boolean;
     function GetPacket: Packet;

     procedure AddRealmData(Data: string);
     function CheckRealmBuffer: boolean;
     function GetRealmPacket: Packet;
     
     constructor create(useProtocol: byte);


   private

     protocol: byte;

 end;

implementation

constructor TRecieveBuffer.create(useProtocol: byte);
begin
 Buffer:='';
 RealmBuffer:='';
 protocol:=useProtocol;
end;

procedure TRecieveBuffer.AddData(Data: string);
begin
 Buffer:=Buffer+Data;
end;

function TRecieveBuffer.CheckBuffer: boolean;
var PacketLen: word;
begin
 Result:=false;
 if (length(Buffer)>0) and (Buffer[1]=char(protocol)) then
 begin
   PacketLen:=byte(Buffer[3])+( (byte(Buffer[4]) and $FF00) shl 8);
   if length(Buffer) >= PacketLen then result:=true;
 end;
end;
   
function TRecieveBuffer.GetPacket: Packet;
begin
 if Buffer[1]=char(protocol) then
 begin
   result.header:=copy(Buffer, 1, 4);
   result.ID:=byte(Buffer[2]);
   result.Length:=(byte(Buffer[4]) shl 8) + byte(Buffer[3]);
   result.data:=copy(Buffer, 5, result.length-4);

   Delete(Buffer, 1, result.length);
 end
 else
   result.ID:=-1;
end;

function TRecieveBuffer.CheckRealmBuffer: boolean;
var PacketLen: word;
begin
 Result:=false;
 if (length(RealmBuffer)>0) then
 begin
   PacketLen:=byte(RealmBuffer[2])+( (byte(RealmBuffer[3]) and $FF00) shl 8);
   if length(RealmBuffer) >= PacketLen then result:=true;
 end;
end;

procedure TRecieveBuffer.AddRealmData(Data: string);
begin
 RealmBuffer:=RealmBuffer+Data;
end;

function TRecieveBuffer.GetRealmPacket: Packet;
begin
 result.header:=copy(RealmBuffer, 1, 3);
 result.ID:=byte(RealmBuffer[3]);
 result.Length:=(byte(RealmBuffer[2]) shl 8) + byte(RealmBuffer[1]);

 if result.length>length(RealmBuffer) then
 begin
   result.id:=-1;
   Delete(RealmBuffer, 1, Result.Length);
   exit;
 end;
 
 result.data:=copy(RealmBuffer, 4, result.length-3);

 Delete(RealmBuffer, 1, result.length);
end;

end.

CrAzY

CrAzY

Banana fanna fo fanna

#4
QuoteJust trying to get a rise out of you.

Maybe because it's fucking delphi, douchbag.

RyanIdium

Thanks! i wont rip you off (and just take it), but ill look at it a bit and figure out what your getting at.

Arta


RyanIdium

There is one thing i have a question about though.  It has to deal with the addition of a DWord.  Now i think i know what it is (an un-allocated(sp?) integer), but im kindof confused on the rest of the code.


procedure TPacketBuffer.AddDWord(data : int64);
var tmp: string[4];
begin
 tmp:=char( Data and $FF ) + char((Data and $FF00) shr 8) + char( (Data and $FF0000) shr 16) + char( (Data and $FF000000) shr 24);
 Buffer:=Buffer+Tmp;
end;

now lets see here..

tmp = stores the string version of DWord.
char() = converts hex to ascii
and $FF = your using $FF with data (can you use + also?)
shr = shift hex right, not clear on why its needed though :-/
buffer = cant be the buffer! :P

Arta

#8
The shifting and anding converts it to the correct byte ordering.
char() takes a number and returns the ascii equivalent.
I had to make data an int64 to avoid some annoying error (lazy fix)

I'm not sure what your question is! You said you didn't understand and then explained it :P

RyanIdium

Quote from: Arta[vL] on December 09, 2003, 09:42 PM
The shifting and anding converts it to the correct byte ordering.
char() takes a number and returns the ascii equivalent.
I had to make data an int64 to avoid some annoying error (lazy fix)

I'm not sure what your question is! You said you didn't understand and then explained it :P
what i thought i did was tell (or try to) what i 'think' i know.  guess i should have said that :P

thanks again! (hopefully i wont have to ask anymore questions)