http://www.bnetdocs.org/verbyte.html
Open source release motivated by Don Cullen, and you know what it is ;)
* Made a mistake, SEC_IMAGE from CreateFileMapping should be removed :o
Well, that simplifies matters a bit, doesn't it?
Got bored and ported it to vb:
Option Explicit
Private Declare Sub RtlMoveMemory Lib "kernel32" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Sub Form_Load()
Dim sData As String
Dim I As Long
Dim FindStr As String
Dim RVal As Long
Open "C:\Path\To\STAR\Starcraft.exe" For Binary Access Read As #1
sData = Space(LOF(1))
Get #1, , sData
Close #1
FindStr = Chr$(&HC7) & Chr$(&H46) & Chr$(&H10) & "????" & Chr$(&HC7) & Chr$(&H46) & Chr$(&H18) & "????" & Chr$(&HC7) & Chr$(&H46)
For I = 1 To Len(sData)
If Mid$(sData, I, 16) Like FindStr Then
RtlMoveMemory RVal, ByVal Mid$(sData, I + 3, 4), 4
End If
Next I
Debug.Print "VerByte: " & RVal
End Sub
(And no, I'm not planning on using it or taking any credit)
Edit: Works for War2 as well.
Thanks DevCode for releasing it, it is certainly much appreciated. :)
Quote from: devcode on October 16, 2007, 08:52 PM
* Made a mistake, SEC_IMAGE from CreateFileMapping should be removed :o
and yea, guess it works for W2BN as well, not for any other games though, at least with the supplied pattern.
Quote from: Andy on October 16, 2007, 09:14 PM
Well, that simplifies matters a bit, doesn't it?
Got bored and ported it to vb:
Option Explicit
Private Declare Sub RtlMoveMemory Lib "kernel32" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Sub Form_Load()
Dim sData As String
Dim I As Long
Dim FindStr As String
Dim RVal As Long
Open "C:\Path\To\STAR\Starcraft.exe" For Binary Access Read As #1
sData = Space(LOF(1))
Get #1, , sData
Close #1
FindStr = Chr$(&HC7) & Chr$(&H46) & Chr$(&H10) & "????" & Chr$(&HC7) & Chr$(&H46) & Chr$(&H18) & "????" & Chr$(&HC7) & Chr$(&H46)
For I = 1 To Len(sData)
If Mid$(sData, I, 16) Like FindStr Then
RtlMoveMemory RVal, ByVal Mid$(sData, I + 3, 4), 4
End If
Next I
Debug.Print "VerByte: " & RVal
End Sub
(And no, I'm not planning on using it or taking any credit)
Edit: Works for War2 as well.
What do you mean, got bored? You live on the side of a mountain in the middle of nowhere, what else do you have to do besides go on the internet and shoot squirrels for food?
Lay off, squiggly. Don't flame him for his lifestyle preferences.
Anyone feel like finding the patterns for D2/WC3/JSTR and the like?
I would like to see how this stands up to a new patch. *sits down and waits for one*
But, What is the use? When it comes without a form of patching the files. You're pretty much not gunna find the hashes without finding the verbyte posted a long with it.
I can see where this would come in handy. (Working with stealthbot -.-) But I am merely concerned with it's reliability. But, We'll see.
~Hdx
Quote from: Hdx on October 16, 2007, 10:07 PM
Anyone feel like finding the patterns for D2/WC3/JSTR and the like?
I would like to see how this stands up to a new patch. *sits down and waits for one*
But, What is the use? When it comes without a form of patching the files. You're pretty much not gunna find the hashes without finding the verbyte posted a long with it.
I can see where this would come in handy. (Working with stealthbot -.-) But I am merely concerned with it's reliability. But, We'll see.
~Hdx
RealityRipple is working on it.
As for patches:
http://img148.imageshack.us/img148/6759/vbyteow4.png
DevCode tested it against various versions of Starcraft, and all of them apparently came up with the correct VerBytes. So I assume it would work for future patches.
Quote from: squiggly on October 16, 2007, 10:03 PM
What do you mean, got bored? You live on the side of a mountain in the middle of nowhere, what else do you have to do besides go on the internet and shoot squirrels for food?
I want to be like you.
Would you mind e-mailing me any past hash files you have? (By any I mean any product, Any version)
Zip em on up.
~Hdx
For StarCraft?
I don't have any past hashes, but I could ask DevCode to send them to me so I can host them on bnetdocs.
Well, Anyone with any old hashes. I would be interested in obtaining.
BUT, I would highly advise against hosting the files on Redux. Thats just asking for a DMCA.
~Hdx
Quote from: Warrior on October 16, 2007, 10:14 PM
Quote from: squiggly on October 16, 2007, 10:03 PM
What do you mean, got bored? You live on the side of a mountain in the middle of nowhere, what else do you have to do besides go on the internet and shoot squirrels for food?
I want to be like you.
You want to be like him and he wants to be like me, so I'm making the deduction here that you want to be like me??!?
Quote from: Hdx on October 16, 2007, 10:14 PM
Would you mind e-mailing me any past hash files you have? (By any I mean any product, Any version)
Zip em on up.
~Hdx
Just a thought, but when you first install the game client, it has the oldest possible hash files for that particular game. When you run the client for the first time it updates to the latest hash files. Is there really a need to see if the pattern matching code works with any hash files other than the oldest hash files and the newest, assuming they [Battle.net] didn't use pattern A for the oldest hash files, pattern B for anything inbetween, and pattern A again for the newest? Unless I missed something, I'm pretty sure you just need the oldest hash files and the newest.
Yegg: that's only if you have the oldest cd.
Topaz: No.
Everyone else: I don't care enough to gather all the other values. It's not that big of a deal to me. Someone else can do it.
Not necessarily.
It isn't really a 'pattern'. Its more so how they do there code.
They could be doing something like:
SetConnectionInformation(something, something, verbyte, something, something)
They could just decide to change it to SetVerbyte(verbyte) instead.
Or, they could use different compiler optimizations resulting in a different pattern to search for. (EXA: how theres 2 different 'types' of lockdown dlls)
BUT, thats not the reason I want to have the hashes. I want them merely for shits an giggles.
~Hdx
Quote from: Hdx on October 16, 2007, 10:56 PM
Not necessarily.
It isn't really a 'pattern'. Its more so how they do there code.
They could be doing something like:
SetConnectionInformation(something, something, verbyte, something, something)
They could just decide to change it to SetVerbyte(verbyte) instead.
Or, they could use different compiler optimizations resulting in a different pattern to search for. (EXA: how theres 2 different 'types' of lockdown dlls)
BUT, thats not the reason I want to have the hashes. I want them merely for shits an giggles.
~Hdx
Well, we know for a fact that there hasn't been any code changes in this section from atleast *version 1.08 for SC, and although pattern matching is obviously not a 100% fool proof method, it is reliable enough in this case.
DevCode was so kind as to upload the old hashes, I've made them available at this location:
http://www.bnetdocs.org/archives/
Just navigate to the oldhashes directory, and then choose the version. All files have been scanned and verified clean.
I still need the old hashes from the oldest to the most current for:
w2bn, d2, d2lod, wc3, wc3 tft
if anyone can donate those, it'd be appreciated.
no wow hashes please, as wow is a paid subscription service and i'd rather not annoy blizzard too much.
As for a DCMA, if I get hit with one, well, I'll deal with it when it happens.
you could find some old bot that used hashs and see if those hashs are old enuff for you
Quote from: MysT_DooM on October 17, 2007, 12:45 PM
you could find some old bot that used hashs and see if those hashs are old enuff for you
I've got a copy of Warcraft II that is from 1999 or possibly 2000 if that is of any interest to anyone.
Quote from: Yegg on October 17, 2007, 01:12 PM
Quote from: MysT_DooM on October 17, 2007, 12:45 PM
you could find some old bot that used hashs and see if those hashs are old enuff for you
I've got a copy of Warcraft II that is from 1999 or possibly 2000 if that is of any interest to anyone.
What version
Hex$() returns a string.
Ya... I was doing Debug.Print for it and forgot to remove the Hex$() bit. Also, I found where D2 stores the verbyte (BNClient.dll), so I'll add that in a few.
Added D2 and War3 as well.
Andy, you forgot to include the values for FindStr it will just error... :P
No, KP deleted them.
Anyone using the default skin:
https://addons.mozilla.org/en-US/firefox/addon/2108
@namespace url(http://www.w3.org/1999/xhtml);
@-moz-document domain("forum.valhallalegends.com") {
.code{
overflow: auto;
height: 200px;
}
}
~Hdx
Why the hell was my entire post deleted?
Edit: Whatever. I'll just post the patterns and you guys can write your own code:
(XX represents a "wildcard" byte)
DRTL/DSHR:
Read from - Diablo.exe / Diablo_s.exe
C7 85 64 FF FF FF XX XX XX XX C7 85 68 FF FF FF XX XX XX XX
(First DWORD of X's is LTRD or RHSD. Second DWORD of X's is Version Byte.)
STAR/SEXP/W2BN:
Read from - Starcraft.exe / Warcraft II BNE.exe
C7 46 10 XX XX XX XX C7 46 18 XX XX XX XX C7 46
(First DWORD of X's is Version Byte. Second DWORD of X's is currently 08 00 00 00.)
JSTR:
Read from - StarcraftJ.exe
8B 4D F4 C7 41 0C XX XX XX XX 8B 55 F4 C7 42 10 XX XX XX XX
(First DWORD of X's is RTSJ. Second DWORD of X's is Version Byte.)
SSHR:
Read from - Starcraft.exe
C7 46 0C XX XX XX XX C7 46 10 XX XX XX XX
(First DWORD of X's is RHSS. Second DWORD of X's is Version Byte.)
D2DV/D2XP:
Read from - Bnclient.dll
56 44 32 44 89 44 24 58 6A 03 8D 44 24 64 50 C7 44 24 64 XX XX XX XX
(First 4 bytes are VD2D (in both D2DV and D2XP). DWORD of X's is Version Byte.)
WAR3/W3XP:
Read from - game.dll
C7 85 4C FD FF FF XX XX XX XX 89 8D 50 FD FF FF
(DWORD of X's is Version Byte.)
SC VerByte = Hex(179 + 2 x Version_Number)
Wouldn't the simple algorithm above be just as reliable as this pattern-finding code you guys have come up with?
Except that the versioning system in SC just changed from letters to numbers, and revision number increases had no effect on the verbyte. The patterns above are more than patterns, they're searching for the code that compiles 0x50, which isn't likely to change.
Quote from: Andy on November 20, 2007, 09:46 AMExcept that the versioning system in SC just changed from letters to numbers, and revision number increases had no effect on the verbyte.
In my post, Version_Number is ment to refer to the Major change. Hence it ignores the revision letters/numbers and the change doesn't effect it's correct output.
If you want to hope that they'll not change the way they increment the verbyte, go ahead. I'll hope they don't change how they build AUTH_INFO. Not much difference, I suppose.
Quote from: Andy on November 20, 2007, 09:46 AM
Except that the versioning system in SC just changed from letters to numbers, and revision number increases had no effect on the verbyte. The patterns above are more than patterns, they're searching for the code that compiles 0x50, which isn't likely to change.
¿que?
Do you mean the revision (1.15b, 1.15c, etc)? The verbyte changes with the minor version.
Quote
I'll just post the patterns
How are they patterns? That's a set way of doing things.
http://pdos.csail.mit.edu/6.828/2006/readings/i386/MOV.htm
Quote
C7 MOV r/m32,imm32 2/2 Move immediate dword to r/m dword
Although i wouldn't be suprised if they start using polymorphic code to form that mov that move's the verbyte value (as in iago's signature) to make drama..
1.15b doesn't exist. They switched to numbers. And they're byte patterns. It doesn't matter what they actually are, they're still a pattern of bytes.
Quote from: Andy on November 20, 2007, 04:27 PM
1.15b doesn't exist.
I was using it as an example.
Quote from: Andy on November 20, 2007, 04:27 PM
They switched to numbers.
???
as opposed to: vegetables?
As opposed to letters. It's 1.15.1 now, not 1.15b
Quote from: Andy on November 20, 2007, 05:58 PM
As opposed to letters. It's 1.15.1 now, not 1.15b
Oh, i see now. I think that's pretty lame.
follows proper versioning now tho....
major version . minor version . revision
public partial class Form1 : Form
{
[DllImport("kernel32.dll")]
public static extern void RtlMoveMemory(object lpvDest, object lpvSource, long cbCopy);
//VOID
//RtlMoveMemory(
// IN VOID UNALIGNED *Destination,
// IN CONST VOID UNALIGNED *Source,
// IN SIZE_T Length
// );
public Form1()
{
InitializeComponent();
string Data;
long RVal = 0;
StreamReader sr = new StreamReader("C:\\Program Files\\Starcraft\\Starcraft.exe");
for (int I = 1; I < Data.Length - 16; I++)
{
Regex r = new Regex(Convert.ToChar(0xC7) + Convert.ToChar(0x46) + Convert.ToChar(0x10) + "[a-zA-Z]" + Convert.ToChar(0xC7) +
Convert.ToChar(0x46) + Convert.ToChar(0x18) + "[a-zA-Z]" + Convert.ToChar(0xC7) + Convert.ToChar(0x46));
if (r.IsMatch(Data.Substring(Convert.ToInt32(I), 16)))
{
RtlMoveMemory(RVal, Data.Substring(Convert.ToInt32(I) + 3, 4), 4);
}
}
MessageBox.Show("Verbyte: " + RVal);
}
}
I attempted to port Andy's code to C#, but it doesn't seem to find the string, although i'm reading it as text, so I belive that'd be why, meh it's a start if anyone wants to finish it? lol
"[a-zA-Z]": don't use that. it can be any bytes, not just letters.
Smarter, have a look at the System.Runtime.InteropServices.Marshal class instead of using the rtlMoveMemory API in C# :)
void* does not map to object in C#. Consider System.BitConverter or System.IO.BinaryReader.
I'm confused: why do people still think this is a good idea? Searching for the verbyte is only slightly less fallible than hardcoding the values.
If you want to offer forwards compatibility, add an option to support BNLS for verbyte/checkrevision.
public string getVersionByte()
{
byte[] data = File.ReadAllBytes(@"C:\Program Files\Starcraft\StarCraft.exe");
StringBuilder sb = new StringBuilder();
foreach (byte b in data)
{
sb.Append(Convert.ToChar(b));
}
Regex r = new Regex(Convert.ToChar(0xC7) + Convert.ToChar(0x46) + Convert.ToChar(0x10) + "...." + Convert.ToChar(0xC7) +
Convert.ToChar(0x46) + Convert.ToChar(0x18) + "...." + Convert.ToChar(0xC7) + Convert.ToChar(0x46), RegexOptions.IgnoreCase);
string s = sb.ToString();
long rval;
for (int i = 0; i < s.Length; i++)
{
if (r.IsMatch(s.Substring(Convert.ToInt32(i) + 3, 16)))
{
rval = Convert.ToInt64(s.Substring(Convert.ToInt32(i) + 3, 4));
}
}
return rval.ToString();
}
Hmmm, still not working any ideas?