forked from endeav0r/rdis-lua
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgdb-util.lua
98 lines (82 loc) · 2.57 KB
/
gdb-util.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
GDB_TMP_FILENAME = '/tmp/rdis.gdb.tmp'
Gdb = require("gdb")
function gdb_remote(host, port, arch)
-- create gdb remote connection
local gdb, errormsg = Gdb.new(host, port, arch)
if gdb == nil then
rdis.console(errormsg)
return nil
end
rdis.console('gdb connected')
-- get process id
gdb.pid = gdb:thread_pid()
if gdb.pid == nil then
gdb:close()
rdis.console('Could not get process id')
return nil
end
rdis.console('process id: ' .. gdb.pid)
-- get path to remote process
gdb.filename = gdb:readlink('/proc/' .. tostring(gdb:thread_pid()) .. '/exe')
if gdb.filename == nil then
gdb:close()
rdis.console('Could not get process filename')
return nil
end
rdis.console('process filename: ' .. gdb.filename)
-- get remote file, store in tmp file, load in rdis
local file = gdb:readfile(gdb.filename)
if file == nil then
gdb:close()
rdis.console('Could not read debugged executable file')
return nil
end
local fh, errormsg = io.open(GDB_TMP_FILENAME, 'w')
if fh == nil then
gdb:close()
rdis.console('IO ERROR: ' .. errormsg)
return nil
end
fh:write(file)
fh:close()
local loader_error = rdis.loader(GDB_TMP_FILENAME)
if loader_error == false then
gdb:close()
rdis.console('error loading debug executable file')
return nil
end
gdb_remote_update_mem(gdb)
return gdb
end
function gdb_remote_update_mem (gdb)
local filename = '/proc/' .. tostring(gdb.pid) .. '/maps'
local maps = gdb:readfile(filename)
local tofetch = {}
for line in string.gmatch(maps, '(.-)\n') do
local low = line.match(line, '([%dabcdef]+).*')
local high = line.match(line, '.-%-([%dabcdef]+).*')
low = uint64('0x' .. low)
high = uint64('0x' .. high)
local size = high - low
if size ~= uint64(0) then
tofetch[low] = size
end
end
maps = {}
local filename = '/proc/' .. tostring(gdb.pid) .. '/mem'
for base,size in pairs(tofetch) do
base_str = tostring(base):sub(3)
size_str = tostring(size):sub(3)
local bytes = gdb:readfileoffset(filename, base_str, size_str)
if bytes == nil then
bytes = gdb:memory(base, size)
end
if bytes == nil then
rdis.console('failed fetching mem at ' .. tostring(base))
else
print(type(base))
print(type(bytes))
rdis.poke(base, bytes)
end
end
end