Valhalla Legends Forums Archive | Battle.net Bot Development | I made my first class today

AuthorMessageTime
bethra
I made my first class today!

I decided to make a class that kind of did the opposite of DarkMinion's PacketBuffer class which creates a buffer and sends it.

I made a class to help me take/extract parts (BYTE, DWORD, WORD etc.) out of a packet.

I didn't quite know what to call it, but I figured that since DarkMinion's packet buffer class is name "PacketBuffer". I named my class "PacketDebuffer". Sounds stupid and stuff but that is what I called it.

Here it is:
[code]
'===============================
'PacketDebuffer Class
'By Bethra, aka. Sorc.Polgara =)
'===============================

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal numBytes As Long)

Private Debuffer As String '// Debuffering string

'Sets the Debuffer string
Public Function DebuffPacket(PacketData As String)
Debuffer = PacketData
End Function

'Resets/clears the Debuffer
Public Function Clear()
Debuffer = vbNullString
End Function

'=======================================================
'Public Functions that debuffer a part from the Debuffer
'=======================================================

'Debuffers a DWORD from the Debuffer
Public Function DebuffDWORD()
Dim DWORD As String * 4
DWORD = GetDWORD
RemoveDWORD
DebuffDWORD = DWORD
End Function

'Debuffers a WORD from the Debuffer
Public Function DebuffWORD()
Dim WORD As String * 2
WORD = GetWORD
RemoveWORD
DebuffWORD = WORD
End Function

'Debuffers a BYTE from the Debuffer
Public Function DebuffBYTE()
Dim PBYTE As String
PBYTE = GetBYTE
RemoveBYTE
DebuffBYTE = PBYTE
End Function

'Debuffers a FILETIME from the Debuffer
Public Function DebuffFILETIME()
Dim FILETIME As String * 8
FILETIME = GetFILETIME
RemoveFILETIME
DebuffFILETIME = FILETIME
End Function

'Debuffers a null-terminating string from the Debuffer
Public Function DebuffNTString()
Dim NTString As String
NTString = GetNTString
RemoveNTString
DebuffNTString = NTString
End Function

'=====================================================
'Public Functions that remove a part from the Debuffer
'=====================================================

'Removes a BYTE from the Debuffer
Public Function RemoveBYTE()
Debuffer = Mid(Debuffer, 2)
End Function

'Removes a WORD from the Debuffer
Public Function RemoveWORD()
Debuffer = Mid(Debuffer, 3)
End Function

'Removes a DWORD from the Debuffer
Public Function RemoveDWORD()
Debuffer = Mid(Debuffer, 5)
End Function

'Removes a FILETIME structure from the Debuffer
Public Function RemoveFILETIME()
Debuffer = Mid(Debuffer, 9)
End Function

'Removes a null-terminating string from the Debuffer
Public Function RemoveNTString()
Dim Pos As Integer
Pos = InStr(1, Debuffer, Chr(0), vbBinaryCompare)
Debuffer = Mid(Debuffer, Pos + 1)
End Function

'=======================================================
'Functions that get parts from the front of the Debuffer
'=======================================================

'Gets a BYTE from the Debuffer
Function GetBYTE() As String
Dim PBYTE As String
PBYTE = Mid(Debuffer, 1, 1)
GetBYTE = PBYTE
End Function

'Gets a WORD from the Debuffer
Function GetWORD() As String
Dim WORD As String * 2
CopyMemory WORD, Debuffer, 2
GetWORD = WORD
End Function

'Gets a DWORD from the Debuffer
Function GetDWORD() As String
Dim DWORD As String * 4
CopyMemory DWORD, Debuffer, 4
GetDWORD = DWORD
End Function

'Gets a FILETIME from the Debuffer
Function GetFILETIME() As String
Dim FILETIME As String * 8
CopyMemory FILETIME, Debuffer, 8
GetFILETIME = FILETIME
End Function

'Gets a null-terminating string from the Debuffer
Function GetNTString() As String
Dim NTString As String
Dim Pos As Integer
Pos = InStr(1, Debuffer, Chr(0), vbBinaryCompare)
NTString = Mid(Debuffer, 1, Pos)
GetNTString = NTString
End Function


