首页
社区
课程
招聘
奇怪的算法
发表于: 2010-9-26 22:58 4181

奇怪的算法

2010-9-26 22:58
4181
00497A50    81EC 14010000   sub     esp, 114
00497A56    A1 D0C15900     mov     eax, dword ptr [59C1D0]
00497A5B    53              push    ebx
00497A5C    55              push    ebp
00497A5D    56              push    esi
00497A5E    898424 1C010000 mov     dword ptr [esp+11C], eax
00497A65    8BF2            mov     esi, edx
00497A67    57              push    edi
00497A68    8D5424 20       lea     edx, dword ptr [esp+20]
00497A6C    33C0            xor     eax, eax
00497A6E    8BFF            mov     edi, edi
00497A70    880408          mov     byte ptr [eax+ecx], al
00497A73    40              inc     eax
00497A74    3D 00010000     cmp     eax, 100
00497A79  ^ 7C F5           jl      short 00497A70
00497A7B    33C0            xor     eax, eax
00497A7D    8D49 00         lea     ecx, dword ptr [ecx]
00497A80    8BF8            mov     edi, eax
00497A82    33FE            xor     edi, esi
00497A84    893A            mov     dword ptr [edx], edi
00497A86    40              inc     eax
00497A87    83C2 04         add     edx, 4
00497A8A    83F8 40         cmp     eax, 40
00497A8D  ^ 7C F1           jl      short 00497A80
00497A8F    8D5424 21       lea     edx, dword ptr [esp+21]
00497A93    2BD1            sub     edx, ecx                                      ; 不懂这里是什么意思
00497A95    895424 1C       mov     dword ptr [esp+1C], edx
00497A99    8D5424 22       lea     edx, dword ptr [esp+22]
00497A9D    2BD1            sub     edx, ecx
00497A9F    895424 14       mov     dword ptr [esp+14], edx
00497AA3    8D7C24 20       lea     edi, dword ptr [esp+20]
00497AA7    8D5424 23       lea     edx, dword ptr [esp+23]
00497AAB    33F6            xor     esi, esi
00497AAD    2BF9            sub     edi, ecx
00497AAF    2BD1            sub     edx, ecx
00497AB1    8BC1            mov     eax, ecx
00497AB3    895424 18       mov     dword ptr [esp+18], edx
00497AB7    C74424 10 40000>mov     dword ptr [esp+10], 40
00497ABF    90              nop
00497AC0    8A10            mov     dl, byte ptr [eax]
00497AC2    0FB61C07        movzx   ebx, byte ptr [edi+eax]
00497AC6    0FB6EA          movzx   ebp, dl
00497AC9    03DE            add     ebx, esi
00497ACB    03EB            add     ebp, ebx
00497ACD    8BF5            mov     esi, ebp
00497ACF    81E6 FF000080   and     esi, 800000FF
00497AD5    79 08           jns     short 00497ADF
00497AD7    4E              dec     esi
00497AD8    81CE 00FFFFFF   or      esi, FFFFFF00
00497ADE    46              inc     esi
00497ADF    8A1C0E          mov     bl, byte ptr [esi+ecx]
00497AE2    8818            mov     byte ptr [eax], bl
00497AE4    8B5C24 1C       mov     ebx, dword ptr [esp+1C]
00497AE8    0FB61C03        movzx   ebx, byte ptr [ebx+eax]
00497AEC    88140E          mov     byte ptr [esi+ecx], dl
00497AEF    8A50 01         mov     dl, byte ptr [eax+1]
00497AF2    0FB6EA          movzx   ebp, dl
00497AF5    03DE            add     ebx, esi
00497AF7    03EB            add     ebp, ebx
00497AF9    8BF5            mov     esi, ebp
00497AFB    81E6 FF000080   and     esi, 800000FF
00497B01    79 08           jns     short 00497B0B
00497B03    4E              dec     esi
00497B04    81CE 00FFFFFF   or      esi, FFFFFF00
00497B0A    46              inc     esi
00497B0B    8A1C0E          mov     bl, byte ptr [esi+ecx]
00497B0E    8858 01         mov     byte ptr [eax+1], bl
00497B11    8B5C24 14       mov     ebx, dword ptr [esp+14]
00497B15    0FB61C03        movzx   ebx, byte ptr [ebx+eax]
00497B19    88140E          mov     byte ptr [esi+ecx], dl
00497B1C    8A50 02         mov     dl, byte ptr [eax+2]
00497B1F    0FB6EA          movzx   ebp, dl
00497B22    03DE            add     ebx, esi
00497B24    03EB            add     ebp, ebx
00497B26    8BF5            mov     esi, ebp
00497B28    81E6 FF000080   and     esi, 800000FF
00497B2E    79 08           jns     short 00497B38
00497B30    4E              dec     esi
00497B31    81CE 00FFFFFF   or      esi, FFFFFF00
00497B37    46              inc     esi
00497B38    8A1C0E          mov     bl, byte ptr [esi+ecx]
00497B3B    8858 02         mov     byte ptr [eax+2], bl
00497B3E    8B5C24 18       mov     ebx, dword ptr [esp+18]
00497B42    0FB61C03        movzx   ebx, byte ptr [ebx+eax]
00497B46    88140E          mov     byte ptr [esi+ecx], dl
00497B49    8A50 03         mov     dl, byte ptr [eax+3]
00497B4C    0FB6EA          movzx   ebp, dl
00497B4F    03DE            add     ebx, esi
00497B51    03EB            add     ebp, ebx
00497B53    8BF5            mov     esi, ebp
00497B55    81E6 FF000080   and     esi, 800000FF
00497B5B    79 08           jns     short 00497B65
00497B5D    4E              dec     esi
00497B5E    81CE 00FFFFFF   or      esi, FFFFFF00
00497B64    46              inc     esi
00497B65    8A1C0E          mov     bl, byte ptr [esi+ecx]
00497B68    8858 03         mov     byte ptr [eax+3], bl
00497B6B    88140E          mov     byte ptr [esi+ecx], dl
00497B6E    8B5424 10       mov     edx, dword ptr [esp+10]
00497B72    83C0 04         add     eax, 4
00497B75    4A              dec     edx
00497B76    895424 10       mov     dword ptr [esp+10], edx
00497B7A  ^ 0F85 40FFFFFF   jnz     00497AC0
00497B80    5F              pop     edi
00497B81    33C0            xor     eax, eax
00497B83    5E              pop     esi
00497B84    8981 04010000   mov     dword ptr [ecx+104], eax
00497B8A    8981 00010000   mov     dword ptr [ecx+100], eax
00497B90    8B8C24 18010000 mov     ecx, dword ptr [esp+118]
00497B97    5D              pop     ebp
00497B98    5B              pop     ebx
00497B99    E8 E25E0700     call    0050DA80
00497B9E    81C4 14010000   add     esp, 114
00497BA4    C3              retn

