一个电子相册制作软件的算法分析

按正常流程来,先用Peid查壳,显示为:ASPack 2.12 -> Alexey Solodovnikov

算了,不脱了,直接查找一下特征:
push 0
retn
快速来到程序的OEP,然后F9运行起来!

通过F12堆栈暂停的方法,很快找到程序注册的关键点:


0057BAA0   |> \8D55 F8     lea edx,dword ptr ss:[ebp-8]
0057BAA3   |.  8B83 FC0200>mov eax,dword ptr ds:[ebx+2FC]
0057BAA9   |.  E8 3A0FEDFF call music.0044C9E8                  ;  计算出机器码
0057BAAE   |.  8B45 F8     mov eax,dword ptr ss:[ebp-8]         ;  此时,堆栈难看到机器码了
0057BAB1   |.  50          push eax
0057BAB2   |.  8B45 F8     mov eax,dword ptr ss:[ebp-8]
0057BAB5   |.  50          push eax
0057BAB6   |.  8D45 FC     lea eax,dword ptr ss:[ebp-4]
0057BAB9   |.  50          push eax
0057BABA   |.  E8 D9E0FFFF call music.00579B98                  ;  对机器码变形,算法分析关键CALL一
0057BABF   |.  8D4D F4     lea ecx,dword ptr ss:[ebp-C]
0057BAC2   |.  BA CCC15700 mov edx,music.0057C1CC
0057BAC7   |.  8B45 FC     mov eax,dword ptr ss:[ebp-4]
0057BACA   |.  E8 75E1FFFF call music.00579C44                  ;  关键CALL二,此CALL后,堆栈出现了真码
0057BACF   |.  8D55 D0     lea edx,dword ptr ss:[ebp-30]

……………………………………
0057BB20   |.  8B55 D4     mov edx,dword ptr ss:[ebp-2C]        ;  假码
0057BB23   |.  8B45 F4     mov eax,dword ptr ss:[ebp-C]         ;  真码
0057BB26   |.  E8 7194E8FF call music.00404F9C
0057BB2B   |.  74 17       je short music.0057BB44

我们先跟进关键CALL :call music.00579B98,单步,很快就找到了对机器码变形的地方:


003ABC81   |> /8B45 10     /mov eax,dword ptr ss:[ebp+10]
003ABC84   |. |0FB67C30 FF |movzx edi,byte ptr ds:[eax+esi-1]   ;  按位取机器码的ASCII值到EDI
003ABC89   |. |EB 0B       |jmp short zxysys.003ABC96
003ABC8B   |> |8B45 0C     |/mov eax,dword ptr ss:[ebp+C]       ;  内循环
003ABC8E   |. |0FB64418 FF ||movzx eax,byte ptr ds:[eax+ebx-1]  ;  按位取机器码的ASCII值,EBX-1为索引值
003ABC93   |. |33F8        ||xor edi,eax                        ;  与EDI进行异或运算
003ABC95   |. |43          ||inc ebx
003ABC96   |> |8B45 0C     | mov eax,dword ptr ss:[ebp+C]
003ABC99   |. |E8 0E78FFFF ||call zxysys.003A34AC
003ABC9E   |. |3BD8        ||cmp ebx,eax
003ABCA0   |.^|7E E9       |\jle short zxysys.003ABC8B          ;  判断内循环是否结束
003ABCA2   |. |BB 01000000 |mov ebx,1
003ABCA7   |. |8D45 F8     |lea eax,dword ptr ss:[ebp-8]
003ABCAA   |. |8BD7        |mov edx,edi
003ABCAC   |. |E8 4777FFFF |call zxysys.003A33F8
003ABCB1   |. |8B55 F8     |mov edx,dword ptr ss:[ebp-8]
003ABCB4   |. |8D45 FC     |lea eax,dword ptr ss:[ebp-4]
003ABCB7   |. |E8 F877FFFF |call zxysys.003A34B4
003ABCBC   |. |46          |inc esi
003ABCBD   |> |8B45 10      mov eax,dword ptr ss:[ebp+10]
003ABCC0   |. |E8 E777FFFF |call zxysys.003A34AC
003ABCC5   |. |3BF0        |cmp esi,eax
003ABCC7   |.^\7E B8       \jle short zxysys.003ABC81           ;  判断外循环是否结束

相对C++来言,表示如下:


