Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
end_of_line = crlf
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.py]
indent_style = space

[*.yml]
indent_style = space
indent_size = 2
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.spec
dist
build
57 changes: 57 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# env:
# global:
# - PYTHONIOENCODING=utf-8
jobs:
include:
- os: windows
language: shell
env: PATH=/c/Python38:/c/Python38/Scripts:$PATH
before_install:
- choco install --x86 python
- choco install zip
script:
- zip -r ./LuaObfuscator-win-x32 ./dist
- os: windows
language: shell
env: PATH=/c/Python38:/c/Python38/Scripts:$PATH
before_install:
- choco install python
- choco install zip
script:
- zip -r ./LuaObfuscator-win-x64 ./dist
- os: linux
language: python
python: "3.6" # 3.6 works!
- os: osx
language: generic
cache:
directories:
- ./dist
addons:
apt:
packages:
- zip
install:
- pip install pyinstaller

branches:
only:
- master

before_script:
- ls ./dist
- pyinstaller --onefile __main__.py -n LuaObfuscator
script:
- zip -r ./LuaObfuscator-$TRAVIS_OS_NAME ./dist
before_deploy:
- export TRAVIS_TAG=$(date +'%Y.%m.%d')

deploy:
provider: releases
api_key: $GITHUB_TOKEN
file_glob: true
file: ./LuaObfuscator-*
skip_cleanup: true
name: $(date +'%Y.%m.%d')
on:
branch: master
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/__main__.py",
"console": "integratedTerminal"
}
]
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.jediEnabled": false
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# LuaObfuscator
# LuaObfuscator [![Build Status](https://travis-ci.com/SupinePandora43/LuaObfuscator.svg)](https://travis-ci.com/SupinePandora43/LuaObfuscator)

This lua obfuscator was originally designed for Garry's Mod, but should work on vanilla lua.
Written for private use in January 2016. I never did anything with it so I decided to put it on GitHub.
Expand Down
24 changes: 3 additions & 21 deletions __main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@
print("The obfuscator may not work correctly!")


VERSION = "Beta 1.0.3"
VERSION_DATE = time.strftime("%b %d, %Y @ %I:%M %p", time.localtime(os.path.getmtime(__file__)))

print("Version: {0} (Updated on {1})".format(VERSION, VERSION_DATE))


in_file = "input.lua"
out_file = "output.lua"
decrypt_file = "__decrypt.lua"
Expand All @@ -39,9 +33,6 @@
parser.add_argument("--level",
help='0 = original strings, 1 = small file, 2 = large file, 3 = huge file',
default=1)
parser.add_argument("--dontcopy",
help='Disable copying the output',
action='store_true')
parser.add_argument("--debug",
help="Enable debug mode",
action='store_true')
Expand All @@ -67,9 +58,9 @@
with open(global_file, "r") as f:
globs = json.loads(f.read())


# Do the obfuscation
lua, tokens, strings, comments = obfuscator.obfuscate(lua, encoder, globs, debug_mode)
lua, tokens, strings, comments = obfuscator.obfuscate(
lua, encoder, globs, debug_mode)

except:
if not debug_mode:
Expand All @@ -79,15 +70,6 @@
raise


if not dontcopy:
try:
import pyperclip
pyperclip.copy(lua)
print("Code copied to clipboard.")
except:
pass


# Write the results
with open(out_file, "wb") as f:
f.write(lua.encode("utf-8"))
f.write(lua.encode("utf-8"))
5 changes: 3 additions & 2 deletions finalize.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import re
import tokenizer

WORD_PTRN = re.compile(r"^[^" + re.escape("".join(tokenizer.SPECIAL_CHARS)) + r"]*$")
WORD_PTRN = re.compile(
r"^[^" + re.escape("".join(tokenizer.SPECIAL_CHARS)) + r"]*$")


def finalize(tokens, decrypt_code):
Expand Down Expand Up @@ -43,4 +44,4 @@ def render_code(tokens, decrypt_code):


def is_word(s):
return WORD_PTRN.match(s)
return WORD_PTRN.match(s)
11 changes: 7 additions & 4 deletions obfuscator.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def obfuscate(lua, encoder, globs, debug=False, xor_val=-1):

# Strip comments and strings
lua, strings, comments = stringstripper.strip(lua)
log("Stripped {0} strings and {1} comments.".format(len(strings), len(comments)), False)
log("Stripped {0} strings and {1} comments.".format(
len(strings), len(comments)), False)

# Tokenize
tokens = tokenizer.tokenize(lua)
Expand Down Expand Up @@ -96,7 +97,8 @@ def obfuscate(lua, encoder, globs, debug=False, xor_val=-1):
strings = encoder.encode_all(strings, xor_val)
log("Obfuscated strings.")

