注册机

来源:互联网 发布:网上商城模块图 知乎 编辑:程序博客网 时间:2024/04/29 01:13
原创】crack的分析和注册机写法
后恋 当前在线

原软件下载地址:http://crackmes.de/users/yo_mismo/crackme_v1/
引用:
注:软件下载原文说加壳了,结果下下来发现没壳。
  分析成功了之后再看这些代码感觉简单了,但是在没分析清楚之前真是累得我头晕眼花。不断地尝试之后总算完成了,大牛就不要来拍我了。
  OD载入很轻松就可以找到关键call。进入后我给予瓜分分为五个步骤:
0、对用户名、密码长度进行判定
1、对用户名前四个字符进行一次异或处理
2、对处理的四个字符进一步进行处理
3、将用户名+处理的字符(有个转化十进制的过程) == 新用户名
4、拿新用户名与密码比较。
下面进行详细分析:
0、对用户名、密码长度进行判定
strlen()然后比较,很简单就略过了。

1、对用户名前四个字符进行一次异或处理

代码:
00401302  |> /8A91 10404000 /mov     dl, byte ptr [ecx+404010]  // 取user [1-4]字符。404010==user;404020==pass00401308  |. |8A81 13204000 |mov     al, byte ptr [ecx+402013]  // 取0X59  0X6F 0X2D 0X4D进行0040130E  |. |30D0          |xor     al, dl                     **异或00401310  |. |8881 30404000 |mov     byte ptr [ecx+404030], al  //将异或的值传递到pass的第[17-20]个字符00401316  |. |41            |inc     ecx                        //ecx循环四次00401317  |. |83F9 04       |cmp     ecx, 40040131A  |.^\75 E6         \jnz     short 00401302             //403030处为目前处理过后的字符串。
2、对处理的四个字符进一步进行处理
代码:
0040131C  |.  68 30404000   push    00404030                         ; /s = ""00401321  |.  E8 CA040000   call    <jmp.&msvcrt.strlen>             ; \strlen00401326  |.  89C2          mov     edx, eax                         ;  //将4030处字符串长度放入edx00401328  |.  31C0          xor     eax, eax                         ;  //eax清零0040132A  |.  31C9          xor     ecx, ecx                         ;  //ecx清零0040132C  |> /39D1          /cmp     ecx, edx                         //循环四次0040132E  |. |74 0A         |je      short 0040133A          00401330  |. |66:0381 30404>|add     ax, word ptr [ecx+404030]        //[40301][40300] + [40302][40301] + [40303][40302]+[xx][0x40303]        00401337  |. |41            |inc     ecx00401338  |.^\EB F2         \jmp     short 0040132C                  //结果就是eax中保存了处理后的值。0040133A  |> \69C0 66060000 imul    eax, eax, 666                          //eax *666 -》eax00401340  |.  C1E8 02       shr     eax, 2                                 //EAX/400401343  |.  C1C0 0E       rol     eax, 0E                               //循环左移14位00401346  |.  C1C8 14       ror     eax, 14                               //循环右移20位  ==> 此两步最终运算结果为将eax进行循环右移6位。00401349  |.  6BC0 02       imul    eax, eax, 2                           //eax *2 -》eax 【溢出部分舍弃】0040134C  |.  F7D0          not     eax                                   //取反      0040134E  |.  05 99090000   add     eax, 999                              //eax+0x999h【此处wsprintf的作用是将上文处理的eax的值(如今存放在404040中)转化为无符号十进制数,放入404050处】00401353  |.  A3 40404000   mov     dword ptr [404040], eax          ; |//将处理过后的eax值放到404040处00401358  |.  FF35 40404000 push    dword ptr [404040]               ; |/<%u> = 97F7B3D2 (2549593042.)0040135E  |.  68 22204000   push    00402022                         ; ||Format = "%u"00401363  |.  68 50404000   push    00404050                         ; ||s = crack_No.0040405000401368  |.  E8 F3040000   call    <jmp.&USER32.wsprintfA>          ; |\wsprintfA
3、将用户名+处理的字符(有个转化十进制的过程) == 新用户名
代码:
【此处strcat是将输入的用户名+转化后的十进制字符串相连接。】0040136D  |.  68 50404000   push    00404050                         ; |/src = "2549593042"00401372  |.  68 10404000   push    00404010                         ; ||dest = "AAAAAAAA"00401377  |.  E8 84040000   call    <jmp.&msvcrt.strcat>             ; |\strcat
4、拿新用户名与密码比较。
代码:
0040137C  |.  68 10404000   push    00404010                         ; |s1 = "AAAAAAAA"00401381  |.  C74424 04 204>mov     dword ptr [esp+4], 00404020      ; |ASCII "BBBBBBBB"00401389  |.  E8 52040000   call    <jmp.&msvcrt.strcmp>             ; \strcmp0040138E  |.  83F8 00       cmp     eax, 000401391      74 02         je      short 00401395                   ;  //成功!
  故可以推算出一组序列号:
