科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网网络频道系统安全之关于Alarm Master破解的分析

系统安全之关于Alarm Master破解的分析

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

我这个菜鸟也才有了练手的机会,由于代码中没有考虑到输入空格时的处理,因此有很多不足之处

作者: 赛迪网 来源:赛迪网安全社区 2007年10月17日

关键字: 系统安全 alarm Master

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共6页)

分析过程

试验码:

Regname:ligyuan

Regcode:1234 5678 abcd efgh

运行软件,有nag和剩余时间提示,点注册弹出注册对话框,输入试验码,下断点

bp getDlgItem,bp GetDlgItemTextA,bp GetWindowTextA

点确定,没有被断下。弹出错误对话框,点try again,程序被截下,Ctrl+F9返回 F9几次后,弹出了注册对话框,再次输入试验码,点确定程序运行返回到这里:

100020C1    51              push ecx
100020C2    68 2D1F0010     push BSSuppor.10001F2D
100020C7    FF71 0C         push dword ptr ds:[ecx+C]
100020CA    FF71 10         push dword ptr ds:[ecx+10]
100020CD    FF71 04         push dword ptr ds:[ecx+4]
100020D0    FF15 54D10010   call dword ptr ds:[<&USER32.DialogBoxParamA>]          ; 
100020D6    8BF0            mov esi,eax
100020D8    83FE FF         cmp esi,-1
100020DB    75 05           jnz short BSSuppor.100020E2
100020DD    E8 1EEFFFFF     call BSSuppor.10001000
100020E2    8BC6            mov eax,esi                        ;F8单步运行
100020E4    5E              pop esi
100020E5    C3              retn                               ;运行到这后返回
/////////////////////////////////////////////////////////////////////////
10002DC6    8B06            mov eax,dword ptr ds:[esi]         ;来到这里
10002DC8    FFB0 CC010000   push dword ptr ds:[eax+1CC]
10002DCE    8D4D E8         lea ecx,dword ptr ss:[ebp-18]
10002DD1    E8 46FAFFFF     call BSSuppor.1000281C             ;这里是把每一组注册码
转为16进制
10002DD6    8B06            mov eax,dword ptr ds:[esi]
10002DD8    8B4D AC         mov ecx,dword ptr ss:[ebp-54]      ;第一组的16进制送ecx
10002DDB    8988 F0010000   mov dword ptr ds:[eax+1F0],ecx     ;转存到ds:[eax+1F0]
10002DE1    8B06            mov eax,dword ptr ds:[esi]
10002DE3    8B4D B0         mov ecx,dword ptr ss:[ebp-50]      ;第二组的16进制送ecx
10002DE6    8988 F4010000   mov dword ptr ds:[eax+1F4],ecx     ;转存到ds:[eax+1F4] 
10002DEC    8B06            mov eax,dword ptr ds:[esi]
10002DEE    8B4D B4         mov ecx,dword ptr ss:[ebp-4C]      ;第三组的16进制送ecx
10002DF1    8988 F8010000   mov dword ptr ds:[eax+1F8],ecx     ;转存到ds:[eax+1F8]
10002DF7    8B06            mov eax,dword ptr ds:[esi]
10002DF9    8B4D B8         mov ecx,dword ptr ss:[ebp-48]      ;第四组的16进制送ecx
10002DFC    8988 FC010000   mov dword ptr ds:[eax+1FC],ecx     ;转存到ds:[eax+1FC]
10002E02    8B0E            mov ecx,dword ptr ds:[esi]
10002E04    8D45 90         lea eax,dword ptr ss:[ebp-70]
10002E07    50              push eax
10002E08    E8 8EFEFFFF     call BSSuppor.10002C9B             
10002E0D    8B1E            mov ebx,dword ptr ds:[esi]
10002E0F    8BCB            mov ecx,ebx
10002E11    E8 AEFBFFFF     call BSSuppor.100029C4           
10002E16    85C0            test eax,eax
10002E18   /74 08           je short BSSuppor.10002E22
10002E1A   |6A 02           push 2
10002E1C   |5F              pop edi
10002E1D   |E9 02010000     jmp BSSuppor.10002F24
10002E22   \8D45 BC         lea eax,dword ptr ss:[ebp-44]
10002E25    50              push eax
10002E26    8BCB            mov ecx,ebx
10002E28    E8 24FFFFFF     call BSSuppor.10002D51
10002E2D    8945 F0         mov dword ptr ss:[ebp-10],eax
10002E30    8B0E            mov ecx,dword ptr ds:[esi]
10002E32    8B81 F8010000   mov eax,dword ptr ds:[ecx+1F8]
10002E38    8B91 FC010000   mov edx,dword ptr ds:[ecx+1FC]
10002E3E    52              push edx
10002E3F    8945 EC         mov dword ptr ss:[ebp-14],eax
10002E42    FF75 EC         push dword ptr ss:[ebp-14]
10002E45    8B81 F4010000   mov eax,dword ptr ds:[ecx+1F4]
10002E4B    8B89 F0010000   mov ecx,dword ptr ds:[ecx+1F0]
10002E51    50              push eax
10002E52    51              push ecx
10002E53    FF75 F0         push dword ptr ss:[ebp-10]
10002E56    33DB            xor ebx,ebx
10002E58    43              inc ebx
10002E59    8D4D E8         lea ecx,dword ptr ss:[ebp-18]
10002E5C    885D FC         mov byte ptr ss:[ebp-4],bl
10002E5F    E8 E9FAFFFF     call BSSuppor.1000294D             ;关键call,F7跟进
10002E64    57              push edi
10002E65    53              push ebx
10002E66    8D4D BC         lea ecx,dword ptr ss:[ebp-44]
10002E69    8945 F0         mov dword ptr ss:[ebp-10],eax
10002E6C    C645 FC 00      mov byte ptr ss:[ebp-4],0
10002E70    E8 9DE4FFFF     call BSSuppor.10001312
10002E75    397D F0         cmp dword ptr ss:[ebp-10],edi
10002E78    0F85 A6000000   jnz BSSuppor.10002F24
下面是跟进后,里面的关键部分,中间省略了一些过程
//////////////////////////////////////////////////////////////对输入的用户名进行处理
10002874     3B7B 14       cmp edi,dword ptr ds:[ebx+14]      ;edi是否大于或等于
用户名的长度
10002877     7D 2F         jge short BSSuppor.100028A8        ;大就跳
10002879     C745 08 01000>mov dword ptr ss:[ebp+8],1
10002880     57            push edi
10002881     8BCB          mov ecx,ebx
10002883     E8 BFFFFFFF   call BSSuppor.10002847             ;读取用户名的一个字符
10002888     8038 20       cmp byte ptr ds:[eax],20           ;字符的ASCII值是否为0X20
1000288B     75 0A         jnz short BSSuppor.10002897        ;不是就跳
1000288D     47            inc edi                            
1000288E     FF45 08       inc dword ptr ss:[ebp+8]
10002891     837D 08 64    cmp dword ptr ss:[ebp+8],64        ;是否大于0X64
10002895   ^ 7C E9         jl short BSSuppor.10002880         ;不是往上跳取下一个字符
10002897     57            push edi
10002898     8BCB          mov ecx,ebx
1000289A     E8 A8FFFFFF   call BSSuppor.10002847
1000289F     8A00          mov al,byte ptr ds:[eax]           ;用户名字符的ASCII值送al
100028A1     884435 E8     mov byte ptr ss:[ebp+esi-18],al    ;al转送到堆栈中
100028A5     47            inc edi
100028A6     EB 05         jmp short BSSuppor.100028AD
100028A8     C64435 E8 40  mov byte ptr ss:[ebp+esi-18],40 ;用户名长度小于0X10时,用40填充
100028AD     46            inc esi
100028AE     83FE 10       cmp esi,10                      ;比较是否进行了0X10 次操作
100028B1   ^ 7C C1         jl short BSSuppor.10002874      ;不是往上跳继续

