Fix interpreter loader (#115)
* Correctly compute total interp size * Rename * Make staticmethod * Add basic loading test
This commit is contained in:
parent
83cb4de825
commit
ffe758f5f3
@ -731,11 +731,7 @@ class Linux(object):
|
|||||||
|
|
||||||
if base == 0 and interpreter.header.e_type == 'ET_DYN':
|
if base == 0 and interpreter.header.e_type == 'ET_DYN':
|
||||||
assert vaddr == 0
|
assert vaddr == 0
|
||||||
total_size = 0
|
total_size = self._interp_total_size(interpreter)
|
||||||
for _elf_segment in interpreter.iter_segments():
|
|
||||||
if _elf_segment.header.p_type == 'PT_LOAD':
|
|
||||||
_memsz = elf_segment.header.p_memsz + (_elf_segment.header.p_vaddr & (align-1))
|
|
||||||
total_size += cpu.memory._ceil(_memsz)
|
|
||||||
base = stack_base - total_size
|
base = stack_base - total_size
|
||||||
|
|
||||||
if base == 0:
|
if base == 0:
|
||||||
@ -1766,6 +1762,20 @@ class Linux(object):
|
|||||||
for reg, val in x86_defaults.iteritems():
|
for reg, val in x86_defaults.iteritems():
|
||||||
cpu.regfile.write(reg, val)
|
cpu.regfile.write(reg, val)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _interp_total_size(interp):
|
||||||
|
'''
|
||||||
|
Compute total load size of interpreter.
|
||||||
|
|
||||||
|
:param ELFFile interp: interpreter ELF .so
|
||||||
|
:return: total load size of interpreter, not aligned
|
||||||
|
:rtype: int
|
||||||
|
'''
|
||||||
|
load_segs = filter(lambda x: x.header.p_type == 'PT_LOAD', interp.iter_segments())
|
||||||
|
last = load_segs[-1]
|
||||||
|
return last.header.p_vaddr + last.header.p_memsz
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
# Symbolic versions follows
|
# Symbolic versions follows
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,9 @@ from manticore.models import linux
|
|||||||
|
|
||||||
|
|
||||||
class LinuxTest(unittest.TestCase):
|
class LinuxTest(unittest.TestCase):
|
||||||
|
'''
|
||||||
|
TODO(mark): these tests assumes /bin/ls is a dynamic x64 binary
|
||||||
|
'''
|
||||||
BIN_PATH = '/bin/ls'
|
BIN_PATH = '/bin/ls'
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -22,9 +25,6 @@ class LinuxTest(unittest.TestCase):
|
|||||||
self.assertEqual(cpu.regfile.read(reg), val)
|
self.assertEqual(cpu.regfile.read(reg), val)
|
||||||
|
|
||||||
def test_stack_init(self):
|
def test_stack_init(self):
|
||||||
'''
|
|
||||||
TODO(mark): this test assumes /bin/ls is a x64 binary
|
|
||||||
'''
|
|
||||||
argv = ['arg1', 'arg2', 'arg3']
|
argv = ['arg1', 'arg2', 'arg3']
|
||||||
real_argv = [self.BIN_PATH] + argv
|
real_argv = [self.BIN_PATH] + argv
|
||||||
envp = ['env1', 'env2', 'env3']
|
envp = ['env1', 'env2', 'env3']
|
||||||
@ -41,3 +41,19 @@ class LinuxTest(unittest.TestCase):
|
|||||||
|
|
||||||
for i, env in enumerate(envp):
|
for i, env in enumerate(envp):
|
||||||
self.assertEqual(self.linux._read_string(cpu, cpu.read_int(envp_ptr + i*8)), env)
|
self.assertEqual(self.linux._read_string(cpu, cpu.read_int(envp_ptr + i*8)), env)
|
||||||
|
|
||||||
|
def test_load_maps(self):
|
||||||
|
mappings = self.linux.current.memory.mappings()
|
||||||
|
|
||||||
|
# stack should be last
|
||||||
|
last_map = mappings[-1]
|
||||||
|
last_map_perms = last_map[2]
|
||||||
|
self.assertEqual(last_map_perms, 'rwx')
|
||||||
|
|
||||||
|
# binary should be first two
|
||||||
|
first_map, second_map = mappings[:2]
|
||||||
|
first_map_name = first_map[4]
|
||||||
|
second_map_name = second_map[4]
|
||||||
|
self.assertEqual(first_map_name, '/bin/ls')
|
||||||
|
self.assertEqual(second_map_name, '/bin/ls')
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user