怎样写出一个相对安全的注册程序
本帖最后由 baitang36 于 2020-8-12 23:16 编辑注册程序是保护版权的关键,要想绝对安全是不可能的,只能做到尽可能的安全,让破解者不容易找到关键信息。
怎样才能写出一个相对安全的注册程序呢?
先看一个不安全的注册程序例子,有很多人都是用类似这种注册程序,破解起来是很容易的。
(VL-LOAD-COM)
(setq NUM1 3)
(setq NUM2 123456)(DEFUN MIMA (/ FIND_SERIALNUMBER REGNUMBER
REGNUMBER1 NUM REGNUM REG_PATH
*ERROR*
)
(DEFUN *ERROR* (MSG / ENT COUNT) (PRINC))
(DEFUN FIND_SERIALNUMBER (DRIVE / FILSYS VAL)
(setq FILSYS (VLAX-CREATE-OBJECT "Scripting.FileSystemObject"))
(setq VAL (VLAX-INVOKE FILSYS "GetDrive" DRIVE))
(setq VAL (VL-CATCH-ALL-APPLY 'VLAX-GET (LIST VAL "SerialNumber")))
(VLAX-RELEASE-OBJECT FILSYS)
(if (VL-CATCH-ALL-ERROR-P VAL)
(setq VAL 0)
VAL
)
)
(setq REG_PATH
"HKEY_CURRENT_USER\\Software\\VB and VBA Program Settings\\temp"
)
(setq REGNUMBER (VL-REGISTRY-READ REG_PATH "注册码"))
(if (/= REGNUMBER
(ITOA
(+ (/ (ATOI (RTOS (ATOI (RTOS (FIND_SERIALNUMBER "C:")))))
NUM1
)
NUM2
)
)
)
(PROGN (setq NUM (RTOS (FIND_SERIALNUMBER "C:")))
(setq REGNUM (ITOA (+ (/ (ATOI (RTOS (ATOI NUM))) NUM1) NUM2)))
(TEXTSCR)
(setq FNAME (VL-FILENAME-MKTEMP "zhuc.dcl"))
(setq F (OPEN FNAME "w"))
(WRITE-LINE "zhuc:dialog{ label=\"注册联系qq5520971\";" 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" NUM)
(ACTION_TILE
"e03"
"(setq regNumber1(get_tile \"e02\")) (done_dialog 1)"
)
(if (= (START_DIALOG) 1)
(PROGN (setq REGNUMBER REGNUMBER1))
)
(UNLOAD_DIALOG DCL_RE)
(VL-FILE-DELETE FNAME)
(if (/= REGNUMBER REGNUM)
(PROGN (ALERT "注册码无效!") (EXIT))
(PROGN (VL-REGISTRY-WRITE REG_PATH "注册码" REGNUMBER)
(ALERT "您已成功注册!")
)
)
)
)
)
(MIMA)
这程序犯了几个错误:
1.函数名、变量名和提示信息用了敏感词。
reg 申请码 授权码 注册码 zhuce 成功注册 REGNUMBER SerialNumber 注册失败 等都是破解者的最爱,相当于直接告诉破解者自己的秘密在哪里。
敏感词尽量少用,可以改成无意义的字符串,替换成乱码效果更好。
2.用了if语句,对注册码进行明码比较。
这样的语句,在fas和vlx中特征明显,可以直接找到,改一两个字节就能破解。
3.判断是否注册,只用了一个函数(mima),只要拿掉它就可以破解了。
解决第一个问题比较简单,写程序时注意就行了。原则就是只做不说,成功了不说成功,失败也不讲失败,结果拿来就用,不做任何判断。
解决第二个问题,就是不用if,这对初学者来说有一定难度,有的人不用if不会写程序。可以把它变通一下,把if语句变成cond 变成while 变成repeat
解决第三个问题,可以向猫老师学一下,弄几百上千个名字怪异的变量,想检查哪一个就检查哪一个,每个函数中都检查、判断不同的变量。几千个变量,让破解者找到吐血。
最后我把上面的程序改一下,起个抛砖引玉的作用。为方便大家阅读,第一个问题就不解决了,变量和函数名还用敏感词。
希望高手不要笑话我。
改好的代码见附件:
(VL-LOAD-COM)
(setq NUM1 3)
(setq NUM2 123456)
(DEFUN MIMA (/ FIND_SERIALNUMBER REGNUMBER
REGNUMBER1 NUM REGNUM
*ERROR*
)
(DEFUN *ERROR* (MSG / ENT COUNT) (PRINC))
(DEFUN FIND_SERIALNUMBER (DRIVE / FILSYS VAL)
(setq FILSYS (VLAX-CREATE-OBJECT "Scripting.FileSystemObject"))
(setq VAL (VLAX-INVOKE FILSYS "GetDrive" DRIVE))
(setq VAL (VL-CATCH-ALL-APPLY 'VLAX-GET (LIST VAL "SerialNumber")))
(VLAX-RELEASE-OBJECT FILSYS)
(if (VL-CATCH-ALL-ERROR-P VAL)
(setq VAL 0)
VAL
)
)
(setq REG_PATH
"HKEY_CURRENT_USER\\Software\\VB and VBA Program Settings\\temp"
)
(setq REGNUMBER (VL-REGISTRY-READ REG_PATH "注册码"))
(if (= REGNUMBER nil) (VL-REGISTRY-WRITE REG_PATH "注册码" "no reg") )
(setq REGNUMBER (VL-REGISTRY-READ REG_PATH "注册码"))
(setq REGNUMBER3
(+ (/ (ATOI (RTOS (ATOI (RTOS (FIND_SERIALNUMBER "C:")))))
NUM1
)
NUM2
)
);注册算法是 注册码=机器码/3+123456
(setq REGNUMBER4
(- (ATOI REGNUMBER) REGNUMBER3)
) ;注册表读出来的注册码和计算出来的相减,正确时等于0
(setq result (vl-catch-all-apply '/ (list 12345 REGNUMBER4)))
(setq aat (vl-catch-all-error-p result))
(setq bbt (not aat))
(while bbt
(PROGN (setq NUM (RTOS (FIND_SERIALNUMBER "C:")))
(setq REGNUM (ITOA (+ (/ (ATOI (RTOS (ATOI NUM))) NUM1) NUM2)))
(TEXTSCR)
(setq FNAME (VL-FILENAME-MKTEMP "zhuc.dcl"))
(setq F (OPEN FNAME "w"))
(WRITE-LINE "zhuc:dialog{ label=\"注册联系qq5520971\";" 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" NUM)
(ACTION_TILE
"e03"
"(setq regNumber1(get_tile \"e02\")) (done_dialog 1)"
)
(if (= (START_DIALOG) 1)
(PROGN (setq REGNUMBER REGNUMBER1))
)
(UNLOAD_DIALOG DCL_RE)
(VL-FILE-DELETE FNAME)
(PROGN (VL-REGISTRY-WRITE REG_PATH "注册码" REGNUMBER)
(ALERT "感谢您注册,请重启程序验证!")
(EXIT)
)
(setq bbt nil)
)
)
(while aat
(PROGN
(setq ^#{N 284) ;这里是抄猫工具的,感谢猫老师!
(setq II 0)
(REPEAT 450
(SET (READ (STRCAT "^#{n" (ITOA (setq II (1+ II)))))
(setq ^#{N (1+ ^#{N))
) ;给450个名字怪异的变量赋值,变量名是 ^#{n1到 ^#{n450
)
(princ "注册码正确!")
(setq aat nil)
)
)
(princ)
)
(MIMA)
(defun c:ph()(VL-REGISTRY-WRITE REG_PATH "注册码" "no reg"));破坏注册码,便于重复试验。
(defun c:tt() ;试验函数,检查变量^#{n10,判断是否已注册
(if (= ^#{n10 294)
(princ "已注册,试验成功!")
)
(princ)
)
这例子程序的亮点是把if语句改成了while语句,这样在fas中不好找。
发现一个bug,没注册过的机器会出错,导致注册对话框弹不出来。调试时没发现这个问题,抱歉。请按红色部分修改。
注意:注册码=机器码/3+123456 取整数
附件重新上传,不再收币。
xj6019 发表于 2020-8-13 11:53
感谢感谢,终于会玩了,还挺好玩的,特意做了一个放上面玩玩,热心的反馈一下怎么样呀。
楼主:我发现即 ...
重启验证,是对抗破解的有效手段。
你输入个注册码,不管对错,都写入注册表。
让破解者没法当场知道破解是否有效。 (setq ^#{N 284) ;这里是抄猫工具的,感谢猫老师!
(setq II 0)
(REPEAT 450
(SET (READ (STRCAT "^#{n" (ITOA (setq II (1+ II)))))
(setq ^#{N (1+ ^#{N))
) ;给450个名字怪异的变量赋值,变量名是 ^#{n1到 ^#{n450
)
这几句代码猫老师写的很精巧,它的意思就相当于 (setq ^#{n1 285)(setq ^#{n2 286)(setq ^#{n3 287)(setq ^#{n4 288)(setq ^#{n5 289)........
一直到(setq ^#{n450 734) baitang36 发表于 2020-8-12 21:18
你发个你自己的程序上来,我示范给你看?
就比如这个记忆拉伸的代码吧
(defun c:jyls (/ s_dis)
(cmdla0)
(command ".STRETCH" (ssget) "")
(command (setq BasicPoint (getpoint "\n指定基点:")))
(if (= nil s_dis_all)
(progn
(setq s_dis_all (getreal "\n输入拉伸距离:"))
(command s_dis_all)
)
(progn
(setq
s_dis (getreal
(strcat "\n输入拉伸距离<" (rtos s_dis_all 2 4) ">:")
)
)
(if (= nil s_dis)
(setq s_dis s_dis_all)
)
(command s_dis)
(setq s_dis_all s_dis)
(cmdla1)
)
)
)
大师出高作,支持大师!!! 厉害,大师 难点是怎么绕过常用的破解关键点。 xvjiex 发表于 2020-8-5 13:51
难点是怎么绕过常用的破解关键点。
如果你的注册程序中没有if语句,基本上都比较难破。 重点是要绕过那些节点。 厉害了大神 厉害了大神 非常不错,赞一个