获取lua脚本中的所有字符串

时间:2016-12-28 10:04:29

标签: string lua

我正在尝试在我的lua脚本中编码一些字符串,因为我有一个超过200k字符的lua脚本,使用如下例子的函数加密脚本中的每个字符串查询

local string   =    "stackoverflow"
local string   =   [[stackoverflow]]
local string   = [==[stackoverflow]==]
local string   =    'stackoverflow'

local string=decode("jkrtbfmviwcfn",519211)

尝试提供以上所有结果来穿过gsub并让gsub使用随机偏移号对字符串文本进行编码。

到目前为止,我只能通过编写完整的引号。

function encode(x,offset,a)
    for char in string.gmatch(x, "%a") do
        local encrypted = string.byte(char) + offset
        while encrypted > 122 do
            encrypted = encrypted - 26
        end
        while encrypted < 97 do
            encrypted = encrypted + 26
        end
        a[#a+1] = string.char(encrypted)
    end
    return table.concat(a) 
end
luacode=[==[thatstring.Value="Encryptme!" testvalue.Value=[[string with
a linebreak]] string.Text="STOP!"]==]
luacode=luacode:gsub([=["(.-)"]=],function(s)
    print("Caught "..s)
    local offset=math.random(1,4)
    local encoded=encode(s,offset,{})
    return [[decode("]]..encoded..[[",]]..offset..[[)]]
end)
print("\n"..luacode)

输出为

Caught Encryptme!
Caught STOP!

thatstring.Value=decode("crgvctxqi",4) testvalue.Value=[[string with
a linebreak]] string.Text=decode("opkl",2)

有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

local function strings_and_comments(lua_code, callback)
   -- lua_code must be valid Lua code (an error may be raised on syntax error)
   -- callback will be invoked as callback(object_type, value, start_pos, end_pos)
   --    callback("comment", comment_text, start_pos, end_pos)  -- for comments
   --    callback("string", string_value, start_pos, end_pos)   -- for string literals
   local objects = {}  -- possible comments and string literals in the code
   -- search for all start positions of comments (with false positives)
   for pos, br1, eq, br2 in lua_code:gmatch"()%-%-(%-*%[?)(=*)(%[?)" do
      table.insert(objects, {start_pos = pos,
         terminator = br1 == "[" and br2 == "[" and "]"..eq.."]" or "\n"})
   end
   -- search for all start positions of string literals (with false positives)
   for pos, eq in lua_code:gmatch"()%[(=*)%[[%[=]*" do
      table.insert(objects, {is_string = true, start_pos = pos,
         terminator = "]"..eq.."]"})
   end
   for pos, quote in lua_code:gmatch"()(['\"])" do
      table.insert(objects, {is_string = true, start_pos = pos, quote = quote})
   end
   table.sort(objects, function(a, b) return a.start_pos < b.start_pos end)
   local end_pos = 0
   for _, object in ipairs(objects) do
      local start_pos, ok, symbol = object.start_pos
      if start_pos > end_pos then
         if object.terminator == "\n" then
            end_pos = lua_code:find("\n", start_pos + 1, true) or #lua_code
            -- exclude last spaces and newline
            while lua_code:sub(end_pos, end_pos):match"%s" do
               end_pos = end_pos - 1
            end
         elseif object.terminator then
            ok, end_pos = lua_code:find(object.terminator, start_pos + 1, true)
            assert(ok, "Not a valid Lua code")
         else
            end_pos = start_pos
            repeat
               ok, end_pos, symbol = lua_code:find("(\\?.)", end_pos + 1)
               assert(ok, "Not a valid Lua code")
            until symbol == object.quote
         end
         local value = lua_code:sub(start_pos, end_pos):gsub("^%-*%s*", "")
         if object.terminator ~= "\n" then
            value = assert((loadstring or load)("return "..value))()
         end
         callback(object.is_string and "string" or "comment", value, start_pos, end_pos)
      end
   end
end

local inv256

local function encode(str)
   local seed = math.random(0x7FFFFFFF)
   local result = '",'..seed..'))'
   if not inv256 then
      inv256 = {}
      for M = 0, 127 do
         local inv = -1
         repeat inv = inv + 2
         until inv * (2*M + 1) % 256 == 1
         inv256[M] = inv
      end
   end
   repeat
      seed = seed * 3
   until seed > 2^43
   local K = 8186484168865098 + seed
   result = '(decode("'..str:gsub('.',
      function(m)
         local L = K % 274877906944   -- 2^38
         local H = (K - L) / 274877906944
         local M = H % 128
         m = m:byte()
         local c = (m * inv256[M] - (H - M) / 128) % 256
         K = L * 21271 + H + c + m
         return ('%02x'):format(c)
      end
   )..result
   return result
end

function hide_strings_in_lua_code(lua_code)
   local text = { [[
local function decode(str, seed)
   repeat
      seed = seed * 3
   until seed > 2^43
   local K = 8186484168865098 + seed
   return (str:gsub('%x%x',
      function(c)
         local L = K % 274877906944   -- 2^38
         local H = (K - L) / 274877906944
         local M = H % 128
         c = tonumber(c, 16)
         local m = (c + (H - M) / 128) * (2*M + 1) % 256
         K = L * 21271 + H + c + m
         return string.char(m)
      end
   ))
end
]] }
   local pos = 1
   strings_and_comments(lua_code,
      function (object_type, value, start_pos, end_pos)
         if object_type == "string" then
            table.insert(text, lua_code:sub(pos, start_pos - 1))
            table.insert(text, encode(value))
            pos = end_pos + 1
         end
      end)
   table.insert(text, lua_code:sub(pos))
   return table.concat(text)
end

<强>用法:

math.randomseed(os.time())

-- This is the program to be converted
local luacode = [===[
print"Hello world!"
print[[string with
a linebreak]]
local str1 =    "stackoverflow"
local str2 =   [[stackoverflow]]
local str3 = [==[stackoverflow]==]
local str4 =    'stackoverflow'
print(str1)
print(str2)
print(str3)
print(str4)
]===]

-- Conversion
print(hide_strings_in_lua_code(luacode))

输出(已转换的程序)

local function decode(str, seed)
   repeat
      seed = seed * 3
   until seed > 2^43
   local K = 8186484168865098 + seed
   return (str:gsub('%x%x',
      function(c)
         local L = K % 274877906944   -- 2^38
         local H = (K - L) / 274877906944
         local M = H % 128
         c = tonumber(c, 16)
         local m = (c + (H - M) / 128) * (2*M + 1) % 256
         K = L * 21271 + H + c + m
         return string.char(m)
      end
   ))
end
print(decode("ef869b23b69b7fbc7f89bbe7",2686976))
print(decode("c2dc20f7061c452db49302f8a1d9317aad1009711e0984",1210253312))
local str1 =    (decode("84854df4599affe9c894060431",415105024))
local str2 =   (decode("a5d7db792f0b514417827f34e3",1736704000))
local str3 = (decode("6a61bcf9fd6f403ed1b4846e58",1256259584))
local str4 =    (decode("cad56d9dea239514aca9c8b8e0",1030488064))
print(str1)
print(str2)
print(str3)
print(str4)

输出输出(转换后的程序产生的输出)

Hello world!
string with
a linebreak
stackoverflow
stackoverflow
stackoverflow
stackoverflow