tokens = stringstripper.replace(tokens, strings, DECRYPT_FUNC, encoder.get_str_start(), encoder.get_str_end())
tokens = stringstripper.replace(
tokens, strings, DECRYPT_FUNC, encoder.get_str_start(), encoder.get_str_end())
log("Replaced strings.")

lua = finalize.finalize(tokens, decrypt_code)
Expand Down Expand Up @@ -297,7 +299,8 @@ def rename_loops(tokens):
args = tokens[i+1:e:2]
for arg in args:
if arg not in replaced:
tokens = replace_locals(tokens, arg, new_local_name(index(tokens, arg)), i)
tokens = replace_locals(
tokens, arg, new_local_name(index(tokens, arg)), i)
replaced.append(arg)

return tokens
Expand Down Expand Up @@ -457,4 +460,4 @@ def index(tokens, item, start_index=0):
i = tokens.index(item, start_index)
return i
except:
return -1
return -1
6 changes: 4 additions & 2 deletions stringencoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class Level3Encoder(Encoder):
Up to 2 additional ascii characters will be added,
and then each character is closed with '|'.
"""

def __init__(self):
self.level = 3

Expand All @@ -113,7 +114,8 @@ def encode_char(self, c, xor):
# number of invis characters (lua counts 1 invis as 3)
invis = math.floor(total / 3)

regchars = ''.join(random.choice(ascii_letters + digits) for _ in range(regular))
regchars = ''.join(random.choice(ascii_letters + digits)
for _ in range(regular))

return obfuscator.INVISIBLE_CHAR * invis + regchars + "|"

Expand All @@ -132,4 +134,4 @@ def get_by_level(level):

def _read_decrypt_file(level, xor):
with open("__decrypt_" + str(level) + ".lua", "rb") as f:
return f.read().decode("utf-8").replace("__XOR__", str(xor))
return f.read().decode("utf-8").replace("__XOR__", str(xor))
23 changes: 13 additions & 10 deletions stringstripper.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ def replace(lua, strings, decrypt_func="", start="[[", end="]]"):

def strip_multiline_comments(lua):
removed = []
for i in range(len(COMMENT_START)):
r = _build_regex(COMMENT_START[i], COMMENT_END[i])
while True:
match = r.search(lua)
if match is None:
break
removed.append(match.group(0))
lua = lua[:match.start()] + lua[match.end():]
print(match)
# for i in range(len(COMMENT_START)):
# r = _build_regex(COMMENT_START[i], COMMENT_END[i])
# while True:
# match = r.search(lua)
# if match is None:
# break
# removed.append(match.group(0))
# lua = lua[:match.start()] + lua[match.end():]
# print(match)

return lua, removed

Expand Down Expand Up @@ -110,7 +110,8 @@ def _strip_regular_strings(lua):
if found is not None:
placeholder = _build_string_placeholder()
removed[placeholder] = found.group()[len(start):-len(end)]
lua = lua[:found.start()] + " " + placeholder + " " + lua[found.end():]
lua = lua[:found.start()] + " " + placeholder + \
" " + lua[found.end():]
else:
break

Expand All @@ -133,6 +134,8 @@ def _strip_multiline_strings(lua):


string_index = -1


def _build_string_placeholder():
global string_index
string_index += 1
Expand Down
11 changes: 7 additions & 4 deletions tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@

TOKEN_PATTERN = re.compile(r"(\d*\.?\d+|[^\s" # Checks for decimals with optional lead and required end ex: ".5", "0.5"
+ re.escape("".join(SPECIAL_CHARS)) + r"]+|"
+ re.escape("___sep___".join(SPECIAL_STRINGS)).replace("___sep___", "|") + r"|["
+ re.escape("___sep___".join(SPECIAL_STRINGS)
).replace("___sep___", "|") + r"|["
+ re.escape("".join(SPECIAL_CHARS)) + r"])")

WORD_PATTERN = re.compile(r"^[^\s"
+ re.escape("".join(SPECIAL_CHARS)) + r"]+$")

SCOPE_IN = ['do', 'then', 'function']
SCOPE_OUT = ['end', 'elseif'] # 'elseif' because it comes with a second 'then'.
# 'elseif' because it comes with a second 'then'.
SCOPE_OUT = ['end', 'elseif']


def tokenize(lua):
Expand Down Expand Up @@ -136,7 +138,8 @@ def find_table_end(tokens, start_index):
if depth == 0:
return i + 1

print("Fatal error occurred.", "Please check that your input is syntactically correct.", sep="\n")
print("Fatal error occurred.",
"Please check that your input is syntactically correct.", sep="\n")
exit(0)


Expand All @@ -162,4 +165,4 @@ def is_word(s):


def is_number(s):
return s.isdigit()
return s.isdigit()