string
  • lua
  • 2016-12-28 131 views 1 likes 
    1

    我試圖在我的lua腳本中對一些字符串進行編碼,並且因爲我有一個超過200k字符的lua腳本,所以在腳本中使用一個函數(如本示例)加密每個字符串查詢下面獲取lua腳本中的所有字符串

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

    local string=decode("jkrtbfmviwcfn",519211) 
    

    試圖提供所有上述結果通過GSUB線程並具有GSUB編碼具有隨機偏移數的字符串的文本。

    到目前爲止,我只能通過gsubbing全引號。

    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

    我很好奇:你爲什麼想這麼做?這是[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)?在Lua源代碼中處理字符串需要一些詞法分析。試試我的[ltokenp](http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/index.html#ltokenp)。 – lhf

    +0

    我想要一些形式的字符串文本加密,以防止有我的源代碼的人輕鬆地刪除我的信用。但是,有經驗的用戶可能會在我的200k角色腳本中添加他們自己的功勞。 – Dolvik

    +0

    @Nickoplier從給出源代碼的那一刻開始,跟蹤腳本執行的過程非常簡單,找到打印出的加密信用點,並用自己的非加密信用代替它們。或者,我錯過了什麼? – tonypdmtr

    回答

    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 
    
    相關問題