|
You last visited: Today at 14:41
Advertisement
Developer's Corner
Discussion on Developer's Corner within the DarkOrbit forum part of the Browsergames category.
02/04/2015, 22:43
|
#1
|
elite*gold: 0
Join Date: May 2014
Posts: 662
Received Thanks: 1,154
|
Developer's Corner
Developer's Corner
Welcome to the developer's corner, this thread is a place were developers can talk about their stuff, ask for help for their stuff or learn new stuff without worry about their threads being spammed by people that don't know what is about asking for "I understood a shit, explain me" so if you don't know anything about programming, cracking, reverse engineering or security please, leave this thread to avoid spam
Please, also keep in mind that there's a thread called "PrivateServer - Info and support thread" as its name says, that post is for everything related with private servers, this one is for DarkOrbit related shit.
Some things you might consider:
How does DarkOrbit's encryption works:
-The client sends VersionRequest packet
-Server sends the response and waits for the handshake
-Client sends InjectedObfuscation packet
-Server responds with a packet that contains less than 4096 bytes of ABC (ActionScript ByteCode)
-The client starts an avm2 (ActionScript VirtualMachine 2) and runs the bytes sent from server + the header and footer bytes
-The client ask the server for the ARC4 key
-The server responds with the ARC4 key encrypted with RSA
-Client decrypts RSA and sets the ARC
That's all, it might be wrong, maybe ARC4 key is requested before InjectedObfuscation, also there's something about Pandora's Boxs that you can see when you inject some traces to main.swf
1 More thing about InjectedObfuscation:
This are the header bytes:
Code:
public static const §_-x2f§:Array = [67,87,83,11,227,11,0,0,64,3,192,3,192,0,24,1,0,68,17,25,0,0,0,198,10,97,98,99,95,65,0];
This are the last bytes:
Code:
public static const §_-1A§:Array = [10,19,1,0,0,0,100,105,100,73,68,0,64,0,0,0];
I said that InjectedObfuscation's bytes are less than 4096 because of this:
Code:
public static const §_-i13§:uint = 4096;
//...
public function injectAndBuild(injectedObfuscationBytes:ByteArray, param2:uint, param3:Function) : void
{
this.§_-N24§ = param3;
if(param2 > 0)
{
this.§_-F2O§(param2);
}
if(injectedObfuscationBytes.length < §_-i13§)
{
this.§_-S37§(param1);
}
}
If you want to add something here, post it in the comments.
Hope we can keep this thread up, away from spammers (like me) and usefull for people interested in this shit.
See you!
|
|
|
02/04/2015, 23:09
|
#2
|
elite*gold: 3800
Join Date: Dec 2012
Posts: 13,037
Received Thanks: 8,238
|
Quote:
Originally Posted by manulaiko3.0
Hope we can keep this thread up, away from spammers (like me) and usefull for people interested in this ****.
|
You can just report the spam and the moderator team will look for it
|
|
|
02/05/2015, 01:34
|
#3
|
elite*gold: 0
Join Date: Dec 2008
Posts: 288
Received Thanks: 1,170
|
Hi,
the game works with an DH key-exchange. The both public keys (server and client public key) are encrypted with RSA. First decrypt the public key with RSA, then you can generate the shared key with the DH key-exchange algorithm. The game use the first 16 bytes of the shared key for the ARC4 algorithm. Fine.
The game client receives from the game server a fragmented SWF. The game client use the fragmented SWF to generate a runnable SWF by "injected obfuscation". The generated SWF which loaded the game client, includes a encoder/decoder algorithm which the game client use about the ARC4 algorithm. The darkorbit server send every time a different fragment, a changed encoding/decoding algorithm. The encoding/decoding algorithm about ARC4 is every time different! The game client can't identify the encoding/decoding which the server use about the ARC4 algorithm. The game client execute the swf without care about which encoding/decoding includes in the SWF. Problem.
Bad for the packet bots. You can't identify the algorithm about ARC4 by packets (You're so freaky to identify the algorithm by the fragment size and reverse every fragment which the server can send?). Solution is, that the packet bot use the encoders/decoders includes in the fragmented SWF. (For example your bot has an AS3-Virtualmachine and load the fragmented SWF) Yeah.
But that is not a problem for private servers. You can build a own fragmented SWF with blank encoders/decoders. Your server can send your own. So you've only to implement the ARC4 algorithm.
DH = Diffie Hellman
With regards,
Anohros
|
|
|
02/05/2015, 10:10
|
#4
|
elite*gold: 46
Join Date: Oct 2010
Posts: 782
Received Thanks: 525
|
Hey guys
just wanted to ask wether someone is interested in what I would call a decent packet parsing "api" written in c++.
Some features of it:
- "Automatic" conversion from a packet parameter to it's underlying type (std::string -> what_ever_the_parameter_needs)
- "Automatic" dispatching of packets to a set of given callbacks
Gonna show you some example code:
Code:
// Create a sample string
std::string s = "0|a|1|2|5|0|1";
// Call the appropiate callback. The packet type is found at runtime, so the string does not need to be known at compile time
dispatch<server_packets::all_packets>(s);
// Convert the raw string to a attack_packet
auto packet = to_packet<server_packets::attack_packet>(s);
// Convert the attack_packet to a custom structure
auto attack_info = from_packet<game::attack_information>(packet);
attack_info.attacker_id = 999;
// Get the raw string from the structure
std::string s2 = to_packet<server_packets::attack_packet>(attack_info).raw();
assert(s2 == "0|a|999|2|5|0|1");
This is the code for the actual packet and the conversion functions. It's not too hard to understand aswell I guess. If someone is interested and wants to have the code of this I can share it. But I have to tell you that it makes the compile time somewhat longer.
Code:
class attack_packet : public detail::packet_base < attack_packet >
{
public:
using ThisType = attack_packet;
static const int max_params = 7;
attack_packet() : packet_base() {}
attack_packet(const std::string& s) : packet_base(s) { }
attack_packet(const attack_packet& other) : packet_base(other) { }
attack_packet(attack_packet&& other) : packet_base(other) { }
attack_packet& operator=(const attack_packet& other)
{
packet_base::operator=(other);
return *this;
}
attack_packet& operator=(attack_packet&& other)
{
packet_base::operator=(other);
return *this;
}
struct header : boost::mpl::int_ < 0 > { using TargetType = std::string; using PacketType = ThisType; };
struct sub_header : boost::mpl::int_ < 1 > { using TargetType = std::string; using PacketType = ThisType; };
struct attacker_uid : boost::mpl::int_ < 2 > { using TargetType = std::uint64_t; using PacketType = ThisType; };
struct victim_uid : boost::mpl::int_ < 3 > { using TargetType = std::uint64_t; using PacketType = ThisType; };
struct laser_id : boost::mpl::int_ < 4 > { using TargetType = std::uint16_t; using PacketType = ThisType; };
struct big_shield : boost::mpl::int_ < 5 > { using TargetType = bool; using PacketType = ThisType; };
struct big_laser : boost::mpl::int_ < 6 > { using TargetType = bool; using PacketType = ThisType; };
};
// I did not copy the whole all_packets definition
struct all_packets : boost::mpl::list<create_ship_packet, cloack_packet, attack_packet> {};
template<>
struct from_packet < server_packets::attack_packet >
{
using PacketType = server_packets::attack_packet;
template<typename TargetType>
static TargetType apply(const PacketType& packet);
template<>
static game::attack_information apply(const PacketType& packet)
{
return game::attack_information{
const_get(packet, PacketType::attacker_uid{}),
const_get(packet, PacketType::victim_uid{}),
const_get(packet, PacketType::laser_id{}),
const_get(packet, PacketType::big_shield{}),
const_get(packet, PacketType::big_laser{})
};
}
};
template<>
struct to_packet < server_packets::attack_packet >
{
using PacketType = server_packets::attack_packet;
static void _set_header(PacketType& packet)
{
set(packet, PacketType::header{}, "0");
set(packet, PacketType::sub_header{}, "a");
}
template<typename FromType>
static PacketType apply(const FromType&);
template<>
static PacketType apply(const std::string& str)
{
return PacketType{ str };
}
template<>
static PacketType apply(const game::attack_information& info)
{
PacketType ret;
_set_header(ret);
set(ret, PacketType::attacker_uid{}, info.attacker_id);
set(ret, PacketType::victim_uid{}, info.victim_id);
set(ret, PacketType::laser_id{}, info.laser_id);
set(ret, PacketType::big_shield{}, info.shield_effect);
set(ret, PacketType::big_laser{}, info.big_laser);
return ret;
}
template<typename FromType>
static bool is_convertible(const FromType& from);
template<>
static bool is_convertible(const std::string& from)
{
return !from.empty() && boost::starts_with(from, "0|a");
}
};
|
|
|
02/05/2015, 14:23
|
#5
|
elite*gold: 0
Join Date: May 2014
Posts: 662
Received Thanks: 1,154
|
Quote:
Originally Posted by Anohros
Hi,
the game works with an DH key-exchange. The both public keys (server and client public key) are encrypted with RSA. First decrypt the public key with RSA, then you can generate the shared key with the DH key-exchange algorithm. The game use the first 16 bytes of the shared key for the ARC4 algorithm. Fine.
The game client receives from the game server a fragmented SWF. The game client use the fragmented SWF to generate a runnable SWF by "injected obfuscation". The generated SWF which loaded the game client, includes a encoder/decoder algorithm which the game client use about the ARC4 algorithm. The darkorbit server send every time a different fragment, a changed encoding/decoding algorithm. The encoding/decoding algorithm about ARC4 is every time different! The game client can't identify the encoding/decoding which the server use about the ARC4 algorithm. The game client execute the swf without care about which encoding/decoding includes in the SWF. Problem.
Bad for the packet bots. You can't identify the algorithm about ARC4 by packets (You're so freaky to identify the algorithm by the fragment size and reverse every fragment which the server can send?). Solution is, that the packet bot use the encoders/decoders includes in the fragmented SWF. (For example your bot has an AS3-Virtualmachine and load the fragmented SWF) Yeah.
But that is not a problem for private servers. You can build a own fragmented SWF with blank encoders/decoders. Your server can send your own. So you've only to implement the ARC4 algorithm.
DH = Diffie Hellman
With regards,
Anohros
|
With a kind of ABC parser so we can write ABC directly from C#, C++, Java or any other language (and viceversa) the packet bots will come back.
But untill that happens I will continue with ASBot which will be coded in ActionScript.
See you!
Quote:
Originally Posted by C0untLizzi
Hey guys
just wanted to ask wether someone is interested in what I would call a decent packet parsing "api" written in c++.
Some features of it:
- "Automatic" conversion from a packet parameter to it's underlying type (std::string -> what_ever_the_parameter_needs)
- "Automatic" dispatching of packets to a set of given callbacks
Gonna show you some example code:
Code:
// Create a sample string
std::string s = "0|a|1|2|5|0|1";
// Call the appropiate callback. The packet type is found at runtime, so the string does not need to be known at compile time
dispatch<server_packets::all_packets>(s);
// Convert the raw string to a attack_packet
auto packet = to_packet<server_packets::attack_packet>(s);
// Convert the attack_packet to a custom structure
auto attack_info = from_packet<game::attack_information>(packet);
attack_info.attacker_id = 999;
// Get the raw string from the structure
std::string s2 = to_packet<server_packets::attack_packet>(attack_info).raw();
assert(s2 == "0|a|999|2|5|0|1");
This is the code for the actual packet and the conversion functions. It's not too hard to understand aswell I guess. If someone is interested and wants to have the code of this I can share it. But I have to tell you that it makes the compile time somewhat longer.
Code:
class attack_packet : public detail::packet_base < attack_packet >
{
public:
using ThisType = attack_packet;
static const int max_params = 7;
attack_packet() : packet_base() {}
attack_packet(const std::string& s) : packet_base(s) { }
attack_packet(const attack_packet& other) : packet_base(other) { }
attack_packet(attack_packet&& other) : packet_base(other) { }
attack_packet& operator=(const attack_packet& other)
{
packet_base::operator=(other);
return *this;
}
attack_packet& operator=(attack_packet&& other)
{
packet_base::operator=(other);
return *this;
}
struct header : boost::mpl::int_ < 0 > { using TargetType = std::string; using PacketType = ThisType; };
struct sub_header : boost::mpl::int_ < 1 > { using TargetType = std::string; using PacketType = ThisType; };
struct attacker_uid : boost::mpl::int_ < 2 > { using TargetType = std::uint64_t; using PacketType = ThisType; };
struct victim_uid : boost::mpl::int_ < 3 > { using TargetType = std::uint64_t; using PacketType = ThisType; };
struct laser_id : boost::mpl::int_ < 4 > { using TargetType = std::uint16_t; using PacketType = ThisType; };
struct big_shield : boost::mpl::int_ < 5 > { using TargetType = bool; using PacketType = ThisType; };
struct big_laser : boost::mpl::int_ < 6 > { using TargetType = bool; using PacketType = ThisType; };
};
// I did not copy the whole all_packets definition
struct all_packets : boost::mpl::list<create_ship_packet, cloack_packet, attack_packet> {};
template<>
struct from_packet < server_packets::attack_packet >
{
using PacketType = server_packets::attack_packet;
template<typename TargetType>
static TargetType apply(const PacketType& packet);
template<>
static game::attack_information apply(const PacketType& packet)
{
return game::attack_information{
const_get(packet, PacketType::attacker_uid{}),
const_get(packet, PacketType::victim_uid{}),
const_get(packet, PacketType::laser_id{}),
const_get(packet, PacketType::big_shield{}),
const_get(packet, PacketType::big_laser{})
};
}
};
template<>
struct to_packet < server_packets::attack_packet >
{
using PacketType = server_packets::attack_packet;
static void _set_header(PacketType& packet)
{
set(packet, PacketType::header{}, "0");
set(packet, PacketType::sub_header{}, "a");
}
template<typename FromType>
static PacketType apply(const FromType&);
template<>
static PacketType apply(const std::string& str)
{
return PacketType{ str };
}
template<>
static PacketType apply(const game::attack_information& info)
{
PacketType ret;
_set_header(ret);
set(ret, PacketType::attacker_uid{}, info.attacker_id);
set(ret, PacketType::victim_uid{}, info.victim_id);
set(ret, PacketType::laser_id{}, info.laser_id);
set(ret, PacketType::big_shield{}, info.shield_effect);
set(ret, PacketType::big_laser{}, info.big_laser);
return ret;
}
template<typename FromType>
static bool is_convertible(const FromType& from);
template<>
static bool is_convertible(const std::string& from)
{
return !from.empty() && boost::starts_with(from, "0|a");
}
};
|
Nice idea, the problem is that it will be only for private servers, and here there are not much private server developers that works in C++, although that I personally would like to see the project finish and learn new things
See you!
|
|
|
02/06/2015, 02:16
|
#6
|
elite*gold: 0
Join Date: Oct 2014
Posts: 84
Received Thanks: 100
|
I think that this thread should probably be stick'd, that way people can see the official thread and all developers will have a place to talk and share things with each other.
#VoteForSticky
Regards,
Jacob
|
|
|
02/06/2015, 02:16
|
#7
|
elite*gold: 0
Join Date: Jan 2014
Posts: 466
Received Thanks: 446
|
#StickyMaybe This Would be good place for all the DO P-server/Bot Developers To HangOut and get some advice and tips from other developers to improve their projects.
Edit!
Damint Asus you said it first xD
|
|
|
02/06/2015, 02:23
|
#8
|
elite*gold: 3800
Join Date: Dec 2012
Posts: 13,037
Received Thanks: 8,238
|
Quote:
Originally Posted by DarkSkiesDO
I think that this thread should probably be stick'd, that way people can see the official thread and all developers will have a place to talk and share things with each other.
#VoteForSticky
Regards,
Jacob
|
Quote:
Originally Posted by Real.epvp
#StickyMaybe This Would be good place for all the DO P-server/Bot Developers To HangOut and get some advice and tips from other developers to improve their projects.
Edit!
Damint Asus you said it first xD
|
I already told Asus in Skype, but a topic needs some activity to get sticky. If the other moderators are okay with this and there is some decent activity, it can be sticked.
|
|
|
02/06/2015, 02:33
|
#9
|
elite*gold: 0
Join Date: Jan 2014
Posts: 466
Received Thanks: 446
|
Quote:
I already told Asus in Skype, but a topic needs some activity to get sticky. If the other moderators are okay with this and there is some decent activity, it can be sticked.
|
Okay So Let's Start To get this thread Active It's a great way for all the developers to get along and help each other With there codes and also like i said for tips and advice
|
|
|
02/06/2015, 02:33
|
#10
|
elite*gold: 0
Join Date: May 2014
Posts: 662
Received Thanks: 1,154
|
Is this game unhackable or what? I've tried to modfy and inject request almost in 70% of DarkOrbit html and nothing -.- I'll need to look deeper.
According to ASBot: I've already established a connection with DO servers and sent (and received obviusly) some packets. I found something kinda funny, if the VersionRequest packet is different than server's version it gives you................ A BAN!!! (at least a kick for me, after that I can't enter to the dummy account :P) This means that if you're unlucky and DO updates their server and your browser loads a cached version of main.swf you will receive a cool gift
|
|
|
02/06/2015, 03:31
|
#11
|
elite*gold: 237
Join Date: Sep 2010
Posts: 1,152
Received Thanks: 4,910
|
The encryption is just a toy to discourage developers from bots. Its trivial at best to bypass. You can all say "I have made a bot" but the difficulty in packet bots these days isn't any of their encryption, its the way they update their client.
Every update they randomize the ordering of variables in their packets. One version it might be UID, X, Y, Movement Time the next it might be Y, UID, Movement Time, X. You just never know. Going through every packet which is highly obfuscated and trying to figure out what everything does for over 40 packets (and thats a light weight bot) is not worth the time. Mr.Smith and I did a few updates of PBDO-Bot by hand but we had a lot of help from the tools we developed. Eventually it wasn't worth the time and we had to rethink our strategy. I'm considering writing a post in a sort of journal form of everything thats happened over the last 4 years in DarkOrbit from my point of view as a bot developer. I might not be able to remember everything but some people might find it interesting. Anyone?
|
|
|
02/06/2015, 03:58
|
#12
|
elite*gold: 0
Join Date: Oct 2014
Posts: 84
Received Thanks: 100
|
Quote:
Originally Posted by »jD«
The encryption is just a toy to discourage developers from bots. Its trivial at best to bypass. You can all say "I have made a bot" but the difficulty in packet bots these days isn't any of their encryption, its the way they update their client.
Every update they randomize the ordering of variables in their packets. One version it might be UID, X, Y, Movement Time the next it might be Y, UID, Movement Time, X. You just never know. Going through every packet which is highly obfuscated and trying to figure out what everything does for over 40 packets (and thats a light weight bot) is not worth the time. Mr.Smith and I did a few updates of PBDO-Bot by hand but we had a lot of help from the tools we developed. Eventually it wasn't worth the time and we had to rethink our strategy. I'm considering writing a post in a sort of journal form of everything thats happened over the last 4 years in DarkOrbit from my point of view as a bot developer. I might not be able to remember everything but some people might find it interesting. Anyone?
|
Sure, I'm up to hear about it all »jD«, also one question. Did you go inactive on Skype? I never got to finish talking to you before, last we talked was when you went and was setting up your server :P
Anyways, if you changed your Skype, please re-add me. Skype name: reptilen13
I would like to speak to you in private rather than use the PM system on here and all as it's a hassle to wait for it to all load and etc.
Regards,
Jacob
|
|
|
02/06/2015, 04:02
|
#13
|
elite*gold: 237
Join Date: Sep 2010
Posts: 1,152
Received Thanks: 4,910
|
I have two skypes, one I use personally and one I use for "other stuff". I hardly ever go on my other one. I'll sign into my other one sometime.
-jD
|
|
|
02/06/2015, 07:46
|
#14
|
elite*gold: 0
Join Date: May 2014
Posts: 662
Received Thanks: 1,154
|
Quote:
Originally Posted by »jD«
The encryption is just a toy to discourage developers from bots. Its trivial at best to bypass. You can all say "I have made a bot" but the difficulty in packet bots these days isn't any of their encryption, its the way they update their client.
Every update they randomize the ordering of variables in their packets. One version it might be UID, X, Y, Movement Time the next it might be Y, UID, Movement Time, X. You just never know. Going through every packet which is highly obfuscated and trying to figure out what everything does for over 40 packets (and thats a light weight bot) is not worth the time. Mr.Smith and I did a few updates of PBDO-Bot by hand but we had a lot of help from the tools we developed. Eventually it wasn't worth the time and we had to rethink our strategy. I'm considering writing a post in a sort of journal form of everything thats happened over the last 4 years in DarkOrbit from my point of view as a bot developer. I might not be able to remember everything but some people might find it interesting. Anyone?
|
Untill a magic tool that deobfuscates and analizes swf files bots won't come back to stay, I'm sure of that. But the prupouse of ASBot is for pure knowledge so I don't care if it's down each week and I have to rewrite packets by hand.
See you!
|
|
|
02/06/2015, 22:38
|
#15
|
elite*gold: 820
Join Date: May 2009
Posts: 1,748
Received Thanks: 5,339
|
Quote:
Originally Posted by »jD«
The encryption is just a toy to discourage developers from bots. Its trivial at best to bypass. You can all say "I have made a bot" but the difficulty in packet bots these days isn't any of their encryption, its the way they update their client.
Every update they randomize the ordering of variables in their packets. One version it might be UID, X, Y, Movement Time the next it might be Y, UID, Movement Time, X. You just never know. Going through every packet which is highly obfuscated and trying to figure out what everything does for over 40 packets (and thats a light weight bot) is not worth the time. Mr.Smith and I did a few updates of PBDO-Bot by hand but we had a lot of help from the tools we developed. Eventually it wasn't worth the time and we had to rethink our strategy. I'm considering writing a post in a sort of journal form of everything thats happened over the last 4 years in DarkOrbit from my point of view as a bot developer. I might not be able to remember everything but some people might find it interesting. Anyone?
|
They are doing the same method in Seafight.
At first it may seem impossible, but if you understand the context of each command you are able to get the right ordering.
For example the Login Command definitely has a sid string and an uid integer: So you are searching for a class that derives from the Command class and has these parameters -> There is just one, done.
There are a lot more parameters you can use to build a protocol updater.
I did the same thing with my "Marid" tool in Seafight and now it's just a simple "./protocol_updater main.swf > protocol.dat" and the bot is online again.
I think the biggest problem nowadays is it to make your program safe and prevent bans.
It's just not possible to check all the time in the Client if they changed a Byte or two in their protocol. (Maybe with huge effort if you write a tool that completely takes control of most aspects of their as3 protocol code)
But Bigpoint may do this and your program is unsafe from one moment to another. (Again, this is just the case for packet bots)
Just look at Merkava. IMO, their effort is just useless: BP makes use of this method to ban all of their customers and nobody wants to use their program anymore.
|
|
|
|
|
Similar Threads
|
GFX-CorneR | The Corner for GFXer
10/03/2012 - General Art - 4 Replies
Guten Tag ePvPers Community,
Mir kam gestern der Gedankenschuss ein Forum zu eröffnen, in dem es nur ums GFXen, etc. geht. Mir ist klar dass es schon einen Haufen, voll von solchen Foren gibt, jedoch wollte ich einfach mal ein Projekt, für ein solches starten. Falls ihr Lust und Interesse habt, registriert euch doch einfach mal. Da ich einfach nur eines der vorhandenen "PHPbb3" Themes genommen habe, und diese Buttons umgefärbt habe, ist das Forum u.U. noch ein wenig verbuggt, da ich aber,...
|
Going back to the corner, where I first saw you
12/30/2011 - RF Online - 2 Replies
Hey guys!!! Been a long time since I played RF haha.... so what are the new hacks available these days??? 2.2.3 isnt it???
|
2 Very important suggestion for web developer from experienced developer [English]]
11/21/2011 - General Coding - 0 Replies
I have been developing websites now over 3 years now. My biggest regret is i started developing web sites without knowing CSS & Jquery. Yes before starting development learn CSS 3 and Jquery. These are even more important than your programming skills :) And they are hard to fix once you developed without knowing them.
|
Geo Three Corner
06/04/2011 - Main - 1 Replies
YouTube - ‪Buddy Ogün - THE GAME - Der Deal‬‏
|
All times are GMT +1. The time now is 14:41.
|
|