Ahmeds Posted December 3, 2012 Posted December 3, 2012 I create LISP routines for my Geodetic friends that they used for their surveying activities, may i ask anyone here how could i create or associate an external program (VB for example) before executing my LISPs? In short. I want to make my LISPs secured by a license key generated depends on my MAC address so that it couldn't copy to another computer? does anyone here did this before? may I ask for a kindly share? Quote
BIGAL Posted December 3, 2012 Posted December 3, 2012 Theres another post running now about FAS files, compiled lisp via VLIDE you can do stuff like mac address, disk id, read registery, put a file somewhere its up to you, the simplest eg (getvar "_pkser"). FAS can not be opened and read. Search here using "security" as a search word lots of examples of methods to lock then create a FAS. There was a post about two way communication via a web site to install end user software. Quote
irneb Posted December 3, 2012 Posted December 3, 2012 You'd basically calculate the key value from some other value. Say from acad's serial number, or the user's name, or whatever else you can think of - probably combine some together. Then you need to devise your own "hashing" function - something which uses loops and math to change those into a required string which will be checked against the saved license key (this algorithm is what you need to keep secret). Then you need to compile your LSP into FAS/VLX so the user can't easily see how to calculate the license key. That's basically how most programs work. However the "online" checking does much the same - only the calculation codes are not inside the program anymore. The program sends the saved key and the sources for calculation to a server - the server checks the key's validity against the sources and/or a databse and returns a can-use / illegal state back to the program. Quote
irneb Posted December 3, 2012 Posted December 3, 2012 As for getting a PC's mac address (defun get_macaddress (/ Locator Server Query ret) (if (and (setq Locator (vlax-create-object "WbemScripting.SWbemLocator")) (setq Server (vlax-invoke Locator 'ConnectServer "." "root\\cimv2")) (setq Query (vlax-invoke Server 'ExecQuery "select * from Win32_NetworkAdapterConfiguration where IPEnabled = True"))) (vlax-for item Query (setq ret (vlax-get item 'MacAddress)))) (foreach obj '(Locator Server Query) (vl-catch-all-apply 'vlax-release-object (list obj))) ret) Quote
BIGAL Posted December 3, 2012 Posted December 3, 2012 irneb at the speed of light walked away for 1 minute simple serial number lock just paste into start of every lisp you make create a bat file like a script CMD security.bat copy pser.lsp+lipsprog1.lsp c:\enduser\lispprog1.lsp copy pser.lsp+lipsprog2.lsp c:\enduser\lispprog2.lsp Then use vlide to make FAS, any body script to make FAS ? (setq run (getvar "_pkser")) (if (or (= run "392-12345678")(= run "392-87654321")) (princ "\nSecurity check passed") (progn (princ "\nYou have tried to run XYZ SOFTWARE on a non authorised machine") (princ "\nPlease contact me on 1234567 and I will rip your arms off") (/e) ) ) Quote
irneb Posted December 3, 2012 Posted December 3, 2012 That would be fine if you don't envision 100's of users. Since you'd need to compile a FAS for each (or at least for each batch of serial numbers). Anyhow, here's another thread about this subject: http://www.cadtutor.net/forum/showthread.php?60625-Can-you-protect-a-LISP-routine-so-no-one-can-see-or-modify-it& Quote
Ahmeds Posted December 3, 2012 Author Posted December 3, 2012 As for getting a PC's mac address(defun get_macaddress (/ Locator Server Query ret) (if (and (setq Locator (vlax-create-object "WbemScripting.SWbemLocator")) (setq Server (vlax-invoke Locator 'ConnectServer "." "root\\cimv2")) (setq Query (vlax-invoke Server 'ExecQuery "select * from Win32_NetworkAdapterConfiguration where IPEnabled = True"))) (vlax-for item Query (setq ret (vlax-get item 'MacAddress)))) (foreach obj '(Locator Server Query) (vl-catch-all-apply 'vlax-release-object (list obj))) ret) Thanks irneb, I just add some lines in it and save it as my ACADDOC.lsp (defun get_macaddress (/ Locator Server Query ret) (vl-load-com) (if (and (setq Locator (vlax-create-object "WbemScripting.SWbemLocator")) (setq Server (vlax-invoke Locator 'ConnectServer "." "root\\cimv2")) (setq Query (vlax-invoke Server 'ExecQuery "select * from Win32_NetworkAdapterConfiguration where IPEnabled = True"))) (vlax-for item Query (setq ret (vlax-get item 'MacAddress)))) (foreach obj '(Locator Server Query) (vl-catch-all-apply 'vlax-release-object (list obj))) (if (/= "44:6D:57:B2:0A:D3" ret)(exit)) (princ)) (vmon)(setvar "cmdecho" 0) (defun s::startup(/ x) (if(setq x (findfile "ahmeds.lsp"))(load x))(princ)) I want to satisfy the condition that matches MAC address of my computer, if not, it should abort/exit loading all of my LISP routines but here's what I get AutoCAD menu utilities loaded.; error: quit / exit abortby adding (exit) after the IF condition.. can u help me to abort it silently without displaying this error message? Thank you again with your very nice codes.. Quote
irneb Posted December 3, 2012 Posted December 3, 2012 If you want to stop all and not see the abort message, then what about overwriting the default *error* routine? (defun *error* (msg) (cond ((or (/= (type msg) 'Str) (wcmatch (strcase msg) "*ABORT*,*QUIT*,*EXIT*"))) ((princ msg))) (princ)) Or if you're going to compile it into a FAS (which I'd highly suggest) - then perhaps look into the vl-exit-with-* functions and use a separate namespace for your FAS file. Also ensure that all your LSP files are copmpiled into the same FAS/VLX file - else they can still be manually loaded. About changing the defun, I'd not change it but use it somewhere else. E.g. (and (not (member (get_macaddress) '("44:6D:57:B2:0A:D3"))) (quit)) That way you can use it in various parts in your code. E.g. allowing only sertain FAS files to run on some machines, but others to work on another set of PCs. Also note the use of member - so you can test against multiple addresses. Quote
viviancarvalho Posted December 3, 2012 Posted December 3, 2012 Apply a TIME BOMB to the lisp convert to fas check out this thread http://www.cadtutor.net/forum/showthread.php?54624-Time-bound-Lisp its really very useful. Quote
irneb Posted December 3, 2012 Posted December 3, 2012 That would help if you want your program to be shareware for a set time period - after which you'd want the user to get a fully licensed version. Quote
Ahmeds Posted December 5, 2012 Author Posted December 5, 2012 Apply a TIME BOMB to the lisp convert to fas check out this thread http://www.cadtutor.net/forum/showthread.php?54624-Time-bound-Lisp its really very useful. I think there's a way to escape that time BOMB by just getting you system date back from the date that is not affected by this TIME BOMB.. How should we do with that? Quote
Lee Mac Posted December 5, 2012 Posted December 5, 2012 I think there's a way to escape that time BOMB by just getting you system date back from the date that is not affected by this TIME BOMB.. How should we do with that? Internet Time & Date Function [ may require membership to the Swamp ] Quote
viviancarvalho Posted December 5, 2012 Posted December 5, 2012 (edited) If the file that you have shared with someone is a fas file. After a particular date, when the program is run it displays a big error message without harming his system, i think no one will ever think in this direction. Tried & tested in my company , people just delete the program from their system. I am pasting my code for your reference. (defun c:lg(/) (if (< (rtos (getvar "cdate") 2 0) "20121214") ;;;;;;; (lineargrille) (Alert "\n \n FATAL ERROR: Unhandled Access Violation Writing 0x0008 Exception at 61c4b0e0h \n \n \n")) (princ "\n Program by Vivian ©") (princ)) Edited December 5, 2012 by rkmcswain added [CODE] tags Quote
irneb Posted December 5, 2012 Posted December 5, 2012 Similar to my warning here: http://forums.augi.com/showthread.php?80070-Code-help&p=842603&viewfull=1#post842603 There's no perfect way to stop unlicensed use (i.e. piracy). All you can hope for is to make it too dificult for the average user to bother trying. Comes down to the same principle as the useless DRM protection schemes: http://arstechnica.com/tech-policy/2012/11/how-four-microsoft-engineers-proved-copy-protection-would-fail/ Quote
irneb Posted December 5, 2012 Posted December 5, 2012 (Alert "\n \n FATAL ERROR: Unhandled Access Violation Writing 0x0008 Exception at 61c4b0e0h \n \n \n")Very sneeky! Trying to trick prospective pirates into contacting you because of a "bug"! Quote
viviancarvalho Posted December 8, 2012 Posted December 8, 2012 HA HA HA. Thats the best way to keep pirates away. Very sneeky! Trying to trick prospective pirates into contacting you because of a "bug"! Quote
Ahmeds Posted December 10, 2012 Author Posted December 10, 2012 Internet Time & Date Function [ may require membership to the Swamp ] Registration is currently disabled Quote
irneb Posted December 10, 2012 Posted December 10, 2012 A cobbled together version (not using regular expressions) (vl-load-com) (defun InternetTime (/ con str) (if (setq con (vlax-create-object "MSXML2.XMLHTTP.3.0")) (progn (vlax-invoke-method con 'open "POST" "http://time.nist.gov:13" :vlax-false) (vlax-invoke-method con 'Send) (setq str (vl-string-trim " *" (vl-string-trim "\n0123456789" (vlax-get-property con 'ResponseText)))) (vlax-release-object con) (strcat (if (< (vl-string-search "-" str) 4) "20" "") (substr (setq str (substr str 1 (vl-string-search "(" str))) 1 (+ 3 (vl-string-search ":" str 14))) (substr str (1+ (vl-string-search " " str (vl-string-search "." str)))))))) (defun IsoDate->ACadDate (str / ) (apply '+ (mapcar '(lambda (n m f) (* f (atoi (substr str n m)))) '(1 6 9 12 15 18) '(4 2 2 2 2 2) '(10000.0 100.0 1.0 0.01 0.0001 0.000001)))) You can check the current UTC (Greenwich Time) by this: (IsoDate->ACadDate (InternetTime)) Which is compatible with the value of the CDate system variable. Quote
Lee Mac Posted December 10, 2012 Posted December 10, 2012 (edited) Registration is currently disabled Here is the function: [color=GREEN];;---------------------=={ Internet Time }==------------------;;[/color] [color=GREEN];; ;;[/color] [color=GREEN];; Returns the date and/or UTC time as a string in the ;;[/color] [color=GREEN];; format specified. Data is sourced from a NIST server. ;;[/color] [color=GREEN];;------------------------------------------------------------;;[/color] [color=GREEN];; Author: Lee Mac, Copyright © 2011 - www.lee-mac.com ;;[/color] [color=GREEN];;------------------------------------------------------------;;[/color] [color=GREEN];; Arguments: ;;[/color] [color=GREEN];; format - string specifying format of returned information ;;[/color] [color=GREEN];; using the following identifiers to represent ;;[/color] [color=GREEN];; date & time quantities: ;;[/color] [color=GREEN];; YYYY = 4-digit year ;;[/color] [color=GREEN];; YY = Year, MO = Month, DD = Day ;;[/color] [color=GREEN];; HH = Hour, MM = Minutes, SS = Seconds ;;[/color] [color=GREEN];;------------------------------------------------------------;;[/color] [color=GREEN];; Returns: String containing formatted date/time data ;;[/color] [color=GREEN];;------------------------------------------------------------;;[/color] ([color=BLUE]defun[/color] LM:InternetTime ( format [color=BLUE]/[/color] result rgx server xml ) ([color=BLUE]setq[/color] server [color=MAROON]"http://time.nist.gov:13"[/color]) ([color=BLUE]setq[/color] result ([color=BLUE]vl-catch-all-apply[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( [color=BLUE]/[/color] str ) ([color=BLUE]setq[/color] xml ([color=BLUE]vlax-create-object[/color] [color=MAROON]"MSXML2.XMLHTTP.3.0"[/color])) ([color=BLUE]setq[/color] rgx ([color=BLUE]vlax-create-object[/color] [color=MAROON]"vbscript.regexp"[/color])) ([color=BLUE]vlax-invoke-method[/color] xml '[color=BLUE]open[/color] [color=MAROON]"POST"[/color] server [color=BLUE]:vlax-false[/color]) ([color=BLUE]vlax-invoke-method[/color] xml 'send) ([color=BLUE]if[/color] ([color=BLUE]setq[/color] str ([color=BLUE]vlax-get-property[/color] xml 'responsetext)) ([color=BLUE]progn[/color] ([color=BLUE]vlax-put-property[/color] rgx 'global [color=BLUE]actrue[/color]) ([color=BLUE]vlax-put-property[/color] rgx 'ignorecase [color=BLUE]actrue[/color]) ([color=BLUE]vlax-put-property[/color] rgx 'multiline [color=BLUE]actrue[/color]) ([color=BLUE]setq[/color] str ([color=BLUE]strcat[/color] [color=MAROON]" "[/color] ([color=BLUE]itoa[/color] (jtoy ([color=BLUE]+[/color] ([color=BLUE]atoi[/color] ([color=BLUE]substr[/color] str 2 5)) 2400000.5))) ([color=BLUE]substr[/color] str 7))) ([color=BLUE]mapcar[/color] ([color=BLUE]function[/color] ([color=BLUE]lambda[/color] ( a b ) ([color=BLUE]vlax-put-property[/color] rgx 'pattern a) ([color=BLUE]setq[/color] format ([color=BLUE]vlax-invoke[/color] rgx 'replace format b)) ) ) '([color=MAROON]"YYYY"[/color] [color=MAROON]"YY"[/color] [color=MAROON]"MO"[/color] [color=MAROON]"DD"[/color] [color=MAROON]"HH"[/color] [color=MAROON]"MM"[/color] [color=MAROON]"SS"[/color]) '( [color=MAROON]"$1"[/color] [color=MAROON]"$2"[/color] [color=MAROON]"$3"[/color] [color=MAROON]"$4"[/color] [color=MAROON]"$5"[/color] [color=MAROON]"$6"[/color] [color=MAROON]"$7"[/color]) ) ([color=BLUE]vlax-put-property[/color] rgx 'pattern ([color=BLUE]strcat[/color] [color=MAROON]"(?:[^\\d]+)([\\d]+)(?:[^\\d]+)([\\d]+)"[/color] [color=MAROON]"(?:[^\\d]+)([\\d]+)(?:[^\\d]+)([\\d]+)"[/color] [color=MAROON]"(?:[^\\d]+)([\\d]+)(?:[^\\d]+)([\\d]+)"[/color] [color=MAROON]"(?:[^\\d]+)([\\d]+)(?:.+)\\n"[/color] ) ) ([color=BLUE]vlax-invoke-method[/color] rgx 'replace str format) ) ) ) ) ) ) ([color=BLUE]if[/color] xml ([color=BLUE]vlax-release-object[/color] xml)) ([color=BLUE]if[/color] rgx ([color=BLUE]vlax-release-object[/color] rgx)) ([color=BLUE]if[/color] ([color=BLUE]vl-catch-all-error-p[/color] result) ([color=BLUE]prompt[/color] ([color=BLUE]vl-catch-all-error-message[/color] result)) result ) ) [color=GREEN];; Julian Date to Calendar Year - Lee Mac[/color] [color=GREEN];; Algorithm from: Meeus, Jean. Astronomical Algorithms.[/color] ([color=BLUE]defun[/color] jtoy ( j [color=BLUE]/[/color] a b c d ) ([color=BLUE]setq[/color] j ([color=BLUE]fix[/color] j) a ([color=BLUE]fix[/color] ([color=BLUE]/[/color] ([color=BLUE]-[/color] j 1867216.25) 36524.25)) b ([color=BLUE]+[/color] ([color=BLUE]-[/color] ([color=BLUE]+[/color] j 1 a) ([color=BLUE]fix[/color] ([color=BLUE]/[/color] a 4))) 1524) c ([color=BLUE]fix[/color] ([color=BLUE]/[/color] ([color=BLUE]-[/color] b 122.1) 365.25)) d ([color=BLUE]fix[/color] ([color=BLUE]/[/color] ([color=BLUE]-[/color] b ([color=BLUE]fix[/color] ([color=BLUE]*[/color] 365.25 c))) 30.6001)) ) ([color=BLUE]fix[/color] ([color=BLUE]-[/color] c ([color=BLUE]if[/color] ([color=BLUE]<[/color] 2 ([color=BLUE]fix[/color] ([color=BLUE]if[/color] ([color=BLUE]<[/color] d 14) ([color=BLUE]1-[/color] d) ([color=BLUE]-[/color] d 13)))) 4716 4715))) ) ([color=BLUE]vl-load-com[/color]) ([color=BLUE]princ[/color]) The 'format' parameter This parameter is a string specifying the format for the returned data. It is used in a similar way to the 'picture' parameter for the edtime DIESEL function, using the following identifiers to represent date & time quantities: YYYY = 4-digit Year YY = Year MO = Month DD = Day HH = Hours MM = Minutes SS = Seconds Examples _$ (LM:InternetTime "DD/MO/YY, HH:MM:SS") "17/09/11, 19:37:07" _$ (LM:InternetTime "MO.DD.YY") "09.17.11" _$ (LM:InternetTime "HH:MM") "19:37" _$ (LM:InternetTime "DD.MO.YYYY") "21.09.2011" Since the data is retrieved from the NIST time server, please take note of the following from the NIST website: All users should ensure that their software NEVER queries a server more frequently than once every 4 seconds. Systems that exceed this rate will be refused service. Besides the obvious use of displaying the correct time or date, this utility could also be used where program licensing is concerned, for example: to prevent a program from running after a certain date or time; since the date as returned by most other means is read from the user-modifiable computer clock. Edited December 12, 2012 by Lee Mac Quote
Shawndoe Posted December 11, 2012 Posted December 11, 2012 Hi Lee, Long time no see. I just wanted to let you know there is an FAS decompiler floating around. It's hard to find and not very easy to use, but if there is something that makes your routine truely unique you might want to protect that piece by writting it in ARX, and making it a lisp function. I would also place your DRM in the ARX, such that if the DRM check fails the function returns "Invalid copy contact Lee at... ". DRM is all about getting as much security as you can without annoying end users. The trick is to make the skill level required for overcoming the DRM so high that, if you are that skilled, you can write your own code faster. I'm not a big fan of routines that call a server with each use. I have worked in places where you may not have access to the net, this situation is especially true if you work on a secured network or computer, these machines are often physically isolated from the internet. Have a good one. Shawn Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.