开发者

Help with assembler code

开发者 https://www.devze.com 2023-02-20 03:01 出处:网络
push eax push ecx and eax,0x3C ror eax,1 ror eax,1 inc eax mov edx,eax pop eax xor eax,edx pop ecx xor eax,ecx
push eax 
push ecx 
and eax,0x3C 
ror eax,1 
ror eax,1 
inc eax 
mov edx,eax 
pop eax 
xor eax,edx 
pop ecx 
xor eax,ecx 
rol al,1 
ret 

can anybody help me understand what this开发者_如何学运维 code is doing by commenting it and why we do such routines like and and ror? Thanks


This code does the same as:

unsigned int func(arg0, arg1)
{
    unsigned int tmp = (arg1 ^ (((arg0 & 0x3C) >> 2) + 1)) ^ arg0;
    unsigned char c = (unsigned char)(tmp & 0xff);
    return (tmp & ~0xff) | (unsigned int)((c << 7) | (c >> 1));
}

If I read it all right, that is. Quite convoluted - where's it from ?

In any case, for the details:

Start with: From the use of EAX / ECX as arguments, it can be seen that this uses Microsoft's __fastcall calling convention (arg0 of a function in EAX, arg1 in ECX).

Then just follow the arithmetic through. Apart from the last use of rotation on AL only, it's actually simple then:

push eax         ; saves arg0 to stack
push ecx         ; saves arg1 to stack
and eax,0x3C     ; tmp = arg0 & 0x3C (this isolates bits 3-6, makes all else zero)
ror eax,1        ;
ror eax,1        ; twice rot right. Since upper bits are zero: tmp >>= 2;
inc eax          ; tmp++
mov edx,eax      ; EDX = tmp
pop eax          ; retrieve last item on stack, tmp2 = arg1
xor eax,edx      ; tmp2 ^= tmp;
pop ecx          ; retrieve prev item on stack, tmp3 = arg0
xor eax,ecx      ; tmp2 ^= tmp3
                 ;     full line: (arg1 ^ (((arg0 & 0x3C) >> 2) + 1)) ^ arg0
rol al,1         ; complex ... rotate lowest byte right by one
                 ;            al = (al >> 1) | (al << 7)
                 ; 
ret 

Edit: Zuljin gave me an idea here ... if the function actually operates on bytes explicitly, then it can be stated in a simpler way:

char transmogrify(char arg0, char arg1)
{
    char tmp = (arg1 ^ (((arg0 << 2) >> 4) + 1))) ^ arg0;
    return ((tmp << 7) | (tmp >> 1));
}

This sort of rotate(a ^ X ^ b, 1) operation is used as part of some ciphers like DES, but what exactly you have depends on the X (which is just a bit shuffle here). I'm not a cryptography expert, and don't recognize the specific case. It'd be interesting if someone can fill the gap in ...


push eax            ; pushing eax into stack
push ecx            ; pushing ecx into stack
and eax,0x3C        ; performs logical and operation on eax and 0x3C
ror eax,1           ; one bit right shift value from eax with carrying shifted bit to most significant bit (cyclic right shift)
ror eax,1           ; one bit right shift value from eax with carrying shifted bit to most significant bit (cyclic right shift)
inc eax         ; increment eax value
mov edx,eax         ; copy value from eax to edx
pop eax         ; restore eax value from stack, which was pushed by this command "push ecx"
xor eax,edx         ; exclusive or operation on eax and edx values
pop ecx         ; restore ecx value from stack, which was pushed by this command "push eax"
xor eax,ecx         ; exclusive or operation on eax and ecx values
rol al,1            ; one bit left shift value from al (least significant byte from eax) with carrying shifted bit to least significant bit (cyclic left shift)
ret             ; return from function

and I suggest you to read some articles from https://stackoverflow.com/questions/199679/good-beginners-books-for-assembly-languages


push eax - saves eax to stack
push ecx - saves ecx to stack
and eax,0x3C - logical AND register eax with 0x3c ( 111100 in binary) - this means that only 4 bits starting from bit 2 are interesting - in C : a = a & 

0x3C;
ror eax,1 - rotate one bit right - in C : a = a >> 1;
ror eax,1 - rotate one bit right - in C : a = a >> 1; so after this command these 4 interesting bits starting in position 0;
inc eax - increse these 4 bits value by one - in C : a++;
mov edx,eax - copy value from register eax to register edx
pop eax - load value from stack (value that was previously in ecx) and copy it to eax registry
xor eax,edx - xor value from stack(previously ecx) with incremented 4bits value - in C : b = b ^ a;
pop ecx - load value from stack (value that was previously in eax) and copy it to ecx registry
xor eax,ecx - xor value from stack(previously eax) once again - in C : c = c ^ b;
rol al,1 - rotate left by one bit the last byte (al) of registry eax - in C : c = (unsigned char)c << 1;
ret - return from function - probably this what is in EAX is a return value

So more or less this is how this function could looks like in C

unsigned char func1(unsigned int parm1, insigned int parm2)
{
  unsigned int a = par1 & 0x3C;
  a = a >> 1;
  a = a >> 1;
  a++;
  a = parm2 ^ a;
  a = parm1 ^ a;
  return (unsigned char)a << 1;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号