AAAAA
AAAAA2549593042
  注册机算法如下:

代码:
/*crack_1*name cr_1_noname*author houlen*date 2011-4-18*/#include <stdio.h>#define MAX 100int main(){  char user[MAX], str[MAX];  int i=0, cat[4], sum =0;  printf("User:");  scanf("%s",user);  if(strlen(user) <4 )  {    printf("the len of user is too low\n");    return 0;  }    cat[0] = (int)user[0]^0x59;  cat[1] = (int)user[1]^0x6f;  cat[2] = (int)user[2]^0x2d;  cat[3] = (int)user[3]^0x4d;    for(i=0; i<3; i++)  {    sum+= cat[i+1]*16*16+cat[i];      }  sum+= cat[3];  sum*= 0x666;  sum=sum>>2;  _asm  {    push eax;    mov eax,sum;    ror eax,6;    imul eax,eax,2    not eax;    add eax,0x999;      mov sum,eax;    pop eax;  }    sprintf(str, "%u", sum);  strcat(user, str);  printf("Serial: %s\n", user);  getchar();  return 0;}
引用:
在分析这个crackme的过程中遇到的几个问题,可能新手都会有这类疑问,1、ror、rol是循环右移,左移。2、wsprintf函数在本软件作用是将数字转化为字符串。3、IA-32机的小头问题,别弄错了顺序。4、c语言中的异或操作符"^"移位“>>”.5、嵌入汇编注意保护寄存器
引用:
原软件包好像有源码,但是自始至终没看过它的源代码,所以分析起来很辛苦,但是分析出来也很有成就感。。哈哈
~
上传的附件文件类型: rarcrack_No_UPX.rar (4.5 KB, 35 次下载)
 

[公告]请注意言行举止,不要让大家觉得不适!
回复时引用此帖 返回顶端
elianmeng
级别:16 | 在线时长:336小时 | 升级还需:21小时

初级会员
初级会员

