首页
社区
课程
招聘
再来一个CRACKME算法分析(适合新手)[讨论]
发表于: 2006-2-10 10:38 8790

再来一个CRACKME算法分析(适合新手)[讨论]

2006-2-10 10:38
8790

------------------------------------------------------------------------
1)PEID检查,MASM32 / TASM32 [Overlay] ,无壳。
2)试运行程序,任意输入注册信息后,出现错误提示“try,again”
3)OD载入程序,用超级字符串查找。
超级字串参考+        , 条目 3
地址=004011F6
反汇编=PUSH CrackMe0.004020E9
文本字串=try again
双击,来到004011F6,向上找,发现有两处调用了GetDlgItemTextA.那就在第一处下断。
4)OD重新载入程序,任意输入注册信息确定后,程序被中断。
00401139   $  6A 32         PUSH 32                                  ; /Count = 32 (50.)
0040113B   .  68 F3204000   PUSH CrackMe0.004020F3                   ; |Buffer = CrackMe0.004020F3
00401140   .  68 C8000000   PUSH 0C8                                 ; |ControlID = C8 (200.)
00401145   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
00401148   .  E8 DE000000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \取注册名位数
0040114D   .  83F8 00       CMP EAX,0                                ;  输入注册名了吗
00401150   .  0F84 99000000 JE CrackMe0.004011EF                     ;  没有注册名则跳向失败
00401156   .  83F8 04       CMP EAX,4                                ;  注册名是否大于四位
00401159   .  0F82 90000000 JB CrackMe0.004011EF                     ;  小于四位就跳向失败
0040115F   .  33C9          XOR ECX,ECX                              ;  ECX清零
00401161   .  33DB          XOR EBX,EBX                              ;  EBX清零
00401163   .  33F6          XOR ESI,ESI                              ;  ESI清零
00401165   .  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX             ;  EAX=注册名位数,放进EBP-4
00401168   >  0FBE81 F32040>MOVSX EAX,BYTE PTR DS:[ECX+4020F3]       ;  取注册名每一位的ASCII值,并放进EAX
0040116F   .  83F8 20       CMP EAX,20                               ;  比较注册名每一位的ASCII值是否等于20
00401172   .  74 07         JE SHORT CrackMe0.0040117B              
00401174   .  6BC0 04       IMUL EAX,EAX,4                           ;  EAX=EAX*4  (过程1开始)
00401177   .  03D8          ADD EBX,EAX                              ;  EBX=EAX+EBX
00401179   .  8BF3          MOV ESI,EBX                              ;  EBX的值给ESI
0040117B   >  41            INC ECX                                  ;  每计算一次ECX+1
0040117C   .  3B4D FC       CMP ECX,DWORD PTR SS:[EBP-4]             ;  计算完了没,没有则继续计算
0040117F   .^ 75 E7         JNZ SHORT CrackMe0.00401168                 
00401181   .  83FE 00       CMP ESI,0                                ;  结果是否为零
00401184   .  74 69         JE SHORT CrackMe0.004011EF               ;  等于零则跳向失败
00401186   .  BB 89476500   MOV EBX,654789                           ;  令EBX=654789         (过程2开始)
0040118B   >  0FBE81 F22040>MOVSX EAX,BYTE PTR DS:[ECX+4020F2]       ;  从右向左取用户名每一位的ASCII值
00401192   .  4B            DEC EBX                                  ;  每计算一次EBX-1
00401193   .  6BC3 02       IMUL EAX,EBX,2                           ;  EAX=EBX*2
00401196   .  03D8          ADD EBX,EAX                              ;  EBX=EAX+EBX
00401198   .  4B            DEC EBX                                  ;  每计算一次EBX-1
00401199   .  49            DEC ECX                                  ;  每计算一次ECX-1
0040119A   .^ 75 EF         JNZ SHORT CrackMe0.0040118B              ;  
0040119C   .  56            PUSH ESI                                 ; /<%lu>
0040119D   .  53            PUSH EBX                                 ; |<%lX>
0040119E   .  68 C7204000   PUSH CrackMe0.004020C7                   ; |bs-%lx-%lu
004011A3   .  68 BB214000   PUSH CrackMe0.004021BB                   ; |s = CrackMe0.004021BB
004011A8   .  E8 6C000000   CALL <JMP.&USER32.wsprintfA>             ; 连接各段注册码
004011AD   .  58            POP EAX
004011AE   .  58            POP EAX
004011AF   .  58            POP EAX
004011B0   .  58            POP EAX
004011B1   .  E8 01000000   CALL CrackMe0.004011B7
004011B6   .  C3            RETN
004011B7   $  33C9          XOR ECX,ECX
004011B9   .  6A 32         PUSH 32                                  ; /Count = 32 (50.)
004011BB   .  68 57214000   PUSH CrackMe0.00402157                   ; |Buffer = CrackMe0.00402157
004011C0   .  68 C9000000   PUSH 0C9                                 ; |ControlID = C9 (201.)
004011C5   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004011C8   .  E8 5E000000   CALL <JMP.&USER32.GetDlgItemTextA>       ; \GetDlgItemTextA
004011CD   .  83F8 00       CMP EAX,0
004011D0   .  74 1D         JE SHORT CrackMe0.004011EF
004011D2   .  33C9          XOR ECX,ECX
004011D4   >  0FBE81 572140>MOVSX EAX,BYTE PTR DS:[ECX+402157]
004011DB   .  0FBE99 BB2140>MOVSX EBX,BYTE PTR DS:[ECX+4021BB]
004011E2   .  3BC3          CMP EAX,EBX
004011E4   .  75 09         JNZ SHORT CrackMe0.004011EF
004011E6   .  83F8 00       CMP EAX,0
004011E9   .  74 19         JE SHORT CrackMe0.00401204
004011EB   .  41            INC ECX
004011EC   .^ EB E6         JMP SHORT CrackMe0.004011D4
004011EE   .  C3            RETN
004011EF   >  6A 10         PUSH 10                                  ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
004011F1   .  68 E4204000   PUSH CrackMe0.004020E4                   ; |nope
004011F6   .  68 E9204000   PUSH CrackMe0.004020E9                   ; |try again
004011FB   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
004011FE   .  E8 34000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA
00401203   .  C3            RETN                                       
00401204   >  6A 40         PUSH 40                                  ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401206   .  68 D2204000   PUSH CrackMe0.004020D2                   ; |solved
0040120B   .  68 D9204000   PUSH CrackMe0.004020D9                   ; |well done.
00401210   .  FF75 08       PUSH DWORD PTR SS:[EBP+8]                ; |hOwner
00401213   .  E8 1F000000   CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA

------------------------------------------------------------------------
BY 逍遥风
算法总结:
1)过程1:注册名必须大于等于4位,取用户名每一位的对应的16进制数,与4相乘。并把结果相加,设为“甲”
2)过程2:可以归纳出一个通项公式:其中A1=654789为定值。A2=[(A1-1)*2]-1+(A1-1)。。。A(n)={[A(n-1)-1]*2}-1+[A(n-1)-1],n=注册名位数。所得A(n)设为“乙”
3)将“甲”转换成相应的十进制。
4)合并注册码:BS-乙-甲(十进制)
例:注册名tcxb
1)取t的16进制值等于74,74*4=1D0。取c的16进制值等于63,63*4=18C。取x的16进制值等于78,78*4=1E0
   取b的16进制值等于62,62*4=188。1DO+18C+1E0+188=6C4。
2)根据上面所的的通项公式A1=654789,n+1=5,则A2=12FD697,A3=38F83C1,A4=AAE8B3F,A5=200BA1B9
   所以A5=乙
3)联结BS-乙-甲(十进制):BS-200BA1B9-480
所以:注册名tcxb
      注册码BS-200BA1B9-1732
----------------------------------------------------------------------
有疏漏或错误的地方请大家指出。谢谢


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
0040116F   .  83F8 20       CMP EAX,20                               ;  比较注册名每一位的ASCII值是否等于20
为什么只比较20,不比较其他数值呢?