'=====================Credits============================
'DarkMinion for using his PacketBuffer class as a guide,
'this is the first class I have ever made =)
'-----------------
'Bot Developement Forum members who helped me understand
'some stuff that I need to know inorder to make this =)
'=======================================================
[/code]

Here is an example of usage:
[code]
Dim PArray(0 To 6) As String
Dim PDebuf As PacketDebuffer
Set PDebuf = New PacketDebuffer

With PDebuf
.DebuffPacket sIn
PArray(0) = .DebuffDWORD
PArray(1) = .DebuffDWORD
PArray(2) = .DebuffDWORD
PArray(3) = .DebuffDWORD
PArray(4) = .DebuffFILETIME
PArray(5) = .DebuffNTString
PArray(6) = .DebuffNTString
End With

For i = 0 To 6
lstDebug2.AddItem DebugOutput(PArray(i))
Next
[/code]
This takes SID_AUTH_INFO packet that is returned by the server and stores the parts in an array.

I like to use comments so I put alot of comments in my code.
I also put some information about it in the class module itself.

I wanted to post this and try to see if I can get some constructive critism and/or advice on my class. Since it is my first class it is probably very n00bish so please no flames or bashing =\. Thanks
August 19, 2004, 12:39 AM
UserLoser.
[quote]
Gets a non-terminating string from the Debuffer
[/quote]

The term NTString has been accepted as Null-terminated string, atleast, for many others and I. The FILETIME struct isn't a string either, should make it appropriately copy the right values into the struct :)
August 19, 2004, 12:41 AM
Myndfyr
Outstanding! Great for you, insert-non-gender-specific-pronoun-as-pointed-out-to-me-by-Zakath!

For those of you who find yourself having trouble frequently, or come here for help all the time, this is something that you can learn from.

Now, Chr0nic is doing pretty well nowadays, but I'm still going to use him as an example.

A while back, he was having trouble parsing the packet that has your binary friends list. I was trying to talk him through it, but I wasn't very sure of myself with respect to Visual Basic (I'm still not really), and I really couldn't relate, because I had set up a similar class in C# to the one that this guy had made. It acted like a stream, automatically advancing when I'd read data.