下面是IDA F5出来的

int __fastcall sub_497A50(byte *buf, int dwKey)
{
  signed int v2; // eax@1
  byte *v3; // edx@1
  int v4; // esi@1
  signed int v5; // eax@3
  byte *Buf; // eax@5
  int v7; // esi@5
  char v8; // dl@6
  int v9; // esi@6
  int v10; // ebx@6
  char v11; // dl@6
  int v12; // esi@6
  int v13; // ebx@6
  char v14; // dl@6
  int v15; // esi@6
  int v16; // ebx@6
  char v17; // dl@6
  int result; // eax@7
  signed int v20; // [sp+10h] [bp-114h]@5
  DWORD dwTemps[64]; // [sp+20h] [bp-104h]@1
  char v22; // [sp+21h] [bp-103h]@6
  char v23; // [sp+22h] [bp-102h]@6
  char v24[253]; // [sp+23h] [bp-101h]@6
  int v25; // [sp+120h] [bp-4h]@1

  v25 = dword_59C1D0;
  v4 = dwKey;
  v3 = (byte *)dwTemps;
  v2 = 0;
  do
  {
    buf[v2] = v2;
    ++v2;
  }
  while ( v2 < 256 );
  v5 = 0;
  do
  {
    *(_DWORD *)v3 = v4 ^ v5++;
    v3 += 4;
  }
  while ( v5 < 64 );
  v7 = 0;
  Buf = buf;
  v20 = 64;
  do
  {
    v8 = *Buf;
    v9 = (v7 + Buf[(char *)dwTemps - (char *)buf] + *Buf) % 256;   //()char *)dwTemps - (char *)buf 是什么意思呢
    *Buf = buf[v9];
    v10 = Buf[&v22 - (char *)buf];
    buf[v9] = v8;
    v11 = Buf[1];
    v12 = (v9 + v10 + Buf[1]) % 256;
    Buf[1] = buf[v12];
    v13 = Buf[&v23 - (char *)buf];
    buf[v12] = v11;
    v14 = Buf[2];
    v15 = (v12 + v13 + Buf[2]) % 256;
    Buf[2] = buf[v15];
    v16 = Buf[v24 - (char *)buf];
    buf[v15] = v14;
    v17 = Buf[3];
    v7 = (v15 + v16 + Buf[3]) % 256;
    Buf[3] = buf[v7];
    buf[v7] = v17;
    Buf += 4;
  }
  while ( v20-- != 1 );
  result = 0;
  *((_DWORD *)buf + 65) = 0;
  *((_DWORD *)buf + 64) = 0;
  return result;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 137
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
%256被优化成 &0x800000FF的形式
局部数组的地址减去个全局的EncodeTable的地址又是什么意思呢,求高手解答
2010-9-26 23:00
0
雪    币: 261
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
乱猜一下。。。
signed int v20; // [sp+10h] [bp-114h]@5
DWORD dwTemps[64]; // [sp+20h] [bp-104h]@1
char v22; // [sp+21h] [bp-103h]@6
char v23; // [sp+22h] [bp-102h]@6
char v24[253]; // [sp+23h] [bp-101h]@6
int v25; // [sp+120h] [bp-4h]@1

dwTemps从堆栈的空间来看,不够256个字节,其实也就一个DWORD而已,因此,这里其实是声明一个
整形的指针,指向参数的buf

00497A7D    8D49 00         lea     ecx, dword ptr [ecx]
ecx是参数传进来的地址,这里应该是声明一个新的指针
int *dwTemps = (int*)buf;

00497A8F    8D5424 21       lea     edx, dword ptr [esp+21]
00497A93    2BD1            sub     edx, ecx                                      ;esp+21 是v22,变量的空间是连续的,edx - ecx = 1
00497A95    895424 1C       mov     dword ptr [esp+1C], edx
00497A99    8D5424 22       lea     edx, dword ptr [esp+22]  // 同上 esp+22 是v23 edx - ecx = 2
00497A9D    2BD1            sub     edx, ecx
00497A9F    895424 14       mov     dword ptr [esp+14], edx
00497AA3    8D7C24 20       lea     edi, dword ptr [esp+20] // esp+20 是dwTemps
00497AA7    8D5424 23       lea     edx, dword ptr [esp+23]// esp+23是v24
00497AAB    33F6            xor     esi, esi
00497AAD    2BF9            sub     edi, ecx // edi - ecx = 0
00497AAF    2BD1            sub     edx, ecx // edx - ecx = 3
00497AB1    8BC1            mov     eax, ecx

因此大概是这样
int __fastcall sub_497a50(byte *buf, int dwKey)
{
    int* dwTemps = (int*)buf;

    for (int i=0; i<256; i++)
    {
        buf[i] = i;
    }

    for (int i=0; i<64; i++)
    {
        dwTemps[i] = dwKey ^ i;
    }

    char v7 = 0;
    char v8;
    char v9;
    char v10;
   
    char v11;
    char v12;
    char v13;
    char v14;

    char v15;
    char v16;
    char v17;

    byte* Buf = dwTemps;
    for (int i=0; i <64; i++)
    {
        v8 = Buf[0];
        v9 = (v7 + Buf[Buf-dwTemps] + Buf[0]) % 256;
        Buf[0] = buf[v9];
        v10 = Buf[1];
        buf[v9] = v8;

        v11 = Buf[1];
        v12 = (v9 + v10 + Buf[1]) % 256;
        Buf[1] = buf[v12];
        v13 = Buf[2];
        buf[v12] = v11;

        v14 = Buf[2];
        v15 = (v12 + v13 + Buf[2]) % 256;
        Buf[2] = buf[v15];
        v16 = Buf[3];
        buf[v15] = v14;
       
        v17 = Buf[3];
        v7 = (v15 + v16 + Buf[3]) % 256;
        Buf[3] = buf[v7];
        buf[v7] = v17;

        Buf += 4;
    }

    buf[65] = 0;
    buf[64] = 0;
    return 0;
}
2010-9-27 01:02
0
雪    币: 137
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
动态调试的时候dwTemps确实是栈中的一个数组。。。我的意思是问,什么样的代码会编译成那样的汇编码。。。
因为Buf-dwTemps不符合逻辑
2010-9-27 02:24
0
雪    币: 137
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
高手都哪去了
2010-9-27 11:45
0
雪    币: 270
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Buf[(char *)dwTemps - (char *)buf]

这句话运行的结果应该是取 dwTemps的字节值。

第一次循环:
(char *)dwTemps - (char *)buf  虽然超出了BUF的地址范围,但它正好落在dwTemps的首字节地址。
这其实是利用BUF来读取dwTemps地址的内存值。

  sub     edx, ecx                                      ; 不懂这里是什么意思

------------------------------------------------------------------------------------------------
这其实就是为了下面相加得到dwTemps地址用的。
2010-9-27 13:58
0
雪    币: 137
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
额,虽然我自己也研究出来的,还是谢谢你的回复
结贴
2010-9-27 15:49
0
游客
登录 | 注册 方可回帖
返回
//