///////////////////////////////////////////////////////下面是由上面处理后的用户名
得出注册码的过程
100028BC     8D7C1D E8     lea edi,dword ptr ss:[ebp+ebx-18] ;用户名的基址送edi  
100028C0     C745 08 04000>mov dword ptr ss:[ebp+8],4        ;ss:[ebp+8]=4,
用来得出4位注册码
100028C7     8B4D FC       mov ecx,dword ptr ss:[ebp-4]      ;为ecx赋值一个内存地址
100028CA     E8 58FFFFFF   call BSSuppor.10002827            ;算法call
100028CF     0FBE0F        movsx ecx,byte ptr ds:[edi]       ;取用户名的一个字符值送ecx
100028D2     33D2          xor edx,edx
100028D4     8D4408 F6     lea eax,dword ptr ds:[eax+ecx-A]  ;eax=eax+ecx-0xa
100028D8     6A 0A         push 0A
100028DA     59            pop ecx                           ;ecx=0xa
100028DB     F7F1          div ecx                           ;eax=eax/ecx,edx=eax%ecx
100028DD     83C7 04       add edi,4                         ;edi+=4,相当于隔3个字符取
下一字符  
100028E0     80C2 30       add dl,30                         ;dl+=30
100028E3     889435 E8FEFF>mov byte ptr ss:[ebp+esi-118],dl  ;得到值的对应字符送到存储
空间保存
100028EA     46            inc esi                           ;esi++
100028EB     FF4D 08       dec dword ptr ss:[ebp+8]          ;从4减到0
100028EE   ^ 75 D7         jnz short BSSuppor.100028C7       ;不为0就往上跳继续下一个字符
100028F0     C68435 E8FEFF>mov byte ptr ss:[ebp+esi-118],20  ;每4个字符用空格隔开
100028F8     46            inc esi
100028F9     43            inc ebx                           ;ebx++(ebx初始为0)
100028FA     83FB 04       cmp ebx,4                         ;比较ebx是否小于4 
100028FD   ^ 7C BD         jl short BSSuppor.100028BC        ;小就往上跳,获得另一4位
注册码
100028FF     C68435 E7FEFF>mov byte ptr ss:[ebp+esi-119],0
10002907     33F6          xor esi,esi
10002909     8D85 FAFEFFFF lea eax,dword ptr ss:[ebp-106]
1000290F     8A18          mov bl,byte ptr ds:[eax]          ;下面这段代码是把上面4组
注册码反向
10002911     8D8C35 E8FEFF>lea ecx,dword ptr ss:[ebp+esi-118] 
10002918     0FBE11        movsx edx,byte ptr ds:[ecx]
1000291B     8819          mov byte ptr ds:[ecx],bl
1000291D     46            inc esi
1000291E     8810          mov byte ptr ds:[eax],dl          
10002920     48            dec eax
10002921     83FE 09       cmp esi,9
10002924   ^ 7C E9         jl short BSSuppor.1000290F        ;这个变换后得到的就是
正确的注册码

