Этот код делает то же, что и:
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));
}
Если я все правильно прочитал, то есть. Весьма запутанный - откуда он?
В любом случае, для деталей:
Начните с: Из использования EAX
/ ECX
в качестве аргументов видно, что при этом используется __fastcall
соглашение о вызовах Microsoft (arg0
функции в EAX
, arg1
в ECX
).
Тогда просто следуйте арифметике до конца. Помимо последнего использования вращения только на AL
, на самом деле все просто:
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 дал мне идею здесь ... если функция на самом деле работает с байтами явно, то это можно сформулировать более простым способом:
char transmogrify(char arg0, char arg1)
{
char tmp = (arg1 ^ (((arg0 << 2) >> 4) + 1))) ^ arg0;
return ((tmp << 7) | (tmp >> 1));
}
Этот вид операции rotate(a ^ X ^ b, 1)
используется как часть некоторых шифров, таких как DES, но то, что именно у вас есть, зависит от X
(который здесь немного перемешан). Я не специалист по криптографии и не распознаю конкретный случай. Было бы интересно, если бы кто-то смог заполнить пробел в ...