一国产加锁王的算法分析

程序加了强壳,用PEID查壳显示为:ASProtect 2.0x Registered -> Alexey Solodovnikov
再用VerA插件赤查找一下,则显示为:Version: ASProtect 1.32 build 10.20 Beta
怀疑是ASPR的高版本,毕竟VerA已经N久没更新了,呵呵!不过,用VolX大侠的脚本,低版本的也许要手脱,高版的却是一健搞定,呵呵!

用脚本脱过后,OD载入!在输入假码后,通过堆栈调用,很快就找到注册验证的关键点:


004B9388    /$  55              push ebp
004B9389    |.  8BEC            mov ebp,esp
004B938B    |.  83C4 F0         add esp,-10
004B938E    |.  53              push ebx
004B938F    |.  33DB            xor ebx,ebx
004B9391    |.  895D F0         mov dword ptr ss:[ebp-10],ebx
…………
004B93C5    |.  8B45 FC         mov eax,dword ptr ss:[ebp-4]
004B93C8    |.  E8 93B6F4FF     call de_folde.00404A60
004B93CD    |.  3B43 4C         cmp eax,dword ptr ds:[ebx+4C]   ;  比较用户名长度,不得大于0x64
004B93D0    |.  7F 19           jg short de_folde.004B93EB      ;  大于则跳转将EBX清0,然后直接跳转到段尾
004B93D2    |.  8B45 FC         mov eax,dword ptr ss:[ebp-4]
004B93D5    |.  E8 86B6F4FF     call de_folde.00404A60
004B93DA    |.  3B43 50         cmp eax,dword ptr ds:[ebx+50]   ;  比较用户名长度,不得小于0x3
004B93DD    |.  7C 0C           jl short de_folde.004B93EB
004B93DF    |.  8B45 08         mov eax,dword ptr ss:[ebp+8]
004B93E2    |.  E8 79B6F4FF     call de_folde.00404A60
004B93E7    |.  85C0            test eax,eax                    ;  测试注册码是否为空
004B93E9    |.  75 04           jnz short de_folde.004B93EF
004B93EB    |>  33DB            xor ebx,ebx
004B93ED    |.  EB 60           jmp short de_folde.004B944F
………………
004B9405    |.  8D4D F0         lea ecx,dword ptr ss:[ebp-10]
004B9408    |.  8B55 FC         mov edx,dword ptr ss:[ebp-4]
004B940B    |.  8BC3            mov eax,ebx
004B940D    |.  E8 BAFBFFFF     call de_folde.004B8FCC          ;  关键CALL,计算注册码
004B9412    |.  8B45 F0         mov eax,dword ptr ss:[ebp-10]
004B9415    |.  8B55 08         mov edx,dword ptr ss:[ebp+8]
004B9418    |.  E8 33F8F4FF     call de_folde.00408C50
004B941D    |.  85C0            test eax,eax
004B941F    |.  74 04           je short de_folde.004B9425
004B9421    |.  33DB            xor ebx,ebx
004B9423    |.  EB 2A           jmp short de_folde.004B944F
………………

跟进call de_folde.004B8FCC :


004B8FCC    /$  55              push ebp
004B8FCD    |.  8BEC            mov ebp,esp
004B8FCF    |.  83C4 E0         add esp,-20
004B8FD2    |.  53              push ebx
004B8FD3    |.  56              push esi
004B8FD4    |.  57              push edi
004B8FD5    |.  33DB            xor ebx,ebx
004B8FD7    |.  895D EC         mov dword ptr ss:[ebp-14],ebx

004B9003    |.  BA 7C914B00     mov edx,de_folde.004B917C        ;  ASCII "gf258369gf"
004B9008    |.  E8 33B8F4FF     call de_folde.00404840           ;  出现一个全局字符
004B900D    |.  837D EC 00      cmp dword ptr ss:[ebp-14],0      ;  测试全局字符是否为空
004B9011    |.  75 0D           jnz short de_folde.004B9020


004B9028    |.  8BD8            mov ebx,eax                     ;  取全局字符的长度
004B902A    |.  8D45 E8         lea eax,dword ptr ss:[ebp-18]
004B902D    |.  50              push eax
004B902E    |.  8BCB            mov ecx,ebx
004B9030    |.  D1F9            sar ecx,1                       ;  将全局字符长度/2
004B9032    |.  79 03           jns short de_folde.004B9037
004B9034    |.  83D1 00         adc ecx,0
004B9037    |>  BA 01000000     mov edx,1
004B903C    |.  8B45 EC         mov eax,dword ptr ss:[ebp-14]
004B903F    |.  E8 74BCF4FF     call de_folde.00404CB8
004B9044    |.  8D45 E4         lea eax,dword ptr ss:[ebp-1C]
004B9047    |.  50              push eax
004B9048    |.  8BC3            mov eax,ebx
004B904A    |.  D1F8            sar eax,1
004B904C    |.  79 03           jns short de_folde.004B9051
004B904E    |.  83D0 00         adc eax,0
004B9051    |>  8BCB            mov ecx,ebx
004B9053    |.  2BC8            sub ecx,eax
004B9055    |.  8BD3            mov edx,ebx
004B9057    |.  D1FA            sar edx,1
004B9059    |.  79 03           jns short de_folde.004B905E
004B905B    |.  83D2 00         adc edx,0
004B905E    |>  42              inc edx
004B905F    |.  8B45 EC         mov eax,dword ptr ss:[ebp-14]
004B9062    |.  E8 51BCF4FF     call de_folde.00404CB8          ;  以上:将全局字符平均分为2个部分
004B9067    |.  FF75 E8         push dword ptr ss:[ebp-18]
004B906A    |.  FF75 FC         push dword ptr ss:[ebp-4]
004B906D    |.  FF75 E4         push dword ptr ss:[ebp-1C]
004B9070    |.  8D45 E0         lea eax,dword ptr ss:[ebp-20]
004B9073    |.  BA 03000000     mov edx,3
004B9078    |.  E8 A3BAF4FF     call de_folde.00404B20          ;  将用户名居中插入到全局字符串中
004B907D    |>  C745 F0 0000000>mov dword ptr ss:[ebp-10],0