///////////////////////////////////////////////////////////////跟进算法call
10002827     8B01          mov eax,dword ptr ds:[ecx]
10002829     69C0 FD430300 imul eax,eax,343FD          ;eax*=0X343FD 
1000282F     05 C39E2600   add eax,269EC3              ;eax+=0x269ec3  
10002834     8901          mov dword ptr ds:[ecx],eax  ;eax的值保存在ds:[ecx]地址中
10002836     C1F8 10       sar eax,10                  ;eax>>=10
10002839     25 FF7F0000   and eax,7FFF                ;eax^=0x7fff
1000283E     99            cdq                         ;edx符号扩展
1000283F     6A 0A         push 0A
10002841     59            pop ecx                     ;ecx=0xa 
10002842     F7F9          idiv ecx                    ;eax=eax/ecx,edx=eax%0xa
10002844     8BC2          mov eax,edx                 ;eax=edx 
10002846     C3            retn
////////////////////////////////////////////////////////下面这里是输入的家假码与
真码比较的部分
1000297D    8B45 0C         mov eax,dword ptr ss:[ebp+C]   ;假码第1部分送eax
10002980    3B45 FC         cmp eax,dword ptr ss:[ebp-4]   ;与真码第1部分比较
10002983    8B5D 18         mov ebx,dword ptr ss:[ebp+18]  ;假码第2部分送ebx
10002986    8B7D 14         mov edi,dword ptr ss:[ebp+14]  ;假码第3部分送edi
10002989    8B55 10         mov edx,dword ptr ss:[ebp+10]  ;假码第4部分送edx
1000298C    75 0F           jnz short BSSuppor.1000299D    ;不等就跳
1000298E    3B55 F8         cmp edx,dword ptr ss:[ebp-8]   ;与真码第2部分比较
10002991    75 0A           jnz short BSSuppor.1000299D
10002993    3B7D F4         cmp edi,dword ptr ss:[ebp-C]   ;与真码第3部分比较
10002996    75 05           jnz short BSSuppor.1000299D
10002998    3B5D F0         cmp ebx,dword ptr ss:[ebp-10]  ;与真码第4部分比较
1000299B    74 1A           je short BSSuppor.100029B7     ;都相等就跳到结束(成功)
1000299D    B9 D2040000     mov ecx,4D2             ;上面任一部分不同都会来到这里4d2=1234
100029A2    3BC1            cmp eax,ecx             ;第一部分是不是为1234      
100029A4    75 16           jnz short BSSuppor.100029BC
100029A6    B8 2E160000     mov eax,162E            ;162e=5678   
100029AB    3BD0            cmp edx,eax             ;第4部分是否为5678
100029AD    75 0D           jnz short BSSuppor.100029BC
100029AF    3BF9            cmp edi,ecx             ;第3部分是不是为1234 
100029B1    75 09           jnz short BSSuppor.100029BC
100029B3    3BD8            cmp ebx,eax             ;第2部分是否为5678
100029B5    75 05           jnz short BSSuppor.100029BC;满足上面的4个比较也能成功注册
100029B7    33C0            xor eax,eax              ;因此有一个万能码1234-5678-1234-5678
100029B9    40              inc eax
100029BA    EB 02           jmp short BSSuppor.100029BE
100029BC    33C0            xor eax,eax

