Skip to content

Commit

Permalink
增加exe导入表检查
Browse files Browse the repository at this point in the history
  • Loading branch information
qux-bbb committed Sep 9, 2023
1 parent bccaea0 commit 3478f85
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
18 changes: 18 additions & 0 deletions tests/test_exe_import_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pathlib import Path
from xanalyzer.file import FileAnalyzer
from xanalyzer.file_process.pe import PeAnalyzer

cur_dir_path = Path(__file__).parent


def test_exe_import_api():
pe_path = cur_dir_path / "test_data" / "Hello_upx.exe_"
file_analyzer = FileAnalyzer(pe_path)
pe_analyzer = PeAnalyzer(file_analyzer)
exe_import_api_list = pe_analyzer.get_exe_import_api_list()
assert exe_import_api_list == [
"KERNEL32.LoadLibraryA",
"KERNEL32.ExitProcess",
"KERNEL32.GetProcAddress",
"KERNEL32.VirtualProtect",
]
39 changes: 39 additions & 0 deletions xanalyzer/file_process/pe.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ def get_dll_name(self):
return self.pe_file.DIRECTORY_ENTRY_EXPORT.name
return

def get_exe_import_api_list(self, lower_flag=False):
exe_import_api_list = []
directory_entry_import = self.pe_file.DIRECTORY_ENTRY_IMPORT
for entry_import in directory_entry_import:
dll_name = entry_import.dll.decode()
dll_base_name = dll_name
if dll_name.lower().endswith(".dll"):
dll_base_name = dll_name[:-4]
for the_api in entry_import.imports:
if hasattr(the_api, "name"):
api_name = the_api.name.decode()
item_name = f"{dll_base_name}.{api_name}"
if lower_flag:
item_name = item_name.lower()
exe_import_api_list.append(item_name)
return exe_import_api_list

def get_packer_result(self):
matches = self.peid_signatures.match(self.pe_file, ep_only=True)

Expand Down Expand Up @@ -349,6 +366,27 @@ def cert_scan(self):
else:
log.warning(" Verify result: {}".format(verify_result))

def exe_import_api_scan(self):
if self.file_analyzer.possible_extension_names != [".exe"]:
return
exe_import_api_list = self.get_exe_import_api_list(lower_flag=True)
api_num = len(exe_import_api_list)
if api_num == 0:
log.warning("the exe does not have import api")
elif api_num == 1:
the_api = exe_import_api_list[0]
if the_api.startswith("kernel32.loadlibrary"):
log.warning(f"the exe only has 1 import api: {the_api}")
elif api_num == 2:
if "kernel32.getprocaddress" in exe_import_api_list:
warning_flag = False
for the_api in exe_import_api_list:
if the_api != "kernel32.getprocaddress" and the_api.startswith("kernel32.loadlibrary"):
warning_flag = True
break
if warning_flag:
log.warning(f"the exe only has 2 import api: {exe_import_api_list}")

def resource_scan(self):
"""
检查资源类型
Expand All @@ -375,4 +413,5 @@ def run(self):
self.section_name_scan()
self.dll_name_scan()
self.packer_scan()
self.exe_import_api_scan()
self.resource_scan()

0 comments on commit 3478f85

Please sign in to comment.