飘云 发表于 2010-5-9 17:57:03

梁龙凭证打印 1.1.203 算法分析+ASM注册函数

【破文标题】梁龙凭证打印 1.1.203 算法分析+ASM注册函数
【破文作者】飘云/P.Y.G
【官方主页】https://www.chinapyg.com
【作者博客】http://blog.piaoyunsoft.com
【破解平台】WinXp SP3
【破解工具】PEiD0.94、OD
【作者邮箱】[email protected]
【软件名称】梁龙凭证打印 1.1.203
【软件大小】2.66 MB
【原版下载】http://www.llwsoft.cn/xzzx.htm
【破解过程】


看到软件仓库
https://www.chinapyg.com/viewthread.php?tid=55356&extra=page%3D1
lzq1973兄弟发布了 这个系列的破解,那么就没有秘密了~~ 拿来做教程了~~
注意:上面提供的注册机是有少许问题的(原因在八进制转换上,不在本文范围,读者自行分析)

OD载入程序:

点击【软件注册】输入注册信息,找到关键处,发现只是对比注册码的过程了~~ 说明注册码在 窗体加载的时候 就已经生成了,那我们找到FormLoad事件开始分析:

输入注册信息:123456789 断下,来到这里:

006D70D0push    ebp                              ;FormLoad事件
006D70D1mov   ebp, esp
006D70D3sub   esp, 0C
006D70D6push    <jmp.&MSVBVM60.__vbaExceptHandle>;SE 处理程序安装
006D70DBmov   eax, dword ptr fs:
006D70E1push    eax
006D70E2mov   dword ptr fs:, esp
006D70E9sub   esp, 134
006D70EFpush    ebx
006D70F0push    esi
006D70F1push    edi
006D70F2mov   dword ptr [ebp-C], esp
006D70F5mov   dword ptr [ebp-8], 00401790
006D70FCmov   esi, dword ptr [ebp+8]
006D70FFmov   eax, esi
006D7101and   eax, 1
006D7104mov   dword ptr [ebp-4], eax
006D7107and   esi, FFFFFFFE
006D710Apush    esi
006D710Bmov   dword ptr [ebp+8], esi
006D710Emov   ecx, dword ptr [esi]
006D7110call    dword ptr [ecx+4]
006D7113mov   eax, dword ptr
006D7118xor   edi, edi
006D711Acmp   eax, edi
.
.
.无关代码--省略
.
.
006D7CEBmov   eax, dword ptr [ebp-74]          ;机器码
006D7CEElea   edx, dword ptr [ebp-A4]
006D7CF4lea   ecx, dword ptr [ebp-54]
006D7CF7mov   dword ptr [ebp-74], 0
006D7CFEmov   dword ptr [ebp-9C], eax
006D7D04mov   dword ptr [ebp-A4], 8
006D7D0Ecall    dword ptr [<&MSVBVM60.__vbaVarMo>;MSVBVM60.__vbaVarMove
006D7D14lea   ecx, dword ptr [ebp-8C]
006D7D1Acall    dword ptr [<&MSVBVM60.__vbaFreeO>;MSVBVM60.__vbaFreeObj
006D7D20mov   ecx, dword ptr [esi]
006D7D22push    esi
006D7D23call    dword ptr [ecx+328]
006D7D29lea   edx, dword ptr [ebp-8C]
006D7D2Fpush    eax
006D7D30push    edx
006D7D31call    edi
006D7D33mov   dword ptr [ebp-9C], 4            ;参数
006D7D3Dmov   dword ptr [ebp-A4], 2
006D7D47mov   ebx, dword ptr [eax]
006D7D49mov   dword ptr [ebp-F4], eax
006D7D4Flea   eax, dword ptr [ebp-A4]
006D7D55lea   ecx, dword ptr [ebp-54]
006D7D58push    eax
006D7D59push    1                              ;参数
006D7D5Blea   edx, dword ptr [ebp-74]
006D7D5Epush    ecx                              ; /String8
006D7D5Fpush    edx                              ; |ARG2
006D7D60call    dword ptr [<&MSVBVM60.__vbaStrVa>; \__vbaStrVarVal
006D7D66push    eax
006D7D67call    dword ptr [<&MSVBVM60.#631>]   ;截取前4位设为 A
006D7D6Dmov   edx, eax
006D7D6Flea   ecx, dword ptr [ebp-78]
006D7D72call    dword ptr [<&MSVBVM60.__vbaStrMo>;MSVBVM60.__vbaStrMove
006D7D78mov   dword ptr [ebp-138], ebx
006D7D7Emov   ebx, dword ptr [ebp-F4]
006D7D84push    eax
006D7D85mov   eax, dword ptr [ebp-138]
006D7D8Bpush    ebx
006D7D8Ccall    dword ptr [eax+A4]
006D7D92test    eax, eax
006D7D94fclex
006D7D96jge   short 006D7DAA
006D7D98push    0A4
006D7D9Dpush    00662290
006D7DA2push    ebx
006D7DA3push    eax
006D7DA4call    dword ptr [<&MSVBVM60.__vbaHresu>;MSVBVM60.__vbaHresultCheckObj
006D7DAAlea   ecx, dword ptr [ebp-78]
006D7DADlea   edx, dword ptr [ebp-74]
006D7DB0push    ecx
006D7DB1push    edx
006D7DB2push    2
006D7DB4call    dword ptr [<&MSVBVM60.__vbaFreeS>;MSVBVM60.__vbaFreeStrList
006D7DBAadd   esp, 0C
006D7DBDlea   ecx, dword ptr [ebp-8C]
006D7DC3call    dword ptr [<&MSVBVM60.__vbaFreeO>;MSVBVM60.__vbaFreeObj
006D7DC9lea   ecx, dword ptr [ebp-A4]
006D7DCFcall    dword ptr [<&MSVBVM60.__vbaFreeV>;MSVBVM60.__vbaFreeVar
006D7DD5mov   eax, dword ptr [esi]
006D7DD7push    esi
006D7DD8call    dword ptr [eax+318]
006D7DDElea   ecx, dword ptr [ebp-8C]
006D7DE4push    eax
006D7DE5push    ecx
006D7DE6call    edi
006D7DE8mov   ebx, dword ptr [eax]
006D7DEAmov   dword ptr [ebp-F4], eax
006D7DF0lea   edx, dword ptr [ebp-54]
006D7DF3push    4                              ;参数
006D7DF5lea   eax, dword ptr [ebp-74]
006D7DF8push    edx                              ; /String8
006D7DF9push    eax                              ; |ARG2
006D7DFAcall    dword ptr [<&MSVBVM60.__vbaStrVa>; \__vbaStrVarVal
006D7E00push    eax
006D7E01call    dword ptr [<&MSVBVM60.#618>]   ;截取右边4位 设为B
006D7E07mov   edx, eax
006D7E09lea   ecx, dword ptr [ebp-78]
006D7E0Ccall    dword ptr [<&MSVBVM60.__vbaStrMo>;MSVBVM60.__vbaStrMove
.
.
.无关代码--省略
.
.
006D7EF3mov   ebx, dword ptr [edx]
006D7EF5push    ecx                              ; /String
006D7EF6call    dword ptr [<&MSVBVM60.__vbaStrCa>; \连接 A、B
006D7EFCmov   edx, eax                         ;连接后的字符串设为C
006D7EFElea   ecx, dword ptr [ebp-7C]
006D7F01call    dword ptr [<&MSVBVM60.__vbaStrMo>;MSVBVM60.__vbaStrMove
006D7F07mov   edx, ebx
.
.
.无关代码--省略
.
.
006D7FBFpush    ecx
006D7FC0mov   ebx, dword ptr [eax]
006D7FC2call    dword ptr [<&MSVBVM60.#581>]   ;把字符串C转换成浮点数值 = D
006D7FC8fadd    qword ptr                ;D + 10871006(常量) = E
006D7FCEsub   esp, 8
006D7FD1fstsw   ax
006D7FD3test    al, 0D
006D7FD5jnz   006D8398
006D7FDBfstp    qword ptr [esp]
006D7FDEcall    dword ptr [<&MSVBVM60.__vbaStrR8>;把E转换成字符串
006D7FE4mov   edx, eax
006D7FE6lea   ecx, dword ptr [ebp-78]
006D7FE9call    dword ptr [<&MSVBVM60.__vbaStrMo>;MSVBVM60.__vbaStrMove
006D7FEFmov   edx, ebx
.
.
.无关代码--省略
.
.
006D8081push    0A0
006D8086push    00662290
006D808Bpush    ebx
006D808Cpush    eax
006D808Dcall    dword ptr [<&MSVBVM60.__vbaHresu>;MSVBVM60.__vbaHresultCheckObj
006D8093mov   ecx, dword ptr [ebp-74]          ;字符串E
006D8096push    ecx
006D8097call    dword ptr [<&MSVBVM60.#581>]   ;字符串E转换成浮点数值 = F
006D809Dfstp    qword ptr [ebp-9C]
006D80A3lea   edx, dword ptr [ebp-A4]
006D80A9lea   eax, dword ptr [ebp-B4]
006D80AFpush    edx
006D80B0push    eax
006D80B1mov   dword ptr [ebp-A4], 5
006D80BBcall    dword ptr [<&MSVBVM60.#575>]   ;将F转换成八进制 G
006D80C1mov   ecx, dword ptr [ebp-FC]
006D80C7lea   edx, dword ptr [ebp-B4]
006D80CDlea   eax, dword ptr [ebp-78]
006D80D0push    edx                              ; /String8
006D80D1mov   ebx, dword ptr [ecx]             ; |
006D80D3push    eax                              ; |ARG2
006D80D4call    dword ptr [<&MSVBVM60.__vbaStrVa>; \将G转换成字符串即为注册码 SN
006D80DAmov   ecx, ebx
006D80DCmov   ebx, dword ptr [ebp-FC]
006D80E2push    eax
006D80E3push    ebx
006D80E4call    dword ptr [ecx+A4]


【算法总结】
这里我省略了很多无关代码(VB的代码就是冗长,没必要都贴出来),方便读者参考~~

所以这里很清楚了理清了算法流程:

1.截取机器码左边4位注册码设为A
2.截取机器码右边4位注册码设为B
3.连接A、B设为C
4.把C转换成浮点数值设为D
5.D + 10871006(常量)并转换成字符设为E
7.将E转换成浮点数值设为F
8.将F转换成八进制设为G
9.将G转换成字符串即为正确注册码SN

【算法函数】
;说明下,由于wsprintf 函数不能处理 %o 八进制~~所以导致这个代码有点长~ 不过那段进制转换函数还是值得收藏~
;参考自看雪论坛小虾版主的代码,感谢!

dwCount                db      ?

.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;函数功能:将字符串转换成数值
;Code By PiaoYun/P.Y.G
;http://blog.piaoyunsoft.com
;说明:仅做转换用,没有判断传入字符串的合法性~~如 "1111" --> 1111
;
;函数参数:
;lpszStr:指针,传入字符串的地址
;返回值:16进制数值
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcStrToDword proc lpszStr:dword
      mov         esi,lpszStr
      xoreax, eax
      xorebx, ebx
      
@@:
      movbl, byte ptr [esi]
      test bl, bl
      je         @F
      subbl, 30h
      leaeax, dword ptr [eax+eax*4]
      addeax, eax
      addeax, ebx
      incesi
      jmp         @B
@@:
      ret
_ProcStrToDword endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;函数功能:进制转换
;函数参数:
;    lpOutBuff:输出缓冲区
;    dwValue:为要转换的整数值
;    nType:转换类型,分别可以是2、8、10、16进制都可以转换。
;此段代码参考自看雪论坛小虾版主,在此表示感谢!
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
dwtos proc uses ebx esi lpOutBuff:DWORD,dwValue:DWORD,nType:DWORD
    LOCAL      @szBuffer:BYTE
    ;LOCAL         dwCount:DWORD
    xor eax,eax
    .if !(lpOutBuff)
    ret
    .endif
    xor esi,esi
    lea esi,@szBuffer
    mov ebx,lpOutBuff
    mov ecx,nType
    mov eax,dwValue
    .while eax > ecx || eax
      xor edx,edx
      div ecx
      .if dl > 9
          add dl,'A' - 10
      .else
          add dl,'0'
      .endif
      mov byte ptr [esi],dl
      inc esi
      inc dwCount
    .endw
    .while dwCount
       mov   cl,[esi-1]
       mov   [ebx],cl
       dec   esi
       dec   dwCount
       inc   ebx
    .endw
    ret
dwtos endp

;=================================================
;注册算法:
;1.截取机器码左边4位注册码设为A
;2.截取机器码右边4位注册码设为B
;3.连接A、B设为C
;4.把C转换成浮点数值设为D
;5.D + 10871006(常量)并转换成字符设为E
;7.将E转换成浮点数值设为F
;8.将F转换成八进制设为G
;9.将G转换成字符串即为正确注册码SN
;=================================================
KeyGen    proc    uses ecx edx lpID:DWORD
    LOCAL    @szTemp:BYTE
    LOCAL    @dwTemp:DWORD
    LOCAL   @szOctBuffer:BYTE
   
    invoke    RtlZeroMemory,addr @szTemp,sizeof @szTemp   
    invoke    RtlZeroMemory,addr @szOctBuffer,sizeof @szOctBuffer   
   
    xor    ecx,ecx
    xor    edx,edx
    xor    esi,esi
   
   
    ;截取左边4位
    mov eax,lpID
    mov    ecx,4
    xor    esi,esi
    @@:
      movzx    ebx,byte ptr[eax+esi]
      mov      byte ptr[@szTemp+esi],bl
      inc      esi
      loop    @B
   
    invoke lstrlen,lpID
    ;移动到倒数第四位
    sub    eax,4
    mov    esi,eax
   
    ;截取右边四位
    mov eax,lpID
    mov    ecx,4
    mov edx,4
    @@:
      movzx    ebx,byte ptr[eax+esi]
      mov      byte ptr[@szTemp+edx],bl
      inc      esi
      inc      edx
      loop    @B
   
    ;上面@szTemp里面已经是连接好的字符串了
   
    ;字符串转换成数值
    invoke    _ProcStrToDword,addr @szTemp
       ;加10871006
      
    add      eax,10871006
   
    ;转换成八进制
    invoke   dwtos,addr @szOctBuffer,eax,8
   
    ;输出最终注册码
    lea      eax,@szOctBuffer

    ret

KeyGen endp

【版权声明】 本文纯属技术交流, 原创于PYG官方论坛, 转载请注明作者并保持文章的完整, 谢谢!

zxc 发表于 2010-5-9 19:01:45

/:011 初学者闪过,看不懂,呵

樊盟 发表于 2010-5-9 20:37:28

好久不见坛主出作品了,破文代码着色也好看,膜拜大牛!/:good

漏网小鱼 发表于 2010-5-11 08:01:58

看不懂的飘过。。。

imlove 发表于 2011-4-20 15:25:02

楼主的算法很不错!

159357 发表于 2014-7-29 10:07:40

梁龙系列 算法注册机

DaShanRen 发表于 2014-7-31 13:01:17

唉,汇编真是浪费财力物力啊!

xinbinchi 发表于 2016-7-6 20:30:00

谢谢分享,路过必顶。
页: [1]
查看完整版本: 梁龙凭证打印 1.1.203 算法分析+ASM注册函数