Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Hearthstone: an analysis of game network protocols
Andrea Del Fiandra & Marco Cuciniello
MILAN 25-26 NOVEMBER 2016
Wow
Such surprise
Very unpredictable
What are google protocol buffers?
• data serialization format
• flexible and efficient
• easily portable
How do protocol buffers work?
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;...
Games using protocol buffers
github.com/Armax/Pokemon-GO-node-api
github.com/Armax/Elix
Back to Hearthstone
halp pls
Time for decompilation
How to extract .proto files
github.com/HearthSim/proto-extractor
Packets used during a Hearthstone match
{
"1": "GetGameState",
"2": "ChooseOption",
"3": "ChooseEntities",
"11": "Concede"...
Packets used during a Hearthstone match
Handshake
message Handshake {
enum PacketID {
ID = 168;
}
required int32 game_hand...
Packets used during a Hearthstone match
GameSetup
message GameSetup {
enum PacketID {
ID = 16;
}
required int32 board = 1;...
Packets used during a Hearthstone match
Ping & Pong
message Ping {
enum PacketID {
ID = 115;
}
}
message Pong {
enum Packe...
Packets used during a Hearthstone match
PowerHistory
message PowerHistory {
enum PacketID {
ID = 19;
}
repeated PowerHisto...
Packets used during a Hearthstone match
PowerHistoryEntity
message PowerHistoryEntity {
required int32 entity = 1;
require...
Packets used during a Hearthstone match
EntityChoices
message EntityChoices {
enum PacketID {
ID = 17;
}
required int32 id...
Implementation
Demo Time
What we learnt
Encryption
Encryption
Encryption
// Modules
var ProtoBuf = require('protobufjs');
var PegasusPacket = require('./pegasuspacket').PegasusPacket;
var net = r...
net.createServer(function(sock) {
console.log('[+] connection from: ' + sock.remoteAddress +':'+ sock.remotePort);
sock.on...
Demo Time
Server / Client
Q & A Time!
Thanks for your attention
Marco Cuciniello - arm4x@becreatives.com
Andrea Del Fiandra - delfioh@gmail.com
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016
Prochain SlideShare
Chargement dans…5
×

Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016

934 vues

Publié le

In this talk we will delve into one of the most played games of the moment: Blizzard Interactive's Hearthstone. We will focus on analysing Hearthstone's implementation of Google Protocol Buffers and proceed to show how the game handles communication by providing some code examples and by showing how to create a Deck Tracking application.

Publié dans : Technologie
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Hearthstone: an analysis of game network protocols - Marco Cuciniello, Andrea Del Fiandra - Codemotion Milan 2016

  1. 1. Hearthstone: an analysis of game network protocols Andrea Del Fiandra & Marco Cuciniello MILAN 25-26 NOVEMBER 2016
  2. 2. Wow Such surprise Very unpredictable
  3. 3. What are google protocol buffers? • data serialization format • flexible and efficient • easily portable
  4. 4. How do protocol buffers work? message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; }
  5. 5. Games using protocol buffers github.com/Armax/Pokemon-GO-node-api github.com/Armax/Elix
  6. 6. Back to Hearthstone
  7. 7. halp pls Time for decompilation
  8. 8. How to extract .proto files github.com/HearthSim/proto-extractor
  9. 9. Packets used during a Hearthstone match { "1": "GetGameState", "2": "ChooseOption", "3": "ChooseEntities", "11": "Concede", "13": "EntitiesChosen", "14": "AllOptions", "15": "UserUI", "16": "GameSetup", "17": "EntityChoices", "19": "PowerHistory", "24": "SpectatorNotify", "115": "Ping", "116": "Pong", "168": "Handshake" }
  10. 10. Packets used during a Hearthstone match Handshake message Handshake { enum PacketID { ID = 168; } required int32 game_handle = 1; required string password = 2; required int64 client_handle = 3; optional int32 mission = 4; required string version = 5; required PegasusShared.Platform platform = 7; }
  11. 11. Packets used during a Hearthstone match GameSetup message GameSetup { enum PacketID { ID = 16; } required int32 board = 1; required int32 max_secrets_per_player = 2; required int32 max_friendly_minions_per_player = 3; optional int32 keep_alive_frequency_seconds = 4; optional int32 disconnect_when_stuck_seconds = 5; }
  12. 12. Packets used during a Hearthstone match Ping & Pong message Ping { enum PacketID { ID = 115; } } message Pong { enum PacketID { ID = 116; } }
  13. 13. Packets used during a Hearthstone match PowerHistory message PowerHistory { enum PacketID { ID = 19; } repeated PowerHistoryData list = 1; } message PowerHistoryData { optional PowerHistoryEntity full_entity = 1; optional PowerHistoryEntity show_entity = 2; optional PowerHistoryHide hide_entity = 3; optional PowerHistoryTagChange tag_change = 4; optional PowerHistoryCreateGame create_game = 5; optional PowerHistoryStart power_start = 6; optional PowerHistoryEnd power_end = 7; optional PowerHistoryMetaData meta_data = 8; optional PowerHistoryEntity change_entity = 9;
  14. 14. Packets used during a Hearthstone match PowerHistoryEntity message PowerHistoryEntity { required int32 entity = 1; required string name = 2; repeated Tag tags = 3; }
  15. 15. Packets used during a Hearthstone match EntityChoices message EntityChoices { enum PacketID { ID = 17; } required int32 id = 1; required int32 choice_type = 2; required int32 count_min = 4; required int32 count_max = 5; repeated int32 entities = 6 [packed = true]; optional int32 source = 7; required int32 player_id = 8; }
  16. 16. Implementation
  17. 17. Demo Time
  18. 18. What we learnt
  19. 19. Encryption
  20. 20. Encryption
  21. 21. Encryption
  22. 22. // Modules var ProtoBuf = require('protobufjs'); var PegasusPacket = require('./pegasuspacket').PegasusPacket; var net = require('net'); var client = new net.Socket(); var builder = ProtoBuf.loadProtoFile(__dirname + '/proto/game.proto'); var PegasusGame = builder.build(); var serverIp = "127.0.0.1" var handshake = "qAAAAFkAAAAIpoKkChIGY0RnZ2xvGLmgmQIgggIqBjI4OTYwNjo6CAIQBBoOTWFjQm9va1BybzExLDUqJEJBQTVGNzV handshake.game_handle = 1; // Crafting ping packet var ping = new PegasusGame.PegasusGame.Ping(); var encoded_ping = PegasusGame.PegasusGame.Ping.encode(ping); var type = PegasusGame.PegasusGame.Ping.PacketID.ID; var pegasus_ping = new PegasusPacket(); var encoded_pegasus_ping = pegasus_ping.Encode(encoded_ping, type); // Craft USERUI packet var userui = new PegasusGame.PegasusGame.UserUI(); userui.mouse_info = null; userui.emote = 4; userui.player_id = null; var encoded_userui = PegasusGame.PegasusGame.UserUI.encode(userui); var type_userui = PegasusGame.PegasusGame.UserUI.PacketID.ID; var pegasus_userui = new PegasusPacket(); var encoded_pegasus_userui = pegasus_ping.Encode(encoded_userui, type_userui); client.connect(3724, serverIp, function() { client.write(Buffer.from(args.options.handshake, 'base64')); setInterval(function() { console.log("[+] ping sent"); client.write(encoded_pegasus_ping); }, 5000); setInterval(function() { client.write(encoded_pegasus_userui); }, 1000);
  23. 23. net.createServer(function(sock) { console.log('[+] connection from: ' + sock.remoteAddress +':'+ sock.remotePort); sock.on('data', function(data) { var pegasuspacket = new PegasusPacket(); var bytes_decoded = pegasuspacket.Decode(data, 0, data.length); if(bytes_decoded >= 4) { var decoded = Hearthnode.Decode(pegasuspacket); if(decoded != null && decoded != "unimplemented") { // Handling console.log(pegasuspacket.Type); switch(pegasuspacket.Type) { // Handshake case 168: console.log("[i] Received handshake from client"); console.log(decoded); // Reply with GameSetup var GameSetup = new PegasusGame.PegasusGame.GameSetup(); GameSetup.board = 6; GameSetup.max_secrets_per_player = 5; GameSetup.max_friendly_minions_per_player = 7; GameSetup.keep_alive_frequency_seconds = 5; GameSetup.disconnect_when_stuck_seconds = 25; var encoded_GameSetup = PegasusGame.PegasusGame.GameSetup.encode(GameSetup); var type = PegasusGame.PegasusGame.GameSetup.PacketID.ID; var pegasus_GameSetup = new PegasusPacket(); var encoded_pegasus_GameSetup = pegasus_GameSetup.Encode(encoded_GameSetup, type); sock.write(encoded_pegasus_GameSetup); break; case 115: // Crafting ping packet console.log("[i] Received ping from client"); console.log(decoded) var Pong = new PegasusGame.PegasusGame.Pong(); var encoded_Pong = PegasusGame.PegasusGame.Pong.encode(Pong); var type = PegasusGame.PegasusGame.Pong.PacketID.ID; var pegasus_Pong = new PegasusPacket(); var encoded_pegasus_Pong = pegasus_ping.Encode(encoded_Pong, type); sock.write(encoded_pegasus_Pong); break; case 15: // Received UserUI console.log("[i] Received UserUI"); console.log(decoded);
  24. 24. Demo Time
  25. 25. Server / Client
  26. 26. Q & A Time!
  27. 27. Thanks for your attention Marco Cuciniello - arm4x@becreatives.com Andrea Del Fiandra - delfioh@gmail.com

×