004B9093    |.  3B46 4C         cmp eax,dword ptr ds:[esi+4C]
004B9096    |.  7F 0D           jg short de_folde.004B90A5
004B9098    |.  8B45 FC         mov eax,dword ptr ss:[ebp-4]
004B909B    |.  E8 C0B9F4FF     call de_folde.00404A60
004B90A0    |.  3B46 50         cmp eax,dword ptr ds:[esi+50]
004B90A3    |.  7D 0C           jge short de_folde.004B90B1     ;  再一次测试用户名长度

004B90B9    |.  8BD8            mov ebx,eax                      ;  取插入后的字符串长度
004B90BB    |.  EB 37           jmp short de_folde.004B90F4
004B90BD    |>  8B46 68         /mov eax,dword ptr ds:[esi+68]   ;  ?全局常量:777888999(2E5DA4E7)
004B90C0    |.  8B56 6C         |mov edx,dword ptr ds:[esi+6C]
004B90C3    |.  0345 F0         |add eax,dword ptr ss:[ebp-10]   ;  累加到EAX
004B90C6    |.  1355 F4         |adc edx,dword ptr ss:[ebp-C]
004B90C9    |.  52              |push edx
004B90CA    |.  50              |push eax
004B90CB    |.  8B45 E0         |mov eax,dword ptr ss:[ebp-20]
004B90CE    |.  0FB64418 FF     |movzx eax,byte ptr ds:[eax+ebx->;  按位取字符串的字符
004B90D3    |.  50              |push eax
004B90D4    |.  B8 59040000     |mov eax,459                     ;  常数0x459
004B90D9    |.  5A              |pop edx
004B90DA    |.  8BCA            |mov ecx,edx
004B90DC    |.  33D2            |xor edx,edx
004B90DE    |.  F7F1            |div ecx                         ;  将常量除以字符
004B90E0    |.  8BC2            |mov eax,edx                     ;  保留余数
004B90E2    |.  33D2            |xor edx,edx
004B90E4    |.  290424          |sub dword ptr ss:[esp],eax      ;  将全局常量减去余数
004B90E7    |.  195424 04       |sbb dword ptr ss:[esp+4],edx
004B90EB    |.  58              |pop eax
004B90EC    |.  5A              |pop edx
004B90ED    |.  8945 F0         |mov dword ptr ss:[ebp-10],eax   ;  保存到esp-10处(局域变量)
004B90F0    |.  8955 F4         |mov dword ptr ss:[ebp-C],edx
004B90F3    |.  4B              |dec ebx
004B90F4    |>  8B45 E0          mov eax,dword ptr ss:[ebp-20]
004B90F7    |.  E8 64B9F4FF     |call de_folde.00404A60
004B90FC    |.  3BD8            |cmp ebx,eax
004B90FE    |.  7F 04           |jg short de_folde.004B9104
004B9100    |.  85DB            |test ebx,ebx
004B9102    |.^ 7F B9           \jg short de_folde.004B90BD
004B9104    |>  8B5E 60         mov ebx,dword ptr ds:[esi+60]

分析完了,开始写KeyGeN了,呵呵!
完整的C++代码如下:


#include
#include
using namespace std;

int main()
{
  char gstr[]="gf258369gf";
  char name[100]={0};
  cout<<"Please Enter Your Name:(Not Space,>3)\n";
  cin>>name;
  
  char tmpStr[128]={0};
  int i=0;
  for(i=0;i<5;i++)
    tmpStr[i]=gstr[i];
  
  int len=strlen(name);
  for(int j=0;j    tmpStr[i]=name[j];
    
  for(int j=5;j<10;j++,i++)
    tmpStr[i]=gstr[j];
    
  __int64 nCode=0;
  len=strlen(tmpStr);
  len--;
  while(tmpStr[len]){
    nCode+=0x2E5DA4E7;
    nCode-=(0x459 % tmpStr[len]);
    len--;
  }
  
  cout<<"Your RegCode is: ";
  cout.width(10);
  cout.fill('0');
  cout.setf(ios_base::uppercase);
  cout<  
  cout<<"Please Enter a Key to Exit…………\n";
  getchar();
  getchar();
  return 0;
}

发表评论