• Welcome to Valhalla Legends Archive.
 

Reversing Skills #2

Started by iago, March 15, 2004, 08:47 PM

Previous topic - Next topic

iago

This is the same as the one above.  13-digit parameter is stored as a char* pointed at by <FIX>esi</FIX>.  Can you convert this to C?

   lea     edi, [esi+0Bh]
   mov     ecx, 0C2h      
top:                            
   mov     eax, ecx        
   mov     ebx, 0Ch        
   cdq                    
   idiv    ebx
   mov     al, [edi]      
   sub     ecx, 11h        
   dec     edi            
   cmp     ecx, 7          
   mov     bl, [edx+esi]  
   mov     [edi+1], bl    
   mov     [edx+esi], al  
   jge     top




Solution (in plain C this time):
Quotevoid shuffleStarcraftCDKey(char *CDKey)
{
   int i;
   int edi = 0x0b;

   for(i = 0xC2; i >= 7; i -= 0x11)
      swap(&CDKey[edi--], &CDKey[i % 0x0C]);
}
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Maddox

#1
Interesting. What does esi contain at the beginning?
asdf.

iago

Sorry, I made a mistake typing that.  It's fixed and I put <FIX> tags around it.

My bad :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Maddox

I don't believe swap() is in the Standard C Library.
asdf.

iago

Quote from: Maddox on March 16, 2004, 08:26 PM
I don't believe swap() is in the Standard C Library.

I forgot to say, in my solution I used a "swap" function I didn't include, you can assume it exists :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Maddox

#5
I got the same solution as you iago. It looks like cdq is just there to set edx = 0. What's the advantage of this over xor edx, edx? I've seen the cdq - idiv combination several times.
asdf.

iago

I'm guessing that using cdq before a division is standard.  That's the first time I seen it, but that's perfectly logical.

One thing is, say eax is negative.  The cdq will make sure that the div uses the negative number and not the equivolant positive.  The sign extension is important.

I know that this number *can't possibly* be negative, so it would be no change (and perhaps an optimization) to do xor edx, edx, but that wouldn't always work.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Skywing

Quote from: iago on March 17, 2004, 08:07 AM
I'm guessing that using cdq before a division is standard.  That's the first time I seen it, but that's perfectly logical.

One thing is, say eax is negative.  The cdq will make sure that the div uses the negative number and not the equivolant positive.  The sign extension is important.

I know that this number *can't possibly* be negative, so it would be no change (and perhaps an optimization) to do xor edx, edx, but that wouldn't always work.
Sounds to me like the programmer used int needlessly instead of unsigned.  Don't do that!

iago

Quote from: Skywing on March 17, 2004, 09:33 AM
Quote from: iago on March 17, 2004, 08:07 AM
I'm guessing that using cdq before a division is standard.  That's the first time I seen it, but that's perfectly logical.

One thing is, say eax is negative.  The cdq will make sure that the div uses the negative number and not the equivolant positive.  The sign extension is important.

I know that this number *can't possibly* be negative, so it would be no change (and perhaps an optimization) to do xor edx, edx, but that wouldn't always work.
Sounds to me like the programmer used int needlessly instead of unsigned.  Don't do that!

I suspect it was stored as a char*, so he put it into a char then did the arithmatic on it.  If he had used an unsigned char, he would have had to cast it to that.  

Which brings up an interesting question: why ARE chars signed by default?
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Skywing

#9
They aren't.  The signedness of char is implementation-defined, which is even worse.  You can't rely on it being either signed or unsigned (unless explicitly qualifying the signed-ness; then again, signed char* is incompatible with char* which is incompatible with unsigned char*, so you have ugly casts needed for all stdlib string functions).

cl.exe provides a command-line switch to set the default char to act unsigned (it's default is signed).  I don't know about any other compilers, though.

iago

That's eww.  We should all start using Java which uses wide characters by default (I screwed up a few times assuming that sizeof(char) == 1).
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Kp

Quote from: Skywing on March 17, 2004, 10:54 AMcl.exe provides a command-line switch to set the default char to act unsigned (it's default is signed).  I don't know about any other compilers, though.

gcc also has a switch for controlling this: -fsigned-char and -funsigned-char.

Quote from: iago on March 17, 2004, 11:28 AMThat's eww.  We should all start using Java which uses wide characters by default (I screwed up a few times assuming that sizeof(char) == 1).

Java avoids this problem by not even supporting signed types properly!  Just try declaring an unsigned 32bit quantity in Java. :)
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

iago

Why would you ever have to?  Well, the only time I've ever seen a need is in division.  Java can do unsigned shifting in much the same was as assembly: different operator.
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Skywing

Quote from: iago on March 17, 2004, 12:38 PM
Why would you ever have to?  Well, the only time I've ever seen a need is in division.  Java can do unsigned shifting in much the same was as assembly: different operator.

Probably because unsigned numbers are (rightly) used all the time in The Rest Of The World, and despite Sun's best attempts, Java can't completely ignore reality.

iago

Quote from: Skywing on March 17, 2004, 03:00 PM
Quote from: iago on March 17, 2004, 12:38 PM
Why would you ever have to?  Well, the only time I've ever seen a need is in division.  Java can do unsigned shifting in much the same was as assembly: different operator.

Probably because unsigned numbers are (rightly) used all the time in The Rest Of The World, and despite Sun's best attempts, Java can't completely ignore reality.

But,what would you need an unsigned number for that a signed number + unsigned operators can't handle?  

In writing the functions to log onto battle.net (check revision, cdkey decode, broken sha-1) I never had to do anything weird to shift variables besides use the unsigned shift operator rather than the signed one (like assembly does).
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*