一个简单的注册机:

void main(){
char regname[50],regcode[20];
long temp1=0,temp2=0;
printf("请输入Regname:");
gets(regname);
int stlen=strlen(regname);
if(stlen<16)
  for(;stlen<16;stlen++)
   regname[stlen]=0x40;
for(int i=0, t=0;i<4;i++, t=0){
  if(i)regcode[19-5*i]=0x2d;
  for(int j=0;j<16;j+=4,t++){
   temp1*=0x343FD;
   temp1+=0x269ec3;
   temp2=temp1;
   __asm{
    mov eax,temp2
    sar eax,010h
    and eax,07FFFh
    cdq
    mov ecx,0ah
    idiv ecx
    mov temp2,edx
   }
   temp2=temp2+regname[j+i]-0xa;
   temp2=temp2%0xa+0x30;
   regcode[18-5*i-t]=temp2;
  }
}
regcode[19]='\0';
printf("你的Regcode:%s\n",regcode);
}

请输入Regname:ligyuan

你的Regcode:5153-4723-9940-1266

也可以用万能码:1234-5678-1234-5678

软件的注册保护没有过多的考虑,找到关键点后能够轻松的实现算法注册机,还留了万能码,差一点我就中了头奖。这样,我这个菜鸟也才有了练手的机会,由于代码中没有考虑到输入空格时的处理,因此有很多不足之处,还望不要笑话鄙人。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章