本帖最后由 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 取整数
附件重新上传,不再收币。
|