Skip to content

Commit 8ec9d42

Browse files
authored
Merge pull request #16 from BNETDocs/statstrings
fix(enterchat): fixing statstring buffer overwrite of product
2 parents e2178cd + 4583993 commit 8ec9d42

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

src/Atlasd/Battlenet/Protocols/Game/Messages/SID_ENTERCHAT.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using System.IO;
6+
using System.Linq;
67
using System.Text;
78

89
namespace Atlasd.Battlenet.Protocols.Game.Messages
@@ -51,17 +52,10 @@ public override bool Invoke(MessageContext context)
5152

5253
var productId = (UInt32)gameState.Product;
5354

54-
// Statstring length is either 0 bytes or 4-128 bytes, not including the null-terminator.
55-
if (statstring.Length != 0 && (statstring.Length < 4 || statstring.Length > 128))
55+
// Statstring has a maximum length of 128 bytes
56+
if (statstring.Length > 128)
5657
throw new GameProtocolViolationException(context.Client, $"Client sent invalid statstring size in {MessageName(Id)}");
5758

58-
if (statstring.Length < 4) statstring = new byte[4];
59-
60-
using var _m = new MemoryStream(statstring);
61-
using var _w = new BinaryWriter(_m);
62-
_w.BaseStream.Position = 0;
63-
_w.Write(productId); // ensure first 4 bytes of statstring always matches their agreed upon productId
64-
6559
return new SID_ENTERCHAT().Invoke(new MessageContext(context.Client, MessageDirection.ServerToClient,
6660
new Dictionary<string, dynamic>(){{ "username", username }, { "statstring", statstring }})
6761
);
@@ -72,9 +66,14 @@ public override bool Invoke(MessageContext context)
7266
var statstring = context.Arguments.ContainsKey("statstring") ? (byte[])context.Arguments["statstring"] : gameState.Statstring;
7367
var accountName = gameState.Username;
7468

69+
if (Product.IsDiabloII(gameState.Product))
70+
{
71+
statstring = Product.ToByteArray(gameState.Product);
72+
}
73+
7574
// Do not use client-provided statstring if config.battlenet.emulation.statstring_updates is not enabled for this product.
7675
// Blizzard servers allowed statstring updates for Diablo, Diablo II (changing characters), Warcraft III (changing icons), and Shareware variants.
77-
if (!GameState.CanStatstringUpdate(gameState.Product)) statstring = gameState.GenerateStatstring();
76+
if (!GameState.CanStatstringUpdate(gameState.Product) || statstring.Length == 0) statstring = gameState.GenerateStatstring();
7877

7978
/**
8079
* (STRING) Unique name

src/Atlasd/Battlenet/Protocols/Game/Messages/SID_QUERYREALMS2.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ public override bool Invoke(MessageContext context)
4242
}
4343
case MessageDirection.ServerToClient:
4444
{
45-
Dictionary<byte[], byte[]> realms = context.Arguments.ContainsKey("realms") ? (Dictionary<byte[], byte[]>)context.Arguments["realms"] : new Dictionary<byte[], byte[]>();
45+
Logging.WriteLine(Logging.LogLevel.Debug, Logging.LogType.Client_Game, context.Client.RemoteEndPoint, $"[{Common.DirectionToString(context.Direction)}] {MessageName(Id)} ({4 + Buffer.Length} bytes)");
46+
47+
Dictionary<byte[], byte[]> realms =
48+
context.Arguments == null || !context.Arguments.ContainsKey("realms") ?
49+
new Dictionary<byte[], byte[]>() :
50+
(Dictionary<byte[], byte[]>)context.Arguments["realms"];
4651

4752
/**
4853
* (UINT32) Unknown (0)

0 commit comments

Comments
 (0)