[How-to]Protect your lua code

09/21/2012 03:10 d3m0n3#1
hello all,

Today I want to explain how to protect your code from prying eyes, first we have to install the lua 5.0 support on freebsd if you do not have it in this way:

Code:
# cd /usr/ports/lang/lua50  && make install clean
now we have installed on our server lua 5.0 support and can pass to the compilation of the code in this way:

Code:
# /usr/local/bin/lua50/luac -o myFile myFile.lua
We get a compiled file ( myFile ) can not be read by eye but we can load it using the "dofile"

for example of an application we can use my tournament quest:
[Only registered and activated users can see links. Click Here To Register...]

we can see the quest using various functions written by me

functions:

Code:
TORNEO_READ			= 0
TORNEO_PLUS			= 1
TORNEO_NEW			= 3
TORNEO_NEXT			= 4

TORNEO_MEMBER		= 1
TORNEO_REGISTRED	= 2
TORNEO_START		= 3
TORNEO_FINISH		= 4
TORNEO_STAGE		= 5
TORNEO_ROUND		= 6

function torneo_open_regi()
	local TORNEO_PATH = "locale/italy/quest/object/torneo/"
	local TORNEO_FILE = "torneo_stage_*"
	os.execute("cd "..TORNEO_PATH.." && rm -rf "..TORNEO_FILE)
	game.set_event_flag("torneo_close", 0)
end

function torneo_round(number)
	local stage = { 8,16,24,32,40,48,56,64 }
	local x = 1
	while true do
		if stage[x] == nil then break end
		if number <= stage[x] then
			return x
		end
		x = x + 1
	end
end

function torneo_tool(linea, stage, round, modo)
	local TORNEO_PATH = "locale/italy/quest/object/torneo/"
	local TORNEO_FILE = "torneo_stage_"..stage.."_round_"..round..".txt"
	local x = 1
	local file
	local newRound
	local result
	if modo == 0 then
		file = io.open(TORNEO_PATH..TORNEO_FILE, "r")
		while true do
			local line = file:read("*l")
			if line == nil then 
				break 
			end
			local text = string.gsub(line, "\n", "")
			if x == linea then 
				io.close(file)
				return text
			end
			x = x + 1
		end
		io.close(file)
	elseif modo == 1 then
		file = io.open(TORNEO_PATH..TORNEO_FILE, "a+")
		file:write(linea.."\n")
		io.close(file)
	elseif modo == 2 then
		if round <= 2 then
			newRound = 1
		elseif round <= 4 then
			newRound = 2
		elseif round <= 6 then
			newRound = 3
		elseif round <= 8 then
			newRound = 4
		end
		local TORNEO_NEWFILE = "torneo_stage_"..stage.."_round_"..newRound..".txt"
		file = io.open(TORNEO_PATH..TORNEO_NEWFILE, "a+")
		file:write(linea.."\n")
		io.close(file)
		return newRound
	end
end

function torneo_data(linea, modo)
	local TORNEO_PATH = "locale/italy/quest/object/torneo/"
	local TORNEO_FILE = "torneo.txt"
	local x = 1
	local file = ""
	if modo == TORNEO_READ then
		file = io.open(TORNEO_PATH..TORNEO_FILE, "r")
		while true do
			local line = file:read("*l")
			if line == nil then 
				break 
			end
			local text = string.gsub(line, "\n", "")
			if x == linea then 
				io.close(file)
				return text
			end
			x = x + 1
		end
		io.close(file)
	elseif modo == TORNEO_PLUS then
		local linee = {}
		local x = 1
		local y = 1
		file = io.open(TORNEO_PATH..TORNEO_FILE, "r")
		while true do
			linee[x] = file:read("*l")
			if linee[x] == nil then 
				break 
			end
			x = x + 1
		end
		io.close(file)
		os.rename(TORNEO_PATH..TORNEO_FILE, TORNEO_PATH..TORNEO_FILE..".BAK")
		local update = io.open(TORNEO_PATH..TORNEO_FILE, "a+")
		while true do
			if linee[y] == nil then break end
			if y == linea then 
				local newPoint = tonumber(linee[y]) + 1
				update:write(newPoint.."\n")
			else
				update:write(linee[y].."\n")
			end
			io.flush()
			y = y + 1
		end
		io.close(update)
	elseif modo == TORNEO_NEXT then
		local linee = {}
		local x = 1
		local y = 1
		file = io.open(TORNEO_PATH..TORNEO_FILE, "r")
		while true do
			linee[x] = file:read("*l")
			if linee[x] == nil then 
				break 
			end
			x = x + 1
		end
		io.close(file)
		local newMember = tonumber(linee[1])/2
		local newFinish = 0
		local newStage = tonumber(linee[5])+1
		local newRound = 1
		local newStart = tonumber(linee[3])+1
		local update = io.open(TORNEO_PATH..TORNEO_FILE, "w+")
		update:write(newMember.."\n"..linee[2].."\n"..newStart.."\n"..newFinish.."\n"..newStage.."\n"..newRound.."\n")
		io.close(update)
	elseif modo == TORNEO_NEW then
		file = io.open(TORNEO_PATH..TORNEO_FILE, "w+")
		file:write(linea.."\n0\n0\n0\n1\n1\n")
		io.close(file)
	end
