Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Eclipse: Origins (With a new packet handler!)


emblem
 Share

Recommended Posts

After like, 12 hours work I figured out a way to basically emulate function pointers in VB6.

Which I then used to implement a packet handling class, which is a lot cleaner (as far as the actual packet handing) than using CallWindowProc.

You're free to modify / redistribute this as you feel fit.

I'll write a tutorial on how to convert existing EO's over to this system tommorow, as I have to leave in 15 minutes.

If you're curious, the main changes are the new class called **clsPacketHandler**, and changes to **InitMessages** in **modHandleData** and **every** HandleData packet sub's definition.

**Update:** When running the Client or Server from the VB6 IDE. Make SURE to always run the application with a full compilation.

You can do this by either [hitting Ctrl-F5, selecting "Start With Full Compile" from the menu](http://i.tylian.net/CxbmFa.png) or [unchecking "Compile on Demand" in the options.](http://i.tylian.net/K8D4vV.png)
Link to comment
Share on other sites

If this was the thing he told me about, he actually use assembly to handle the packets.
Either way, I would love to see this when I get home.

EDIT: I took a look and…mind blown. Now theoretically, this would be faster, right? And I see the CallHandler are assembly code but written in comments. I don't understand this completely yet so if you have time to explain a bit more, I would really appreciate it. I've also finished reading the article you gave me.

Sincerely,
Rithy
Link to comment
Share on other sites

@Scrooge:

> Interesting. Apart from the code being a bit cleaner is there any real improvement in performance?

Technically, it should give a boost in performance because the actual packet handling jump is pure assembly (meaning no array checks, no visual basic overhead, no overhead from function prelogue/epilogue, etc), the only other faster way of doing an array lookup like it currently is would be to somehow make a stub for every single packet, which I can't even imagine how I'd manage. xD

So yeah, there should be a performance boost. Not sure how much but knowing me probably not much.

@Rithy58:

> If this was the thing he told me about, he actually use assembly to handle the packets.
> Either way, I would love to see this when I get home.
>
> EDIT: I took a look and…mind blown. Now theoretically, this would be faster, right? And I see the CallHandler are assembly code but written in comments. I don't understand this completely yet so if you have time to explain a bit more, I would really appreciate it. I've also finished reading the article you gave me.
>
> Sincerely,
> Rithy

The actual assembly is in the Constant string at the top of the Class, I assembled it using ollydbg(lol).
The comments are just there so I remember what the assembly for that routine is. XD
Link to comment
Share on other sites

@Tylian!:

> The actual assembly is in the Constant string at the top of the Class, I assembled it using ollydbg(lol).
> The comments are just there so I remember what the assembly for that routine is. XD

Private Const CallStub As String = "58595950493E8B0C8D00000000FFE1"
That's the only likely line I found and if that's it, I'm completely lost lol.

Sincerely,
Rithy
Link to comment
Share on other sites

@Rithy58:

> Private Const CallStub As String = "58595950493E8B0C8D00000000FFE1"
> That's the only likely line I found and if that's it, I'm completely lost lol.
>
> Sincerely,
> Rithy

Yeah that's it. In case you didn't know, there's a direct relationship between bytes in memory (which are usually represented with hex) and assembly.

![](http://i.tylian.net/vmz21c.png)
Link to comment
Share on other sites

@Tylian!:

> Yeah that's it. In case you didn't know, there's a direct relationship between bytes in memory (which are usually represented with hex) and assembly.
>
> ![](http://i.tylian.net/vmz21c.png)

Oh, shoot. I didn't know that. Well then that's great that you included the instruction in the comments. My assembly knowledge is way too limited to understand it lol. This is great though, you make me want to get further knowledge with assembly.

Sincerely,
Rithy
Link to comment
Share on other sites

Honestly, it's neat to know about if you're either an optimization whore or just like knowing these kind of things
(I'm both!)

But now-a-days where we have higer level languages like C# and C++, most of the stuff is handled for you, and the only time you'll really need it is if you're detouring functions or making super-optimized code.

And lol. Assembly is not hard at all, it's fairly easy.
The problem with assembly is that it's at such a low level that, it's extremely hard to visualize how one bit of code affects the entire program since it all looks similar.
Link to comment
Share on other sites

Added a little notice to the first page that I forgot to mention.
Make sure to read it, this is important!

>! For all those people wondering why I say this. It's because, if you don't do a full compile when running the application the memory is not reset so the VFT "hook" isn't cleared from memory which could (and probably will) cause errors.
Link to comment
Share on other sites

Depends if it works fully. I've tested this and it works for me but, nothing beats public testing when it comes to breaking stuff.

Other than the packet handler, this is a fresh download of EO 2.0.
I literally downloaded EO, added my system to it, checked if it worked, deleted my account then posted this. :P

Why do you ask?
Link to comment
Share on other sites

@[THE-KRIS:

> link=topic=77283.msg827986#msg827986 date=1325340741]
> surely this will only speed up the compilation process or running through vb6\. once it's compiled it's just a bunch of binary either way you look at it…

The binary is the same, but from how I understand it the packet handlers are written in assembly, and so it receives and sends packets faster.

Someone please correct me if I'm wrong.
Link to comment
Share on other sites

@Eckhart:

> The binary is the same, but from how I understand it the packet handlers are written in assembly, and so it receives and sends packets faster.
>
> Someone please correct me if I'm wrong.

That is correct.

Visual Basic 6 does indeed compile your client code into native code, but when it does this it adds a bunch of error checking and function prologue's / epilogue's which is really a bunch of extra code you don't really need in this specific case.

The assembly I wrote is small and fast, and should speed up the packet sending.
Link to comment
Share on other sites

This is a great work-around.

Next, we need another way to emulate _Do Events_ without all the overhead it produces. C/C++/C# give a demonstration of this when using the SlimDX graphics library. Doing this would make the client/server process much smoother, if I'm not mistaken.
Link to comment
Share on other sites

@Scootaloo:

> ![](http://i.tylian.net/vmz21c.png)

On the left is the **x86 machine code**, on the right the **x86 Assembly language using Intel syntax**.

@Scootaloo:

> But now-a-days where we have higer level languages like C# and C++, most of the stuff is handled for you, and the only time you'll really need it is if you're detouring functions or making super-optimized code.

Bitwise rotations (used in encryption, not to mention that Intel has introduced instructions to perform AES encryption), all arithmetic instructions (used to implement BigInteger et al.), all bitwise instructions [including BSF, BSR, BT, BTC, BTR and BTS since the 80386] (used to implement bit sets containing n bits, instead of a mere 32 or 64), SIMD [3DNow!, MMX, SSE, AVX et al. [x86]; Altivec [POWER]; ARM Neon [ARM]; etc.] (used to implement vector- and matrix-optimisations), timestamp counter [RDTSC, RDTSCP, etc.] (code profiling), byte order swaps [XCHG, BSWAP [x86]; RLWIMI [POWER]; etc.], and so further are all important reasons to use machine code or Assembly as neither the language and the compiler of any of those languages will support it (properly).

@Scootaloo:

> - snip -

Nevertheless, it's a neat way of abusing machine code to get things that get called frequently optimised.

@Scrooge:

> Or just use threads.

If VB6 just had proper support for those.

Yours faithfully,
  Stephan.
Link to comment
Share on other sites

@S.J.R.:

> On the left is the **x86 machine code**, on the right the **x86 Assembly language using Intel syntax**.
> Bitwise rotations (used in encryption, not to mention that Intel has introduced instructions to perform AES encryption), all arithmetic instructions (used to implement BigInteger et al.), all bitwise instructions [including BSF, BSR, BT, BTC, BTR and BTS since the 80386] (used to implement bit sets containing n bits, instead of a mere 32 or 64), SIMD [3DNow!, MMX, SSE, AVX et al. [x86]; Altivec [POWER]; ARM Neon [ARM]; etc.] (used to implement vector- and matrix-optimisations), timestamp counter [RDTSC, RDTSCP, etc.] (code profiling), byte order swaps [XCHG, BSWAP [x86]; RLWIMI [POWER]; etc.], and so further are all important reasons to use machine code or Assembly as neither the language and the compiler of any of those languages will support it (properly).

![](http://i2.photobucket.com/albums/y23/Alexanderthegreat91/woah.png)
Link to comment
Share on other sites

@S.J.R.:

> Bitwise rotations (used in encryption, not to mention that Intel has introduced instructions to perform AES encryption), all arithmetic instructions (used to implement BigInteger et al.), all bitwise instructions [including BSF, BSR, BT, BTC, BTR and BTS since the 80386] (used to implement bit sets containing n bits, instead of a mere 32 or 64), SIMD [3DNow!, MMX, SSE, AVX et al. [x86]; Altivec [POWER]; ARM Neon [ARM]; etc.] (used to implement vector- and matrix-optimisations), timestamp counter [RDTSC, RDTSCP, etc.] (code profiling), byte order swaps [XCHG, BSWAP [x86]; RLWIMI [POWER]; etc.], and so further are all important reasons to use machine code or Assembly as neither the language and the compiler of any of those languages will support it (properly).

Haha, you totally have a point here. I guess I should add a third clause to that:
You only really need asm for detouring, code optimization, and when you can create an assembly listing that handles a specific task better than the compiler can.

Although through recent experiences, the compilers now-a-days seem to handle code optimization pretty well.
… Except they seem to swap registry values a lot more than they should.

Ignore my terminology, I learnt from less than creditable sources.
@S.J.R.:

> Nevertheless, it's a neat way of abusing machine code to get things that get called frequently optimised.

Yeah. It was really fun to learn how to do this. :P

@S.J.R.:

> If VB6 just had proper support for those.

I wonder how horribly VB6 would explode if you tried to call CreateThread from a C DLL with the thread start pointing to a function in the VB6 application. Haha.

Must.. resist.. trying.
Link to comment
Share on other sites

@Scootaloo:

> I wonder how horribly VB6 would explode if you tried to call CreateThread from a C DLL with the thread start pointing to a function in the VB6 application. Haha.

I guess it will work, but that you will simply lack debugging utilities that do work properly. CreateThread will simply call a function that uses the stdcall calling convention, and not the cdecl calling convention (so if VB6 simply uses the stdcall calling convention as well, there are no issues with using CreateThread). The actual issues you will have are the fact that events can only be handled in the main thread, and that "DoEvents" is a call that is way too abstract (so it's worth an attempt to get WaitMessage, and in case of Eclipse, PeekMessage to work).

The question should actually not be whether it should work or not, but rather if it is worth doing it in VB6, as it is supposed to be used in C/C++ like that (without all the issues of accessing the bloody functions).

Yours faithfully,
  Stephan.
Link to comment
Share on other sites

Forgot about calling conventions.

Pretty sure Visual Basic invents it's own calling convention, where it pushes a pointer to a variable to store the return value in on to the stack before the parameters ..

So it would explode pretty badly. xD
Link to comment
Share on other sites

  • 1 month later...
So basically, add you **clsBuffer.cls** and **clsPacketHandler.cls**

Remove the whole **GetAddress Function** from **modHandleData**

Add
**Set PacketHandler = New clsPacketHandler
    PacketHandler.Initialize ServerPackets.SMSG_COUNT**

Before
**HandleDataSub(SAlertMsg) = GetAddress(AddressOf HandleAlertMsg)**

Change all InitMessages lines from
**HandleDataSub(SAlertMsg) = GetAddress(AddressOf HandleAlertMsg)**

To look like
**PacketHandler.AddHandler SAlertMsg, AddressOf HandleAlertMsg**

Change all
**(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)**

To
**ByRef Data() As Byte**
–---------------------------------------------------------

And everything else is the same? (Obviously doing this for server source also)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...