• Welcome to Valhalla Legends Archive.
 

Dll contains CheckRevision()

Started by Trunning, April 30, 2010, 05:16 PM

Previous topic - Next topic

Trunning

#45
Yeah don't worry, I plan to always clean code up, put it in functions, pass variables as parameters, etc.

I'll be waiting for you improved version of my code ::)

Hdx

You're using C++, think Objects!
If you notice pretty much everything for the network communication is exactly the same for BNLS/BNCS. Just different in the structure of the header.
If you make a object doing all the generic stuff, then inherite it to more protocol specific objects.. anyways.

I said I *should* not that I would.

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

#47
Wow never mind, aren't I stupid.

Hdx

..... I don't even think I should answer why that doesn't work.
It's so obvious...
Hint: How many variables are you passing?

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

#49
Nevermind, I was setting ya to 0, with memset after memcpy, stupid order Eh?

Trunning

Printing out the Version Check Stat String, prints out some unknown characters apparently.

http://pastebin.com/tELnwtCz

Also what data do I use from 0x1A, for 0x51.

0x1A - 0x51
(DWORD) Version - (DWORD) EXE Version
(DWORD) Checksum - (DWORD) EXE Hash

Do they match up?

Hdx

Quote from: Trunning on May 06, 2010, 04:03 PMPrinting out the Version Check Stat String, prints out some unknown characters apparently.
Well no shit, thats because a char * is supposto point to a char array, which is not whas going on.
As you see in the other code, we malloc some space, then do strcpy.
So you have to do some memory shuffling to get the struct filled out properly.
Quote from: Trunning on May 06, 2010, 04:03 PMAlso what data do I use from 0x1A, for 0x51.

0x1A - 0x51
(DWORD) Version - (DWORD) EXE Version
(DWORD) Checksum - (DWORD) EXE Hash

Do they match up?
Yes.

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

#52
I see you've done that here:

SMSG_SID_AUTH_INFO pkt;
int raw_size = 20; //sizeof(pkt) - (sizeof(char *) * 2);
memcpy(&pkt, data, raw_size);

char *name_addr = data + raw_size;
int   name_len  = strlen(name_addr);
char *seed_addr = name_addr + name_len + 1;
int   seed_len  = strlen(seed_addr);

pkt.ArchiveName = (char*)malloc(name_len + 1);
strcpy_s(pkt.ArchiveName, name_len + 1, name_addr);

pkt.Seed = (char*)malloc(seed_len + 1);
strcpy_s(pkt.Seed, seed_len + 1, seed_addr);


Can you explain how this works, and give an example with the packet 0x1A?

Hmm I think I could pull this off, if the 1 char* in SMSG_BNLS_VERCHECK was at the end, but it's in the middle.

Hdx

#53
No, i've already given you enough code for you to be able to do it yourself, BUT I will explain whats going on.

