Skip to content

Commit

Permalink
Refactor module loader
Browse files Browse the repository at this point in the history
  • Loading branch information
serpilliere committed Oct 30, 2020
1 parent 9dd500f commit 4f8db1e
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 439 deletions.
1 change: 1 addition & 0 deletions example/jitter/run_with_linuxenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
ld_path = linux_env.filesystem.resolve_path(ld_path)
cont_ld = Container.from_stream(
open(ld_path, "rb"),
loc_db=loc_db,
vm=jitter.vm,
addr=0x80000000,
apply_reloc=True
Expand Down
4 changes: 3 additions & 1 deletion example/jitter/unpack_upx.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ def kernel32_GetProcAddress(jitter):

# Get the generated address of the library, and store it in memory to
# dst_ad
ad = sb.loader.lib_get_add_func(args.libbase, fname, dst_ad)
#ad = sb.loader.lib_get_add_func(args.libbase, fname, dst_ad)
name = sb.loader.module_base_address_to_name[args.libbase]
ad = sb.loader.resolve_function(name, fname, dst_ad=dst_ad)
# Add a breakpoint in case of a call on the resolved function
# NOTE: never happens in UPX, just for skeleton
jitter.handle_function(ad)
Expand Down
4 changes: 2 additions & 2 deletions miasm/analysis/dse.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,14 @@ def add_lib_handler(self, loader, namespace):

# lambda cannot contain statement
def default_func(dse):
fname = loader.fad2cname[dse.jitter.pc]
fname = loader.module_base_address_to_name(dse.jitter.pc)
if isinstance(fname, tuple):
fname = b"%s_%d_symb" % (force_bytes(fname[0]), fname[1])
else:
fname = b"%s_symb" % force_bytes(fname)
raise RuntimeError("Symbolic stub '%s' not found" % fname)

for addr, fname in viewitems(loader.fad2cname):
for addr, fname in viewitems(loader.function_address_to_canonical_name):
if isinstance(fname, tuple):
fname = b"%s_%d_symb" % (force_bytes(fname[0]), fname[1])
else:
Expand Down
70 changes: 8 additions & 62 deletions miasm/analysis/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def init_loader(self, options):
loader_start_address = int(options.loader_start_address, 0)
else:
loader_start_address = None
loader = LoaderWindows(loader_start_address=loader_start_address)
loader = LoaderWindows(self.jitter.vm, loader_start_address=loader_start_address)
self.loader = loader
winobjs.loader = loader

Expand All @@ -242,60 +242,19 @@ def use_windows_structs(self):
win_api_x86_32_seh.main_pe_name = self.fname_basename
win_api_x86_32_seh.main_pe = self.pe
win_api_x86_32.winobjs.hcurmodule = self.pe.NThdr.ImageBase
win_api_x86_32_seh.name2module = self.name2module
win_api_x86_32_seh.name2module = self.loader.module_name_to_module
win_api_x86_32_seh.set_win_fs_0(self.jitter)
win_api_x86_32_seh.init_seh(self.jitter)

def load_main_pe(self, options):
from miasm.jitter.loader.pe import vm_load_pe
from miasm.os_dep.win_api_x86_32 import winobjs

self.name2module = {}

# Load main pe
with open(options.filename, "rb") as fstream:
self.pe = vm_load_pe(
self.jitter.vm,
fstream.read(),
load_hdr=options.load_hdr,
name=options.filename,
winobjs=winobjs,
)
self.name2module[self.fname_basename] = self.pe
module_image_base = self.loader.load_module(options.filename)
name = self.loader.module_base_address_to_name[module_image_base]
self.pe = self.loader.module_name_to_module[name]
winobjs.current_pe = self.pe

def load_base_dll(self):
from miasm.os_dep.win_api_x86_32 import winobjs
from miasm.jitter.loader.pe import vm_load_pe_libs, fix_pe_imports

# Load libs in memory
self.name2module.update(
vm_load_pe_libs(
self.jitter.vm,
self.LOADED_DLLS,
self.loader,
self.PATH_DLLS,
winobjs=winobjs,
)
)

# Patch libs imports
for name, pe in self.name2module.items():
fix_pe_imports(self.jitter.vm, pe, self.loader, pe_name=name)

def load_dependencies(self):
from miasm.os_dep.win_api_x86_32 import winobjs
from miasm.jitter.loader.pe import vm_load_pe_and_dependencies

vm_load_pe_and_dependencies(
self.jitter.vm,
self.fname_basename,
self.name2module,
self.loader,
self.PATH_DLLS,
winobjs=winobjs,
)

def set_call_handler(self, custom_methods):
# Library calls handler
from miasm.os_dep import win_api_x86_32
Expand All @@ -306,27 +265,14 @@ def set_call_handler(self, custom_methods):
methods.update(custom_methods)
self.jitter.add_lib_handler(self.loader, methods)

def fix_pe_imports(self):
# Fix pe imports
from miasm.jitter.loader.pe import fix_pe_imports

fix_pe_imports(
self.jitter.vm, self.pe, self.loader, pe_name=self.fname_basename
)

def __init__(self, jitter, options, custom_methods=None):
self.fname_basename = os.path.basename(options.filename).lower()
self.jitter = jitter

self.init_stack()
self.init_loader(options)
self.load_main_pe(options)
if options.loadbasedll:
self.load_base_dll()
if options.dependencies:
self.load_dependencies()

self.fix_pe_imports()
self.set_call_handler(custom_methods)

# Manage SEH
Expand Down Expand Up @@ -419,7 +365,7 @@ def init_loader(self, options):
loader_start_address = int(options.loader_start_address, 0)
else:
loader_start_address = None
loader = LoaderWindows(apiset=apiset, loader_start_address=loader_start_address)
loader = LoaderWindows(self.jitter.vm, apiset=apiset, loader_start_address=loader_start_address)
self.loader = loader
winobjs.loader = loader

Expand Down Expand Up @@ -503,7 +449,7 @@ def __init__(self, jitter, options, custom_methods=None):
self.jitter.init_stack()

# Import manager
self.loader = LoaderUnix()
self.loader = LoaderUnix(self.jitter.vm)

with open(options.filename, "rb") as fstream:
self.elf = vm_load_elf(
Expand Down Expand Up @@ -562,7 +508,7 @@ def __init__(self, jitter, options, custom_methods=None):
self.jitter.init_stack()

# Import manager
self.loader = LoaderUnix()
self.loader = LoaderUnix(self.jitter.vm)

data = open(options.filename, "rb").read()
options.load_base_addr = int(options.load_base_addr, 0)
Expand Down
12 changes: 6 additions & 6 deletions miasm/jitter/jitload.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ def handle_lib(jitter):
"""Resolve the name of the function which cause the handler call. Then
call the corresponding handler from users callback.
"""
fname = jitter.libs.fad2cname[jitter.pc]
fname = jitter.loader.function_address_to_canonical_name[jitter.pc]
if fname in jitter.user_globals:
func = jitter.user_globals[fname]
else:
Expand All @@ -510,21 +510,21 @@ def handle_function(self, f_addr):
"""Add a breakpoint which will trigger the function handler"""
self.add_breakpoint(f_addr, self.handle_lib)

def add_lib_handler(self, libs, user_globals=None):
"""Add a function to handle libs call with breakpoints
@libs: libimp instance
def add_lib_handler(self, loader, user_globals=None):
"""Add a function to handle loader call with breakpoints
@loader: Loader instance
@user_globals: dictionary for defined user function
"""
if user_globals is None:
user_globals = {}

self.libs = libs
self.loader = loader
out = {}
for name, func in viewitems(user_globals):
out[name] = func
self.user_globals = out

for f_addr in libs.fad2cname:
for f_addr in loader.function_address_to_canonical_name:
self.handle_function(f_addr)

def eval_expr(self, expr):
Expand Down
14 changes: 12 additions & 2 deletions miasm/jitter/loader/elf.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def preload_elf(vm, e, loader, patch_vm_imp=True, loc_db=None):
continue
for ad in ads:
ad_base_lib = loader.lib_get_add_base(libname)
ad_libfunc = loader.lib_get_add_func(ad_base_lib, libfunc, ad)
ad_libfunc = loader.resolve_function(vm, ad_base_lib, libfunc, ad)

libname_s = canon_libname_libfunc(libname, libfunc)
dyn_funcs[libname_s] = ad_libfunc
Expand Down Expand Up @@ -317,7 +317,17 @@ def vm_load_elf(vm, fdata, name="", base_addr=0, loc_db=None, apply_reloc=False,


class LoaderUnix(Loader):
pass

def lib_get_add_base(self, name):
name = name.lower().strip(' ')
if name in self.module_name_to_base_address:
ad = self.module_name_to_base_address[name]
else:
ad = self.fake_library_entry(name)
return ad

def resolve_function(self, vm, libad, imp_ord_or_name, dst_ad=None):
return self.fake_resolve_function(libad, imp_ord_or_name, dst_ad=dst_ad)


class libimp_elf(LoaderUnix):
Expand Down
Loading

0 comments on commit 4f8db1e

Please sign in to comment.