Showing posts with label AS3. Show all posts
Showing posts with label AS3. Show all posts

Sunday, April 6, 2014

Things and Stuff

What on earth have I been doing for the last 6 months?
That's a pretty damn decent question.

Here's a rough overview:
  - I wrote an AS3-based SWF/AVM2 dis/reassembler that's blazingly fast.
  - I used that reassembler to make a fixed loader and a thing that makes all variables public, and it runs a lot faster and is more stable than the one or two public open source ones.
  - I wrote some fancy new SWF encryption/obfuscation technologies. They're not quite finished. But I found out how to beat all current decrypters, including memory dumpers for the foreseeable future ;)
  - I discovered a new, not-yet-documented hacking method for injecting code into SWFs, think class overriding but without inheritance problems
  - I wrote a magical, fully working program that once installed could potentially allow users access hacks for any flash game in-place on any site with the press of a single button. Need testers/hackers.
  - At some point I wrote an aimbot for an AS3 game using a mixture of bytecode modification, Loader-based variable modification and class overriding. Just thought I'd put it out there for the record. It can definitely be done, and with some of these new techniques I've found, it's not actually that difficult to make hacks with that kind of complexity.

Now, I really want to share these new, beautiful things around, but they're not quite ready for public release. I need some people to do some private testing.

So, if anyone is interested in learning some new things, seeing some awesome stuff and helping a brother out, flick me a message or your email/msn/skype/aim or something.

There's a lot of really awesome, mind-blowing flash hacking tools I want to create. I've been working on what I believe is the ultimate flash hacking platform. It's more awesome then you could possibly know, but I can't really put much more time into it unless I start getting support from people.

Thursday, August 29, 2013

Basic SWF Bytecode modification (AVM2/AS3) tutorial

I decided I would write up a basic SWF modification tutorial, and explain the basics of SWF modification, AoBs, ect.
I'm gonna go into some serious detail in this tutorial, so be prepared.

Before you start doing any extreme SWF hacks, you're gonna need a pretty good understanding of how SWFs work. Luckily, there are a lot of tools out there nowadays that allow you to take apart a SWF and see it's juicy innards.

There are some things you will need to know