end

function torneo_opp(posizione, stage, round)
	local member = {}
	local x = 1
	local sfidanti = tonumber(torneo_member(stage, round))/2
	while true do
		member[x] = torneo_tool(x, stage, round, 0)
		if member[x] == nil then break end
		x = x + 1
	end
	local opps = sfidanti + posizione
	local chll = posizione - sfidanti
	if posizione <= sfidanti then
		return member[opps]
	else
		return member[chll]
	end
end

function torneo_member(stage, round)
	local TORNEO_PATH = "locale/italy/quest/object/torneo/"
	local TORNEO_FILE = "torneo_stage_"..stage.."_round_"..round..".txt"
	local x = 1
	local file = io.open(TORNEO_PATH..TORNEO_FILE, "r")
	while true do
		local line = file:read("*l")
		if line == nil then break end
		x = x + 1
	end
	io.close(file)
	local result = x - 1
	return result
end		

function torneo_number(name, stage, round)
	local player = {}
	local x = 1
	while true do
		player[x] = torneo_tool(x, stage, round, 0)
		if player[x] == name then break end
		x = x + 1
	end
	return x
end
how can I protect my code?

simple compiling the source "torneo_lib.lua" as described previously we get a file like this:

[Only registered and activated users can see links. Click Here To Register...]

now we need only to put in questlib.lua the line(I created the lib directory but we can put it anywhere):

Code:
dofile("locale/italy/quest/lib/torneo_lib");
and functions name in quest_functions


i hope be useful

enjoy

d3m0n3
09/21/2012 04:48 Cescoso#2
[Only registered and activated users can see links. Click Here To Register...]
09/21/2012 07:42 d3m0n3#3
Quote:
Originally Posted by Cescoso View Post
[Only registered and activated users can see links. Click Here To Register...]
and?
09/21/2012 10:06 ReckLess.#4
It can still easily be converted..
09/21/2012 10:45 d3m0n3#5
Quote:
Originally Posted by ReckLess. View Post
It can still easily be converted..
it's true but are not left unencrypted data if someone wants to take it have a complication
is like saying I leave the door open because you can break it have no sense
09/21/2012 12:13 Mijago#6
Nothing really new..
I can convert it back with just 1 Lua Command :D
Try to do it as i did - write an obfuscater for Questfiles :p
09/21/2012 13:18 atag#7
It's not a protection...

[Only registered and activated users can see links. Click Here To Register...] (lua 5.0)
[Only registered and activated users can see links. Click Here To Register...] (lua 5.1)
09/21/2012 13:19 d3m0n3#8
Quote:
Originally Posted by Mijago View Post
Nothing really new..
I can convert it back with just 1 Lua Command :D
Try to do it as i did - write an obfuscater for Questfiles :p
obfuscator is a locally way but you can not distribute code without giving a library to make it readable to interpreter
if you want only to protect your private code there are many ways...

in this case the code can also be redistributed

Quote:
Originally Posted by atag View Post
It's not a protection...

[Only registered and activated users can see links. Click Here To Register...]
this tool is for lua 5.1 we use lua 5.0 :)
09/21/2012 13:54 Mijago#9
I have created a difference File for the Game so it can read crypted Quests from mine..
So it is still possible; And Lua hast some really awesome "hidden" functions to do the same or some like this without give out the function itself; You can also run LBytecode that noone can decrypt/decompile if you compile it the right way
09/21/2012 17:56 Laben#10
thanks a lot for share @d3m0n3
09/21/2012 20:43 wzy26022#11
Fare molto bene
10/01/2012 19:17 WarXWar#12
How decompile your lua protect code (only with luaC)

Go to

[Only registered and activated users can see links. Click Here To Register...]

Download and enjoy!
10/01/2012 21:56 GerardFernandes#13
It's an old and knowed method, and this don't give a protection.