资 料:
注册日期: Sep 2008
帖子: 196 elianmeng 品行端正
精华: 0
现金: 335 Kx
致谢数: 0
获感谢文章数:1
获会员感谢数:1
2 旧 2011-04-18, 19:28:49 默认
elianmeng 当前离线
#include "stdio.h"
#include <Windows.h>
#include <shlwapi.h>
char User[MAX_PATH];
char Pass[MAX_PATH];
char First[MAX_PATH];
const char cStr[]="Yo-Mismo";
DWORD Sec;
char Thr[MAX_PATH];
BOOL test()
{
  BOOL bResult=FALSE;
  int i=0;
  int ieax=0,iecx=0;
  int ifirstlen=0;
  printf("Usuario:");
  scanf("%s",User);
  if (strlen(User)<4)
  goto Finally;
    printf("Serial:");
    scanf("%s",Pass);
    if (strlen(Pass)<4)
    goto Finally;
    do 
    {
      First[i]=User[i] ^cStr[i];
      i++;
    } while (i!=4);
    ifirstlen=strlen(First);
  for (i=0;i<ifirstlen;i++)
  {
    ieax+=*((WORD *)(First+i));
  }
  __asm
  {
    push eax
      push edx
      mov eax,ieax
    imul    eax, 666h
      shr     eax, 2
      rol     eax, 0Eh
      ror     eax, 14h
      imul    eax, 2
      not     eax
      add     eax, 999h
      mov ieax,eax
      pop edx
   pop eax
  }
  Sec=ieax;
  wsprintfA(Thr,"%u",Sec);
  StrCatA(User,Thr);
  if (StrCmpA(User,Pass))
  goto Finally;
printf("--------------------\nFelicidades, crack");

Finally:
  return bResult;
}
void main()
{
  test();

}
 

[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮!
回复时引用此帖 返回顶端
elianmeng
级别:16 | 在线时长:336小时 | 升级还需:21小时

初级会员
初级会员

资 料:
注册日期: Sep 2008
帖子: 196 elianmeng 品行端正
精华: 0
现金: 335 Kx
致谢数: 0
获感谢文章数:1
获会员感谢数:1
3 旧 2011-04-18, 19:29:23 默认
elianmeng 当前离线
汗 我真无聊啊
 

[公告]请注意言行举止,不要让大家觉得不适!
回复时引用此帖 返回顶端
ycmint
级别:32 | 在线时长:1152小时 | 升级还需:69小时级别:32 | 在线时长:1152小时 | 升级还需:69小时

ycmint 的头像

普通会员
普通会员

资 料:
注册日期: Jul 2010
帖子: 630 ycmint 品行端正
精华: 2
现金: 174 Kx
致谢数: 3
获感谢文章数:27
获会员感谢数:28
4 旧 2011-04-18, 19:39:28 默认
帅哥 ycmint 当前离线
整副帖子,你一个人发言,看的出你灰常无聊......
 

[公告]如果你觉得有人语言挑衅,请点每帖右上角的“举报”按钮!
回复时引用此帖 返回顶端
后恋
级别:11 | 在线时长:165小时 | 升级还需:27小时级别:11 | 在线时长:165小时 | 升级还需:27小时级别:11 | 在线时长:165小时 | 升级还需:27小时级别:11 | 在线时长:165小时 | 升级还需:27小时级别:11 | 在线时长:165小时 | 升级还需:27小时

普通会员
普通会员

资 料:
注册日期: May 2009
帖子: 80 后恋 品行端正
精华: 2
现金: 53 Kx
致谢数: 1
获感谢文章数:1
获会员感谢数:1
5 旧 2011-04-18, 22:43:13 默认
后恋 当前在线
引用:
最初由 elianmeng发布 查看帖子
#include "stdio.h"
#include <Windows.h>
#include <shlwapi.h>
char User[MAX_PATH];
char Pass[MAX_PATH];
char First[MAX_PATH];
const char cStr[]="...
怎么了?我看着代码也能写出来。可是你确定你能够逆向出来吗?
 

[公告]请注意言行举止,不要让大家觉得不适!
回复时引用此帖 返回顶端
elianmeng
级别:16 | 在线时长:336小时 | 升级还需:21小时

初级会员
初级会员

资 料:
注册日期: Sep 2008
帖子: 196 elianmeng 品行端正
精华: 0
现金: 335 Kx
致谢数: 0
获感谢文章数:1
获会员感谢数:1
6 旧 2011-04-19, 07:29:24 默认
elianmeng 当前离线
 我写的就是源码
我不写破文,我只写别人的源码

个人认为破解的最高境界就是:拿出别人的源码
没必要写什么过程
比较改什么跳转之类
这样在工作中才有意义
原创粉丝点击