As everyone has probably noticed, I've moved on in life. This will likely be the last post I put on this blog.
I've become a more or less functional adult working in the tech industry (shocking, I know!).
I've long since moved away from any morally- or ethically-questionable applications of hacking and reverse-engineering. I still reverse-engineer applications and games as a hobby (though only single-player, and for the purposes of modding rather than cheating/hacking). I haven't touched flash in many years, and I don't plan on changing that.
I've mostly cut ties with my "bmanatee" alias. I don't particularly want the actions of my dumb teenage self following me forever.
I still check my CheatEngine PMs once or twice a year, so if you want to contact me, that's probably the best way.
Wishing you all the best,
Bmanatee.
Bmanatee's blog
Saturday, January 5, 2019
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.
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.
Labels:
actionscript,
AS3,
AVM2,
bmanatee,
cheat,
disassembler,
encryption,
flash,
hacking,
injection,
obfuscation,
reassembler
Saturday, November 30, 2013
A momentary lapse in existance
So, you might have noticed I've disappeared under a rock for the time being.
I'm working on a few big, exciting new projects right now that I can't say a huge amount about.
I guess you could say the last year or so of my flash hacking has kind of been leading up to these projects, and they should blow some minds when they get released.
It's gonna be a few months before I can start to shed light on then, and until I can I probably won't be making much in the way of new posts here.
So basically, I'm probably going to be inactive for a couple months.
I'll release more info when I can.
I'm working on a few big, exciting new projects right now that I can't say a huge amount about.
I guess you could say the last year or so of my flash hacking has kind of been leading up to these projects, and they should blow some minds when they get released.
It's gonna be a few months before I can start to shed light on then, and until I can I probably won't be making much in the way of new posts here.
So basically, I'm probably going to be inactive for a couple months.
I'll release more info when I can.
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:
From the gameLoop function:
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.
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.
Packet editor progress #8
Work on BPE has been going slow lately, as usual.
Adding UDP support creates a whole lot of problems.
The only "good" way of doing it is binding to the UDP port on each IP that's been hooked, which is messy and generally a pain to implement.
It seems like that's the only option, though since the AIR DatagramSocket doesn't allow you to get the destination IP address of an incoming packet if you bind 0.0.0.0 (their address for binding to all incoming addresses)
The good news is that gives me a reason to redesign BPE a little bit. For a while now, I've been thinking it would be good to manage hooked ports on a per-server basis, instead of having to hook ports on all servers. The bad news is making that work will require some pretty huge modifications, which will take some time.
I'm thinking for now I might just make it you can only hook one UDP server, since I can't think of a clean solution for multiple UDP hooks right now. Plus, the only use I've found for hooking UDP is DNS requests which would only require one server hook anyway.
So, it's highly likely 1.3 will only have partial UDP support.
I'm also modifying the socket open hook so that plugins can redirect connections. This is useful for games that use more than one server. You could for example use it to write a plugin that allows you to choose from one of many private servers.
I'll probably release an example plugin using it which works as a quickstart server/game chooser for Stick Arena and/or BBH.
I haven't started work on the server/port adding plugin hooks, but they should be simple enough to add. I still plan on putting them in the next release, since those hooks and UDP support would be a powerful combination allowing me to automatically hook servers, as I have mentioned before.
While I'm at it I might as well mention I'm currently working on a new tutorial on SWF bytecode modification. Just the basics.
It's going to be really detailed, since I haven't seen any really in-depth tutorials out there on the subject.
Be warned, though. I'm not even half way done and it's already stupidly long.
Adding UDP support creates a whole lot of problems.
The only "good" way of doing it is binding to the UDP port on each IP that's been hooked, which is messy and generally a pain to implement.
It seems like that's the only option, though since the AIR DatagramSocket doesn't allow you to get the destination IP address of an incoming packet if you bind 0.0.0.0 (their address for binding to all incoming addresses)
The good news is that gives me a reason to redesign BPE a little bit. For a while now, I've been thinking it would be good to manage hooked ports on a per-server basis, instead of having to hook ports on all servers. The bad news is making that work will require some pretty huge modifications, which will take some time.
I'm thinking for now I might just make it you can only hook one UDP server, since I can't think of a clean solution for multiple UDP hooks right now. Plus, the only use I've found for hooking UDP is DNS requests which would only require one server hook anyway.
So, it's highly likely 1.3 will only have partial UDP support.
I'm also modifying the socket open hook so that plugins can redirect connections. This is useful for games that use more than one server. You could for example use it to write a plugin that allows you to choose from one of many private servers.
I'll probably release an example plugin using it which works as a quickstart server/game chooser for Stick Arena and/or BBH.
I haven't started work on the server/port adding plugin hooks, but they should be simple enough to add. I still plan on putting them in the next release, since those hooks and UDP support would be a powerful combination allowing me to automatically hook servers, as I have mentioned before.
While I'm at it I might as well mention I'm currently working on a new tutorial on SWF bytecode modification. Just the basics.
It's going to be really detailed, since I haven't seen any really in-depth tutorials out there on the subject.
Be warned, though. I'm not even half way done and it's already stupidly long.
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.
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.
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 |
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.
Labels:
actionscript,
adobe,
AS3,
AVM2,
cheat,
class,
flash,
hack,
hacking,
obfuscation,
programming,
swf
Wednesday, June 5, 2013
Server-sided values
Someone (Jazy) mentioned server-sided values in a comment today-ish, so I've decided I'm going to do a long-ass post explaining in detail just what server-sided means in hacking.
server-sided is a term used too often and too generally, usually by people who don't understand it.
The concept of server sidedness is relatively simple.
data that is stored and processed by the client is said to be client sided, and data that is stored and processed by a server, or any other computer you don't have direct access to is said to be server sided.
However, these phrases are a bit ambiguous, and the more hacking you do, the more you will find that there is in fact a fair bit of overlap between them.
In reality, the vast majority of the time when people say something is "server sided", it means that no one has discovered a way of hacking it, as opposed to it being unhackable.
in theory, the only way of changing fully server-sided values, values which the client has absolutely no influence on, is by gaining access to the server the values are stored on, which is not only usually incredibly difficult but also highly illegal. Like, jail time illegal.
However, since the majority of the time people use the term "server-sided" much more loosely, a lot of the time it is still possible to hack things people have deemed "server-sided". It usually requires doing some pretty low-level hacking (hacking with very little abstraction), though.
Packet editors are wonderful for this, as packet editors give you raw access to the communication channel between the client and the server. As a general rule, if a value on a server is hackable then a good packet editor can hack it.
A good example someone told me of how server sided values work:
Imagine you are playing a game with a friend. They pick a random number, and you have to guess it.
Your friend picks the number 5.
You guess the number 7.
He tells you you are wrong.
In this situation, your friend is the server and the number he picked is the server-sided value.
You have no control over the number he picks. The only thing you can change is the number you guess, which is a client-sided value.
Trying to hack a server-sided value is like trying to tell your friend that he cannot have chosen 5 because you said he chose 7, which makes no sense.
An example of a "server-side" value hack would be my boxhead bounty hunter money hack.
In boxhead bounty hunter, money is server sided. Every purchase you make with the in-game currency is processed by the server, and there is no way to directly set your money. You can't even tell the server you gained X money. I did however manage to indirectly hack the value by sending a packet to the server whenever a new money pickup was dropped saying "I picked up money drop #X", which meant I would gain money so fast it was effectively the same as being able to change my money directly.
In summary, there are two ways people use the term "server-sided":
1) A value stored/processed/ect by the server
2) A value stored/processed/ect by the server that the client has no influence on
Personally, I find it's best practice to only use the second use of the word.
And a tip to everyone out there: use the terms "server-sided" and "impossible" as sparingly as you can, cause when it comes to hacking almost anything is possible if you know how.
Also, for the record: most hackers just throw the term "server-sided" around to scare newbies. It's usually their way of politely saying "stop spamming me asking me to hack this goddam game" or "hacking this game is probably wayyy above your skill level".
server-sided is a term used too often and too generally, usually by people who don't understand it.
The concept of server sidedness is relatively simple.
data that is stored and processed by the client is said to be client sided, and data that is stored and processed by a server, or any other computer you don't have direct access to is said to be server sided.
However, these phrases are a bit ambiguous, and the more hacking you do, the more you will find that there is in fact a fair bit of overlap between them.
In reality, the vast majority of the time when people say something is "server sided", it means that no one has discovered a way of hacking it, as opposed to it being unhackable.
in theory, the only way of changing fully server-sided values, values which the client has absolutely no influence on, is by gaining access to the server the values are stored on, which is not only usually incredibly difficult but also highly illegal. Like, jail time illegal.
However, since the majority of the time people use the term "server-sided" much more loosely, a lot of the time it is still possible to hack things people have deemed "server-sided". It usually requires doing some pretty low-level hacking (hacking with very little abstraction), though.
Packet editors are wonderful for this, as packet editors give you raw access to the communication channel between the client and the server. As a general rule, if a value on a server is hackable then a good packet editor can hack it.
A good example someone told me of how server sided values work:
Imagine you are playing a game with a friend. They pick a random number, and you have to guess it.
Your friend picks the number 5.
You guess the number 7.
He tells you you are wrong.
In this situation, your friend is the server and the number he picked is the server-sided value.
You have no control over the number he picks. The only thing you can change is the number you guess, which is a client-sided value.
Trying to hack a server-sided value is like trying to tell your friend that he cannot have chosen 5 because you said he chose 7, which makes no sense.
An example of a "server-side" value hack would be my boxhead bounty hunter money hack.
In boxhead bounty hunter, money is server sided. Every purchase you make with the in-game currency is processed by the server, and there is no way to directly set your money. You can't even tell the server you gained X money. I did however manage to indirectly hack the value by sending a packet to the server whenever a new money pickup was dropped saying "I picked up money drop #X", which meant I would gain money so fast it was effectively the same as being able to change my money directly.
In summary, there are two ways people use the term "server-sided":
1) A value stored/processed/ect by the server
2) A value stored/processed/ect by the server that the client has no influence on
Personally, I find it's best practice to only use the second use of the word.
And a tip to everyone out there: use the terms "server-sided" and "impossible" as sparingly as you can, cause when it comes to hacking almost anything is possible if you know how.
Also, for the record: most hackers just throw the term "server-sided" around to scare newbies. It's usually their way of politely saying "stop spamming me asking me to hack this goddam game" or "hacking this game is probably wayyy above your skill level".
Labels:
editor,
flash,
hack,
hacking,
multiplayer,
packet,
server,
server-sided,
sided
Subscribe to:
Posts (Atom)