• Welcome to Valhalla Legends Archive.
 

Reversing Skills #2

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

Previous topic - Next topic

Adron

Quote from: Maddox on March 17, 2004, 01:18 AM
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.

It is standard to use cdq before idiv because idiv means signed division. It is standard to use xor before div because div means unsigned division. You should never see cdq div or xor idiv.

Skywing

#16
Quote from: iago on March 17, 2004, 03:08 PM
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).
You would need to support unsigned numbers to do lots of things (or go to a lot of [performance-degrading] trouble to work around it).  For instance, sequence numbers in lots of network protocols are unsigned, and there are many file formats with unsigned numbers.  In fact, if you were ever to try and process a .mpq file you downloaded from Battle.net within Java, you would probably run into problems with no unsigned support.

Adron

If you have all the unsigned operators available, then sure, you can use unsigned multiplication, unsigned division etc when they are needed, but it's a pain to remember to use the right multiplication operator every time compared to defining the signedness of a variable correctly once.

iago

Quote from: Adron on March 17, 2004, 03:18 PM
If you have all the unsigned operators available, then sure, you can use unsigned multiplication, unsigned division etc when they are needed, but it's a pain to remember to use the right multiplication operator every time compared to defining the signedness of a variable correctly once.

Multiplication works out the same in both signed and unsigned, doesn't it?
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Adron

Quote from: iago on March 17, 2004, 05:53 PM
Multiplication works out the same in both signed and unsigned, doesn't it?

No, multiplication is different for signed and unsigned.

iago

Quote from: Adron on March 17, 2004, 05:58 PM
Quote from: iago on March 17, 2004, 05:53 PM
Multiplication works out the same in both signed and unsigned, doesn't it?

No, multiplication is different for signed and unsigned.

I can't think of any situation where that would happen, and I remember my digital logic prof explaining to us why, so I wrote a quick program to test it
#include <stdio.h>
int main()
{
       for(int i = -10; i < 10; i++)
       {
               for(int j = -10; j < 10; j++)
               {
                       int a = i;
                       int b = j;
                       unsigned int c = i;
                       unsigned int d = j;

                       if((int)(a*b) != (int)(c*d))
                               printf("doesn't match at %d %d", i, j);
               }
       }

       return 0;
}

It outputs nothing.  Can you come up with a case where it wouldn't?  I'm testing both positive and negative numbers in every combination.

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


Adron

It matters when you use all of the result, i.e. multiplying two 32-bit numbers generates a 64-bit result.

iago

Quote from: Adron on March 17, 2004, 07:33 PM
It matters when you use all of the result, i.e. multiplying two 32-bit numbers generates a 64-bit result.

hmm, I've never done or seen that before.  How's that work in assembly?
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Adron

Well, a similar example:


0CBC:0100 mov ax,8001
0CBC:0103 mov dx,ffff
0CBC:0106 imul dx


dx = 0, ax = 7fff


0CBC:0108 mov ax,8001
0CBC:010B mov dx,ffff
0CBC:010E mul dx


dx = 8000, ax = 7fff

iago

Ah, so it works exactly reverse of division, using edx:eax.  Neat! :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*