//设strM为保存机器码的字符串
//设strT为保存变形码的字符串
char strT[20]={0};
  int len=strlen(strM);
  for(int i=0;i    strT[i]=strM[i];
    for(int j=0;j      strT[i] ^= strM[j];
  }

对于这个软件来说,要理解其算法,明白了这里也就差不多了,呵呵要!
不说其他了,我们先跟完第2个关键CALL:call music.00579C44吧:


00579CA9   |. /0F8E 540100>jle music.00579E03
00579CAF   |. |8945 E0     mov dword ptr ss:[ebp-20],eax
00579CB2   |. |BE 01000000 mov esi,1
00579CB7   |> |83FE 01     /cmp esi,1
00579CBA   |. |74 0B       |je short music.00579CC7
00579CBC   |. |8D45 EC     |lea eax,dword ptr ss:[ebp-14]
00579CBF   |. |8B55 E8     |mov edx,dword ptr ss:[ebp-18]
00579CC2   |. |E8 71AFE8FF |call music.00404C38
00579CC7   |> |8D45 E8     |lea eax,dword ptr ss:[ebp-18]
00579CCA   |. |E8 D1AEE8FF |call music.00404BA0
00579CCF   |. |8B45 EC     |mov eax,dword ptr ss:[ebp-14]
00579CD2   |. |E8 81B1E8FF |call music.00404E58
00579CD7   |. |8BF8        |mov edi,eax
00579CD9   |. |D1FF        |sar edi,1
00579CDB   |. |79 03       |jns short music.00579CE0
00579CDD   |. |83D7 00     |adc edi,0
00579CE0   |> |85FF        |test edi,edi
00579CE2   |. |0F8E 110100>|jle music.00579DF9
00579CE8   |. |BB 01000000 |mov ebx,1
00579CED   |> |BA 549E5700 |/mov edx,music.00579E54
00579CF2   |. |8D45 D8     ||lea eax,dword ptr ss:[ebp-28]
00579CF5   |. |E8 9E95E8FF ||call music.00403298
00579CFA   |. |8D45 D4     ||lea eax,dword ptr ss:[ebp-2C]
00579CFD   |. |8BD3        ||mov edx,ebx
00579CFF   |. |03D2        ||add edx,edx
00579D01   |. |8B4D EC     ||mov ecx,dword ptr ss:[ebp-14]
00579D04   |. |8A5411 FE   ||mov dl,byte ptr ds:[ecx+edx-2]
00579D08   |. |8850 01     ||mov byte ptr ds:[eax+1],dl
00579D0B   |. |C600 01     ||mov byte ptr ds:[eax],1
00579D0E   |. |8D55 D4     ||lea edx,dword ptr ss:[ebp-2C]
00579D11   |. |8D45 D8     ||lea eax,dword ptr ss:[ebp-28]
00579D14   |. |B1 02       ||mov cl,2
00579D16   |. |E8 4D95E8FF ||call music.00403268
00579D1B   |. |8D55 D8     ||lea edx,dword ptr ss:[ebp-28]
00579D1E   |. |8D45 D0     ||lea eax,dword ptr ss:[ebp-30]
00579D21   |. |E8 7295E8FF ||call music.00403298
00579D26   |. |8D45 D4     ||lea eax,dword ptr ss:[ebp-2C]
00579D29   |. |8BD3        ||mov edx,ebx
00579D2B   |. |03D2        ||add edx,edx
00579D2D   |. |8B4D EC     ||mov ecx,dword ptr ss:[ebp-14]
00579D30   |. |8A5411 FF   ||mov dl,byte ptr ds:[ecx+edx-1]
00579D34   |. |8850 01     ||mov byte ptr ds:[eax+1],dl
00579D37   |. |C600 01     ||mov byte ptr ds:[eax],1
00579D3A   |. |8D55 D4     ||lea edx,dword ptr ss:[ebp-2C]
00579D3D   |. |8D45 D0     ||lea eax,dword ptr ss:[ebp-30]
00579D40   |. |B1 03       ||mov cl,3
00579D42   |. |E8 2195E8FF ||call music.00403268
00579D47   |. |8D55 D0     ||lea edx,dword ptr ss:[ebp-30]
00579D4A   |. |8D45 DC     ||lea eax,dword ptr ss:[ebp-24]
00579D4D   |. |E8 AAB0E8FF ||call music.00404DFC
00579D52   |. |8B45 DC     ||mov eax,dword ptr ss:[ebp-24]
00579D55   |. |E8 8AFFE8FF ||call music.00409CE4
00579D5A   |. |8845 E7     ||mov byte ptr ss:[ebp-19],al
00579D5D   |. |BA 549E5700 ||mov edx,music.00579E54
00579D62   |. |8D45 D8     ||lea eax,dword ptr ss:[ebp-28]
00579D65   |. |E8 2E95E8FF ||call music.00403298
00579D6A   |. |8D45 D4     ||lea eax,dword ptr ss:[ebp-2C]
00579D6D   |. |8BD6        ||mov edx,esi
00579D6F   |. |03D2        ||add edx,edx
00579D71   |. |8B4D F0     ||mov ecx,dword ptr ss:[ebp-10]
00579D74   |. |8A5411 FE   ||mov dl,byte ptr ds:[ecx+edx-2]
00579D78   |. |8850 01     ||mov byte ptr ds:[eax+1],dl
00579D7B   |. |C600 01     ||mov byte ptr ds:[eax],1
00579D7E   |. |8D55 D4     ||lea edx,dword ptr ss:[ebp-2C]
00579D81   |. |8D45 D8     ||lea eax,dword ptr ss:[ebp-28]
00579D84   |. |B1 02       ||mov cl,2
00579D86   |. |E8 DD94E8FF ||call music.00403268
00579D8B   |. |8D55 D8     ||lea edx,dword ptr ss:[ebp-28]
00579D8E   |. |8D45 D0     ||lea eax,dword ptr ss:[ebp-30]
00579D91   |. |E8 0295E8FF ||call music.00403298
00579D96   |. |8D45 D4     ||lea eax,dword ptr ss:[ebp-2C]
00579D99   |. |8BD6        ||mov edx,esi
00579D9B   |. |03D2        ||add edx,edx
00579D9D   |. |8B4D F0     ||mov ecx,dword ptr ss:[ebp-10]
00579DA0   |. |8A5411 FF   ||mov dl,byte ptr ds:[ecx+edx-1]
00579DA4   |. |8850 01     ||mov byte ptr ds:[eax+1],dl
00579DA7   |. |C600 01     ||mov byte ptr ds:[eax],1
00579DAA   |. |8D55 D4     ||lea edx,dword ptr ss:[ebp-2C]
00579DAD   |. |8D45 D0     ||lea eax,dword ptr ss:[ebp-30]
00579DB0   |. |B1 03       ||mov cl,3
00579DB2   |. |E8 B194E8FF ||call music.00403268
00579DB7   |. |8D55 D0     ||lea edx,dword ptr ss:[ebp-30]
00579DBA   |. |8D45 CC     ||lea eax,dword ptr ss:[ebp-34]
00579DBD   |. |E8 3AB0E8FF ||call music.00404DFC
00579DC2   |. |8B45 CC     ||mov eax,dword ptr ss:[ebp-34]
00579DC5   |. |E8 1AFFE8FF ||call music.00409CE4
00579DCA   |. |3245 E7     ||xor al,byte ptr ss:[ebp-19]
00579DCD   |. |8845 E6     ||mov byte ptr ss:[ebp-1A],al
00579DD0   |. |8D45 C4     ||lea eax,dword ptr ss:[ebp-3C]
00579DD3   |. |8A55 E6     ||mov dl,byte ptr ss:[ebp-1A]
00579DD6   |. |E8 A5AFE8FF ||call music.00404D80
00579DDB   |. |8B45 C4     ||mov eax,dword ptr ss:[ebp-3C]
00579DDE   |. |8D55 C8     ||lea edx,dword ptr ss:[ebp-38]
00579DE1   |. |E8 C2FDFFFF ||call music.00579BA8
00579DE6   |. |8B55 C8     ||mov edx,dword ptr ss:[ebp-38]
00579DE9   |. |8D45 E8     ||lea eax,dword ptr ss:[ebp-18]
00579DEC   |. |E8 6FB0E8FF ||call music.00404E60
00579DF1   |. |43          ||inc ebx
00579DF2   |. |4F          ||dec edi
00579DF3   |.^|0F85 F4FEFF>|\jnz music.00579CED
00579DF9   |> |46          |inc esi
00579DFA   |. |FF4D E0     |dec dword ptr ss:[ebp-20]
00579DFD   |.^|0F85 B4FEFF>\jnz music.00579CB7
00579E03   |> \8B45 F8     mov eax,dword ptr ss:[ebp-8]

呵呵中,这么一大段,其实现的东东其实很简单!
完全是作者把算法复杂化了,直白的说C++代码展示如下:


  for(int i=0;i    strT[i] ^= 0x41;

明白了吧,就是按位将变形得到的字符串与0x41这个常量进行案件或运算!
然后转成ASCII杩的文本格式输出就是真码了,呵呵
我这里偷了个巧,直接输出了:


for(int i=0;i<8;i++)
    printf("%02X",strT[i]);

完整的算法代码如下:


#include
#include
using namespace std;

int main()
{
  cout<<"请软件你的机器码:\n";
  char strM[20]={0};
  cin>>strM;

  char strT[20]={0};
  int len=strlen(strM);
  for(int i=0;i    strT[i]=strM[i];
    for(int j=0;j      strT[i] ^= strM[j];
  }
  for(int i=0;i    strT[i] ^= 0x41;
  
  //cout<  cout<<"\n请你的注册码是:\n";
  
  for(int i=0;i<8;i++)
    printf("%02X",strT[i]);
  
  cout<<"\n请按任意键退出…………";
  getchar();
  getchar();
  
  return 0;
}

发表评论