• Welcome to Valhalla Legends Archive.
 

Try Out Your Reversing Skills

Started by iago, March 14, 2004, 06:23 PM

Previous topic - Next topic

iago

Here's a little assembly, can you get the original C or C++ code back?
Note that this is a __fastcall function with a single char* parameter passed in ecx.
BOOL __fastcall func(char *param);
It's a 13-character null-terminated String with every character in the range [0-9].  
(Note: none of the registers are preserved, I just skipped over preservation)

----------------------------------------
   mov     eax, 3
   mov     esi, ecx
   mov     ebp, edx
   xor     ecx, ecx
Top:
   movsx   edx, byte ptr [ecx+esi]
   sub     edx, 30h        
   lea     edi, [eax+eax]  
   xor     edx, edi        
   add     eax, edx        
   inc     ecx            
   cmp     ecx, 0Ch        
   jl      short Top
   xor     edx, edx  
   mov     ecx, 0Ah  
   div     ecx        
   
   movsx   eax, byte ptr [esi+0Ch]
   movsx   edx, dl
   add     edx, 30h
   cmp     eax, edx
   jnz     bottom
   mov     eax, 1  
   retn    8
bottom:
   xor     eax, eax
   retn    8
----------------------------------------


Solution (in C++):
Quotebool verifyStarcraftCDKey(char *cdkey)
{
   int accum = 3;
   for(int i = 0; i < 13; i++)
      accum += ((cdkey - '0') ^ (accum * 2));

   return ((accum % 10) == (cdkey[13] - '0'));
}
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
Exact C code? Or just the same functionality?

Anyways, I suggest not posting the answer in this thread. Maybe people should PM you the answer.

Edit: Ok, done reversing. :) PM'd iago.
asdf.

Maddox

#2
I don't understand the point of rewriting these kind of functions in C when they will probably be slower, and especially when you can use inline assembly.

If I were really going to use this, I probably would leave it like this.

BOOL __declspec(naked) __fastcall func_asm(char *param)
{
   __asm
   {
      pushad
      mov    eax, 3
      mov    esi, ecx
      xor    ecx, ecx
Top:
      movsx  edx, byte ptr [ecx+esi]
      sub    edx, 30h        
      lea    edi, [eax+eax]  
      xor    edx, edi        
      add    eax, edx        
      inc    ecx            
      cmp    ecx, 0Ch        
      jl     Top
      xor    edx, edx  
      mov    ecx, 0Ah  
      div    ecx        

      movsx  eax, byte ptr [esi+0Ch]
      movsx  edx, dl
      add    edx, 30h
      cmp    eax, edx
      jnz    bottom
      popad
      mov    eax, 1
      ret
bottom:
      popad
      xor    eax, eax
      ret
   }
}
asdf.

iago

Assembly != portability.  I use Linux 30% of the time.  And, I'm going to convert this to Java.

Incidentally, stop spamming me with IM's.  3! :P

Anyway, I found that it's easiest to first do it like in his example, then convert them exactly to C, then to cut down the code until there's no redundant statements.
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: iago on March 15, 2004, 08:23 AMAssembly != portability.  I use Linux 30% of the time.  And, I'm going to convert this to Java.

Assembly is quite portable within an ISA. :)  If you're using an x86 based Linux, you can take the assembly with you very easily.  For reasons of personal prejudice, I recommend against doing emulations in Java if it can be avoided.  Some of the things that are needed just don't work right/well (for instance, try doing an efficient CheckRevision in Java :)).
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

iago

Quote from: Kp on March 15, 2004, 08:58 AM
(for instance, try doing an efficient CheckRevision in Java :)).

With a little help from Skywing, I got CheckRevision to run on Starcraft in ~100ms in Java.  
For 100 runs:
Total time:   9682ms
Average time: 96ms
Min time:     76ms
Max time:     547ms
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: iago on March 15, 2004, 09:46 AMWith a little help from Skywing, I got CheckRevision to run on Starcraft in ~100ms in Java.

