2011-03-28 6 views
1
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 

Quelqu'un peut-il m'aider à comprendre ce que ce code fait en le commentant et pourquoi nous faisons de telles routines comme et et ror? MerciAide avec le code assembleur

Répondre

0
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 

donc plus ou moins c'est comment cette fonction pourrait ressemble en 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

Le bit 'return (unsigned char) ...' est incorrect , car l'utilisation de 'AL' ne modifie pas les bits supérieurs de' EAX', qui ne sont pas nuls, au moins dans le cas des arguments ayant des bits supérieurs non nuls. La fonction par conséquent _either_ renvoie une valeur complète de 32 bits, ou _ attend que les deux arguments soient réels 8 bits (tous les bits supérieurs sont effacés). –

1
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 

et je vous suggère de lire quelques articles de https://stackoverflow.com/questions/199679/good-beginners-books-for-assembly-languages

+0

Merci accouplent, pensez-vous pas pourquoi nous et ça ensemble et à quoi ça sert. Idem pour tourner à gauche et à droite? –

+0

Cela ressemble à une sorte de somme de contrôle étrange; D'où vient le code? –

3

Ce code fait la même chose que:

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)); 
} 

Si je lis bien, ce qui est. Tout à fait alambiqué - d'où vient-il?

Dans tous les cas, pour les détails:

Commencez par: De l'utilisation de EAX/ECX comme arguments, on peut voir que celui-ci utilise la convention d'appel __fastcall de Microsoft (arg0 d'une fonction dans EAX, arg1 dans ECX).

Ensuite, il suffit de suivre l'arithmétique à travers. En dehors de la dernière utilisation de la rotation sur AL seulement, il est en fait simple alors:

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 m'a donné une idée ici ... si la fonction fonctionne en fait sur octets explicitement, il peut être déclaré dans une façon plus simple:

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

Ce genre de rotate(a^X^b, 1) opération est utilisée dans le cadre de certains chiffrements comme dES, mais ce que vous avez exactement dépend de la X (qui est juste un remaniement peu ici). Je ne suis pas un expert en cryptographie et je ne reconnais pas le cas spécifique. Il serait intéressant si quelqu'un peut combler le vide dans ...

+0

Son de Uni, pour un programme de décryptage mais j'ai fini par manquer une charge de conférences donc je n'ai pas la moindre idée à ce sujet, je dois le commenter pour un –