• 标 题:轻松试卷 V4.50 算法分析 (5千字)
  • 作 者:PaulYoung[CCG]
  • 时 间:2002-1-3 20:05:19
  • 链 接:http://bbs.pediy.com

ssljx 兄看过来,轻松试卷 V4.50 算法分析,欢迎测试!欢迎写注册机! :)

作者:PaulYoung
下载:http://www.hktk.com:8080/cgi-bin/dl.pl?url=ftp://ftp.cq.hktk.com/soft/soft_cai/eps.zip
简介:可以在答案中插入图片、对象等,编辑题目并把题目加入题库,题库管理、抽取试卷、分数统计,作业系统是教师的一个好帮手。
工具:SoftICE V4.05
日期:2001-12-23
__________________________________________________________________________________________

  (注意,这个软件在不同的电脑看到的地址可能会不一样。)

  真倒霉呀,竟然中了CIH,把我的可执行文件全部破坏了,害我重装……55555555……搞个算法出出气,嘻……嘻……

  老办法,用 bpx hmemcpy 设断并来到这里……


015F:00407088  PUSH      EAX
015F:00407089  CALL      EBX        // F8 跟入
015F:0040708B  CMP      BYTE PTR [00578298],00
015F:00407092  JZ        004070A2

  来到……

015F:006D73E0  MOV      EAX,[ESP+0C]    //假注册码送 EAX
015F:006D73E4  MOV      ECX,[ESP+08]    //用户名送  ECX
015F:006D73E8  MOV      EDX,[ESP+04]    //机器码送  EDX
015F:006D73EC  PUSH      EAX            //假注册码入栈
015F:006D73ED  PUSH      ECX       //用户名入栈
015F:006D73EE  PUSH      EDX       //机器码入栈
015F:006D73EF  CALL      006D7310        //计算,F8跟入
015F:006D73F4  ADD      ESP,0C
015F:006D73F7  TEST      EAX,EAX
015F:006D73F9  JZ        006D7408

  来到……

015F:006D7310  SUB      ESP,10
015F:006D7313  PUSH      EBX
015F:006D7314  PUSH      EBP
015F:006D7315  PUSH      ESI
015F:006D7316  MOV      ESI,[ESP+20]
015F:006D731A  PUSH      EDI
015F:006D731B  MOV      EDI,ESI
015F:006D731D  OR        ECX,-01
015F:006D7320  XOR      EAX,EAX
015F:006D7322  REPNZ SCASB
015F:006D7324  MOV      EBP,[ESP+28]
015F:006D7328  NOT      ECX
015F:006D732A  DEC      ECX
015F:006D732B  MOV      EDI,EBP
015F:006D732D  MOV      EBX,ECX
015F:006D732F  OR        ECX,-01
015F:006D7332  REPNZ SCASB
015F:006D7334  MOV      EDI,[ESP+2C]
015F:006D7338  NOT      ECX
015F:006D733A  DEC      ECX
015F:006D733B  MOV      [ESP+24],ECX
015F:006D733F  OR        ECX,-01
015F:006D7342  REPNZ SCASB
015F:006D7344  NOT      ECX
015F:006D7346  DEC      ECX
015F:006D7347  CMP      ECX,0F                    //注册码是否为15位
015F:006D734A  JZ        006D7359          //相等则跳
015F:006D734C  POP      EDI
015F:006D734D  POP      ESI
015F:006D734E  POP      EBP
015F:006D734F  MOV      EAX,00000001
015F:006D7354  POP      EBX
015F:006D7355  ADD      ESP,10
015F:006D7358  RET
015F:006D7359  XOR      ECX,ECX                  //ECX 清零,作为初始值
015F:006D735B  MOV      EAX,ECX
015F:006D735D  CDQ
015F:006D735E  IDIV      EBX
015F:006D7360  MOVSX    EAX,BYTE PTR [ESI+EDX]    //依次取机器码字符到EAX,取完则从第1个重新开始依次取位
015F:006D7364  CDQ                                //双字扩展(实际上是 EDX 清零)
015F:006D7365  MOV      EDI,EAX                //字符送EDI
015F:006D7367  MOV      EAX,ECX                //EAX=ECX
015F:006D7369  XOR      EDI,EDX                //机器码字符与0异或(EDX=0),结果送EDI
015F:006D736B  SUB      EDI,EDX                //EDI=EDI-EDX(EDX=0)
015F:006D736D  CDQ                                //双字扩展(实际上是 EDX 清零)
015F:006D736E  IDIV      DWORD PTR [ESP+24]        //EAX/用户名长度(EAX=0,1,2...14),商放EAX,余数放EDX(有何用处?不明白 :()
015F:006D7372  MOVSX    EAX,BYTE PTR [EBP+EDX]    //依次取用户名字符ASCII到EAX,取完则从第1个重新开始依次取位
015F:006D7376  CDQ                                //双字扩展(EAX<80000000, EDX=00000000;EAX>= 80000000, EDX则为FFFFFFFF,例如用户字符为中文时,EDX=FFFFFFFF)
015F:006D7377  XOR      EAX,EDX                  //字符与0(或FFFFFFFF)异或,结果送EAX
015F:006D7379  SUB      EAX,EDX                //EAX=EAX-0(或FFFFFFFF),结果送EAX
015F:006D737B  ADD      EAX,EDI                  //EAX=EAX+EDI
015F:006D737D  MOV      EDI,0000001A             //EDI=0X1A
015F:006D7382  CDQ                                //双字扩展(实际上是EDX 清零)
015F:006D7383  IDIV      EDI                      //上面相加的和/0X1A,余数送EDX
015F:006D7385  ADD      DL,41                 //DL=余数+41
015F:006D7388  MOV      [ECX+ESP+10],DL          //以字符形式保存
015F:006D738C  INC      ECX               //ECX=ECX+1
015F:006D738D  CMP      ECX,0F                    //是否取够15位
015F:006D7390  JL        006D735B                  //不足15位则循环
015F:006D7392  MOV      EAX,[ESP+2C]              //假注册码送 EAX
015F:006D7396  LEA      ESI,[ESP+10]
015F:006D739A  MOV      DL,[EAX]                  //取假注册码一个字符
015F:006D739C  MOV      BL,[ESI]                  //取真注册码一个字符,D ESI 可以看到正确注册码
015F:006D739E  MOV      CL,DL                    //CL=DL
015F:006D73A0  CMP      DL,BL                    //一样?
015F:006D73A2  JNZ      006D73C8             //不一样则死
015F:006D73A4  TEST      CL,CL             //是否取完
015F:006D73A6  JZ        006D73BE         //未取完继续
015F:006D73A8  MOV      DL,[EAX+01]          //取假注册码下一位
015F:006D73AB  MOV      BL,[ESI+01]          //取真注册码一个字符
015F:006D73AE  MOV      CL,DL                      (同上)
015F:006D73B0  CMP      DL,BL
015F:006D73B2  JNZ      006D73C8
015F:006D73B4  ADD      EAX,02
015F:006D73B7  ADD      ESI,02
015F:006D73BA  TEST      CL,CL
015F:006D73BC  JNZ      006D739A                  //循环
015F:006D73BE  POP      EDI
015F:006D73BF  POP      ESI
015F:006D73C0  POP      EBP
015F:006D73C1  XOR      EAX,EAX
015F:006D73C3  POP      EBX
015F:006D73C4  ADD      ESP,10
015F:006D73C7  RET


  计算每一位结果后,共计算15次,最后以字符形式依次排列输出,作为正确的注册码。
  如有错误,望各位高手指正!