首页
社区
课程
招聘
[求助]这段IDA的伪代码有没有可能简化为一个公式?
2014-9-24 14:23 7813

[求助]这段IDA的伪代码有没有可能简化为一个公式?

2014-9-24 14:23
7813
请教算法高手,下面这段IDA F5出来的函数(_0x3523)的伪代码,有没有机会简化成一个公式?

程序:见附件

example:

a2 = 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10 F0 E1 D2 C3
a1 = 43 64 30 8A A8 09 88 20 BD 40 72 6C 61 B6 49 DF F2 34 5B F8
run过这段程序后可以得到
a3 = A3 B9 2C 73 31 F2 55 52 3D B3 FB 8C 84 D1 BC CF 70 3B 90 9C

int __cdecl Ox3523(int a1, int a2)
{
  unsigned int v2; // esi@1
  unsigned int v3; // eax@1
  int v4; // ebp@1
  int v5; // edi@1
  int v6; // edx@2
  int v7; // edx@2
  int v8; // ebx@2
  int v9; // ecx@2
  int v10; // ebx@2
  int v11; // ecx@2
  int v12; // ebx@2
  bool v13; // zf@2
  int v14; // ecx@3
  int v15; // ecx@4
  int *v16; // ebx@4
  int v17; // edx@4
  int v18; // ecx@4
  int v19; // edx@4
  int v20; // ebx@4
  bool v21; // sf@4
  unsigned __int8 v22; // of@4
  int v23; // ecx@6
  int *v24; // ebx@6
  int v25; // edx@6
  int v26; // ecx@6
  int v27; // ecx@8
  int *v28; // ebx@8
  int v29; // edx@8
  int v30; // ecx@8
  int v31; // ecx@10
  int *v32; // ebx@10
  int v33; // edx@10
  int v34; // esi@11
  int v35; // edx@11
  int v36; // eax@11
  int v37; // eax@11
  int v39; // [sp+10h] [bp-50h]@1
  signed int v40; // [sp+14h] [bp-4Ch]@1
  int *v41; // [sp+18h] [bp-48h]@1
  signed int v42; // [sp+1Ch] [bp-44h]@1
  int v43[16]; // [sp+20h] [bp-40h]@1

  v2 = *(_DWORD *)a2;
  v3 = *(_DWORD *)(a2 + 4);
  v4 = *(_DWORD *)(a2 + 8);
  v5 = *(_DWORD *)(a2 + 12);
  v39 = *(_DWORD *)(a2 + 16);
  v41 = v43;
  v42 = 16;
  v40 = 16;
  do
  {
    BYTE3(v6) = 0;
    LOBYTE(v6) = *(_BYTE *)(a1 + 1);
    *(_WORD *)((char *)&v6 + 1) = *(_BYTE *)a1;
    v7 = *(_BYTE *)(a1 + 2) | (v6 << 8);
    v8 = *(_BYTE *)(a1 + 3);
    a1 += 4;
    *v41 = v8 | (v7 << 8);
    v9 = *v41 + (32 * v2 | (v2 >> 27)) + (~v3 & v5 | v3 & v4);
    v10 = v39;
    v39 = v5;
    v5 = v4;
    v11 = v9 + v10 + 1518500249;
    v12 = (v3 >> 2) | (v3 << 30);
    v3 = v2;
    v2 = v11;
    v13 = v42 == 1;
    v4 = v12;
    ++v41;
    --v42;
  }
  while ( !v13 );
  LOBYTE(v14) = 16;
  do
  {
    v15 = v14 & 0xF;
    v16 = &v43[v15];
    v17 = *v16 ^ v43[((_BYTE)v15 - 8) & 0xF] ^ v43[((_BYTE)v15 + 2) & 0xF] ^ v43[((_BYTE)v15 - 3) & 0xF];
    v18 = ((unsigned int)v17 >> 31) | 2 * v17;
    *v16 = v18;
    v19 = (~v3 & v5 | v3 & v4) + v18 + (32 * v2 | (v2 >> 27)) + v39 + 1518500249;
    v20 = v5;
    v5 = v4;
    v4 = (v3 >> 2) | (v3 << 30);
    v14 = v40 + 1;
    v3 = v2;
    v22 = __OFSUB__(v40 + 1, 20);
    v21 = v40 - 19 < 0;
    v39 = v20;
    v2 = v19;
    ++v40;
  }
  while ( v21 ^ v22 );
  if ( v14 < 40 )
  {
    do
    {
      v23 = v14 & 0xF;
      v24 = &v43[v23];
      v25 = *v24 ^ v43[((_BYTE)v23 - 8) & 0xF] ^ v43[((_BYTE)v23 + 2) & 0xF] ^ v43[((_BYTE)v23 - 3) & 0xF];
      v26 = ((unsigned int)v25 >> 31) | 2 * v25;
      *v24 = v26;
      v19 = (32 * v2 | (v2 >> 27)) + v26 + (v3 ^ v4 ^ v5) + v39 + 1859775393;
      v20 = v5;
      v5 = v4;
      v4 = (v3 >> 2) | (v3 << 30);
      v3 = v2;
      v14 = v40 + 1;
      v39 = v20;
      v22 = __OFSUB__(v40 + 1, 40);
      v21 = v40 - 39 < 0;
      v2 = v19;
      ++v40;
    }
    while ( v21 ^ v22 );
  }
  if ( v14 < 60 )
  {
    do
    {
      v27 = v14 & 0xF;
      v28 = &v43[v27];
      v29 = *v28 ^ v43[((_BYTE)v27 - 8) & 0xF] ^ v43[((_BYTE)v27 + 2) & 0xF] ^ v43[((_BYTE)v27 - 3) & 0xF];
      v30 = ((unsigned int)v29 >> 31) | 2 * v29;
      *v28 = v30;
      v19 = (v4 & v5 | v3 & v5 | v3 & v4) + v30 + (32 * v2 | (v2 >> 27)) + v39 - 1894007588;
      v20 = v5;
      v5 = v4;
      v4 = (v3 >> 2) | (v3 << 30);
      v14 = v40 + 1;
      v3 = v2;
      v22 = __OFSUB__(v40 + 1, 60);
      v21 = v40 - 59 < 0;
      v39 = v20;
      v2 = v19;
      ++v40;
    }
    while ( v21 ^ v22 );
  }
  if ( v14 < 80 )
  {
    do
    {
      v31 = v14 & 0xF;
      v32 = &v43[v31];
      v33 = *v32 ^ v43[((_BYTE)v31 - 8) & 0xF] ^ v43[((_BYTE)v31 + 2) & 0xF] ^ v43[((_BYTE)v31 - 3) & 0xF];
      v14 = ((unsigned int)v33 >> 31) | 2 * v33;
      *v32 = v14;
      v19 = (32 * v2 | (v2 >> 27)) + v14 + (v3 ^ v4 ^ v5) + v39 - 899497514;
      v20 = v5;
      v5 = v4;
      v4 = (v3 >> 2) | (v3 << 30);
      v3 = v2;
      LOBYTE(v14) = v40 + 1;
      v39 = v20;
      v22 = __OFSUB__(v40 + 1, 80);
      v21 = v40 - 79 < 0;
      v2 = v19;
      ++v40;
    }
    while ( v21 ^ v22 );
  }
  v34 = v19 + *(_DWORD *)a2;
  v35 = v3 + *(_DWORD *)(a2 + 4);
  v36 = v4 + *(_DWORD *)(a2 + 8);
  *(_DWORD *)a2 = v34;
  *(_DWORD *)(a2 + 8) = v36;
  v37 = v5 + *(_DWORD *)(a2 + 12);
  *(_DWORD *)(a2 + 4) = v35;
  *(_DWORD *)(a2 + 12) = v37;
  *(_DWORD *)(a2 + 16) += v20;
  return 0;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
打赏
分享
最新回复 (8)
雪    币: 2180
活跃值: (423)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
疯子 4 2014-9-24 15:45
2
0
应该是SHA1
参考:http://tools.ietf.org/html/rfc3174
雪    币: 484
活跃值: (270)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
bridgeic 2 2014-9-24 15:55
3
0
好像不是啊,初始值虽然一样,但算出来的值跟sha1的输出不一样啊?
雪    币: 100
活跃值: (323)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Arcade 2014-9-24 15:55
4
0
1518500249  1859775393 1894007588  899497514
变成十六进制。 再 google试试
雪    币: 484
活跃值: (270)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
bridgeic 2 2014-9-24 16:08
5
0
嗯,应该是SHA1,可是为什么输出和SHA1的输出对应不上呢?

a1 = 43 64 30 8A A8 09 88 20 BD 40 72 6C 61 B6 49 DF F2 34 5B F8
sha1 hash出来的值不是484b2906cdaf2106191e938f1b1f722d2813820c,跟程序里的输出“A3 B9 2C 73 31 F2 55 52 3D B3 FB 8C 84 D1 BC CF 70 3B 90 9C”对不上啊?疯兄、Arcade兄能帮忙再看下?
雪    币: 263
活跃值: (342)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
ntzwq 2014-9-24 16:36
6
0
应该是SHA1,
雪    币: 7759
活跃值: (3404)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
arab 2014-9-24 16:48
7
0
SHA-1变形, 标准公式是
W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)).
但实际上是
*v32 ^ v43[((_BYTE)v31 - 8) & 0xF] ^ v43[((_BYTE)v31 + 2) & 0xF] ^ v43[((_BYTE)v31 - 3) & 0xF];
即参与计算的四个数是
t, t-8,  t+2, t-3
雪    币: 484
活跃值: (270)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
bridgeic 2 2014-9-24 17:03
8
0
又去跟了下,这个还是个标准的SHA1算法,只是好像在实现上有点不同,它是两次调用后出结果,第一次调用产生的只是中间值。

谢谢疯兄、Arcade兄、arab兄的指点,算法了解的少,之前完全不知道该怎么下手。
雪    币: 7759
活跃值: (3404)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
arab 2014-12-28 12:26
9
0
你找个标准的SHA1算法代码, 然后把标准公式定义按我说的那样变形一下就行了.
(2). 对于 t = 16 到 79 令 Wt = S1(Wt-3 XOR Wt-8 XOR Wt- 14 XOR Wt-16).

你说的调用两次, 其实是标准的步骤, 你看实际代码就明白了, 这部分是Transfer, 每个0x40大小的数据块都会调用一次, 最后Final时再调用一次才得到最后结果.
游客
登录 | 注册 方可回帖
返回