A SWF file always starts with a SWF header, containing compression information, SWF filesize, frame count, frame rate and stage size.
You don't need to know too much about the SWF header, but it is useful to note that all uncompressed SWF files start with "FWS" and all compressed SWF files start with "CWS".
Another thing to note is if the file size in the SWF header is wrong the SWF will most likely not load.
This limitation stops you from being able to increase a SWFs size in memory after it is loaded (however, even if it didn't, forcibly increasing a SWFs size in memory could create a whole lot of problems).
It also means if you increase or decrease the SWFs size when hex editing and don't update the SWF size in the SWF header, the SWF will almost certainly not load.

A SWF is made up of many AVM2 tags. Tags can contain many different things, such as images, shapes, data, actionscript bytecode. If you want to have a look at the tags in a SWF, the tool SWFWire Inspector will disassemble AVM2 tags. Most of the time however, the only tags you will need to care about are the ABC (Actionscript Bytecode) tags.

An ABC tag contains AVM2 ABC bytecode  (sometimes just referred to as AVM2 bytecode or ABC bytecode) which contains class definitions, methods, variables, basically all the compiled code.
There can be more than one ABC tag in a SWF. This generally happens if a SWF uses a code library. The code library is often held in a separate ABC tag from the SWFs main code.

ABC code is stack based. You should be familiar with how stacks work in programming. It's nothing particularly difficult. There's a stack. and ABC instructions access it. That's about all there is to it.

Now to the actual tutorial part.


Part 1: Reverse engineering

I'm going to cover SWF bytecode modification using an AVM2 ABC disassembler, hex editor and decompiler. There are other "better" ways of modifying SWFs, but learning how to hex-edit SWFs is pretty much SWF hacking 101. Everything else follows on from it. Thus, even though there are better ways of doing this, it is an extremely good idea to learn this method before learning the others.

In this tutorial, we'll do a score hack. There's many different ways we could do this. we could increase the score gained from picking up a money item, we could increase the starting score, we could teleport the money object to the player or any number of other ways.

I'll try and cover several different approaches to several different types of score hacks. There are many correct ways of approaching this problem.

For those of you who don't know, unhackable is the name of a simple game engine I use for tutorials, examples and proof-of-concepts. The name "unhackable" comes from the fact I originally made it to test AS2/3 anti-hack code. It's basically the simplest game you could make. I've written about 5 different versions of the unhackable engine, this tutorial will be for the unprotected OOP version of unhackable, which you can find here.

Open up the unhackable SWF in FFDec or another similar decompiler.

We'll start with a little reverse-engineering. SWF reverse engineering almost deserves a tutorial of it's own, but it's the kind of thing that you can only really get good at with practice.
This example SWF isn't very complicated, so there's nothing too deep here. For starters, take a look at the names of the classes:


Obvious classes of interest include Money, Player and ScoreKeeper. The document class is also usually useful (Found by going tools -> go to document class). In this case, the document class is named Unhackable.

So, for starters, take a look at Unhackable.


It's good to note that the player, money and score variables are private. This isn't so important for bytecode modification, but if you were to hack it via loader or overrider, it would be relevant.
Most of this code is useless to us.
Lines of interest for us include:

From the Unhackable constructor:
      this.player=new Player(int(Math.random()*300)+50,int(Math.random()*200)+50);  
      this.money=new Money(int(Math.random()*300)+50,int(Math.random()*200)+50);  

From the gameLoop function:
      this.money.dealWithPlayer(this.player.playerX,this.player.playerY);  

If you take a peek into the Player and Money classes, you'll see they pass their constructor arguments on to their super class Thing, which uses  them to set their position, so in actual fact these lines just create a new Player and Money object with random position. The only thing you could accomplish by changing these two lines is changing the player and money starting position, so it  turns out these two lines are not so helpful.

I'll get to the money.dealWithPlayer line in a minute.
So, for the moment let's move on to the Money class

.

Now, we get to some interesting stuff. But first, it's good to notice Money has a super class Thing. It's usually worth taking a quick look in the super classes as there's usually useful stuff in them. This tutorial is getting pretty long, so I'll skip the Thing class. There's nothing particularly important that isn't self-explanatory in there anyway, but you should definitely take a look at it. I'm not going to cover the Player class either since it's long and doesn't need to be reversed for the score hack, but it also extends Thing.

The dealWithPlayer function takes two ints. If we look up the code in the Unhackable class, we see that those ints are the players x and y position. It then compares the players x and y to it's own x and y boundaries, and if the player is within it's boundaries (meaning the player and the money objects are colliding) the money randomizes it's position and calls the addMoney function.

From this point, we have enough information to perform several score hacks.
We could modify the Money class and remove the if statements checking the players position so the player is always colliding with the money.
We could modify the Money class by making it not randomize it's position when the player touches it, or even make it teleport to and follow the player.
We could modify the Unhackable class so that it passes the Money's  position to the dealWithPlayer function instead of the Players since the money is always "colliding" with itself.

But for now, let's move on to the ScoreKeeper class. There may well be a simpler score hack waiting for us in it.


Look at that juicy addMoney function.
There are two obvious hacks you could do here. You could change the line:
gameScore=gameScore+1;
to something like:
gameScore=gameScore+100;
or you could modify the static initializer.
The static initializer is the function that's called to initialize the static class.
It's not normally shown in the decompiler, but the code that sets gameScore to zero and the code that sets score to a new TextField are both in the static initializer.
We'll get to the static initializer in a second. First, we'll create our first AoB and make a simple score hack that gives you 100x more score via hex editing.

Part 2: A simple hack

Click the "view hex" (button with green on it) in the top-left corner of the bytecode window.
Click somewhere inside the code for the addMoney function, you should see some ABC bytecode and commented out green hex codes in the bytecode window.


Don't get too scared of the bytecode. It's not as nice to read as AS3, but you'll get used to it after a while. Practice makes perfect.
You definitely don't need to understand all those ABC codes. You can find a list of all ABC bytecodes and what they do here. I recommend looking some up just to get the hang of things

Anyway, what we want to do is change the +1 to be +100. This is done by changing the "pushbyte 1" opcode to be "pushbyte 100".
So, first we need to create a "find" AoB. this is simply done by taking the hex codes of a bunch of subsequent instructions around the byte we want to change.
Usually a hex string of 8 bytes or so is enough, but on some larger games longer strings are needed.
Let's take the hex from line 1 to line 15
d0 30 5e 1c 60 1c 24 01 a0  61 1c 60 1d
Now we need to make a hack AoB.
The opcode we want to change is the "pushbyte 1" opcode, which has the hex "24 01"
If you look it up in the AVM2 instruction list in the link above I gave above you will see the pushbyte instruction has the opcode 0x24 and is followed by an argument which is the signed byte to push onto the stack.
If you don't understand half of that above sentence, that's ok. Long story short, by changing "24 01" to "24 64" (0x64 = 100) we will change "pushbyte 1" to "pushbyte 100" and change the line:
gameScore=gameScore+1;
to:
gameScore=gameScore+100;
Therefore, our hack AoB is
d0 30 5e 1c 60 1c 24 64 a0  61 1c 60 1d
(the only difference between the hack AoB and the original is "24 01" being changed to "24 64")

Firstly, the SWF needs to be decompressed. You can get a SWF decompresser here. Drag a SWF onto the decompresser to decompress it.
Once the SWF has been decompressed, open the SWF in your favorite hex editor. I'm using HxD.
You should see the SWF file starts with the text "FWS" (hex: 46 57 53). This is the "magic number" for an uncompressed SWF as I mentioned earlier. All uncompressed SWFs start with these bytes.

Use the find and replace function in your hex editor to find the "find" AoB:
d0 30 5e 1c 24 01 a0  61 1c 60 1d
and replace with the hack AoB:
d0 30 5e 1c 24 64 a0  61 1c 60 1d
Save that and you should see your score goes up by 100 instead of one each time you get the money.

If it works, congratulations! If it doesn't, try again!

For the purposes of this tutorial, I have changed one of the lines in this class to make it easier to hack.
The line:
gameScore=gameScore+1
was originally
gameScore++
This may seem like a pointless modification, but both lines compile into different bytecode, and "++" is harder to hack via hex editing than "+=".

Long story short, it changes the lines:
pushbyte 01
add
to be
increment
since increment is a one-byte opcode, this means you cannot make a simple AoB to modify it to add 100, since you would have to fit 3 bytes of instructions in 1 byte, which is impossible. You would have to update the file size in the header, which is messy and not-so-straightforward to do.
Instead, in this case the easiest hack would be to simply change the starting score.
In order to do this, you will have to modify the static initializer I mentioned earlier.

Part 3: Modifying a static initializer

Go to the ScoreKeeper class in FFDec if you aren't already there.
To access the static initializer, click on "class intitalizer" in the traits window in the bottom left corner.


 

the line we want to change is the one setting gameScore to 0, so we will modify the pushByte 0 to be a pushByte 100 making us to start with 100 score.
Do the same as before, use line 1 to line 13 for the "find" AoB:
d0 30 5e 1c 24 00 61 1c 5e 1d 5d 1e
and change 24 00 to 24 64 like before for the hack AoB
d0 30 5e 1c 24 64 61 1c 5e 1d 5d 1e
Open the decompressed SWF up with your hex editor, find and replace, save and you should start with 100 score.

That concludes the easy part of this tutorial. For the next part, we're gonna do something more complicated. To start with, we're going to modify the dealWithPlayer function on the Money class so that the money thinks it's always touching the player.

Part 4: The NOP instruction

Go to the Money class in FFDec, and make sure you re-enable decompilation.
What we're going to do is replace the code for the if statements with NOP opcodes (0x02).
A NOP or No-OPeration opcode is an opcode that does nothing. It simply fills space and gets skipped over. Replacing a piece of code with NOPs effectively removes the code, and by removing the if statements, the code for gaining money will always be run.


The bytecode in the function should be in the same approximate order as the AS3 code.
If statements in bytecode are done using conditional jumps (iffalse, ifne, ect). These basically check the top item(s) on the stack, and skip to some instruction if conditions are met.
In order to not mess up the stack, we have to remove the conditional jumps and all the code related to them, meaning we need to replace all the ABC code for those lines with NOPs.
Luckily, the code is all in one place at the beginning.
The last conditional marks the end of the if statements. you will find it on line 60 of the commented ABC. The start of the if statement code is line 5 of the commented ABC code.

therefore, we have to NOP out everything from line 5 to line 60.
Here's the before AoB:
d1 60 10 24 0a a0 ad 2a 12 08 00 00 29 d1 60 10 24 0a a1 af 12 4c 00 00 d2 60 11 24 0a a0 ad 2a 12 08 00 00 29 d2 60 11 24 0a a1 af 12 34 00 00
And here's the hack AoB:
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
Hex edit that into the swf, open and you should see your score going up from doing nothing, and the money rapidly randomizing it's position as you automatically pick it up.

this hack could also be performed by just NOPing out the branches and using POP (0x29) to remove any leftover elements on the stack.
e.g using the hack AoB:
d1 60 10 24 0a a0 ad 2a 02 02 02 29 29 d1 60 10 24 0a a1 af 02 02 02 29 d2 60 11 24 0a a0 ad 2a 02 02 02 29 29 d2 60 11 24 0a a1 af 02 02 02 29
In the above AoB each iffalse (12 XX XX XX) was changed to NOPs followed by a pop (02 02 02 29)
This stops the jump from happening and removes the item on the stack that would have been tested by the if. If you wanted to make the code in the if statement never run (i.e make the jump always occur), you could either NOP the code inside the if statement out or replace the conditional jump with an unconditional jump (For example, changing 12 XX XX XX to 11 XX XX XX). There are more ways to do this, but these techniques will work as well as any other.

That's enough on NOPing. Let's move on to an advanced modification involving writing some actual bytecode.
Don't worry, this is still going to be relatively simple. We're gonna make it so the money teleports to and follows the player instead of randomizing it's position when we pick it up.

Part 5: Intermediate bytecode modification

Open up an unmodified Unhackable SWF in FFDec, and go to the dealWithPlayer function in the Money class.
Take the moment to remember that the arguments passed to the function where the players X and Y position.

Long story short, we want to change the lines
               drawX=int(Math.random()*300)+50;
               drawY=int(Math.random()*200)+50;
to be
               drawX=param1;
               drawY=param2;
The code for these lines starts directly after the last iffalse on line 61 of the commented ABC code.
It ends on line 100 where drawY is set.
If you haven't realized yet, ABC bytecode tends to be in reverse order of the AS3 code. Not always, but a lot of the time. For example, the leftmost (or first) part of the bottom line of AS3 code is setting drawY, where as the last line of ABC bytecode is the line that sets it.
This should make sense if you think about it in terms of the order of operations. If you were to execute this line, the first thing you would do is go inside all the brackets. You would get the random number, multiply it by 200, convert the result to an integer, add 50 then set drawY by the result. This is exactly how the AVM2 runs this bytecode, however due to how the commands work, the objects have to be placed on the stack in a specific order for these to be calculated properly. This is because only the top element of the stack can be accessed.
For example, the first code that's run for this line is:
findproperty m[16]"drawX"
this is because the last line is
initproperty m[16]"drawX"
which takes two items off the stack:
the value
the property
in that order. this means before the calculations can begin, the property has to be added to the stack so that the items are in the right order for the last instruction.

Why is all this important, you ask?
because a lot of the time ABC instructions won't operate the way your intuition tells you they do, and they tend to have to be in obscure orders to operate properly. This is one of the reasons bytecode is so painful to work with. you might have to add an instruction 20 opcodes above the one that needs it in order for it to work properly.

Now that we've got all that out of the way, let's make a "find" AoB for this code from lines 63 to 98 (the first and last code from these lines don't need changing so aren't apart of the AoB):
5d 03 60 20 46 21 00 25 ac 02 a2 46 03 01 24 32 a0 68 10 5e 11 5d 03 60 20 46 21 00 25 c8 01 a2 46 03 01 24 32 a0
What we're gonna do is replace all the code between the first:
findpropstrict m[3]"int"
and the first:
add
(lines 63-78)
with NOPs and getlocal1 (the local register containing the first parameter)
Quick piece of information: local registers act like temporary variables that only exist inside a function
We will also replace the code in the next line the same, changing the lines 83-98 to be NOPs and getlocal2 (same as local1 but with second parameter)
This gives us the hack AoB:
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 d1 68 10 5e 11 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 d2
We can clean that up and make it look prettier by moving all the NOPs to one end:
d1 68 10 5e 11 d2 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
hex edit that into your SWF, and it should work. Touch the money to make it start following you.

Part 6: AoB memory editing

You may have heard the term AoB before in relation to modifying a SWF while it's running after it has been loaded into memory using a memory editor such as Cheat Engine.

The AoB codes we've created are the same as ones that would be used with software such as cheat engine. However, there's some things you need to understand about AoB modification via memory editing before you can start making hacks using it.

The Actionscript Virtual Machine uses something called a JIT Compiler (Just-In-Time Compiler). The JIT compiler compiles the SWF into machine code to be run on the CPU. The JIT compiler doesn't compile a function until it's first run, but once it's compiled the SWF bytecode for that function never gets accessed again. Therefore, memory-based AoB modifications have to be done BEFORE the JIT compiler is run and therefore BEFORE the function is first called.
Usually this means they have to be applied in the game's menu before starting the game, or in worse cases before the game starts to run.
In our case, all the AoBs we've made are for functions that are run when the game first starts, thus they cannot be used for memory-based AoB hacks.

After note:

Since I had to modify the Unhackable SWF several times while making this tutorial, there is a chance that some of the bytecode and AoBs are wrong. Here's hoping that's not the case, but it's totally possible. If you find something wrong, leave a comment.

If you're wondering what to learn next, I'd recommend  playing around with some proper ABC bytecode editing software, such as Yogda, RABCDASM or even the bytecode editor in FFDec.
For further reading, I'd recommend skimming through some of Adobe's SWF Specification.

More specifically, I'd recommend any beginner learn a bit about the constants table. Yogda is especially useful for that.

Hopefully this tutorial is cohesive. I tried to make it as in-detail as possible since all the other SWF modification tutorials I've seen have been pretty terrible.

Lastly, I'd really appreciate some feedback on this tutorial, such as whether it was useful or not, whether it was detailed enough or too detailed, ect.

Friday, July 5, 2013

An Introduction to SWF Obfuscation

I keep running into people who need a good explanation of obfuscation. Since it's a pretty difficult subject to go into any detail in, I thought I should do a post about it so I don't have to spend half an hour explaining it to people every time someone wants to learn more about it.

So, what is obfuscation in general?
Obfuscation is the art of making code, compiled or otherwise, unreadable. In programming, it's generally used to make code harder to decompile, disassemble and reverse-engineer.

There are two main forms of obfuscation used on SWFs. Name obfuscation, and Bytecode obfuscation. Normally, the two are used together, and SWFs that only use one are quite rare.

Name obfuscation is simple. Take the names of every class, variable and function and change it to some randomly generated junk.
For example, if you had a class named "player", it might be renamed to "d+.{8]R0%9r".
This makes it difficult to easily identify what classes/functions/properties do what.
Name obfuscation is impossible to reverse. The best you can do is change it to something like class1, class2, class3... function1, function2, function3... ect. Or alternatively, you can reverse engineer the classes and manually re-name them as you figure out what they do, but that is incredibly time consuming, impossible to automate and you still won't end up "reversing" the obfuscation as such, just giving useful labels to the obfuscated classes.

Two lines of  AS3 with compiled AVM2 Actionscript Bytecode
Bytecode obfuscation is a much more complicated subject.
There are many forms of bytecode obfuscation. Some add junk code, some add extra code branches, some restructure the code. There's a crapload of different ways to do bytecode obfuscation.
In order to understand bytecode obfuscation, you have to understand the difference between AS3 and AVM2 Actionscript bytecode. A SWF does not contain any AS3 code in it, but rather a compiled lower-level language. Comparing the code in a SWF to AS3 is like comparing Assembly to C++ (google them if you want).
This difference in languages means that you could in theory have AVM2 Bytecode that has no equivalent in AS3. Bytecode obfuscators use principals like this to their advantage.
They can crash decompilers by adding invalid code to the SWF that in practice, will never be run, and the decompiler will be unable to decompile the code, since the obfuscated AVM2 code in the SWF has no AS equivalent.
Over the years, bytecode obfuscation has gotten more and more advanced. Back in the day, you could remove it with a hex editor if you knew what to search and replace for. Nowadays, it takes complex programs purpose-written to take out specific obfuscation algorithms to remove such defenses.

Apart from completely thwarting the use of decompilers, bytecode obfuscation has another use. By adding lots of junk bytecode and restructuring the bytecode, it makes it much harder to reverse-engineer the disassembled code. This, coupled with name obfuscation can make it near impossible for most hackers to make hacks and reverse engineer the SWF in general. As you can see above, two lines of AS came out to be about 15 lines of AVM2 ABC  Bytecode. It is not uncommon for an obfuscated class to contain well over a thousand lines of such code, barely readable even without obfuscation.

However, most if not all bytecode obfuscation is theoretically removable. That being said, it's almost always impractically difficult to do so.

So, how do we actually deal with obfuscated SWFs, you ask?
The Free and open-source decompiler JPEXS FFDec has some very good deobfuscation routines in it. If that doesn't work:
My biggest piece of advice would be to look for useful unobfuscated strings. Name obfuscation does not obfuscate all strings. names and packages of Adobe classes tend to stay unobfuscated. So do events a lot of the time. you can always go through the strings constant pool (using Yogda or another bytecode editor). Finding unobfuscated strings can quite often allow you to figure out what's what, and a lot of the time it's pretty much the only option you have.
Another piece of advice is don't tackle obfuscated SWFs until you are very confidant with working in bytecode. It's not easy. Even the best hackers tend to dread dealing with obfuscated games.

I would also recommend using a variable scanner if you can, however there are not many (if any?) good AS3 var scanners (there's my shitty one, and AS3Watson), since they really only started being publicly released a year ago, and I don't think there's a single tutorial on the internet on AS3 var scanning. I'll probably make one some time, but not for a while.

I could have written more. Maybe I'll do another post, or a series of posts on obfuscation in the future. There's heaps to write about, and I only scratched the surface on most of the things I mentioned.

Hopefully this is readable and makes sense. I'm pretty exhausted right now.

Thursday, April 4, 2013

Manatee SWF Decrypter V3

Funny story, I was gonna release this a week ago, but my laptop charger broke as I was typing this out. I was hoping to get a release out before the end of the month, but nonetheless here's V3 of my decryptor!Those of you who were paying attention will probably be wondering why there's no V2.
Here's a little explanation:
The V1 method simply loaded the SWF and scanned it for loaders.
The V2 method (which I didn't finish because I discovered the superior V3 method while working on it) functioned by overriding the Loader class in a loaded SWF. some of you may have realized by now that Adobe classes cannot normally be overrided, but with a little black magic, you can do the equivalent.
The V3 method works by using the debug version of flash player and editing mm.cfg to load the SWF alongside the target SWF, and a little black magic.
The V3 method is much harder to detect and defend against than the V1 and V2 methods and less buggy since it doesn't utilize the Loader class to load the game.

Installation
Download and install the flash content debug player on this page
Download this SWF (it's also on the downloads page) and move it to:

C:/ManateeUniversalDecryptorV3.swf

open (or create and open if it doesn't exist):

%userprofile%/mm.cfg

in notepad or equivalent and add the line:

 PreloadSwf=C:/ManateeUniversalDecryptorV3.swf  

to your mm.cfg file.
A helpful hint if you start getting annoyed with all the errors is to add the following line to your mm.cfg

 SuppressDebuggerExceptionDialogs=1  

and then use  the "silent" mode (which I will mention later).

Usage
Once Manatee SWF Decrypter has been installed, it will be automatically injected into any game running in the debug player. So, to use it you just open the game in the debug player you installed. (eg, if you install the Firefox debug plugin, open the game in Firefox to inject the decrypter into it)
Manatee SWF Decrypter V3 is controlled entirely with the numpad.
There are two output modes: normal mode and the slightly ironically named silent mode.
Normal mode outputs messages by throwing errors, and silent mode outputs messages by beeping.
Numpad 1 enters silent mode, and numpad 2 enters normal mode.
Numpad 5 is a kind of "hello world" button that in normal mode simply tells you that the decryptor is connected. In silent mode, a single "beep" shows that the decryptor is connected.
Numpad 3 tells you if there's remaining SWFs to be dumped. in normal mode it throws an error telling you exactly how many SWFs are left for dumping. in silent mode, 3 beeps means 1 or more SWFs remaining, and 9 beeps means there are no SWFs remaining.
Numpad 0 dumps remaining SWFs. In normal mode, it tells you how many SWFs are remaining when the SWF finishes saving. In silent mode when the SWF has finished dumping you get 3 beeps if one or more SWF is remaining to be dumped or 9 beeps if no SWFs remain to be dumped.

Rule of thumb for silent mode:
1 beep = the decryptor is connected
3 beeps = 1+ SWFs remaining
9 beeps = 0 SWFs remaining

Currently, the only major bug is sometimes the AVM2 garbage collector destroys the ByteArray the SWF is held in before you get a chance to dump it.
It doesn't usually happen to "important" SWFs though, so fixing that bug is pretty low priority for me.

Monday, February 4, 2013

Retro-style Raycasting #1

I've decided to start a series of almost tutorial-like posts with information on retro-style raycasting.
More specifically, this series of posts will cover my previous, current and future work with writing Wolfenstein-3D-like 2D array based raycasting engines with various optimizations.

There have been little to no major optimizations in the area of 2D array based raycasting, presumably because all modern hardware is too powerful to need it.
I've spent the last couple of years on and off building and improving raycasting engines.
Most of my early work was in AS2.

Here's a brief overview of my history with the pseudo-3D:

Ye Olde AS2 engines:

I originally started off by porting the code from this tutorial to AS2.
My initial port had graphical errors and a lot of bugs, but worked as a proof-of-concept, which I did about two years ago.
This was my V1 engine.

The V2 engine started off as a complete re-port of the code.
The V2 engine was bug-free, and started off as a texture-less raycaster.
The first improvement I made to the V2 engine was the addition of "fog" which was used as a basic way to implement basic pseudo-lighting.
The second improvement was to draw each wall face as a gradient-filled square instead of a crap-ton of vertical lines, which greatly decreased the time it took to draw the frame.
The V2 engine was also the first engine to support textures, for which I made two drawing algorithms, neither of which were particularly effective.

V3 was my first attempt at implementing my "extra trig" raycasting engine. I'll go into more detail on extra trig raycasting in another post.
The V3 engine, although not a complete failure, required an incredibly buggy piece of code to run: my "edge fix". to put it simply, the edge fix works by using the height of the previous raycasted wall to work out how high the current wall-face edge height is. the edge fix is effectively an interpolation algorithm for the raycaster, it gives a better looking image for many less rays, however, it was unfinished and had many bugs.
The V3 engine was discontinued very early on.

With the partial failure of the V3 engine, I started development on the V3-2 engine, which was built off the V2 engine because the V3 engine was deemed too unstable and bugged.
The V3-2 engine got to be quite powerful after several optimizations.
The V3-2 engine was the first engine to support sprites and have working z-sorting (z-sorting was done per-wall instead of per-pixel, which later gave me the idea of my Left-Right z-sorting algorithm which I may cover in a later post)
Also included in V3-2 was an incredibly snazzy minimap and basic multiplayer support.
V3-2 did not support textures, but was as bug-free and stable as V2.

V4 was a second, more advanced attempt at implementing my "extra-trig" raycasting method, built off of V3-2.
It was filled with bugs and hack-y fixes, but was beginning to show promise before I stopped development.
I stopped development on V4 a little over a year ago.
This was my last iteration of my AS2 raycaster.

About three or four months after the discontinuation of V4, I wrote a full, working AS3 Maze War prototype with a full server running on Adobe Air.

After that, I wrote a quick-and-dirty pseudo-3d engines that used vector-based maps and worked by calculating line intersections and trigonometry, it worked to an extent however there were visual bugs with it.

I dabbled with some experiments and wrote my own basic pseudo-3D engine in C++ that used vector-based maps, A similar "rasterization" technique to my "extra trig" raycasting method and was drawn using SDL late last year in preparation for writing an implementation of my Flood-Fill Raycaster-Like engine, which hasn't been started yet.

So far, I've come up with 3 Wolfenstein-like algorithms for raycasting that are faster than the conventional methods:

Extra-Trig Raycasting:
typically would use less than 50 rays to calculate any scene likely to exist in a game, resolution of display has no effect on rays used or calculation time, however amount of walls on the screen does. uses significantly more maths than regular raycasting but many major operations can be done using precalculation and look-up tables.
Estimated speed VS traditional method:
Depends on resolution, at 640x480, estimated 2-10 times faster.

Binary Raycaster:
Hard to estimate how many rays it would use - however it would definitely use significantly less. at a screen width of 640, maybe around 50-200 rays would be likely. More processing would have to be done per ray, but most likely not much. increased resolution means more calculation, more walls on screen means more calculation. significantly easier to implement than extra-trig
Estimated speed VS traditional method:
estimated 2-10 times faster

Flood-Fill Raycaster
Technically not a raycaster as it doesn't use rays. FFRC is one step on from Extra-Trig. Each tile in view is only checked once, trigonometry is used to do almost everything. heavy use of precalc and look-up tables can greatly increase efficiency. Calculation needed to do is proportional to tiles in view, both empty and filled. Screen resolution has no effect on processing needed.
Estimated speed VS traditional method:
estimated 5-100 times faster.

I have also been working on another perspective-based rasterizer which I believe would be limited to maze-war-like maps, but would allow players to look in all directions and possibly have free movement while still being more efficient than any other method above.

And that concludes a rough overview of my work on pseudo-3D engines. at least all the interesting stuff.

Tuesday, January 29, 2013

BPE Pre-Alpha V1.2

With this release comes good news and bad news.
The bad news is my prehook system doesn't work, so I'm going to have to find a new way of adding IP hooks. I've looked at several alternatives and found that I could quite easily make a cross-platform hook for Linux/Mac, but Windows doesn't like letting anyone do any low-ish level network hacks.
The good news is that PEW support has been added, which is a pretty big thing.
I've actually fixed the multiple server hook bug this time - connections now go to where they're meant to go.
I've also done a little more work on the GUI, adding the ability to actually remove port hooks and plugins.
It also no longer saves which hooks you were using. Now that Workspaces  are implemented, it no longer needs to.

I'll update the Wiki with some documentation on Workspace files since to load plugins you have to edit the Workspace file via text editor.

I'd also like to point out that now Workspace files have been implemented, BPE is much more friendly towards having complete game hacks released on it since all an end-user needs to do to use a properly set up plugin-based hack is double click a Workspace file.

Feel free to spread this around.
People should use this.

DOWNLOAD

Changelog:

*BPE Pre-Alpha V1.2 (PEPAPI V1.1) (PEWVer 1.0)
  - added PEW/Workspace support
    - added "resetWorkspace", "hookServer", "hookPort" and "loadPlugin" Workspace commands
  - added save & load workspace buttons
    - save function saves server hooks and plugin hooks but not plugin configuration
  - GUI improvements
    - added ability to unload plugins via "Plugin Options" menu
    - added ability to unhook ports via "Port Options" menu
  - fixed bug where BPE would sometimes not close properly and hang in memory
  - BPE now removes server hooks on close, use workspaces to save them
  - made BPE the default file opener for .pew files (secretly done in V1.1)
  - fixed bug where if more than one server was hooked all connections were routed to the first server in the list
  - cleaned up shit tons of code

Monday, January 28, 2013

Packet Editor Progress #7

It's been a while since I gave a progress update on BPE.
IP hooks (in the form of PreHook) are being added next release. unfortunately, for both hooks to work simultaneously, I have to re-design the entire hook system, which is why this release has been taking quite some time.
Since BPE was originally designed to only have one hook system, it makes things difficult because the server hooks and the port hooks were effectively the same body of code, and now need to be completely separated and mostly re-written (I'm splitting one class into about five to make it work).
There will be a "Server Manager" class that acts as an interface for the different hooks (including plugin interaction, which is controlled by the "Plugin Manager"), and a "Master Server" class that will organize the serversockets and pass connections through the different hooks as they come.

So, next release should fix the two most significant limitations of BPE: the multiple server hook bugs and not being able to hook IPs.

PEW files will probably start being implemented in the release after this next one. I'm focusing on fixing major bugs/limitations before adding new features.

And yes, I still need a Mac tester.
I'd also appreciate a Linux tester.

Thursday, December 20, 2012

Flash AS3 Class overriding template and tutorial

The biggest problem with class overriding I have found so far is that large classes can take a lot of work to "fix" to work with class overriding. So, I have created a template for class overriding that can make this process a vast amount easier.
It certainly has it's limitations, but where it works, it works well.
To be able to use it properly, you need to have a pretty good understanding of how it works.
I'll start with a quick overview of how it works, don't worry too much if you don't understand it properly yet:

A custom loader dynamically generates a SWF containing a single "nullified" class that has no methods or properties and uses class overriding to nullify the document class in an instance of the game SWF (this instance is used solely for accessing the original, unmodified classes in the game).


Template classes use the proxy extends hack to pretend to "extend" the original class in the game. e.g. if you were overriding the class "Money", the template does this by using the proxy hack to pretend to extend the original "Money" class held in the nullified instance of the SWF loaded by the custom loader.

Classes are overridden by extending the BasicOverrider class that is included in the template. This class and the custom loader do all the hard work for you. Any public methods and variables can now be modified, without having to "fix" any code you're not working with.

Here's a nice little visual explanation for the loader:



With any luck, you now have a decent understanding of how the loader works.
so, onto how the template extender works:



If you need more information, you can take a peek at it's source.

Now, hopefully you understand it's limitations. It cannot access private/protected vars and requires a little work to fix type casting problems (Note: a lot of the time this isn't a problem) due to the nature of how it functions.

Now, here's the mini-tutorial and template download link:
You'll need this SWF and the OverriderLoader template for this tutorial.
I will assume you know everything covered in this tutorial.

Setting up the template is really easy.
The SWF name is "Unhackable.swf" and if you open it up with a decompiler, it'll tell you the document class  is "Unhackable".
open up the Overrider class and change:

 loader.load("SWF NAME HERE.swf","DocumentClassNameHere");  

to:

 loader.load("unhackable.swf","Unhackable");  

Next, we need to fix the stage access problem. Unfortunately, template overriding doesn't work on the document class (because it gets nullified so you can load the other classes without running code), so we'll need to use the old method. We'll use the same code we wrote up in the last tutorial. Chuck this code in a new class called "Unhackable":

 package   
 {  
      import flash.utils.*;  
      import flash.display.*;  
      import flash.events.*;  
      public class Unhackable extends MovieClip  
      {  
           private var Player:Class = getDefinitionByName("UnhackableEngine.Player") as Class;  
           private var Money:Class = getDefinitionByName("UnhackableEngine.Money") as Class;  
           private var ScoreKeeper:Class = getDefinitionByName("UnhackableEngine.ScoreKeeper") as Class;  
           private var player:Object;  
           private var money:Object;  
           private var score:Object;  
           public function Unhackable()  
           {  
                this.addEventListener(Event.ADDED_TO_STAGE,addToStage);  
                return;  
           }  
           private function addToStage(e:Event)  
           {  
                this.player = new Player(int(Math.random() * 300) + 50,int(Math.random() * 200) + 50);  
                this.money = new Money(int(Math.random() * 300) + 50,int(Math.random() * 200) + 50);  
                this.score = new ScoreKeeper();  
                addChild(this.score as DisplayObject);  
                addChild(this.money as DisplayObject);  
                addChild(this.player as DisplayObject);  
                stage.addEventListener(Event.ENTER_FRAME, this.gameLoop);  
           }// end function  
           private function gameLoop(event:Event)  
           {  
                this.money.dealWithPlayer(this.player.playerX, this.player.playerY);  
                this.player.doMove();  
                return;  
           }// end function  
      }  
 }  

Now that that problem's solved, we can get on to using the template for something useful.

We'll make each money pickup give you 100 score.
Now, if you remember, the actual score variable is private, which means that template overriding can't touch it. however, the static "addMoney" method is public and can thus be edited.

So, let's start with a basic overrider template class, then.
Create a new class in the package "UnhackableEngine" called "ScoreKeeper" and give it this code:

 package UnhackableEngine {  
      import OverriderLoaderUtils.BasicOverrider;  
      import flash.utils.*;  
      public class ScoreKeeper extends BasicOverrider {  
           public function ScoreKeeper() {  
                super(getQualifiedClassName(this));  
                origObject = new origClass();  
           }  
           static function addMoney()  
           {  
                origClass.addMoney();  
           }  
      }  
 }  

This is just a basic overrider template class with a wrapper function for the addMoney static method (as all static methods need wrapper functions when using the template). Our goal right now is to get it to compile with this.

So, lets add the line

 var scoreKeeper:ScoreKeeper;  

to our Overrider class to make it all compile together and see what errors we get.
You'll get an error telling you it doesn't want to be added as a child. We've been here before, haven't we? last tutorial?
Change:

 addChild(this.score as DisplayObject);  

to:

 addChild(this.score.origObject as DisplayObject);  

in your Overrider class to make it quit it's bitching. Compile, and it should be happy.

Now all we need to do to make money add 100 score is go to our ScoreKeeper class and change:

           static function addMoney()  
           {  
                origClass.addMoney();  
           }  

to:

           static function addMoney()  
           {  
                for(var i:int = 0;i<100;i++){  
                     origClass.addMoney();  
                }  
           }  

Compile, and you're done!

Here's the finished source code for the tutorial.


Oh, and if you're wondering how to fix static variables, you do something like this:

           static function get varName():Object  
           {  
                return origClass.varName();  
           }  
           static function set varName(value:Object):Void  
           {  
                origClass.varName = value;  
           }  

Where varName is the name of the variable.

The pros of using the template:
- no need to fix any non-static functions
- static functions only need to be redirected, so fixing is much simpler compared to the old method

The cons of using the template
- doesn't work on the document class
- doesn't work on private/protected vars/methods
- type casting is still a problem

Monday, December 3, 2012

Flash AS3 Class injection via Loader

I discovered a new technique for hacking flash games a month or so ago. I've been referring to it as class overriding (simply because class injection could be used to refer to injecting bytecode into a SWF).
It's a fairly simple technique that allows you to have extreme control over a loaded SWF.
I was going to do this tutorial on an actual game, but unfortunately there weren't any games that were good examples, so instead I modified my Unhackable Engine base (designed to be the simplest game possible for testing new security measures/ect in a semi-real environment and easy to port to other languages, the original AS3 version is under 90 lines of code, and the AS2 version is less than 60).
I'm going to assume you have some experience with AS3 and flash. If you don't, the source for this tutorial will be available.

Be warned, this SWF was botched together as fast as possible, and modified to function in weird ways specifically for the tutorial. Don't judge me on the quality of it's code.

Download the "game" used in this tutorial here.

 Anyways, to the tutorial:

The first thing we do is we start with a basic loader template that will load the SWF.
Create a new document class (I called mine Overrider), and put this code in it:
 package {  
      import flash.display.MovieClip;  
      import flash.display.Loader;  
      import flash.net.URLRequest;  
      import flash.system.ApplicationDomain;  
      import flash.system.LoaderContext;  
      public class Overrider extends MovieClip {  
           private var ldr:Loader = new Loader();  
           public function Overrider() {  
                this.addChild(ldr);  
                var urlReq:URLRequest = new URLRequest("unhackable.swf");  
                ldr.load(urlReq,new LoaderContext(false,ApplicationDomain.currentDomain));  
           }  
      }  
 }  

This will load the SWF into our SWFs ApplicationDomain, meaning that classes will be loaded into the same space, and when flash player tries to load a class that already exists in the current ApplicationDomain, the new class is dropped, and the old one remains (which is how this hack works).
Now, compile and run that, and you will get an error.

 TypeError: Error #1009: Cannot access a property or method of a null object reference.  
      at Unhackable()  

let's open unhackable.swf with a decompiler, and see what the problem is.
We know from the error that the error is within Unhackable(), so let's look at the code:

 public class Unhackable extends MovieClip  
 {  
   ...  
   public function Unhackable()  
   {  
     this.player = new Player(int(Math.random() * 300) + 50, int(Math.random() * 200) + 50);  
     this.money = new Money(int(Math.random() * 300) + 50, int(Math.random() * 200) + 50);  
     this.score = new ScoreKeeper();  
     addChild(this.score);  
     addChild(this.money);  
     addChild(this.player);  
     stage.addEventListener(Event.ENTER_FRAME, this.gameLoop);  
     return;  
   }  
   ...  
 }  

Ah, there's our problem. Let me explain for those of us who are unfamiliar with the bugs in the Loader class...
When A SWF is loaded normally (without the Loader class), the document class's constructor is called after it has been added to the stage and therefore has the stage property set. When a SWF is loaded with the Loader class, the document class's constructor is called before it has had it's stage property set, so that refference to the stage:

 stage.addEventListener(Event.ENTER_FRAME, this.gameLoop);   

will throw an error, because the stage variable is still a null object reference (it's null), and as the error states, you cannot access a method of a null object reference.

Luckily, we can fix this quite easily with class overriding.

Create a new class in your default package called Unhackable and copy and paste the code the decompiler generated for that class over.

Now, when you compile that, you'll get about a half-dozen errors. this is ok, and completely normal in class overriding. You see, that class imports other classes (Player, Money, ScoreKeeper) that we don't have in our project. The first solution you probably think if would be to decompile and add every class in the SWF, but that would be a pain in the ass and counterproductive, so we're gonna hack our way through this. the question we need to answer is: How do we access a class we can't import? The solution is simple: using the getDefinitionByName function in flash.utils.*.
so, replace:

 import UnhackableEngine.*;  

with:

 import flash.utils.*;  

getDefintionByName will dynamically find the class for us whenever we need it. so, with a little modification we can fix this class.
replace:

     private var player:Player;  
     private var money:Money;  
     private var score:ScoreKeeper;  

with:

           private var Player:Class = getDefinitionByName("UnhackableEngine.Player") as Class;  
           private var Money:Class = getDefinitionByName("UnhackableEngine.Money") as Class;  
           private var ScoreKeeper:Class = getDefinitionByName("UnhackableEngine.ScoreKeeper") as Class;  
           private var player:Object;  
           private var money:Object;  
           private var score:Object;  

Also, since there are no references to  this new class you've added, by default it won't compile into your SWF, so go back to your document class, and under the class variable definitions, add:

 private var unhackable:Unhackable;  

When you try and compile, you'll get some more errors now, but that's OK, cause we're gonna have to replace the function they're in anyway.
So, onto replacing the function, fixing the stage reference problems and adding the needed type casting.
First, we're gonna move all the code in the constructor to another function, and make that function be called when the object has been added to the stage (using the ADDED_TO_STAGE listener).
replace:

           public function Unhackable()  
           {  
                this.player = new Player(int(Math.random() * 300) + 50,int(Math.random() * 200) + 50);  
                this.money = new Money(int(Math.random() * 300) + 50,int(Math.random() * 200) + 50);  
                this.score = new ScoreKeeper();  
                addChild(this.score as DisplayObject);  
                addChild(this.money as DisplayObject);  
                addChild(this.player as DisplayObject);  
                stage.addEventListener(Event.ENTER_FRAME, this.gameLoop);  
                return;  
           }  

with:

           public function Unhackable()  
           {  
                this.addEventListener(Event.ADDED_TO_STAGE,addToStage);  
                return;  
           }  
           private function addToStage(e:Event)  
           {  
                this.player = new Player(int(Math.random() * 300) + 50,int(Math.random() * 200) + 50);  
                this.money = new Money(int(Math.random() * 300) + 50,int(Math.random() * 200) + 50);  
                this.score = new ScoreKeeper();  
                addChild(this.score);  
                addChild(this.money);  
                addChild(this.player);  
                stage.addEventListener(Event.ENTER_FRAME, this.gameLoop);  
           }  

And now we add some type casting to fix the last 3 errors.
replace:

                addChild(this.score);  
                addChild(this.money);  
                addChild(this.player);  

with:

                addChild(this.score as DisplayObject);  
                addChild(this.money as DisplayObject);  
                addChild(this.player as DisplayObject);  

and compile. with any luck, you have no errors, it compiles, loads the SWF and runs perfectly!
If not, try download the source of the finished code and try and figure out what went wrong.

Congratulations! you've successfully overrided your first class!

Now, onto doing something useful.

We'll double player speed and make it so that each "money" pickup gives us 1,000 points.
First, we'll start with the money hack, because the player speed hack is a little more complicated (If you're feeling confident/bored, you can skip to the player speed hack, as it teaches more important stuff).

This one is simple and straightforward.
you'll need a new package (class locations need to be mirrored) called UnhackableEngine, and in there a new class called ScoreKeeper.

Copy and paste the ScoreKeeper code from the decompiler, add this line of code to your document classes variable definitions to make sure it gets compiled in:

 private var scoreKeeper:ScoreKeeper;  

and compile.
You'll get an error.
Don't worry, it's easy to fix.

Our problem is that variables are not being casted from int/whatever to string, so the compiler is getting shitty with us.

replace the two occurrences of:

 score.text = gameScore;  

with:

 score.text = String(gameScore);  

and compile.
It should compile and work without errors.

Now, let's take a look at the addMoney function:

     static function addMoney()  
     {  
       var _loc_2:* = gameScore + 1;  
       gameScore = _loc_2;  
       score.text = String(gameScore);  
       return;  
     }  

seems easy enough to modify. Let's chuck some 0s in there

     static function addMoney()  
     {  
       var _loc_2:* = gameScore + 1000;  
       gameScore = _loc_2;  
       score.text = String(gameScore);  
       return;  
     }  

and boom, money pickups now give us 1000 score.

Onto player movement, and advanced class overriding!
I'm sure you know the drill by now.
Create a new class in the UnhackableEngine package named Player.
C+P the code from the decompiler, add a reference to the class in your document class, try to compile and see what errors you get.

Ooh, we get a new, nasty one.

The definition of base class Thing was not found.

We have two options here, overriding the Thing class will solve this problem, but imagine if Thing extended another custom class, which extended another custom class, which ended up being a class chain 20  classes long? it would be impractical to override them all.

But how can you possibly get around it? you can't just dynamically extend classes. That goes directly against AS3s standards. Luckily, in AS3 there's this nasty little thing called the Proxy class that goes against all of AS3s conventions, and makes this possible.

Although we cannot actually dynamically extend classes, we can pretend we do using the Proxy class to dynamically pretend we have properties of classes which we actually don't.

I'm going to warn you now, everything's about to get messy. Which is why I'm stalling.

I guess I'll explain the Proxy class a little, seems like it's the best way to teach this.

The Proxy class allows you to dynamically change the behavior of an object. When set up, you can make it so that if a property is accessed and doesn't exist in an object, a proxy function is called that can deal with it. we use this functionality to make an object act as if it has the properties of another object by making any attempt to access a property that doesn't exist on the object go to the object it is pretending to extend.

Hopefully, the code will help explain what I mean for those who are still confused...

First thing we need to do is make the Player class extend the Proxy class.
replace:

 public class Player extends Thing  

with:

 public class Player extends Proxy  

now, add these variables to the Player classes variable definitions:

           public var extendedClass:Class = getDefinitionByName("UnhackableEngine.Thing") as Class;  
           public var extended:Object  

add these functions to the class:

  override flash_proxy function getProperty(name:*):*
  {
   return extended[name];
  }
  
  override flash_proxy function setProperty(name:*,value:*):void
  {
   extended[name] = value;
  }

  override flash_proxy function callProperty(name:*, ...rest):*
  {
   extended[name].apply(rest);
  }

these functions are the backbone of our Proxy hack. We don't actually need most (or any) of them. in most situations, you'll need them, though. There are more Proxy functions you may need in other circumstances, but these are the main ones.

We're gonna have to do quite a bit of modifying to make this class work with us.
Any internal references in the player class to the class it extends need to be changed.

replace:

     public function Player(param1, param2)  
     {  
       fillColour = 11141120;  
       this.playerX = param1;  
       this.playerY = param2;  
       this.addEventListener(Event.ADDED_TO_STAGE, this.addListeners);  
       super(param1, param2);  
       return;  
     }  

with:

           public function Player(param1, param2)  
           {  
                extended = new extendedClass(param1, param2);  
                extended.fillColour = 11141120;  
                extended.drawStuff();  
                this.playerX = param1;  
                this.playerY = param2;  
                extended.addEventListener(Event.ADDED_TO_STAGE, this.addListeners);  
                return;  
           }  

and

     public function doMove()  
     {  
       this.playerX = this.playerX + this.xVel * 5;  
       this.playerY = this.playerY + this.yVel * 5;  
       drawX = this.playerX;  
       drawY = this.playerY;  
       drawStuff();  
       return;  
     }  

with:

           public function doMove()  
           {  
                this.playerX = this.playerX + this.xVel * 5;  
                this.playerY = this.playerY + this.yVel * 5;  
                extended.drawX = this.playerX;  
                extended.drawY = this.playerY;  
                extended.drawStuff();  
                return;  
           }  

and

     private function addListeners(event:Event) : void  
     {  
       stage.addEventListener(KeyboardEvent.KEY_DOWN, this.keyDownListener);  
       stage.addEventListener(KeyboardEvent.KEY_UP, this.keyUpListener);  
       return;  
     }  

with:

           private function addListeners(event:Event):void  
           {  
                extended.stage.addEventListener(KeyboardEvent.KEY_DOWN, this.keyDownListener);  
                extended.stage.addEventListener(KeyboardEvent.KEY_UP, this.keyUpListener);  
                return;  
           }  

As you can tell, the Proxy hack can be a bit messy. sometimes, it's better to just override the class it extends as well. cause now where up to the next problem: type casting.
A Proxy object can't be casted to anything the object it's pretending to extend can. And the addChild function which the player object is given as a parameter to expects a DisplayObject. luckily, we're already overriding the class that calls the function, so go back to the Unhackable class and
replace:

 addChild(this.player as DisplayObject);  

with:

 addChild(this.player.extended as DisplayObject);  

compile that and it should work error-free.

The Player class is FINALLY set up for modification (again, the proxy hack isn't really made for this situation, but it's useful to know how to do it).

One quick modification and we'll  have double player speed.

change

                this.playerX = this.playerX + this.xVel * 5;  
                this.playerY = this.playerY + this.yVel * 5;  

to

                this.playerX = this.playerX + this.xVel * 10;  
                this.playerY = this.playerY + this.yVel * 10;  

And we're done!

Download the source for this tutorial here.

Monday, October 8, 2012

BPE Plugin Writing Tutorial #1 (Writing your first plugin)

So, I thought it was about damn time I wrote a tutorial on writing plugins for BPE (Mostly because currently I'm the only person who knows how).
Firstly, I've been updating the Wiki, so hopefully between this tutorial and the Wiki, there should be enough information for people to start writing plugins.
 and now the tutorial:

Writing your first plugin.

So, we're  gonna make a nice, simple plugin that simply outputs everything happening on the servers/ports being listened to.
It'll do the following:
Properly set up it's window
Output all sent/recieved packets
Output when connections are opened/closed

Now, let me explain a little about the hook system BPE uses. there are two kinds of hooks:
Hooks called by BPE, and
Hooks called by the plugin.

Hooks called by BPE are utilized by creating a public function in the document class of the plugin.
eg:

 public function sendPacketHook(packet:ByteArray,socketID:int):ByteArray  
 {  
     output.appendText("["+socketID+"] Sent:"+packet+"\n")  
     return packet;  
 }  

That above code would be called every time a packet is sent by the client. the variable "packet" contains the payload (data) from the packet in the form of a ByteArray. socketID is an integer containing the ID of the socket. The function returns the unmodified packet, so no modification is made.

Hooks called by the plugin are utilized by creating a public Function variable in the document class of the plugin, and then calling that variable/Function when you need to.
eg:

 public var updateWindow:Function;  
 public function someFunction():void  
 {  
     updateWindow(550,400,"Debug");  as
     return;
 }  

That above code (when someFunction is called) will scale the size of the window so that the stage is 550 pixels wide and 400 pixels high, then set the plugins window title to say "Debug".

Also note that all used hooks must be specified in the .pep file that goes with the plugin (more on that later, though).

Anyways, I hope that's enough explanation for understanding the hooking system for now. let's get on to making the actual plugin!
I'm going to assume you know your way around Flash and know a little AS3 at this point.
So, create a new AS3 project and a document class called "BPEDebugPlugin".
now, we're gonna be using ByteArray's (for the sent and received data) and TextFields (for the output), so go ahead and add these lines to the includes:

     import flash.text.TextField;  
     import flash.utils.ByteArray;  

Now, we're gonna need to declare a couple variables in the class.
Firstly, since we want to set the window size and title, we want to use the updateWindow hook, so we need to add a Function variable with the name updateWindow.
Secondly, we want a TextField that we can write our outputted data to.
so, add these lines to your class variable declarations

         public var updateWindow:Function;  
         private var output:TextField = new TextField();  

we're gonna make use of the finishPluginSetup hook. this simple hook function is called after your plugins hooks have been set up and your plugin has been added to the stage. it basically tells you it is now safe to use hooks and access the stage.
Chuck this code right after the end of your constructor function:

         public function finishPluginSetup()  
         {  
             updateWindow(550,400,"Debug");  
             output.x = 20;  
             output.y = 20;  
             output.width = 510;  
             output.height = 360;  
             output.background = true;  
             output.backgroundColor = 0xAAAAAA;  
             output.text = "Output\n";  
             this.addChild(output);  
         }  

As stated before, this function will be called once, when BPE has added it to the stage and set up all it's hooks. it calls the updateWindow hook and changes the window size and label. it will then set up the output TextField for use.

Now, let's get to the actually useful hooks. We'll start with the send and receive hooks, since they're super-similar, and quite simple.

         public function recievePacketHook(packet:ByteArray,socketID:int):ByteArray  
         {  
             output.appendText("["+socketID+"] Recieved:"+packet+"\n")  
             return packet;  
         }  
         public function sendPacketHook(packet:ByteArray,socketID:int):ByteArray  
         {  
             output.appendText("["+socketID+"] Sent:"+packet+"\n")  
             return packet;  
         }  

These functions will be called by BPE every time a packet is sent by the client or received by the client. packet is the ByteArray containing the data payload of the packet, and socketID is the ID number for the socket. We'll output the data being sent in the packet.
This is probably a good time to introduce you to BPE's socket ID system. each socket that connects to BPE is given an ID to make them easy to keep track of.
The first socket to connect is given the ID 0
the second 1
the third 2
ect.
The functions then output the sent/recieved data along with the socket ID.
The ByteArray returned by these functions is then run through any remaining plugins and either sent to the client or server depending on whether the packet is being received or sent.
Since we're returning the same, unmodified ByteArray that was the input of the function, the packet is left untouched. if you return an empty ByteArray, the packet is dropped.

Onto the socketOpen and socketClose hooks.

         public function socketOpenHook(socketID:int,address:String,port:int):void  
         {  
             output.appendText("["+socketID+"] Connected to:"+address+":"+port+"\n")  
             return;  
         }  

The socketOpenHook is run every time a socket connects to BPE. it gives you the new socket's ID, the address it's attempting to connect to and the port on which it's attempting to connect to. We'll output the address and port on the server it's attempting to connect to.

Next is the socketCloseHook.

           public function socketCloseHook(socketID:int,closeSocket:Boolean):Boolean  
           {  
                output.appendText("["+socketID+"] Disconnected, "+closeSocket+"\n")  
                return closeSocket;  
           }  

The socketCloseHook is called when the server disconnects the client. The Boolean closeSocket tells you whether BPE plans on disconnecting the client. if true, the socket is to be disconnected, if false, the socket connected to the client will stay connected. We'll return the closeSocket value given to us to let the other plugins or BPE decide what to do with the socket connected to the client.

Now, compile that sucker and we're up to creating the .pep file to load our plugin.

PEP files are like an external header for the plugin. it tells BPE everything it needs to know to run your plugin.
I created a simple little tool making it easy to generate the .pep file for your plugin. you can get it here or on the downloads page.
Open the PEP Builder up (do it in your browser if you have to).
For plugin name, type "BPEDebug".
For SWF Filename, write the name of your SWF (mine is "BPEDebug.swf")
and we need to tick the box next to each hook we used
tick the box next to hookUpdateWindow, hookFinishPluginSetup, hookRecievePacket, hookSendPacket, hookSocketOpen and hookSocketClose.
Once you've done that, click the "Save PEP File" button, and save it to the same location as your plugin SWF.

You're done!
Load your plugin with BPE, hook a server and port (web servers are the easiest for testing),  and if it works, give yourself a pat on the back.
If it doesn't work, try again or  leave a comment.

Here's a link to my finished source.