轉自:https://blog.csdn.net/clirus/article/details/50499473?utm_source=blogxgwz3
最近把luci代碼深入地剖析了一遍.說實話剛開始看的時候也是雲裏霧裏,特別是dispatch函數, 這其間也是參考了幾篇文章, 特此感謝.
剛開始看luci代碼確實就和逆向沒啥區別, 需要揣摩作者對於各個變量的用途. 於是我就想了一個辦法, 就是把每個變量都打印出來.
爲此我在/usr/lib/lua/luci目錄下引入了log.lua模塊:
local M = {}
local tconcat = table.concat
local tinsert = table.insert
local srep = string.rep
local function local_print(str)
local dbg = io.open("/tmp/luci.output", "a+")
local str = str or ""
if dbg then
dbg:write(str..'\n')
dbg:close()
end
end
function M.print(...)
local dbg = io.open("/tmp/luci.output", "a+")
if dbg then
dbg:write(os.date("[%H:%M:%S]: "))
for _, o in ipairs({...}) do
dbg:write(tostring(o)..' ')
end
dbg:write("\n")
dbg:close()
end
end
function M.print_r(data, depth)
local depth = depth or 3
local cstring = "";
local top_flag = true
local function table_len(t)
local i = 0
for k, v in pairs(t) do
i = i + 1
end
return i
end
local function tableprint(data,cstring, local_depth)
if data == nil then
local_print("core.print data is nil");
end
local cs = cstring .. " ";
if top_flag then
local_print(cstring .."{");
top_flag = false
end
if(type(data)=="table") then
for k, v in pairs(data) do
if type(v) ~= "table" then
if type(v) == "string" then
local_print(cs..tostring(k).." = ".."'"..tostring(v).."'");
else
local_print(cs..tostring(k).." = "..tostring(v));
end
elseif table_len(v) == 0 then
local_print(cs..tostring(k).." = ".."{}")
elseif local_depth < depth then
local_print(cs..tostring(k).." = {");
tableprint(v,cs,local_depth+1);
else
local_print(cs..tostring(k).." = ".."{*}")
end
end
else
local_print(cs..tostring(data));
end
local_print(cstring .."}");
end
tableprint(data,cstring,0);
end
return M
你可以在luci目錄下任何一個地方調用
-
local log = require "luci.log"
-
log.print("Hello World")
-
log.print_r({"Hello", "World"})
另外, log模塊將輸出信息到/tmp/luci.ouput下面, 我們可以用tail命令跟蹤.
# tail -f /tmp/luci.output
於是通過這個小小的模塊, 得以一窺這個openwrt上著名的程序. 確實很有趣, 有時間我會詳細的把luci框架分析寫下來.
另外luci程序自帶了一個debug模塊, 這是一個用來分析內存佔用情況的模塊, 你也可以在dispatcher.lua模塊中開啓.它的信息記錄在/tmp/memtrace中.
參考