分类: 嵌入式
2016-01-20 17:30:05
最近把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中.