Sunday, February 24, 2008

The Lua script

This Lua script takes a single source file as a command line argument - the output of otx. It will attempt to pull out all the useful information and build a list of IDC commands that can be imported into IDA, decorating the disassembly with the obj-c metadata.

Lua can be downloaded from here: http://www.lua.org

if not arg[1] then
print("Usage: otx.lua <otx output*gt;")
return
end

-- create a few string helper functions
--
function string:split(inSplitPattern, outResults)
if not outResults then
outResults = { }
end
local theStart = 1
local theSplitStart, theSplitEnd = string.find(self, inSplitPattern, theStart)
while theSplitStart do
table.insert(outResults, string.sub( self, theStart, theSplitStart-1))
theStart = theSplitEnd + 1
theSplitStart, theSplitEnd = string.find(self, inSplitPattern, theStart)
end
table.insert(outResults, string.sub(self, theStart))
return outResults
end

function string:strip()
return self:gsub("[%^%$%%%(%)%>%{%}%*%+%-%?%[%]]", "%%%1")
end

function string:for_ida()
return self:gsub("[\\\"]", "\\%1")
end

-- main starts here
--
infile = io.open(arg[1], "r")
outfile = io.open("output.idc", "w")

outfile:write("#include \"ida.idc\"\n\nstatic main()\n{\n")

repeat

-- read in the source, one line at a time
line = infile:read("*line")

if line then
-- split on whitespace
parts = line:split("%s+")

if line:find("^[%-%+]") then

-- we have a method name
meth_name = line:match("%[([^%]]+)%]")

parts = infile:read("*line"):split("%s+")

outfile:write("\tMakeNameEx(0x" .. parts[3] .. ", \"" .. meth_name:for_ida() .. "\", 0x102);\n")
end

if parts[3] and parts[7] then

-- we have an extra comment
ea = parts[3]
temp = parts[7]
o = line:find(temp:strip())

comment = line:sub(o, -1)

outfile:write("\tMakeComm(0x" .. ea .. ", \"" .. comment:for_ida() .. "\");\n")
end
end

until not line

outfile:write("}\n")

io.close(outfile)
io.close(infile)

No comments: