怎样防止注册码在内存中泄漏?
本帖最后由 baitang36 于 2021-9-7 18:01 编辑郎大侠的经典注册程序,http://bbs.mjtd.com/forum.php?mod=viewthread&tid=112653&highlight=%D7%A2%B2%E1,简洁、小巧,有很多人在用,也有很多人修改后在用。
;;; ==============================================
;;; lsp注册模块
;;; 使用方法,将(jiany0001)插到你的程序中即可使用
;;; ==============================================
(defun jiany0001(/ bb dcl_re f fname fsys jqm n zcm)
(vl-load-com)
(defun jy (jqm) ; 算法:注册码=(机器码+144356842)^0.89取整,可自己修改
(itoa (fix (expt (+ (atoi jqm) 144356842) 0.89))))
(setq fsys (vlax-create-object "Scripting.FileSystemObject"))
(if (/= (vlax-invoke-method fsys "DriveExists" "C") :vlax-false)
(setq jqm (itoa (vlax-get-property (vlax-invoke-method fsys "GetDrive" "C") "SerialNumber"))))
(setq zcm (vl-registry-read "HKEY_CURRENT_USER\\Software\\TH++\\" "Number"))
(if (/= zcm (jy jqm))
(progn
(setq fname (vl-filename-mktemp "zhuc.dcl") f (open fname "w"))
(write-line "zhuc:dialog{ label=\"注册信息\";" f)
(write-line ":edit_box{label=\" 机器码\";key=\"e01\";edit_width=18;}" f)
(write-line ":edit_box{label=\" 授权码\";key=\"e02\";edit_width=18;}" f)
(write-line ":row{:button {label=\"注册\";key=\"e03\";is_default=true;}" f)
(write-line ":button {label=\"取消\";is_cancel=true;}}}" f)
(close f)
(new_dialog "zhuc" (setq dcl_re (load_dialog fname)))
(set_tile "e01" jqm)
(set_tile "e02" "联系QQ:XXXXXX")
(action_tile "e03" "(setq zcm(get_tile \"e02\")) (done_dialog 1)")
(if (= (start_dialog) 1)(vl-registry-write "HKEY_CURRENT_USER\\software\\TH++\\" "Number" zcm))
(unload_dialog dcl_re)
(vl-file-delete fname)
(if (/= zcm (jy jqm))
(progn(alert "注册失败!") (exit))
(alert "注册成功!"))))
(princ)
)
这个程序有两个致命漏洞:
1.是在命令行输入(jy 机器码) 能够得到真正的注册码。如:在命令行输入: (jy "-1566070612")返回 "1279950820"
2.明码比较,随便输入一个假注册码,用od或winhex在内存中找,假注册码附近就能找到真注册码。
怎样堵上这两个漏洞呢?
第一个漏洞可以加一句(setq jy nil),校验失败就销毁这个函数。
第二个漏洞就有点难度了,因为(jy jqm) 计算出来的真注册码在内存中是无法用lsp代码清除掉的。那怎么办呢?
字符串在内存中是明的,那改成数字或者表,就不容易找到了。
表的存储是个链表,在内存中是不连续的,无法一次找到。整数在内存中存储是2n+1,例如,整数1在内存中是3,变样了,当然找不到。
对于保存注册码来说,表是最安全的,其次是数字,字符串是最不安全的。
防止注册码在内存中泄漏的办法就是:不要用字符串形式的注册码!
任何时候都不要计算出字符串形式的真注册码,中间过程也不行。
修改后的代码如下:;直接把以下程序插入有用代码中间,有多少个函数就插多少次。
(progn
(vl-load-com) (if (/= 1 1)(exit)) ;对抗针对 “/=" 改成"="的破解
(setq fsys (vlax-create-object "Scripting.FileSystemObject"))
(if (/= (vlax-invoke-method fsys "DriveExists" "C") :vlax-false)
(setq jqm(vlax-get-property (vlax-invoke-method fsys "GetDrive" "C") "SerialNumber")))
(setq zcm (vl-registry-read "HKEY_CURRENT_USER\\Software\\TH++\\" "Number"))
(if (/= (atoi zcm) (fix (expt (+jqm 144356842) 2)))
(progn
(setq fname (vl-filename-mktemp "zhuc.dcl") f (open fname "w"))
(write-line "zhuc:dialog{ label=\"注册信息\";" f)
(write-line ":edit_box{label=\" 机器码\";key=\"e01\";edit_width=18;}" f)
(write-line ":edit_box{label=\" 授权码\";key=\"e02\";edit_width=18;}" f)
(write-line ":row{:button {label=\"注册\";key=\"e03\";is_default=true;}" f)
(write-line ":button {label=\"取消\";is_cancel=true;}}}" f)
(close f)
(new_dialog "zhuc" (setq dcl_re (load_dialog fname)))
(set_tile "e01" (itoa jqm))
(set_tile "e02" "联系QQ:XXXXXX")
(action_tile "e03" "(setq zcm(get_tile \"e02\")) (done_dialog 1)")
(if (= (start_dialog) 1)(vl-registry-write "HKEY_CURRENT_USER\\software\\TH++\\" "Number" zcm))
(unload_dialog dcl_re)
(vl-file-delete fname)
(if (/= (atoi zcm) (fix (expt (+jqm 144356842) 2)) )
(progn(alert "注册失败!") (exit) (while t (exit))) ;对抗修改exit的破解
(alert "注册成功!"))))
(princ)
)
本帖最后由 hw8810 于 2021-9-12 01:54 编辑
大神厉害。不过好像需要考虑初始注册状态下zcm这个变量为nil的情况,不然(atoi zcm)这个函数会报错。(setq zcm (vl-registry-read "HKEY_CURRENT_USER\\Software\\TH++\\" "Number"))后面加一句(or zcm (setq zcm "1"))就没问题了。 本帖最后由 baitang36 于 2021-12-16 21:01 编辑
d1742647821 发表于 2021-12-16 18:56
大神,这个函数(vlax-get-property (vlax-invoke-method fsys "GetDrive" "C") "SerialNumber"),我用我们 ...看看这个帖子(2019.5.27上传优化版示例-仅供参考)全盘符选择注册加密代码(2017年9月4日 16:20... - AutoLISP/Visual LISP 编程技术 - CAD论坛 - 明经CAD社区 - Powered by Discuz! (mjtd.com)
读硬件信息的方法有好多,加我qq,我帮你找? tryhi 发表于 2021-9-7 16:12
(setq tem /=)
(setq /= =)
(jiany0001)
可以加and禁止重定义
(if (and (/= 3 2)
(/= zcm (jy jqm))
)
…
本帖最后由 ssyfeng 于 2021-9-7 14:32 编辑
,继续研究 本帖最后由 baitang36 于 2021-9-7 18:07 编辑
用(while t (exit))来代替(exit),可以有效对抗针对exit的破解。如果exit被重定义了,这就是死循环。
大神厉害!!!! 赞赞赞,大神又为lisp保驾护航更进一步 (setq tem /=)
(setq /= =)
(jiany0001)
(setq /= tem)
这样应该就破解了吧 tryhi 发表于 2021-9-7 16:12
(setq tem /=)
(setq /= =)
(jiany0001)
对抗这种破解就是不用jiany0001这个函数,直接插注册代码n次 将机器码和注册码进一步转换再判别,或者两者进行运算以结果判别,会不会好一点 690994 发表于 2021-9-7 18:37
将机器码和注册码进一步转换再判别,或者两者进行运算以结果判别,会不会好一点
越复杂越好 版主,你修改过的,注册,原注册机也能用吗