From e6f3de18b4f8523f06c445f38065a0b0f27e589e Mon Sep 17 00:00:00 2001 From: Dobin Date: Sun, 21 Apr 2024 15:22:47 +0100 Subject: [PATCH] feature: resolve dll imports --- app/templates/exe.html | 13 ++++++-- app/templates/project.html | 4 +++ app/views.py | 3 ++ app/views_project.py | 8 ++++- pe/dllresolver.py | 61 ++++++++++++++++++++++++++++++++++++++ tests/test_dllresolver.py | 24 +++++++++++++++ 6 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 pe/dllresolver.py create mode 100644 tests/test_dllresolver.py diff --git a/app/templates/exe.html b/app/templates/exe.html index f0a25a1..65d5979 100644 --- a/app/templates/exe.html +++ b/app/templates/exe.html @@ -14,17 +14,24 @@
{% if iat|length > 0 %} -

Imports - IAT

+ +

IAT Imports DLLs

+ + +

IAT Imports functions

{% for dll in iat %} {% endfor %} {% endif %}
-
diff --git a/app/templates/project.html b/app/templates/project.html index b01aebb..9813216 100644 --- a/app/templates/project.html +++ b/app/templates/project.html @@ -125,6 +125,10 @@ Data Section largest: {{ data_sect_largest_gap_size}}
-> Payload len: {{ payload_len}}
{{ project_dir }}
+ Unresolved dlls:
+ {% for dll in unresolved_dlls %} + {{ dll }}
+ {% endfor %} EXE INFO
diff --git a/app/views.py b/app/views.py index e63f8a5..7c1e3c2 100644 --- a/app/views.py +++ b/app/views.py @@ -6,6 +6,7 @@ from typing import List, Tuple from pe.superpe import SuperPe from model.defs import * +from pe.dllresolver import resolve_dlls views = Blueprint('views', __name__) logger = logging.getLogger("Views") @@ -20,8 +21,10 @@ def index(): def exe_view(exe_name): path = "{}/{}".format(PATH_EXES, exe_name) superpe = SuperPe(path) + return render_template('exe.html', superpe=superpe, + resolved_dlls=resolve_dlls(superpe), iat=superpe.get_iat_entries(), exports=superpe.get_exports_full(), ) diff --git a/app/views_project.py b/app/views_project.py index 97c96c7..231cc8e 100644 --- a/app/views_project.py +++ b/app/views_project.py @@ -20,8 +20,10 @@ from sender import scannerDetectsBytes from phases.injector import verify_injected_exe from helper import run_process_checkret, run_exe from model.project import prepare_project -from pe.superpe import SuperPe +from pe.superpe import SuperPe from model.exehost import ExeHost +import pe.dllresolver + logger = logging.getLogger("ViewsProjects") @@ -56,6 +58,7 @@ def project(name): data_sect_size = 0 data_sect_largest_gap_size = 0 payload_len = 0 + unresolved_dlls = [] # when we select a shellcode if project.settings.payload_path != "": @@ -73,6 +76,8 @@ def project(name): exehost = ExeHost(project.settings.inject_exe_in) exehost.init() data_sect_largest_gap_size = exehost.get_rdata_relocmanager().find_largest_gap() + unresolved_dlls = pe.dllresolver.unresolved_dlls(superpe) + project_dir = os.path.dirname(os.path.abspath(project.settings.inject_exe_out)) log_files = get_logfiles(project.settings.main_dir) @@ -109,6 +114,7 @@ def project(name): data_sect_size=data_sect_size, data_sect_largest_gap_size=data_sect_largest_gap_size, payload_len=payload_len, + unresolved_dlls=unresolved_dlls, ) def list_files_and_sizes(directory, prepend=""): diff --git a/pe/dllresolver.py b/pe/dllresolver.py new file mode 100644 index 0000000..5790b6c --- /dev/null +++ b/pe/dllresolver.py @@ -0,0 +1,61 @@ +import sys +import ctypes +import os + +from pe.superpe import SuperPe + + +class DllResolve(): + def __init__(self, dllname, cdll_res, path_res): + self.dllname = dllname + self.cdll_res = cdll_res + self.path_res = path_res + + +def all_dll_exist(superpe): + for dll_name in superpe.get_iat_entries(): + if not check_dll_availability(dll_name): + return False + return True + +def unresolved_dlls(superpe): + res = [] + for dll_name in superpe.get_iat_entries(): + if not check_dll_availability(dll_name): + res.append(dll_name) + return res + + +def resolve_dlls(superpe): + res = [] + for dll_name in superpe.get_iat_entries(): + res.append(resolve_dll(dll_name)) + return res + + +def resolve_dll(dllname): + cdll_res = check_dll_availability(dllname) + path_res = search_for_dll(dllname) + return DllResolve(dllname, cdll_res, path_res) + + +def check_dll_availability(dll_name): + try: + _ = ctypes.CDLL(dll_name) + return True + except OSError: + return False + + +def search_for_dll(dll_name): + paths = [ + os.getcwd(), # Current directory + os.environ.get('SYSTEMROOT', '') + '\\System32', # System directory + os.environ.get('SYSTEMROOT', ''), # Windows directory + ] + os.environ.get('PATH', '').split(';') # PATH directories + + for path in paths: + full_path = os.path.join(path, dll_name) + if os.path.exists(full_path): + return full_path + return None diff --git a/tests/test_dllresolver.py b/tests/test_dllresolver.py new file mode 100644 index 0000000..d40038c --- /dev/null +++ b/tests/test_dllresolver.py @@ -0,0 +1,24 @@ +from typing import List +import unittest + +from model.defs import * +from pe.superpe import SuperPe + +from pe.dllresolver import * + + +class DllResolverTest(unittest.TestCase): + + def test_dllresolver(self): + filename = "data/binary/exes/7z.exe" + superpe = SuperPe(filename) + + self.assertTrue(all_dll_exist(superpe)) + + dlls = resolve_dlls(superpe) + self.assertEqual(len(dlls), 5) + + dlls = unresolved_dlls(superpe) + self.assertEqual(len(dlls), 0) + +