来自challenges.re的逆向工程挑战2

逆向工程 拆卸
2021-06-13 08:37:48

我正在尝试解决来自https://challenges.re/2/ 的逆向工程问题——这是挑战 2,目标是尽可能高水平地理解代码的作用。

<f>:
   0:          mov    eax,DWORD PTR [esp+0x4]
   4:          bswap  eax
   6:          mov    edx,eax
   8:          and    eax,0xf0f0f0f
   d:          and    edx,0xf0f0f0f0
  13:          shr    edx,0x4
  16:          shl    eax,0x4
  19:          or     eax,edx
  1b:          mov    edx,eax
  1d:          and    eax,0x33333333
  22:          and    edx,0xcccccccc
  28:          shr    edx,0x2
  2b:          shl    eax,0x2
  2e:          or     eax,edx
  30:          mov    edx,eax
  32:          and    eax,0x55555555
  37:          and    edx,0xaaaaaaaa
  3d:          add    eax,eax
  3f:          shr    edx,1
  41:          or     eax,edx
  43:          ret

这是我的解决方法,在评论中。因为代码没有给我一个初始起点,我假设初始值分配是12 34 56 78

mov    eax,DWORD PTR [esp+0x4] ; eax < 12 34 56 78 (‭305419896‬d)
bswap  eax               ; eax < 78 56 34 12
mov    edx,eax           ; eax = edx = 78 56 34 12
and    eax,0xf0f0f0f         ; eax = 02 04 06 08
and    edx,0xf0f0f0f0        ; edx = 70 50 30 10
shr    edx,0x4           ; edx = 07 05 03 01
shl    eax,0x4           ; eax = 20 40 60 80
or     eax,edx           ; eax = 27 45 63 81
mov    edx,eax           ; edx = eax = 27 45 63 81  
and    eax,0x33333333        ; eax = 23 01 23 01
and    edx,0xcccccccc        ; edx = 04 44 40 80
shr    edx,0x2           ; edx = 01 11 10 20
shl    eax,0x2           ; eax = 8C 04 8C 04
or     eax,edx           ; eax = 8D 15 9C 24
mov    edx,eax           ; eax = edx = 8D 15 9C 24
and    eax,0x55555555          ; eax = 05 15 14 04
and    edx,0xaaaaaaaa        ; edx = 88 00 88 20    
add    eax,eax           ; eax = 8D 15 9C 24
shr    edx,1             ; edx = 44 00 44 10
or     eax,edx           ; eax = CD 15 D6 34
ret                  ; return eax > CD 15 D6 34 (3440760372d)

我仍然不明白的是大局 - 似乎是一些没有目的的随机数学运算,可能我错了。是什么赋予了?

2个回答

这是一个位反转算法。我不确定 OP 示例中显示的数字是否正确。如果我开始(在 MS VStudios 内联汇编程序中)0x12345678(作为DWORD),或

0001 0010 0011 0100 0101 0110 0111 1000

然后我最终得到它的位反转,是0x1E6A2C48,或者

0001 1110 0110 1010 0010 1100 0100 1000

该算法看起来类似于Henry S. Warren Jr. 所著的Hackers Delight一书中的“ Generalized Bit Reversal,第 2 版,第 129 页(在我的 pdf 版本中),尽管未经验证。引用:

if (k & 1) x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1;
if (k & 2) x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2;
if (k & 4) x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4;
if (k & 8) x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
if (k & 16) x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
// The last two 'and' operations can be omitted.


如果你从 12345678 开始,你可能在josh 的操作答案中有一些错误是正确的

mov eax,DWORD PTR [esp+0x4]     eax =       12 34 56 78
bswap eax                       eax =       78 56 34 12
mov edx,eax                     edx = eax = 78 56 34 12
and eax,0x0f0f0f0f              eax =       08 06 04 02
and edx,0xf0f0f0f0              edx =       70 50 30 10
shr edx,0x4                     edx =       07 05 03 01
shl eax,0x4                     eax =       80 60 40 20
or eax,edx                      eax =       87 65 43 21
mov edx,eax                     edx =       87 65 43 21
and eax,0x33333333              eax =       03 21 03 21
and edx,0xcccccccc              edx =       84 44 40 00
shr edx,0x2                     edx =       21 11 10 00
shl eax,0x2                     eax =       0c 84 0c 84
or eax,edx                      eax =       2d 95 1c 84
mov edx,eax                     edx = eax = 2d 95 1c 84
and eax,0x55555555              eax =       05 15 14 04
and edx,0xaaaaaaaa              edx =       28 80 08 80
add eax,eax                     eax =       0a 2a 28 08
shr edx,1                       edx =       14 40 04 40
or eax,edx                      eax =       1e 6a 2c 48
ret

让我们说 python

>>> a = 0x78563412
>>> b = 0x0f0f0f0f
>>> c = 0xf0f0f0f0
>>> d = 0x33333333
>>> e = 0xcccccccc
>>> temp = (((((a&b)<<4|(a&c)>>4)&d)<<2) | ((((a&b)<<4|(a&c)>>4)&e)>>2))
>>> hex(((temp & 0x55555555 )*2) | (temp & 0xaaaaaaaa) >> 1)
'0x1e6a2c48L'