This class should *REALLY REALLY* help you guys who are constantly fiddling with bizarre Mid$() functions and variables. I would recommend testing it, and then posting it on BotDev Reference.
August 19, 2004, 1:31 AM
bethra
[quote author=UserLoser. link=board=17;threadid=8234;start=0#msg76218 date=1092876117]
[quote]
Gets a non-terminating string from the Debuffer
[/quote]

The term NTString has been accepted as Null-terminated string, atleast, for many others and I. The FILETIME struct isn't a string either, should make it appropriately copy the right values into the struct :)
[/quote]

Heh, yeah that is what I meant by "non-terminating". Just mispelled it :D

Yeah, ok, changing the FILETIME thing should be easy enough. Fix it tomarrow, sleepy
August 19, 2004, 1:58 AM
Zakath
[quote author=MyndFyre link=board=17;threadid=8234;start=0#msg76226 date=1092879112]
Outstanding! Great for you, man!
[/quote]

Polgara is a girl's name (comes from the same source as my own). So, unless it's a guy using it for some wierd reason, saying "man" is probably not quite right. :P
August 19, 2004, 4:25 AM
bethra
@Zakath
I'm a male w/ a female SC...umm I'm straight. Yeah Eddings series is the first fantasy series I've read (other than LotR).


Concerning the microsoft FILETIME Structure, its total size is 8-bytes (64-bits). The structure, dwLowDateTime and dwHighDateTime each are 4-bytes (DWORD). here is the MSDN description link

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/filetime_str.asp

Now what I basically have in my code is just extracting a 8-byte string, meaning it takes both DWORDs out as one.

What do you suggest that I do instead?

I mean, it takes out the whole FILETIME DWORD[2]. Shouldn't that be enough?

Or when I extract the FILETIME, should I take each individual DWORD separately?

I haven't really looked into this yet, but what would the best way extracting this FILETIME structure? Using the TYPE keyword?
August 19, 2004, 1:43 PM
Arta
I'd use copymemory for them all. Treating everything as strings is yucky... Then again, I'm not sure if VB makes that any nicer :)
August 19, 2004, 2:36 PM
Zakath
Yes, VB is just icky for that sort of thing. In C++ all you have to do is offset a pointer and use a typecast. :)
August 19, 2004, 11:27 PM
Eli_1
[quote author=Zakath link=board=17;threadid=8234;start=0#msg76329 date=1092958028]
In C++ all you have to do is offset a pointer . . .
[/quote]

Can you show me an example of how you would do that?

00 00 00 00 01 01 01 01 02 02 02 02

The only way I know how to parse the values from this would be with strncpy() and pointer arithmetic.


August 20, 2004, 12:36 AM
Kp
[quote author=Eli_1 link=board=17;threadid=8234;start=0#msg76345 date=1092962198]Can you show me an example of how you would do that?
00 00 00 00 01 01 01 01 02 02 02 02
The only way I know how to parse the values from this would be with strncpy() and pointer arithmetic.[/quote]

Do what, exactly? Your question isn't clear, and there's not enough quoted material to indicate what you want either.
August 20, 2004, 4:48 AM
K
[quote author=Eli_1 link=board=17;threadid=8234;start=0#msg76345 date=1092962198]
[quote author=Zakath link=board=17;threadid=8234;start=0#msg76329 date=1092958028]
In C++ all you have to do is offset a pointer . . .
[/quote]

Can you show me an example of how you would do that?

00 00 00 00 01 01 01 01 02 02 02 02

The only way I know how to parse the values from this would be with strncpy() and pointer arithmetic.
[/quote]

[code]
class Packet
{
protected:
   BYTE* _buffer;
   BYTE* _cur;
public:
   Packet()
   {
      // initialize _buffer,
      // _cur points to _buffer
   }
   // where
   // _cur is a byte pointer to the current location we want to read from
   // note that this clever templated code will not work for
   // types like strings, etc.
   template <typename _T> _T Read()
   {
      // interpret the byte* to the current location
      // as a pointer to a _T type
      _T* val = reinterpret_cast<_T*>(_cur);
      // increment the _cur pointer by the size of a _T in bytes
      _cur += sizeof(_T);
      // dereference and return val
      return *val;
   }
};

// .... you need to put data into _buffer (12 bytes, at least)
Packet p;
int i = p.Read<int>();
cout << hex << i << endl;
__int64 i64 = p.Read<__int64>();
cout << hex << i64 << endl;
[/code]
August 20, 2004, 4:39 PM
tA-Kane
Long ago (close to a year and a half ago), I made a BinaryBuffer class for REALbasic. It's got both reading and writing functions. It's cool.

I made it after I wrote most of my packet parser, so I never really gave it much use except in file usage.

I should redo my sockets to use it though. It would be a lot cleaner, codewise.

I wish REALbasic could directly typecast one object into another without creating stupid "IllegalCast" exceptions. I know what the fuck I'm doing. The objects have essentially the same data. Damnit. So C rocks in that way.

But if REALbasic could directly typecast, I'd typecast the data into a BnetPacket object, then if it turns out to be an event, typecast that data (minus the packet header) into a BnetEvent object. It would be so much easier than having to create a new object three or even four times, and copying the data just as many times.

Really lame.

In my spare time, I'll be moving code to C. It'll be a lot better.

What about VB? Can VB typecast?

...
Back to my origional thoughts: why create a separate class? Just modify DM's PacketBuffer to have reading functions as well as writing functions. Then you could write a string and read as a DWORD, or vice versa. ;)
August 21, 2004, 2:34 AM
shadypalm88
[quote author=tA-Kane link=board=17;threadid=8234;start=0#msg76481 date=1093055651]What about VB? Can VB typecast?[/quote]I don't think so. You can use the RtlMoveMemory to copy memory from a var of one type to one of a different type, but there's no direct corollary.
August 21, 2004, 2:51 AM

Search