• Welcome to Valhalla Legends Archive.
 

[C++] War3 key algorithms

Started by Eibro, November 17, 2004, 10:02 PM

Previous topic - Next topic

Eibro

C++ implementation of war3 key algorithms reversed from install.exe. This was an independant effort; it has nothing to do with the other war3 key code floating around. Email questions/comments to [email protected]

Get it at http://cs.smu.ca/~e_brooks/war3/
Future updates (if any) will be posted there.

The IDB is there for IDA 4.5 if anyone is interested in looking at the reversal. Also, an idc script (maketable.idc) is there that was used to format the key tables into an array.

Eibro of Yeti Lovers.

Skywing

It's not really a C++ implementation if it's mostly inline assembler :p

Eibro

Quote from: Skywing on November 17, 2004, 10:04 PM
It's not really a C++ implementation if it's mostly inline assembler :p
Figured someone would say that. If I get some time (and interest) i'll convert the remaining parts (see the readme).
Eibro of Yeti Lovers.

Skywing

Quote from: Eibro[yL] on November 17, 2004, 10:06 PM
Quote from: Skywing on November 17, 2004, 10:04 PM
It's not really a C++ implementation if it's mostly inline assembler :p
Figured someone would say that. If I get some time (and interest) i'll convert the remaining parts (see the readme).
BTW, there are C++ equivalents for what you call multPass -- it's 64-bit math, though.

Eibro

Quote from: Skywing on November 17, 2004, 11:52 PM
Quote from: Eibro[yL] on November 17, 2004, 10:06 PM
Quote from: Skywing on November 17, 2004, 10:04 PM
It's not really a C++ implementation if it's mostly inline assembler :p
Figured someone would say that. If I get some time (and interest) i'll convert the remaining parts (see the readme).
BTW, there are C++ equivalents for what you call multPass -- it's 64-bit math, though.
Yeah, I figured as much. Though I couldn't get the compiler to emit the correct instructons (see post in the assembly forum)
Eibro of Yeti Lovers.

iago

when we did it, Maddox was stuck on that line for quite awhile.  __int64 or long long works in C++ (VS and gcc respectively), and long works in Java.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Arta

I used LARGE_INTEGER, which works quite nicely. Translates easily from the assembly. That is, if we're talking about the same bit :)

Eibro

#7
Ah, that is how I did it the first time through, but it wasn't generating the correct instructions so I scrapped it. I guess now that that problem is solved I should roll back to my previous code.union LargeInt {
struct {
unsigned long low;
unsigned long high;
};
int64 val;
};   */

BTW, we're talking about the code inside what I called 'tableMult' (.text:0041D050)
Eibro of Yeti Lovers.

Arta

I can't find anything there in my notes, I may have used TFT though.

Maddox

#9
Quote from: Skywing on November 17, 2004, 10:04 PM
It's not really a C++ implementation if it's mostly inline assembler :p

Looks more like a C implementation.

This is the way I ended up doing that specific function.


#ifdef WIN32
typedef unsigned __int64 ULONGLONG;
#else
typedef unsigned long long ULONGLONG;
#endif

DWORD Mult(DWORD Rounds, DWORD Mul, DWORD* BufA, DWORD* BufB, DWORD DecodedByte)
{
while(Rounds--)
{
ULONGLONG edxeax = (ULONGLONG)BufA[Rounds] * (ULONGLONG)Mul;
BufB[Rounds] = DecodedByte + (DWORD)edxeax;
DecodedByte = (DWORD)(edxeax >> 32);
}

return DecodedByte;
}
asdf.

Skywing

#10
Recommend looking at the UInt32x32To64 macro, and the code it generates (for future reference).

Maddox

Quote from: Skywing on November 18, 2004, 10:46 PM
Recommend looking at the UInt32x32To64 macro, and the code it generates (for future reference).

Except that is native only to Windows.
asdf.

Skywing

Yes.  However, you were reverse engineering a Windows program.

Zakath

Haha...this is what I wound up with when I did my port back to C++ of the code that iago released:

void Mult( int nRounds, int nMulX, LPDWORD lpdwBufferA, LPDWORD lpdwBufferB, DWORD dwDecodedByte ) {
while ( nRounds ) {
unsigned __int64 edxeax = (unsigned __int64)((unsigned __int64)lpdwBufferA[ nRounds - 1 ] * (DWORD)nMulX);
lpdwBufferB[ --nRounds ] = dwDecodedByte + (DWORD)edxeax;
dwDecodedByte = (DWORD)(edxeax >> 32);
}
}


I would guess he called the function slightly differently than you do, since he's using different offsets into the buffers.
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Eibro

Quote from: Maddox on November 18, 2004, 07:49 PM
Quote from: Skywing on November 17, 2004, 10:04 PM
It's not really a C++ implementation if it's mostly inline assembler :p

Looks more like a C implementation.

This is the way I ended up doing that specific function.


#ifdef WIN32
typedef unsigned __int64 ULONGLONG;
#else
typedef unsigned long long ULONGLONG;
#endif

DWORD Mult(DWORD Rounds, DWORD Mul, DWORD* BufA, DWORD* BufB, DWORD DecodedByte)
{
while(Rounds--)
{
ULONGLONG edxeax = (ULONGLONG)BufA[Rounds] * (ULONGLONG)Mul;
BufB[Rounds] = DecodedByte + (DWORD)edxeax;
DecodedByte = (DWORD)(edxeax >> 32);
}

return DecodedByte;
}

I tried to make it easy for C programmers to use.

QuoteI would guess he called the function slightly differently than you do, since he's using different offsets into the buffers.
No, look closer. He indexes the buffer by rounds - 1 (rounds--) while I index as buflen - i - 1 (i++)
Eibro of Yeti Lovers.