-
-
Save Pir00t/6d1e8833b2ba2754cce515c1a5ab5c72 to your computer and use it in GitHub Desktop.
My Hawaii Vacation Lua Decode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env lua | |
| -- Placeholder for the actual key | |
| local __K = "YOUR_12K_CHARACTER_KEY_HERE" | |
| -- Helper function to create UTF-8 character from bytes | |
| local function __U8(a, b, c, d) | |
| return string.char(a, b, c, d) | |
| end | |
| -- Create the 16-token alphabet (hex nibbles 0-F) | |
| local function __T() | |
| return { | |
| __U8(240, 159, 140, 186), -- 0 | |
| __U8(240, 159, 140, 180), -- 1 | |
| __U8(240, 159, 140, 138), -- 2 | |
| __U8(240, 159, 140, 139), -- 3 | |
| __U8(240, 159, 165, 165), -- 4 | |
| __U8(240, 159, 140, 136), -- 5 | |
| __U8(240, 159, 144, 162), -- 6 | |
| __U8(240, 159, 144, 160), -- 7 | |
| __U8(240, 159, 144, 172), -- 8 | |
| __U8(240, 159, 144, 139), -- 9 | |
| __U8(240, 159, 144, 154), -- A | |
| __U8(240, 159, 144, 179), -- B | |
| __U8(240, 159, 144, 161), -- C | |
| __U8(240, 159, 166, 128), -- D | |
| __U8(240, 159, 166, 136), -- E | |
| __U8(240, 159, 144, 153) -- F | |
| } | |
| end | |
| -- Simple hash function for key | |
| local function S(k) | |
| k = tostring(k or "") | |
| local s = 3237919422 | |
| for i = 1, #k do | |
| s = (s * 1315423911 + k:byte(i)) % 4294967296 | |
| end | |
| return s | |
| end | |
| -- Linear congruential generator for keystream | |
| local function M(seed) | |
| return function() | |
| seed = (1664525 * seed + 1013904223) % 4294967296 | |
| return seed | |
| end | |
| end | |
| -- 4-bit XOR function | |
| local function X(a, b) | |
| local r, p = 0, 1 | |
| for _ = 1, 4 do | |
| local A = a % 2 | |
| local B = b % 2 | |
| if (A + B) % 2 == 1 then | |
| r = r + p | |
| end | |
| a = (a - A) / 2 | |
| b = (b - B) / 2 | |
| p = p * 2 | |
| end | |
| return r | |
| end | |
| -- Main decoder function | |
| local function __D(t, k) | |
| local T = __T() | |
| local toklen = 4 | |
| if k == nil then | |
| k = __K | |
| end | |
| local key_on = k ~= nil and k ~= "" | |
| local permute = true and key_on | |
| -- Build permutation table | |
| local perm = {} | |
| for n = 0, 15 do | |
| perm[n] = n | |
| end | |
| if permute then | |
| local r = M(S(tostring(k) .. "|perm")) | |
| for i = 15, 1, -1 do | |
| local j = r() % (i + 1) | |
| perm[i], perm[j] = perm[j], perm[i] | |
| end | |
| end | |
| -- Build decode map | |
| local dec_map = {} | |
| for n = 0, 15 do | |
| local idx = permute and perm[n] or n | |
| dec_map[T[idx + 1]] = n | |
| end | |
| -- Remove whitespace from input | |
| t = (t or ""):gsub("%s+", "") | |
| local out, n, i, step = {}, #t, 1, toklen * 2 | |
| -- Setup keystream for XOR | |
| local ks | |
| if key_on then | |
| local r = M(S(tostring(k) .. "|xor")) | |
| function ks() | |
| local v = r() % 256 | |
| return (v - v % 16) / 16, v % 16 | |
| end | |
| end | |
| -- Decode pairs of tokens | |
| while n >= i + step - 1 do | |
| local a = t:sub(i, i + toklen - 1) | |
| local b = t:sub(i + toklen, i + step - 1) | |
| local hi, lo = dec_map[a], dec_map[b] | |
| if not hi or not lo then | |
| break | |
| end | |
| if ks then | |
| local kh, kl = ks() | |
| hi = X(hi, kh) | |
| lo = X(lo, kl) | |
| end | |
| out[#out + 1] = string.char(hi * 16 + lo) | |
| i = i + step | |
| end | |
| return table.concat(out) | |
| end | |
| -- Convert escaped string to actual bytes | |
| local function unescape_string(s) | |
| -- Convert \240\159\140\186 style escapes to actual characters | |
| return s:gsub("\\(%d%d%d)", function(d) | |
| return string.char(tonumber(d)) | |
| end) | |
| end | |
| -- Test function to decode all strings in a file | |
| local function decode_all_strings(filename) | |
| local f = io.open(filename, "r") | |
| if not f then | |
| print("Error: Cannot open file " .. filename) | |
| return | |
| end | |
| local content = f:read("*all") | |
| f:close() | |
| -- Pattern to match __D("...", __K) or __D('...', __K) calls | |
| -- This captures the escaped string content | |
| local results = {} | |
| local count = 0 | |
| -- Match both single and double quoted strings | |
| for encoded in content:gmatch('__D%("([^"]+)", __K%)') do | |
| count = count + 1 | |
| local unescaped = unescape_string(encoded) | |
| local decoded = __D(unescaped, __K) | |
| if decoded and #decoded > 0 then | |
| -- Try to show first 40 chars of encoded for reference | |
| local preview = encoded:sub(1, 40) | |
| if #encoded > 40 then preview = preview .. "..." end | |
| table.insert(results, { | |
| num = count, | |
| encoded = preview, | |
| decoded = decoded | |
| }) | |
| end | |
| end | |
| for encoded in content:gmatch("__D%('([^']+)', __K%)") do | |
| count = count + 1 | |
| local unescaped = unescape_string(encoded) | |
| local decoded = __D(unescaped, __K) | |
| if decoded and #decoded > 0 then | |
| local preview = encoded:sub(1, 40) | |
| if #encoded > 40 then preview = preview .. "..." end | |
| table.insert(results, { | |
| num = count, | |
| encoded = preview, | |
| decoded = decoded | |
| }) | |
| end | |
| end | |
| return results | |
| end | |
| -- Main execution | |
| if arg[1] == "test" then | |
| -- Test with specific encoded string (with escape sequences) | |
| local encoded = arg[2] | |
| if encoded then | |
| local unescaped = unescape_string(encoded) | |
| print("Decoded: " .. __D(unescaped, __K)) | |
| else | |
| print("Usage: lua decoder.lua test <encoded_string>") | |
| end | |
| elseif arg[1] == "file" then | |
| -- Decode all strings from file | |
| local filename = arg[2] or "decompiled.lua" | |
| print("Decoding strings from: " .. filename) | |
| print(string.rep("=", 70)) | |
| local results = decode_all_strings(filename) | |
| if #results == 0 then | |
| print("WARNING: No strings found!") | |
| print("\nDebugging: Checking if key is set...") | |
| if __K == "YOUR_12K_CHARACTER_KEY_HERE" then | |
| print("ERROR: You need to replace __K with the actual key!") | |
| else | |
| print("Key is set (length: " .. #__K .. ")") | |
| print("\nTrying to decode a test string...") | |
| -- Try decoding one of the constants we can see | |
| local test = unescape_string("\\240\\159\\140\\138\\240\\159\\144\\172") | |
| print("Test decode result: [" .. __D(test, __K) .. "]") | |
| end | |
| else | |
| for i, result in ipairs(results) do | |
| print(string.format("%3d. %s", result.num, result.decoded)) | |
| print(" Encoded: " .. result.encoded) | |
| print() | |
| end | |
| end | |
| print(string.rep("=", 70)) | |
| print("Total strings decoded: " .. #results) | |
| else | |
| -- Interactive mode | |
| print("Prometheus String Decoder") | |
| print("Usage:") | |
| print(" lua decoder.lua test <encoded_string> - Decode single string") | |
| print(" lua decoder.lua file [filename] - Decode all strings from file") | |
| print() | |
| if __K == "YOUR_12K_CHARACTER_KEY_HERE" then | |
| print("WARNING: Key not set! Replace __K with actual key") | |
| else | |
| print("Key length: " .. #__K .. " characters") | |
| end | |
| end | |
| -- Export the decoder function for use as module | |
| return { | |
| decode = __D, | |
| decode_all = decode_all_strings | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment