Obscuring your code

Posted by Nick Gammon on Wed 24 Nov 2004 06:32 PM — 10 posts, 36,192 views.

Australia Forum Administrator #0
I have been asked a couple of times if it is possible to obscure scripts, so plugin authors can hide their workings (with a view to getting a fee, I think).

With Lua this is reasonably possible, although bear in mind any copy protection scheme can be cracked if you try hard enough.

Basically you write your script/plugin or whatever "in the clear" first to test it. Then when you are ready, save the script part to a separate file, (eg. myscript.lua) and then use the Lua standalone compiler to "compile" it. This produces byte-code (intermediate interpreter code, not machine code) that can be read by Lua.

eg.

Test file: test.lua



print ("Hello, world") table.foreach (string, print) print "done"


Compile it:


luac -o test.luac test.lua


Run it:


lua test.luac


Inside your script file load the compiled file:


dofile 'test.luac'


The 'dofile' command will load both source or object, auto-detecting the difference.

You can list the "object", and get some information from it, however if suitably obscured then it should hide what you are doing:


luac -l test.luac

main <test.lua:0> (12 instructions, 48 bytes at 00411590)
0 params, 3 stacks, 0 upvalues, 0 locals, 6 constants, 0 functions
        1       [1]     GETGLOBAL       0 0     ; print
        2       [1]     LOADK           1 1     ; "Hello, world"
        3       [1]     CALL            0 2 1
        4       [3]     GETGLOBAL       0 2     ; table
        5       [3]     GETTABLE        0 0 253 ; "foreach"
        6       [3]     GETGLOBAL       1 4     ; string
        7       [3]     GETGLOBAL       2 0     ; print
        8       [3]     CALL            0 3 1
        9       [5]     GETGLOBAL       0 0     ; print
        10      [5]     LOADK           1 5     ; "done"
        11      [5]     CALL            0 2 1
        12      [5]     RETURN          0 1 0






Greece #1
By the way, compiling your script is also a way to speed up the parsing process (if it's anything like Python, that is), since what it does is probably parse the script and then dump the entire parser tree in the compiled file, so the next time you use it, it doesn't have to be parsed again.
Australia Forum Administrator #2
True, however I am finding the parser is pretty fast. And, for scripts and plugins it is parsed once anyway.

When you (re-)load your script file or plugin, it passes the script to the parser as part of creating the Lua "state". Then later on when you call functions from triggers etc. that is the pre-parsed code that is called. The same remark applies to other languages, assuming that they pre-parse as well.

The savings would be very slight.
#3
Compile error
World: HSZ
Immediate execution
Script file: bad header in precompiled chunk


allways got this error....

Nick Gammon said:

I have been asked a couple of times if it is possible to obscure scripts, so plugin authors can hide their workings (with a view to getting a fee, I think).

With Lua this is reasonably possible, although bear in mind any copy protection scheme can be cracked if you try hard enough.

Basically you write your script/plugin or whatever "in the clear" first to test it. Then when you are ready, save the script part to a separate file, (eg. myscript.lua) and then use the Lua standalone compiler to "compile" it. This produces byte-code (intermediate interpreter code, not machine code) that can be read by Lua.

eg.

Test file: test.lua


-----

print ("Hello, world")

table.foreach (string, print)

print "done"
-----


Compile it:


luac -o test.luac test.lua


Run it:


lua test.luac


Inside your script file load the compiled file:


dofile 'test.luac'


The 'dofile' command will load both source or object, auto-detecting the difference.

You can list the "object", and get some information from it, however if suitably obscured then it should hide what you are doing:


luac -l test.luac

main <test.lua:0> (12 instructions, 48 bytes at 00411590)
0 params, 3 stacks, 0 upvalues, 0 locals, 6 constants, 0 functions
        1       [1]     GETGLOBAL       0 0     ; print
        2       [1]     LOADK           1 1     ; "Hello, world"
        3       [1]     CALL            0 2 1
        4       [3]     GETGLOBAL       0 2     ; table
        5       [3]     GETTABLE        0 0 253 ; "foreach"
        6       [3]     GETGLOBAL       1 4     ; string
        7       [3]     GETGLOBAL       2 0     ; print
        8       [3]     CALL            0 3 1
        9       [5]     GETGLOBAL       0 0     ; print
        10      [5]     LOADK           1 5     ; "done"
        11      [5]     CALL            0 2 1
        12      [5]     RETURN          0 1 0







Australia Forum Administrator #4
Possibly you are using a different version of lua (luac) than MUSHclient uses. Without a lot more information (eg. version numbers) it is very hard to say.
#5
I use mushclient 4.92,which lua version can I use?

Nick Gammon said:

Possibly you are using a different version of lua (luac) than MUSHclient uses. Without a lot more information (eg. version numbers) it is very hard to say.
#6
I will try lua 5.1.1,thanks~:)

Michen said:

I use mushclient 4.92,which lua version can I use?

Nick Gammon said:

Possibly you are using a different version of lua (luac) than MUSHclient uses. Without a lot more information (eg. version numbers) it is very hard to say.

#7
It's ok now~~~~

Michen said:

I will try lua 5.1.1,thanks~:)

Michen said:

I use mushclient 4.92,which lua version can I use?

Nick Gammon said:

Possibly you are using a different version of lua (luac) than MUSHclient uses. Without a lot more information (eg. version numbers) it is very hard to say.


Australia Forum Administrator #8
Quote:

Reply #2 on Fri 26 Nov 2004 05:35 AM
...
Reply #3 on Fri 30 Jan 2015 03:48 PM


I'm puzzled as to how you replied to that old thread. It's just that I added "anti-thread-necro" code a while back (like, last year) and it shouldn't be possible to reply to a 9-year old thread.

Was there a "reply" link (do you recall?) or did you manipulate the URL at the top of the page to get a reply through?

I ask because there may be some bug in the forum software.
Australia Forum Administrator #9
Never mind, I worked it out. The "quote" link was active when it should not have been. Fixed.