├── LECENSE ├── res └── luaob.ico ├── manual └── manual.txt ├── src ├── obfuscator.cpp ├── resource.h ├── luaob.rc ├── stack.h ├── global.h ├── stack.cpp ├── obfuscator.h ├── global.cpp └── luaob.cpp ├── trash.bat ├── bin ├── test.lua └── main_test.lua ├── .gitignore ├── luaob.sln └── README.md /LECENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gracerpro/luaob/HEAD/LECENSE -------------------------------------------------------------------------------- /res/luaob.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gracerpro/luaob/HEAD/res/luaob.ico -------------------------------------------------------------------------------- /manual/manual.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gracerpro/luaob/HEAD/manual/manual.txt -------------------------------------------------------------------------------- /src/obfuscator.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gracerpro/luaob/HEAD/src/obfuscator.cpp -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- 1 | #define IDC_STATIC -1 2 | #define IDR_MAINFRAME 1000 3 | -------------------------------------------------------------------------------- /src/luaob.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "resource.h" 3 | 4 | //IDR_MAINFRAME ICON DISCARDABLE "../res/luaob.ico" -------------------------------------------------------------------------------- /trash.bat: -------------------------------------------------------------------------------- 1 | del /Q ".\ide\VC100\*.sdf" 2 | del /Q ".\bin\*.pdb" 3 | del /Q ".\bin\*.ilk" 4 | 5 | rmdir /S /Q ".\ide\VC100\ipch" 6 | rmdir /S /Q ".\ide\VC100\Debug" 7 | rmdir /S /Q ".\ide\VC100\Release" 8 | 9 | pause -------------------------------------------------------------------------------- /bin/test.lua: -------------------------------------------------------------------------------- 1 | -- test local vars and params 2 | local a = 999; 3 | 4 | if a = 2 then 5 | print(a); 6 | local a = 2; 7 | print(a); 8 | if a = 2 then 9 | print(a); 10 | local a = 3; 11 | print(a); 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/* 2 | !/bin/main_test.lua 3 | !/bin/test.lua 4 | 5 | build/VisualStudio/* 6 | !build/VisualStudio/*.filters 7 | !build/VisualStudio/*.vcxproj 8 | 9 | build/codeblocks/ 10 | 11 | *.suo 12 | *.sdf 13 | *.opensdf 14 | -------------------------------------------------------------------------------- /src/stack.h: -------------------------------------------------------------------------------- 1 | // stack.h 2 | #include 3 | 4 | struct stObfuscatedName 5 | { 6 | std::string name; 7 | std::string fake_name; 8 | }; 9 | 10 | class LocalVarsStack { 11 | public: 12 | LocalVarsStack(size_t initCount = STACK_CAPACITY); 13 | ~LocalVarsStack(); 14 | 15 | void push(const stObfuscatedName& obfuscatedName); 16 | void push(const char *name, const char *fake_name); 17 | void pop(); 18 | void pops(size_t elementCount = 1); 19 | 20 | friend LocalVarsStack& operator+= (LocalVarsStack& stackDest, const LocalVarsStack& stackSource); 21 | 22 | stObfuscatedName& top() const; 23 | size_t getTopIndex() const; 24 | 25 | stObfuscatedName& items(const size_t index) const; 26 | 27 | bool find(stObfuscatedName& obfuscatedName) const; 28 | bool find(const std::string& name) const; 29 | bool find(const char *name) const; 30 | 31 | size_t count() const; 32 | bool empty() const; 33 | 34 | private: 35 | enum { 36 | STACK_CAPACITY = 16, 37 | INDEX_NULL = -1 38 | }; 39 | 40 | stObfuscatedName* m_data; 41 | size_t m_count; 42 | size_t m_reservedCount; 43 | }; 44 | -------------------------------------------------------------------------------- /src/global.h: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBAL_H 2 | #define _GLOBAL_H 3 | 4 | #include 5 | #include 6 | 7 | const char* getExeDir(); 8 | const char* getExeFileName(); 9 | const char* getWorkDir(); 10 | char* getFileDir(char const* szFile, char* szDir); 11 | 12 | bool isAbsoluteFilePath(const char *szFileName); 13 | bool fileExists(const char *szFileName); 14 | bool isPathSep(const char c); 15 | 16 | char* strtrim(char* sz); 17 | 18 | 19 | void print(char const *format, ...); 20 | 21 | 22 | #ifdef _WIN32 23 | #define SZ_EXE_FILE_NAME "luaob.exe" 24 | #else 25 | #define SZ_EXE_FILE_NAME "luaob" 26 | #endif 27 | #define SZ_EXE_NAME "luaob" 28 | 29 | #if defined(_WIN32) 30 | #define PATH_SEPARATOR "\\" 31 | #define PATH_SEPARATOR_CHAR '\\' 32 | #else 33 | #define PATH_SEPARATOR "/" 34 | #define PATH_SEPARATOR_CHAR '/' 35 | #endif 36 | 37 | /* 38 | * For obfuscator 39 | */ 40 | bool isSpace(const char c); 41 | bool isNewLine(const char c); 42 | bool isAlphaFun(const char c); 43 | bool isVarChar(const char c); 44 | bool isStringStart(const char *p); 45 | bool isSingleStringStart(const char *p); 46 | bool isMultilineStringStart(const char *p); 47 | bool isEscapedChar(const char* p); 48 | 49 | size_t skipStringAndMove(char **pData, char **pDest); 50 | 51 | char* skipSpace(char *str, bool bForward = true); 52 | char* skipSpaceAndNewLine(char *str, bool bForward = true); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /bin/main_test.lua: -------------------------------------------------------------------------------- 1 | print("Hello World!"); 2 | 3 | --[[ REMOVE COMMENT ]] 4 | -- comment 5 | --[[ comment ]] 6 | 7 | --[[ REMOVE DUPLICATE CHARS ]] 8 | --[[ REMOVE EXTRA LINE LINE ]] 9 | i = 1 ; 10 | j = i + 2; 11 | k = j * 2; 12 | 13 | --[[ REMOVE EXTRA WHITESPACE ]] 14 | t = {}; t = { }; 15 | i = ( 1 ) + 2; i = ( 1 ) + ( 2 ); 16 | t[1] = 1; t [ 1 ] = 1; 17 | t.name = "name"; t. name = "name"; 18 | local a, b = 1, 2; 19 | i = 1 + 2 - 3 / 4 * 5 ^ 6 % 7; 20 | if i == 0 then 21 | i = 0; 22 | end 23 | if i ~= 0 then 24 | i = 0; 25 | end 26 | i = #t; 27 | 28 | --[[ GLOBAL FUNCTION NAMES ]] 29 | 30 | function f1(a) 31 | print(a); 32 | end 33 | 34 | function f2(a, b) 35 | print(a, b); 36 | end 37 | 38 | f1(1); 39 | f2(2, 2); 40 | 41 | --[[ LOCAL VARIABLES AND ARGUMENTS]] 42 | function foo(arg1, arg2, arg3) 43 | print(arg1, arg2, arg3); 44 | arg2 = arg1; 45 | arg3 = arg1; 46 | print(arg1, arg2, arg3); 47 | end 48 | 49 | foo(1, 2, 3); 50 | 51 | --[[ 2 ]] 52 | function foo(arg1, arg2) 53 | print(arg1, arg2); 54 | print("a: ", a); 55 | 56 | do 57 | local a = 2; 58 | print("local a: ", a); 59 | end 60 | 61 | for a = 1, 5 do 62 | local a = 3; 63 | print("a in loop FOR: ", a); 64 | end 65 | 66 | i = 0; 67 | while i < 3 do 68 | local a = 44; 69 | print("a in loop WHILE", a); 70 | i = i + 1; 71 | end 72 | 73 | if true then 74 | local a = 5; 75 | print("a in IF: ", a); 76 | end 77 | 78 | f1 = function(a1, a2) 79 | print(a1, a2); 80 | local a = 6; 81 | print("a in function", a); 82 | end 83 | 84 | f1(111, 222); 85 | end 86 | 87 | foo("arg1", "arg2"); 88 | 89 | -------------------------------------------------------------------------------- /luaob.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual C++ Express 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "luaob", "build\VisualStudio\luaob.vcxproj", "{FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Debug64|Win32 = Debug64|Win32 11 | Debug64|x64 = Debug64|x64 12 | Release|Win32 = Release|Win32 13 | Release|x64 = Release|x64 14 | Release64|Win32 = Release64|Win32 15 | Release64|x64 = Release64|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug|Win32.Build.0 = Debug|Win32 20 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug|x64.ActiveCfg = Debug|Win32 21 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug|x64.Build.0 = Debug|Win32 22 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug64|Win32.ActiveCfg = Debug64|Win32 23 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug64|Win32.Build.0 = Debug64|Win32 24 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug64|x64.ActiveCfg = Debug64|x64 25 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Debug64|x64.Build.0 = Debug64|x64 26 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release|Win32.ActiveCfg = Release|Win32 27 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release|Win32.Build.0 = Release|Win32 28 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release|x64.ActiveCfg = Release|Win32 29 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release|x64.Build.0 = Release|Win32 30 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release64|Win32.ActiveCfg = Release64|Win32 31 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release64|Win32.Build.0 = Release64|Win32 32 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release64|x64.ActiveCfg = Release64|x64 33 | {FDAFF6A5-C6AE-4A92-9B10-2D006D8EDDA3}.Release64|x64.Build.0 = Release64|x64 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Name 2 | luaob -- obfuscator of Lua code. 3 | 4 | #Decsription 5 | Obfuscator for **valid** Lua code. Target code is WoW's Lua and may be read the *.toc file of Addon, but if included files are *.lua. 6 | 7 | #Features 8 | * [always] Remove comments 9 | * [always] Remove duplicated chars (' ', '\n', '\t', '0x160') 10 | * [always] Remove extra whitespace 11 | * [always] Remove extra new line symbols and replace him to semicolon 12 | * Replace global function names 13 | * Replace local variable's names and argument's names 14 | * Replace string value to complex expression (escapes codes) 15 | * Add false comment 16 | 17 | TODO: 18 | * Replace integer number to complex expression 19 | * Replace float number to complex expression 20 | * Add false code 21 | 22 | #Synopsis 23 | luaob [-t toc_file_name] [-gef global_exclude_functions_file_name] [-a FILE] [-dir DIRECTORY] 24 | [-opt-one_file] [-between_lines line_count] [-opt-add_false_code] [-opt-add_false_comment] [-opt-const_float] [-opt-const_int] [-opt-const_string] [-opt-global_function] [-opt-local_function] [-opt-local_vars_args] 25 | 26 | #Options 27 | * **-t tocFileName** (The file name of *.toc file) 28 | * **-gef globalExcludeFunctionsFileName** (The file name of file, included global function names which must be exclude from obfuscating) 29 | * **-a FILE** (*.lua file name) 30 | * **-dir DIRECTORY** (The search directory, must be one!) 31 | * **-between_lines line_count** (count of \n between a lines in one obfuscated file) 32 | * **-opt-one_file** (Create one obfuscated file) 33 | * **-opt-add_false_code** (If this option is sets then will be add false code, default false) 34 | * **-opt-add_false_comment** (If this option is sets then will be add false comment, default false) 35 | * **-opt-const_float** (If this option is sets then will be obfuscates float numbers, default false) 36 | * **-opt-const_int** (If this option is sets then will be obfuscates int numbers, default false) 37 | * **-opt-const_string** (If this option is sets then will be obfuscates strings, default false) 38 | * **-opt-global_function** (If this option is sets then will be obfuscate global function names, default false) 39 | * **-opt-local_function** (If this option is sets then will be obfuscate local function names, default false) 40 | * **-opt-local_vars_args** (If this option is sets then will be obfuscate local variables and arguments, default false) 41 | 42 | 43 | #Version 44 | luaob 1.0 45 | 46 | #Compare 47 | [https://github.com/mlnlover11/XFuscator] 48 | 49 | [http://luasrcdiet.luaforge.net/] 50 | 51 | [http://www.lualearners.org/forum/3869] 52 | 53 | -------------------------------------------------------------------------------- /src/stack.cpp: -------------------------------------------------------------------------------- 1 | // LocalVarsStack.cpp 2 | 3 | #include "Stack.h" 4 | 5 | LocalVarsStack::LocalVarsStack(size_t initCount) { 6 | if (initCount < STACK_CAPACITY) 7 | initCount = STACK_CAPACITY; 8 | else if (initCount % STACK_CAPACITY != 0) 9 | initCount = initCount / STACK_CAPACITY + 1; 10 | 11 | m_data = new stObfuscatedName[initCount]; 12 | m_count = 0; 13 | m_reservedCount = initCount; 14 | } 15 | 16 | LocalVarsStack::~LocalVarsStack() { 17 | if (m_data) 18 | delete[] m_data; 19 | } 20 | 21 | void LocalVarsStack::push(const stObfuscatedName& obfuscatedName) { 22 | if (m_count == m_reservedCount) { 23 | m_reservedCount += STACK_CAPACITY; 24 | stObfuscatedName *pNewData = new stObfuscatedName[m_reservedCount]; 25 | for (size_t i = 0; i < m_count; ++i) 26 | pNewData[i] = m_data[i]; 27 | delete[] m_data; 28 | m_data = pNewData; 29 | } 30 | 31 | m_data[m_count] = obfuscatedName; 32 | ++m_count; 33 | } 34 | 35 | void LocalVarsStack::push(const char *name, const char *fake_name) { 36 | if (m_count == m_reservedCount) { 37 | m_reservedCount += STACK_CAPACITY; 38 | stObfuscatedName *pNewData = new stObfuscatedName[m_reservedCount]; 39 | for (size_t i = 0; i < m_count; ++i) 40 | pNewData[i] = m_data[i]; 41 | delete[] m_data; 42 | } 43 | 44 | m_data[m_count].name = name; 45 | m_data[m_count].fake_name = fake_name; 46 | ++m_count; 47 | } 48 | 49 | void LocalVarsStack::pop() { 50 | if (!m_count) 51 | return; 52 | 53 | --m_count; 54 | } 55 | 56 | void LocalVarsStack::pops(size_t elementCount) { 57 | if (elementCount > m_count) 58 | m_count = 0; 59 | else 60 | m_count -= elementCount; 61 | } 62 | 63 | LocalVarsStack& operator+= (LocalVarsStack& stackDest, const LocalVarsStack& stackSource) { 64 | size_t top = stackSource.getTopIndex(); 65 | 66 | for (size_t i = 0; i <= top; ++i) { 67 | stackDest.push(stackSource.items(i)); 68 | } 69 | 70 | return stackDest; 71 | } 72 | 73 | bool LocalVarsStack::find(const std::string& name) const { 74 | for (size_t i = 0; i < m_count; ++i) { 75 | if (m_data[i].name == name) 76 | return true; 77 | } 78 | 79 | return false; 80 | } 81 | 82 | bool LocalVarsStack::find(const char *name) const { 83 | for (size_t i = 0; i < m_count; ++i) { 84 | if (m_data[i].name == name) 85 | return true; 86 | } 87 | 88 | return false; 89 | } 90 | 91 | bool LocalVarsStack::find(stObfuscatedName& obfuscatedName) const { 92 | if (!m_count) 93 | return false; 94 | 95 | ptrdiff_t top = m_count - 1; 96 | while (top >= 0) { 97 | if (m_data[top].name == obfuscatedName.name) { 98 | obfuscatedName.fake_name = m_data[top].fake_name; 99 | return true; 100 | } 101 | --top; 102 | } 103 | 104 | return false; 105 | } 106 | 107 | stObfuscatedName& LocalVarsStack::top() const { 108 | if (!m_count) 109 | return m_data[0]; 110 | 111 | return m_data[m_count - 1]; 112 | } 113 | 114 | size_t LocalVarsStack::getTopIndex() const { 115 | return m_count - 1; 116 | } 117 | 118 | stObfuscatedName& LocalVarsStack::items(const size_t index) const { 119 | return m_data[index]; 120 | } 121 | 122 | size_t LocalVarsStack::count() const { 123 | return m_count; 124 | } 125 | 126 | bool LocalVarsStack::empty() const { 127 | return m_count == 0; 128 | } -------------------------------------------------------------------------------- /src/obfuscator.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBFUSCATE_H 2 | #define _OBFUSCATE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "stack.h" 9 | 10 | typedef std::list StringList; 11 | typedef std::list::iterator StringListIter; 12 | typedef std::list::const_iterator StringListConstIter; 13 | 14 | typedef std::set StringSet; 15 | typedef std::set::iterator StringSetIter; 16 | typedef std::set::const_iterator StringSetConstIter; 17 | 18 | typedef std::map StringMap; 19 | typedef std::map::iterator StringMapIter; 20 | typedef std::map::const_iterator StringMapConstIter; 21 | 22 | typedef StringSet FunctionSet; 23 | typedef StringMap FakeFunctions; 24 | typedef StringMap ObfuscatedItems; 25 | typedef StringMap LocalVars; 26 | 27 | typedef std::stringstream StringStream; 28 | 29 | 30 | struct stObfuscatorSetting { 31 | bool ObfuscateGlobalFunctionName; 32 | bool ObfuscateLocalFunctionName; 33 | bool ObfuscateConstInt; 34 | bool ObfuscateConstString; 35 | bool ObfuscateConstFloat; 36 | bool ObfuscateLocalVasAndParam; 37 | bool ObfuscateAddFalseComment; 38 | bool ObfuscateAddFalseCode; 39 | bool bCreateBakFile; 40 | bool bCreateOneFile; 41 | unsigned int linesBetweenFiles; 42 | }; 43 | 44 | struct stObfuscatorStatistic { 45 | unsigned singleCommentCount; 46 | unsigned multilineCommentCount; 47 | unsigned newLineCount; // TODO: delete 48 | unsigned extraSpaceCount; // TODO: delete 49 | unsigned intNumberCount; 50 | unsigned floatNumberCount; 51 | unsigned stringCount; 52 | unsigned globalFunctionCount; 53 | unsigned localFunctionCount; 54 | unsigned localeVariableCount; 55 | unsigned formalParameterCount; 56 | 57 | unsigned addFalseCommentCount; 58 | unsigned addFalseCommentSize; 59 | unsigned addFalseCodeCount; 60 | unsigned addFalseCodeSize; 61 | }; 62 | 63 | const int ADDITIONAL_MEMORY = 4096 * 2; 64 | const int FAKE_FUNCTION_LEN = 10; 65 | const int INT_OBFUSCATE_COUNT = 2; // *2 used in integer obfuscation 66 | 67 | const int WORK_BLOCK_SIZE = 1024; 68 | 69 | class LuaObfuscator { 70 | public: 71 | LuaObfuscator(const StringList &luaFiles, const StringList &excludeGlobalFunctions, 72 | std::string &sAddonDir); 73 | ~LuaObfuscator(); 74 | 75 | int obfuscate(const stObfuscatorSetting &settings); 76 | 77 | static size_t readAddonTocFile(char const *szTocFileName, StringList &luaFiles); 78 | static int readAddonGlobalExcludeFunctions(const char *szGlobalExcludeFunctionFileName, 79 | StringList &FunctionsExclude); 80 | 81 | friend char* readAndSkipLocalVariables(char*, ObfuscatedItems&, char**); 82 | friend char* readAndSkipLocalVariables(char*, StringStream&, ObfuscatedItems&); 83 | friend char* obfuscateLocalVars(const char*, const char*, StringStream&); 84 | // friend char* obfuscateLocalVarsInBlock(char*, LocalVars&, StringStream&); 85 | friend char* readAndObfuscateFunctionArguments(char*, LocalVars&, LocalVarsStack&, StringStream&); 86 | friend char* readAndObfuscateLocaleVariables(char*, LocalVars&, LocalVars&, LocalVarsStack&, StringStream&); 87 | 88 | static const char* generateObfuscatedFunctionName(); 89 | static const char* generateObfuscatedLocalVariableName(); // and arguments 90 | static size_t generateFalseComment(char *szAddComment); 91 | 92 | protected: 93 | const char* getFileName(StringListConstIter iter); 94 | 95 | ptrdiff_t removeComments(char *szLuaCode); 96 | ptrdiff_t removeExtraWhitespace(char *szLuaCode); 97 | ptrdiff_t removeDumplicatedChars(char *szLuaCode); // ' ' and '\n' and '\t' 98 | ptrdiff_t removeNewLines(char *szLuaCode); 99 | 100 | void obfuscateInt(StringStream &stream, const char *p, size_t size); 101 | void obfuscateFloat(StringStream &stream, const char *p, size_t size); 102 | void obfuscateSingleString(StringStream &stream, const char *p, size_t size); 103 | //void obfuscateMultilineString(std::stringstream &stream, const char *p, size_t size); 104 | 105 | int obfuscateConst(const char *szLuaCode, StringStream &obfuscatedLuaCode, const bool bInt, const bool bFloat, const bool bStrin); 106 | ptrdiff_t obfuscateGlobalFunctionNames(); 107 | ptrdiff_t obfuscateLocalVarsAndParameters(const char *szLuaCode, StringStream &obfuscatedLuaCode); 108 | int addFalseComment(); 109 | int addFalseCode(); 110 | 111 | private: 112 | const StringList &m_luaFiles; 113 | const StringList &m_excludeFunctions; 114 | const std::string &m_sAddonDir; 115 | stObfuscatorStatistic m_statistic; 116 | 117 | int readGlobalFunctions(const char *szFileName, FakeFunctions &Functions); 118 | }; 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /src/global.cpp: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include 3 | #include 4 | #include 5 | #ifdef _WIN32 6 | #include 7 | #endif 8 | 9 | void print(char const *format, ...) { 10 | const int N = 1024; 11 | char buf[N]; 12 | va_list va; 13 | 14 | if (!format || !format[0]) 15 | return; 16 | 17 | va_start(va, format); 18 | vsprintf(buf, format, va); 19 | va_end(va); 20 | 21 | printf(buf); 22 | } 23 | 24 | bool fileExists(const char *szFile) { 25 | #ifdef WIN32 26 | return access(szFile, 0) == 0; 27 | #else 28 | return std::iostream::good(szFile); // TODO: debug 29 | #endif 30 | } 31 | 32 | char* getFileDir(char const* szFile, char* szDir) { 33 | char const *p = strrchr(szFile, '\\'); 34 | if (!p) 35 | p = strrchr(szFile, '/'); 36 | if (!p) { 37 | return strcpy(szDir, getWorkDir()); 38 | } 39 | int size = p - szFile + 1; 40 | strncpy(szDir, szFile, size); 41 | szDir[size] = 0; 42 | 43 | return szDir; 44 | } 45 | 46 | char const* getExeDir() { 47 | static char buf[MAX_PATH]; 48 | 49 | GetModuleFileName(NULL, buf, MAX_PATH); 50 | char *p = strrchr(buf, '\\'); 51 | *(p + 1) = 0; 52 | 53 | return buf; 54 | } 55 | 56 | const char* getWorkDir() { 57 | static char buf[MAX_PATH]; 58 | 59 | buf[0] = 0; 60 | if (size_t size = GetCurrentDirectory(MAX_PATH, buf)) { 61 | if (!isPathSep(buf[size - 1])) { 62 | buf[size] = PATH_SEPARATOR_CHAR; 63 | buf[size + 1] = 0; 64 | } 65 | } 66 | 67 | return buf; 68 | } 69 | 70 | char const* getExeFileName() { 71 | static char buf[MAX_PATH]; 72 | 73 | GetModuleFileName(NULL, buf, MAX_PATH); 74 | 75 | return buf; 76 | } 77 | 78 | bool isPathSep(const char c) { 79 | return (c == '\\' || c == '/'); 80 | } 81 | 82 | bool isAbsoluteFilePath(const char *szFileName) { 83 | #ifdef _WIN32 84 | return strchr(szFileName, ':') != NULL; 85 | #else 86 | char *p = strchr(szFileName, '/'); 87 | if (p) { 88 | if (p > szFileName) { 89 | return *(p - 1) != '.'; 90 | } 91 | } 92 | return false; 93 | #endif 94 | } 95 | 96 | inline bool isSpaceChar(char c) { 97 | return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); 98 | } 99 | 100 | char* strtrim(char* sz) { 101 | if (!sz || !sz[0]) 102 | return NULL; 103 | 104 | char *p = sz; 105 | while (*p && (isSpaceChar(*p))) 106 | ++p; 107 | 108 | char *pEnd = &p[strlen(p) - 1]; 109 | while (pEnd >= p && isSpaceChar(*pEnd)) 110 | *(pEnd--) = 0; 111 | 112 | return p; 113 | } 114 | 115 | /* 116 | * For obfuscator 117 | */ 118 | bool isStringStart(const char *p) { 119 | return (*p == '"' || *p == '\'' || (*p == '[' && *(p + 1) == '[')); 120 | } 121 | 122 | bool isSingleStringStart(const char *p) { 123 | return (*p == '"' || *p == '\''); 124 | } 125 | 126 | bool isMultilineStringStart(const char *p) { 127 | return (*p == '[' && *(p + 1) == '['); 128 | } 129 | 130 | bool isSpace(const char c) { 131 | return (c == ' ' || c == '\t'); 132 | } 133 | 134 | bool isNewLine(const char c) { 135 | return (c == '\n'); 136 | } 137 | 138 | bool isAlphaFun(const char c) { 139 | return (isalnum(c) || c == '_'); 140 | } 141 | 142 | bool isVarChar(const char c) { 143 | return (isalnum(c) || c == '_'); 144 | } 145 | 146 | /* 147 | * Skip the string in Lua's code and move a pointer 148 | * *pData -- pointer to "string" 149 | */ 150 | size_t skipStringAndMove(char **pData, char **pDest) { 151 | const char *p = *pData; 152 | 153 | if (*p == '"' || *p == '\'') { 154 | const char cStart = *(p++); 155 | while (*p) { 156 | if (*p == cStart) { 157 | if (*(p - 1) == '\\') { 158 | if (isEscapedChar(p)) { 159 | ++p; 160 | continue; 161 | } 162 | } 163 | ++p; 164 | break; 165 | } 166 | ++p; 167 | } 168 | } 169 | else { 170 | while (*p && !(*p == ']' && *(p + 1) == ']')) { 171 | ++p; 172 | } 173 | if (*p) 174 | ++p; 175 | if (*p) 176 | ++p; 177 | } 178 | size_t size = p - *pData; 179 | if (pDest) { 180 | memmove(*pDest, *pData, size); 181 | *pDest += size; 182 | } 183 | *pData += size; 184 | 185 | return size; 186 | } 187 | 188 | /* 189 | * Return true if quote is escaped, i. e. \" or \\\" 190 | * Return true if quote is non escaped, i. e. \\" or \\\\" or _" 191 | */ 192 | bool isEscapedChar(const char* p) { 193 | const char *pCur = p - 1; 194 | 195 | while (*pCur && *pCur == '\\') 196 | --pCur; 197 | 198 | return (p - pCur) % 2 == 0; 199 | } 200 | 201 | /* 202 | * Skip the whitespaces forward or back direction 203 | */ 204 | char* skipSpace(char *str, bool bForward) { 205 | char *p = str; 206 | 207 | if (bForward) { 208 | while (isSpace(*p)) 209 | ++p; 210 | } 211 | else { 212 | while (isSpace(*p)) 213 | --p; 214 | } 215 | 216 | return p; 217 | } 218 | 219 | char* skipSpaceAndNewLine(char *str, bool bForward) { 220 | char *p = str; 221 | 222 | if (bForward) { 223 | while (isSpace(*p) || isNewLine(*p)) 224 | ++p; 225 | } 226 | else { 227 | while (isSpace(*p) || isNewLine(*p)) 228 | --p; 229 | } 230 | 231 | return p; 232 | } 233 | 234 | /* END */ 235 | -------------------------------------------------------------------------------- /src/luaob.cpp: -------------------------------------------------------------------------------- 1 | // 2 | #include "global.h" 3 | #include "obfuscator.h" 4 | #include 5 | #include 6 | 7 | //void printHelp(); 8 | //int parseArguments(int argc, char *argv[], std::string &globalExcludeFunctionFileName); 9 | 10 | 11 | 12 | 13 | void printHelp() { 14 | print("=============== Lua obfuscator, Version 1.0\n"); 15 | print("===== Copyright (C) 2013, Gracer \n"); 16 | print("[-t FILE.toc]\n"); 17 | print("[-gef global_exclude_function_file_name]\n"); 18 | print("[-a FILE]\n"); 19 | print("[-dir DIRECTORY]\n"); 20 | print("[-between_lines line_count]\n"); 21 | print("[-opt-one_file]\n"); 22 | print("[-opt-add_false_code]\n"); 23 | print("[-opt-add_false_comment]\n"); 24 | print("[-opt-const_float]\n"); 25 | print("[-opt-const_int]\n"); 26 | print("[-opt-const_string]\n"); 27 | print("[-opt-global_function]\n"); 28 | print("[-opt-local_function]\n"); 29 | print("[-opt-local_vars_args]\n"); 30 | } 31 | 32 | int parseArguments(int argc, char *argv[], std::string &tocFileName, std::string &addonDir, 33 | std::string &globalExcludeFunctionFileName, StringList &luaFiles, 34 | stObfuscatorSetting &setting) 35 | { 36 | int count = 0; 37 | 38 | // default 39 | setting.bCreateOneFile = false; 40 | setting.ObfuscateAddFalseCode = false; 41 | setting.ObfuscateAddFalseComment = false; 42 | setting.ObfuscateConstFloat = false; 43 | setting.ObfuscateConstInt = false; 44 | setting.ObfuscateConstString = false; 45 | setting.ObfuscateGlobalFunctionName = false; 46 | setting.ObfuscateLocalFunctionName = false; 47 | setting.ObfuscateLocalVasAndParam = false; 48 | setting.bCreateBakFile = true; 49 | setting.linesBetweenFiles = 0; 50 | 51 | // addonDir = "e:/Software/Games/World of Warcraft/Interface/AddOns/chardumps/"; 52 | 53 | for (int i = 1; i < argc; ++i) { 54 | const char *arg = argv[i]; 55 | 56 | if (!strncmp(arg, "-opt-", 5)) { 57 | const char *opt = arg + 5; 58 | 59 | if (!strcmp(opt, "one_file")) { 60 | setting.bCreateOneFile = true; 61 | } 62 | else if (!strcmp(opt, "add_false_code")) { 63 | setting.ObfuscateAddFalseCode = true; 64 | } 65 | else if (!strcmp(opt, "add_false_comment")) { 66 | setting.ObfuscateAddFalseComment = true; 67 | } 68 | else if (!strcmp(opt, "const_float")) { 69 | setting.ObfuscateConstFloat = true; 70 | } 71 | else if (!strcmp(opt, "const_int")) { 72 | setting.ObfuscateConstInt = true; 73 | } 74 | else if (!strcmp(opt, "const_string")) { 75 | setting.ObfuscateConstString = true; 76 | } 77 | else if (!strcmp(opt, "global_function")) { 78 | setting.ObfuscateGlobalFunctionName = true; 79 | } 80 | else if (!strcmp(opt, "local_function")) { 81 | setting.ObfuscateLocalFunctionName = true; 82 | } 83 | else if (!strcmp(opt, "local_vars_args")) { 84 | setting.ObfuscateLocalVasAndParam = true; 85 | } 86 | } 87 | else if (!strcmp(arg, "-t")) { 88 | if (++i < argc) { 89 | tocFileName = argv[i]; 90 | ++count; 91 | } 92 | } 93 | else if (!strcmp(arg, "-gef")) { 94 | if (++i < argc) { 95 | globalExcludeFunctionFileName = argv[i]; 96 | ++count; 97 | } 98 | } 99 | else if (!strcmp(arg, "-a")) { 100 | if (++i < argc) { 101 | luaFiles.push_back(argv[i]); 102 | ++count; 103 | } 104 | } 105 | else if (!strcmp(arg, "-dir")) { 106 | if (++i < argc) { 107 | addonDir = argv[i]; 108 | if (addonDir == ".") { 109 | addonDir = getWorkDir(); 110 | } 111 | char c = addonDir[addonDir.length() - 1]; 112 | if (!isPathSep(c)) 113 | addonDir += PATH_SEPARATOR_CHAR; 114 | ++count; 115 | } 116 | } 117 | else if (!strcmp(arg, "-between_lines")) { 118 | if (++i < argc) { 119 | setting.linesBetweenFiles = atoi(argv[i]); 120 | } 121 | } 122 | } 123 | 124 | if (!tocFileName.empty() && !isAbsoluteFilePath(tocFileName.c_str())) { 125 | if (!addonDir.empty()) 126 | tocFileName = addonDir + tocFileName; 127 | else 128 | tocFileName = getWorkDir() + tocFileName; 129 | } 130 | 131 | return count; 132 | } 133 | 134 | void validateFileNames(StringList &luaFiles, const char *szAddonDir = NULL) { 135 | StringListIter iter = luaFiles.begin(); 136 | 137 | if (!szAddonDir || !szAddonDir[0]) 138 | szAddonDir = getWorkDir(); 139 | 140 | while (iter != luaFiles.end()) { 141 | std::string &str = *iter; 142 | if (!isAbsoluteFilePath(str.c_str())) { 143 | str = szAddonDir + str; 144 | } 145 | ++iter; 146 | } 147 | } 148 | 149 | int main(int argc, char *argv[]) { 150 | StringList excludeGlobalFunctions; 151 | StringList luaFiles; 152 | std::string globalExcludeFunctionFileName; 153 | std::string tocFileName; 154 | std::string addonDir; 155 | stObfuscatorSetting settings; 156 | 157 | srand(static_cast(time(NULL))); 158 | 159 | parseArguments(argc, argv, tocFileName, addonDir, globalExcludeFunctionFileName, luaFiles, settings); 160 | 161 | print("Addon dir: %s\n", addonDir.c_str()); 162 | print("Work dir: %s\n", getWorkDir()); 163 | 164 | LuaObfuscator::readAddonGlobalExcludeFunctions(globalExcludeFunctionFileName.c_str(), excludeGlobalFunctions); 165 | 166 | LuaObfuscator::readAddonTocFile(tocFileName.c_str(), luaFiles); 167 | 168 | // add absolute path name, if need 169 | //validateFileNames(luaFiles, addonDir.c_str()); 170 | 171 | if (luaFiles.empty()) { 172 | printHelp(); 173 | printf("\nNo a files for an obfuscating\n"); 174 | return -1; 175 | } 176 | 177 | try { 178 | LuaObfuscator obfuscator(luaFiles, excludeGlobalFunctions, addonDir); 179 | 180 | print("create bak file: %d\n", settings.bCreateBakFile); 181 | print("create one file: %d\n", settings.bCreateOneFile); 182 | print("obfuscate const int: %d\n", settings.ObfuscateConstInt); 183 | print("obfuscate const float: %d\n", settings.ObfuscateConstFloat); 184 | print("obfuscate const string: %d\n", settings.ObfuscateConstString); 185 | print("obfuscate local vars: %d\n", settings.ObfuscateLocalVasAndParam); 186 | print("obfuscate global fucntions: %d\n", settings.ObfuscateGlobalFunctionName); 187 | 188 | obfuscator.obfuscate(settings); 189 | } 190 | catch (std::exception) { 191 | print("ERROR: obfuscator creating fail\n"); 192 | } 193 | 194 | #ifdef _DEBUG 195 | getchar(); 196 | #endif 197 | 198 | return 0; 199 | } 200 | --------------------------------------------------------------------------------