跟出了我自己的注册码

zero
BS-200BA1B9-1792
2006-2-10 16:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不得不顶,刚学,谢谢指点
2006-10-25 21:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
取20是看是不是数字或者字母,ASCII值32(16进制20)是空格,必须大于32才是数字或者字母.
0FBE81 F22040>MOVSX EAX,BYTE PTR DS:[ECX+4020F2]       ;  从右向左取用户名每一位的ASCII值
  这里我没看懂,MOVSX是先符号扩展再传送,那么为什么是从右向左取呢?
  在OD里看到了堆栈内容,的确如此,但是又产生了疑问,这句好象没什么用?来看下面的代码
00401193   .  6BC3 02       imul    eax, ebx,2                     
上一句赋了值,这一句又直接取代了,那上一句有什么用处?
看OD的自动注释,很容易得到注册码,不过自己分析,还是够呛,新手上路,多多指点.

2006-11-2 20:12
0
雪    币: 191
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这是我看懂的第一篇破文,谢了。。。。。
2006-11-3 09:53
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
确实适合新手 学了
2006-11-5 11:05
0
雪    币: 136
活跃值: (1480)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
7
明码好明显奥。。。适合新手学习
2010-4-4 22:44
0
雪    币: 180
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
本人是菜鸟.请高手们多多指点.

我想纠正一下上面朋友的说法.
下面的代码好象不是判断数字或字母.而是如果是空格就忽略,读下一个字符.
0040116F   .  83F8 20       CMP EAX,20                               ;  比较注册名每一位的ASCII值是否等于20
00401172   .  74 07         JE SHORT CrackMe0.0040117B
2010-4-8 10:25
0
雪    币: 161
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这是我第一个写出注册机的程序,感谢。。。
2010-4-8 11:25
0
雪    币: 161
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
[QUOTE=茶半;239875]取20是看是不是数字或者字母,ASCII值32(16进制20)是空格,必须大于32才是数字或者字母.
0FBE81 F22040>MOVSX EAX,BYTE PTR DS:[ECX+4020F2]       ;  从右向左取用户名每一位的ASCII值
  这里我没看懂,MOVSX是先符号扩展...[/QUOTE]

上面那一句完全没用。。。
2010-4-8 11:29
0
雪    币: 72
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
适合新手  学习了
2010-4-8 11:35
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
12
注册码那么长都是唬人的
BS-200BA1B9-前缀是固定的,后面跟个注册名ascii的和的4倍就好
2010-4-8 11:47
0
雪    币: 161
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
[QUOTE=bitt;787844]注册码那么长都是唬人的
BS-200BA1B9-前缀是固定的,后面跟个注册名ascii的和的4倍就好
#include "stdafx.h"

int main(int argc, char* argv[])
{
        char name[10];
        int pwd=0,i=0;
        printf(&qu...[/QUOTE]

BS- 这一段是一样的,后面的200BA1B9跟name的长度有关的
2010-4-8 15:09
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
14
哦对 看到了
重来个
#include "stdafx.h"
#include <string.h>

int main(int argc, char* argv[])
{
  char name[10];
  int serial1=0x654789,serial2=0,i=0;
  printf("plz input you name:\n");
  scanf("%s",name);
  for(i=0;i<strlen(name);i++)
  {
	serial1--;
	serial1*=3;
	serial1--;
  }
  i=0;
  while(name[i]!='\0')
  {
    serial2+=(int)name[i]*4;
    i++;
  }
  printf("your serial is:BS-%lX-%lu\n",serial1,serial2);
  return 0;
}
2010-4-8 16:09
0
游客
登录 | 注册 方可回帖
返回
//