010破解(三)之算法分析二

010破解(三)之算法分析二

概述

010破解(二)之算法分析一
上一篇详细分析了第一种算法,也就是k[3]=0x9C系列的
之后分析了k[3]=0xFC系列后发现函数返回值最终并不能返回0x2D
因此这篇分析k[3]=0xAC系列的算法,部分地方需要结合上篇文章,在这不重复分析了

逐行分析代码

枯燥的旅程,耐心、耐心、再耐心

013BDCFC    80FB AC         CMP BL,0xAC
013BDCFF    0F85 70010000   JNZ 010Edito.013BDE75
013BDD05    8A45 DD         MOV AL,BYTE PTR SS:[EBP-0x23]            ; k[1]
013BDD08    3245 E3         XOR AL,BYTE PTR SS:[EBP-0x1D]            ; AL=k[0]^k[7]
013BDD0B    0FB6C8          MOVZX ECX,AL                             ; ecx=AL&0xFF
013BDD0E    B8 00010000     MOV EAX,0x100
013BDD13    66:0FAFC8       IMUL CX,AX                               ; CX=(k[0]^k[7]&0xFF)*0x100
013BDD17    8A45 DE         MOV AL,BYTE PTR SS:[EBP-0x22]            ; AL=k[2]
013BDD1A    32C7            XOR AL,BH                                ; k[2]^k[5]
013BDD1C    C747 1C 0200000>MOV DWORD PTR DS:[EDI+0x1C],0x2
013BDD23    0FB6C0          MOVZX EAX,AL                             ; AL=(k[2]^k[5])&0xFF
013BDD26    66:03C8         ADD CX,AX
013BDD29    0FB7C1          MOVZX EAX,CX                             ; CX=(k[0]^k[7]&0xFF)*0x100+(k[2]^k[5])&0xFF
013BDD2C    50              PUSH EAX
013BDD2D    E8 96A604FF     CALL 010Edito.004083C8
013BDD32    0FB7C0          MOVZX EAX,AX
013BDD35    83C4 04         ADD ESP,0x4
013BDD38    8947 20         MOV DWORD PTR DS:[EDI+0x20],EAX
013BDD3B    85C0            TEST EAX,EAX
013BDD3D    0F84 32010000   JE 010Edito.013BDE75
013BDD43    3D E8030000     CMP EAX,0x3E8
013BDD48    0F87 27010000   JA 010Edito.013BDE75
013BDD4E    0FB655 E5       MOVZX EDX,BYTE PTR SS:[EBP-0x1B]         ; k[9]
013BDD52    0FB64D E0       MOVZX ECX,BYTE PTR SS:[EBP-0x20]         ; k[4]
013BDD56    0FB6C7          MOVZX EAX,BH                             ; k[5]
013BDD59    33D0            XOR EDX,EAX                              ; EDX=k[9]^k[5]
013BDD5B    0FB645 E4       MOVZX EAX,BYTE PTR SS:[EBP-0x1C]         ; eax=k[8]
013BDD5F    33C8            XOR ECX,EAX                              ; ecx=k[4]^k[5]
013BDD61    C1E2 08         SHL EDX,0x8                              ; EDX=(k[9]^k[5])<<8
013BDD64    0FB645 E2       MOVZX EAX,BYTE PTR SS:[EBP-0x1E]         ; eax=k[6]
013BDD68    03D1            ADD EDX,ECX                              ; EDX=(k[9]^k[5])<<8+k[4]^k[5]
013BDD6A    0FB64D DC       MOVZX ECX,BYTE PTR SS:[EBP-0x24]         ; ecx=k[0]
013BDD6E    C1E2 08         SHL EDX,0x8                              ; EDX=((k[9]^k[5])<<8+k[4]^k[5])<<8
013BDD71    33C8            XOR ECX,EAX                              ; ecx=k[0]^k[6]
013BDD73    03D1            ADD EDX,ECX                              ; EDX=((k[9]^k[5])<<8+k[4]^k[5])<<8+k[0]^k[6]
013BDD75    68 278C5B00     PUSH 010Edito.005B8C27                   ; ASCII CC,"烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫烫"
013BDD7A    52              PUSH EDX
013BDD7B    E8 0BCA04FF     CALL 010Edito.0040A78B
013BDD80    83C4 08         ADD ESP,0x8


验证完用户名之后会有个判断k[3]==0xAC的比较,继续逐行分析,会发现函数最终返回值是0x2D

013BDE2B    80FB AC         CMP BL,0xAC
013BDE2E    75 1A           JNZ SHORT 010Edito.013BDE4A
013BDE30    8B45 F0         MOV EAX,DWORD PTR SS:[EBP-0x10]
013BDE33    85C0            TEST EAX,EAX
013BDE35    74 13           JE SHORT 010Edito.013BDE4A
013BDE37    3945 0C         CMP DWORD PTR SS:[EBP+0xC],EAX
013BDE3A    76 07           JBE SHORT 010Edito.013BDE43
013BDE3C    BE 4E000000     MOV ESI,0x4E
013BDE41    EB 0C           JMP SHORT 010Edito.013BDE4F
013BDE43    BE 2D000000     MOV ESI,0x2D
013BDE48    EB 05           JMP SHORT 010Edito.013BDE4F
013BDE4A    BE E7000000     MOV ESI,0xE7
013BDE4F    8D4D EC         LEA ECX,DWORD PTR SS:[EBP-0x14]
013BDE52    C745 FC FFFFFFF>MOV DWORD PTR SS:[EBP-0x4],-0x1
013BDE59    FF15 7C24E702   CALL DWORD PTR DS:[<&Qt5Core.??1QByteArr>; Qt5Core.??1QByteArray@@QAE@XZ
013BDE5F    8BC6            MOV EAX,ESI
013BDE61    8B4D F4         MOV ECX,DWORD PTR SS:[EBP-0xC]
013BDE64    64:890D 0000000>MOV DWORD PTR FS:[0],ECX


算法到这就分析全部分析完了

算法总结

  1. 判断用户名/密码是否为空

  2. 将密码字符串转为16进制数据

  3. 验证密码

    1. k[3]=0x9C 或 0xFC 或者 0xAC

    2. sub_00407644函数返回值不能为0

      即AL = (k0 ^ k6 ^ 0x18 + 0x3D) ^ 0xA7

      AL!=0

    3. sub_004083C8函数返回值不能为0 且 小于等于0x3e8

      即esi=((K[2]k[5]&0xFF)+(K[1]k[7]&0xFF)*0x100)&0xFFFF

      EAX=((esi0x7892+0x4D30)0x3421&0xFFFF)/0xB

      if (dwEAX % 0xB == 0 && dwEAX/0xB <= 0x3e8)

  4. 将用户名转为ASCII字符串

  5. 调用sub_402E50函数计算用户名字符串加密值,参数是(用户名,1,0,sub_004083C8函数返回值)

    用户名加密值与k4 k5 k6 k7有对应关系

    K[4]=Ret&0xFF
    k[5]=(Ret>>8)&0xFF
    k[6]=(Ret>>0x10)%0xFF
    k[7]=(Ret>>0x18)&0xFF

  6. 判断参数

    即sub_00407644函数返回值>=9

    或者<=0x4389(根据算法选择不同的参数作比较)

本文仅限学习交流使用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值