baitang36 发表于 2020-8-5 13:08:23

怎样写出一个相对安全的注册程序

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




baitang36 发表于 2020-8-13 16:31:28

xj6019 发表于 2020-8-13 11:53
感谢感谢,终于会玩了,还挺好玩的,特意做了一个放上面玩玩,热心的反馈一下怎么样呀。
楼主:我发现即 ...

重启验证,是对抗破解的有效手段。
你输入个注册码,不管对错,都写入注册表。
让破解者没法当场知道破解是否有效。

baitang36 发表于 2020-8-5 16:45:33

(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)

xj6019 发表于 2020-8-12 21:49:04

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)
   )
   )
)

fangmin723 发表于 2020-8-5 13:25:22

大师出高作,支持大师!!!

funny64 发表于 2020-8-5 13:32:41

厉害,大师

xvjiex 发表于 2020-8-5 13:51:12

难点是怎么绕过常用的破解关键点。

baitang36 发表于 2020-8-5 16:40:38

xvjiex 发表于 2020-8-5 13:51
难点是怎么绕过常用的破解关键点。

如果你的注册程序中没有if语句,基本上都比较难破。

烟盒迷唇 发表于 2020-8-5 17:13:27

重点是要绕过那些节点。

czb203 发表于 2020-8-5 18:30:03

厉害了大神

whyyshy 发表于 2020-8-5 20:46:49

厉害了大神

Yruz 发表于 2020-8-5 22:00:35

非常不错,赞一个
页: [1] 2 3 4 5
查看完整版本: 怎样写出一个相对安全的注册程序