Basically in memory you have this laid out exactly as bellow (Instead of the hex it's the char representative.)
0000   6b 00 1a cc 04 00 00 00 00 00 00 00 fe 07 e1 4b  k..............K
0010   cc cc cc cc 70 5f c7 01 cc cc cc cc 76 65 72 2d  ....p_......ver-
0020   49 58 38 36 2d 31 2e 6d 70 71 00 43 3d 37 33 32  IX86-1.mpq.C=732
0030   39 31 38 33 33 33 20 42 3d 34 32 30 39 36 38 39  918333 B=4209689
0040   37 30 32 20 41 3d 31 31 37 37 33 34 38 31 33 31  702 A=1177348131
0050   20 34 20 41 3d 41 2b 53 20 42 3d 42 2d 43 20 43   4 A=A+S B=B-C C
0060   3d 43 5e 41 20 41 3d 41 2d 42 00                 =C^A A=A-B.

k\x00\x1A\xCC\x04\x00\x00\x00\x00\x00\x00\x00\xFE\x07\xE1K
\xCC\xCC\xCC\xCCp_\xC7\x01\xCC\xCC\xCC\xCCver-IX86-1.mpq\x00
C=732918333 B=4209689702 A=1177348131 4 A=A+S B=B-C C=C^A A=A-B\x00

When we do our memcpy, we copy the data and fit it into the struct. Which works great for normal numeric values, but not for strings, becuse a pointer is actually a 32-bit value which points to another address in memory. Which has our string. So a basic example is:
00000000: 04 00 00 00
00000004: Our String\x0

As you can see, our char * is actually holding the value of 0x00000004, which is the address of our string.

Make sense?
So when you copy the giant chunk, you are actually making the computer think that our string is at address 'ver-' which is obviously a invalid address. (Well it could be valid, just not where we want it.
So what we do is we use malloc to allocate another section in memory to hold the string value we want.
We use memcpy to move the string from where it was, to where we just allocated.
Then we update our struct's value to the new pointer.

So here is some examples:
struct TEST{
    DWORD Value1;
    char *StringVal;
};
01 02 03 04 41 42 43 44 00
.  .  .  .  A  B  C  D  .

So we do a memcpy:TEST t;
memcpy(&t, data, sizeof(TEST)

Our struct now has the following values:
Value1: 0x04030201
StringVal: 0x44434241 -> UNKNOWN MEMORY

As you can see, it has our string as the pointer, this is a no no!
So what we do is move the string:
int string_len = strlen(data + 4); //Data is a pointer to the first 0x01, our string is 4 bytes in, hence the +4
char *str = (char *)malloc(string_len + 1); //strlen() does not include the trailing null 0x00 but we need it.
memcpy(str, data + 4, string_len + 1); //lets copy out string, including the null to the new memory space
t.StringVal = str; //And assign the new pointer to our struct.
printf("String: %s\n", t.StringVal); //Will now print out "String: ABCD"!


I am bad at explaining things but you need to learn and get used to how memory is laid out. It's a simple concept.

Seine  it's in the middle, you are going to have to move the rest of the data into the struct, you can do that with another memcpy() with the proper address (hint: you'll need to use the length of the string)

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

#54
I understand DMA, memory, pointers, etc. And I was thinking, get the size of the 3 dwords, (sizeof(DWORD) * 3).

Then we are at where the char* should be, then we get the string length with strlen(), it stops at the null terminator.

Then there will be 2 more dwords after that, 8 bytes.

Simple questions:

After I find out whats where, how then do I copy, 3 dwords, a char*, and 2 more dwords to pkt.

In the destination do I just use + offset in bytes?

The data that should be hashed for 'Hashed Key Data' is:

  1. Client Token
  2. Server Token
  3. Key Product (from decoded CD key)
  4. Key Public (from decoded CD key)
  5. (DWORD) 0
  6. Key Private (from decoded CD key)

Should the key product contain "D2DV", etc?

Should the key public contain "AAAABBBBCCCCDDDD"? That's an example of a CDKey.

And what does key private contain?

Hdx

The public, private, and product values are all contained within the human readable cdkey.
Blizzard has a proprietary function to decode the cdkeys into these 3 values.
If you use BNLS_CDKEY you don't have to worry about it, you just have to send your raw cdkey, server/client tokens, and it'll return all the proper data.
BUT like I said, if you use D1 for now, you wont need to worry about any cdkeys. [In 0x51 just set the number of cdkeys to 0 and do not include any of the data thats per cdkey.]

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

#56
Ok then, but is this theory right? And can I use X-Sha-1 logon sequence for diablo 1, or do I have to use it's specific logon sequence.

SMSG_BNLS_VERCHECK pkt;

int raw_gap = (sizeof(DWORD) * 3);
char *ss = data + raw_gap;
int ss_len = strlen(ss);

memcpy(&pkt, data, raw_gap);
memcpy(&pkt + raw_gap, ss, ss_len);
memcpy(&pkt + raw_gap + ss_len, data + raw_gap + ss_len, 8); // makes sense to me

Hdx

#57
Quote from: Trunning on May 06, 2010, 04:54 PMAnd can I use X-Sha-1 logon sequence for diablo 1, or do I have to use it's specific logon sequence.
Ya, Blizzard is ually happy with D1 using the SID_AUTH login. Its ok for a temporary thing until you work out how to properly support all the protocols.
Quote from: Trunning on May 06, 2010, 04:54 PMOk then, but is this theory right?
SMSG_BNLS_VERCHECK pkt;

int raw_gap = (sizeof(DWORD) * 3);
char *ss = data + raw_gap;
int ss_len = strlen(ss);

memcpy(&pkt, data, raw_gap);
memcpy(&pkt + raw_gap, ss, ss_len);
memcpy(&pkt + raw_gap + ss_len, data + raw_gap + ss_len, 8); // makes sense to me
Nope, wheres your malloc? BTW your 'gap' is actually strlen+1.

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

Huge breakthrough, I just confirmed the world will end on the 21st of December, 2012.

Ah well I feel good now, this works. I understand it too.
SMSG_BNLS_VERCHECK pkt;

int raw_gap = (sizeof(DWORD) * 3);
char *ss = data + raw_gap;
int ss_len = strlen(ss) + 1;

memcpy(&pkt, data, raw_gap);
pkt.VerCheck = (char*)malloc(ss_len);
memcpy(pkt.VerCheck, ss, ss_len);
memcpy(&pkt + raw_gap + ss_len, data + raw_gap + ss_len, 8); // makes sense to me

printf("Stat String: %s\n", pkt.VerCheck);

Hdx

#59
Only thing I have to say is FINAL-FUCKING-LY!
eek, nvm,

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

|