I'm honestly impressed.  I expected performance much more similar to VB, which just does absolutely horribly with it iirc.  How long was your code that implements it?  I'd consider it a bit cheating if you got this speed just by unrolling all possible combinations of the version check. :)
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

iago

#7
Quote from: Kp on March 15, 2004, 10:32 AM
Quote from: iago on March 15, 2004, 09:46 AMWith a little help from Skywing, I got CheckRevision to run on Starcraft in ~100ms in Java.

I'm honestly impressed.  I expected performance much more similar to VB, which just does absolutely horribly with it iirc.  How long was your code that implements it?  I'd consider it a bit cheating if you got this speed just by unrolling all possible combinations of the version check. :)

Haha, me and skywing talked about that :)

The code is very similar to Yobgul's public one, except I changed the initial parsing a little.  The actual running is pretty much the same as his.

When I actually get this bot working, I'll make it open source, just to prove that bots can be done in Java :)

[edit] I posted it on the Java forum.  
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


UserLoser.

Quote from: iago on March 15, 2004, 09:46 AM
Quote from: Kp on March 15, 2004, 08:58 AM
(for instance, try doing an efficient CheckRevision in Java :)).

With a little help from Skywing, I got CheckRevision to run on Starcraft in ~100ms in Java.  
For 100 runs:
Total time:   9682ms
Average time: 96ms
Min time:     76ms
Max time:     547ms


What's the fastest way to perform CheckRevision?  I'm assuming calling CheckRevision from the ver DLLs would be the fastest -- am I wrong? (If so, explain :P)

Maddox

Quote from: UserLoser. on March 15, 2004, 07:10 PM
Quote from: iago on March 15, 2004, 09:46 AM
Quote from: Kp on March 15, 2004, 08:58 AM
(for instance, try doing an efficient CheckRevision in Java :)).

With a little help from Skywing, I got CheckRevision to run on Starcraft in ~100ms in Java.  
For 100 runs:
Total time:   9682ms
Average time: 96ms
Min time:     76ms
Max time:     547ms


What's the fastest way to perform CheckRevision?  I'm assuming calling CheckRevision from the ver DLLs would be the fastest -- am I wrong? (If so, explain :P)

Like Kp said, "...unrolling all possible combinations of the version check."
asdf.

iago

Or compiling the check revision code into assembly and running it.  I believe that's the way the vercheck dlls, although I heard somewhere that those leak memory.
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

There are several ways to do it, each with their own bonuses and drawbacks.

1) YobGuls' code -- very portable, but not very efficient.
2) BNLS -- very portable, but you suffer network latency and require a BNLS authentication
3) Calling IX86Ver?.dll -- Win32 specific and requires either memory patching the DLL or enduring memory leaks.
4) Performing the revision using a method Skywing designed (which, with my modifications, is used in BNLS afaik)
5) Unrolling all possible combinations of the version check.  This is theoretically slightly faster even than the method that we use internally, but requires a tremendous amount of space to account for all possible combinations.

In all cases, you can gain a slight performance boost (if you reconnect frequently anyway) by keeping the files memory mapped for the duration of execution, rather than loading them on-demand (and thereby incurring all mapping overhead every time).
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Maddox

Quote from: Kp on March 15, 2004, 07:51 PM
4) Performing the revision using a method Skywing designed (which, with my modifications, is used in BNLS afaik)

Very descriptive.
asdf.

Kp

Quote from: Maddox on March 15, 2004, 08:01 PMVery descriptive.

His design, his call whether to explain how it works.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Arta

TestBNCS compiles the version check formula and then runs it. This is the fastest way of doing it, and is the method used by the vercheck DLLs. Mine runs in about 11-15ms, depending on the other things my machine is doing. That doesn't include the time taken to map the hash files into memory. That also doesn't include cache optimisations which I think might improve the speed by a few ms - something I've been meaning to test but never got round to.