mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
refactor: bix cleanup
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class FilePath(str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AllocStyle(Enum):
|
||||||
|
RWX = "rwx_1"
|
||||||
|
#RW_X = "rw_x"
|
||||||
|
#REUSE = "reuse"
|
||||||
|
|
||||||
|
class ExecStyle(Enum):
|
||||||
|
CALL = "direct_1",
|
||||||
|
#JMP = 2,
|
||||||
|
#FIBER = 3,
|
||||||
|
|
||||||
|
class DecoderStyle(Enum):
|
||||||
|
PLAIN_1 = "plain_1"
|
||||||
|
XOR_1 = "xor_1"
|
||||||
|
|
||||||
|
class DataRefStyle(Enum):
|
||||||
|
APPEND = 1
|
||||||
|
|
||||||
|
#class InjectStyle(Enum):
|
||||||
|
|
||||||
|
class SourceStyle(Enum):
|
||||||
|
peb_walk = 1
|
||||||
|
iat_reuse = 2
|
||||||
|
|
||||||
@@ -1,84 +1,18 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
import time
|
|
||||||
import shutil
|
|
||||||
import pathlib
|
import pathlib
|
||||||
import sys
|
|
||||||
import pefile
|
|
||||||
import glob
|
import glob
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from config import config
|
from config import config
|
||||||
from project import project
|
from project import project
|
||||||
from pehelper import *
|
from defs import *
|
||||||
|
|
||||||
logger = logging.getLogger("Helper")
|
logger = logging.getLogger("Helper")
|
||||||
|
|
||||||
SHC_VERIFY_SLEEP = 0.1
|
SHC_VERIFY_SLEEP = 0.1
|
||||||
|
|
||||||
|
|
||||||
verify_filename = r'C:\Temp\a'
|
|
||||||
build_dir = "build"
|
|
||||||
|
|
||||||
|
|
||||||
def remove_trailing_null_bytes(data):
|
|
||||||
for i in range(len(data) - 1, -1, -1):
|
|
||||||
if data[i] != b'\x00'[0]: # Check for a non-null byte
|
|
||||||
return data[:i + 1]
|
|
||||||
return b'' # If the entire sequence is null bytes
|
|
||||||
|
|
||||||
|
|
||||||
def get_code_section_data(pe_file):
|
|
||||||
try:
|
|
||||||
# Load the PE file
|
|
||||||
pe = pefile.PE(pe_file)
|
|
||||||
|
|
||||||
# Iterate over the sections
|
|
||||||
#for section in pe.sections:
|
|
||||||
# # Check if this is the code section
|
|
||||||
# if '.text' in section.Name.decode().rstrip('\x00'):
|
|
||||||
# data = section.get_data()
|
|
||||||
# data = remove_trailing_null_bytes(data)
|
|
||||||
# logger.info(" > 0x{:X} Code Size: {} (raw code section size: {})".format(
|
|
||||||
# section.VirtualAddress,
|
|
||||||
# len(data), section.SizeOfRawData))
|
|
||||||
# return data
|
|
||||||
|
|
||||||
section = get_code_section(pe)
|
|
||||||
if section == None:
|
|
||||||
raise Exception("Code section not found.")
|
|
||||||
|
|
||||||
logger.info("--[ Code section: {}".format(section.Name.decode().rstrip('\x00')))
|
|
||||||
data = section.get_data()
|
|
||||||
data = remove_trailing_null_bytes(data)
|
|
||||||
logger.info(" > 0x{:X} Code Size: {} (raw code section size: {})".format(
|
|
||||||
section.VirtualAddress,
|
|
||||||
len(data), section.SizeOfRawData))
|
|
||||||
return data
|
|
||||||
|
|
||||||
except FileNotFoundError:
|
|
||||||
logger.info(f"File not found: {pe_file}")
|
|
||||||
except pefile.PEFormatError:
|
|
||||||
logger.info(f"Invalid PE file: {pe_file}")
|
|
||||||
|
|
||||||
|
|
||||||
def write_code_section(pe_file, new_data):
|
|
||||||
# Load the PE file
|
|
||||||
pe = pefile.PE(pe_file)
|
|
||||||
|
|
||||||
# Iterate over the sections
|
|
||||||
for section in pe.sections:
|
|
||||||
# Check if this is the code section
|
|
||||||
if '.text' in section.Name.decode().rstrip('\x00'):
|
|
||||||
file_offset = section.PointerToRawData
|
|
||||||
|
|
||||||
with open(pe_file, 'r+b') as f:
|
|
||||||
f.seek(file_offset)
|
|
||||||
f.write(new_data)
|
|
||||||
#logger.info("Successfully overwritten the .text section with new data.")
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
def clean_files():
|
def clean_files():
|
||||||
logger.info("--[ Remove old files")
|
logger.info("--[ Remove old files")
|
||||||
|
|
||||||
@@ -89,13 +23,13 @@ def clean_files():
|
|||||||
"mllink$.lnk",
|
"mllink$.lnk",
|
||||||
|
|
||||||
# out/ stuff
|
# out/ stuff
|
||||||
os.path.join(build_dir, "main.asm"),
|
os.path.join(project.build_dir, "main.asm"),
|
||||||
os.path.join(build_dir, "main.bin"),
|
os.path.join(project.build_dir, "main.bin"),
|
||||||
os.path.join(build_dir, "main.c"),
|
os.path.join(project.build_dir, "main.c"),
|
||||||
os.path.join(build_dir, "peb_lookup.h"),
|
os.path.join(project.build_dir, "peb_lookup.h"),
|
||||||
#os.path.join(build_dir, "main.exe"),
|
#os.path.join(project.build_dir, "main.exe"),
|
||||||
|
|
||||||
verify_filename,
|
project.verify_filename,
|
||||||
]
|
]
|
||||||
for file in files_to_clean:
|
for file in files_to_clean:
|
||||||
pathlib.Path(file).unlink(missing_ok=True)
|
pathlib.Path(file).unlink(missing_ok=True)
|
||||||
@@ -133,7 +67,7 @@ def try_start_shellcode(shc_file):
|
|||||||
subprocess.run([
|
subprocess.run([
|
||||||
config.get["path_runshc"],
|
config.get["path_runshc"],
|
||||||
shc_file,
|
shc_file,
|
||||||
]) # , check=True
|
])
|
||||||
|
|
||||||
|
|
||||||
def file_readall_text(filepath) -> str:
|
def file_readall_text(filepath) -> str:
|
||||||
@@ -155,4 +89,4 @@ def delete_all_files_in_directory(directory_path):
|
|||||||
os.remove(file_path)
|
os.remove(file_path)
|
||||||
#logger.info(f"Deleted {file_path}")
|
#logger.info(f"Deleted {file_path}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f"Error deleting {file_path}: {e}")
|
logger.info(f"Error deleting {file_path}: {e}")
|
||||||
|
|||||||
@@ -1,40 +1,12 @@
|
|||||||
from typing import Dict
|
from typing import Dict
|
||||||
import pehelper
|
|
||||||
import pefile
|
|
||||||
from enum import Enum
|
|
||||||
import logging
|
import logging
|
||||||
|
import pefile
|
||||||
|
|
||||||
|
import pehelper
|
||||||
|
|
||||||
logger = logging.getLogger("Model")
|
logger = logging.getLogger("Model")
|
||||||
|
|
||||||
|
|
||||||
class FilePath(str):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AllocStyle(Enum):
|
|
||||||
RWX = "rwx_1"
|
|
||||||
#RW_X = "rw_x"
|
|
||||||
#REUSE = "reuse"
|
|
||||||
|
|
||||||
class ExecStyle(Enum):
|
|
||||||
CALL = "direct_1",
|
|
||||||
#JMP = 2,
|
|
||||||
#FIBER = 3,
|
|
||||||
|
|
||||||
class DecoderStyle(Enum):
|
|
||||||
PLAIN_1 = "plain_1"
|
|
||||||
XOR_1 = "xor_1"
|
|
||||||
|
|
||||||
class DataRefStyle(Enum):
|
|
||||||
APPEND = 1
|
|
||||||
|
|
||||||
#class InjectStyle(Enum):
|
|
||||||
|
|
||||||
class SourceStyle(Enum):
|
|
||||||
peb_walk = 1
|
|
||||||
iat_reuse = 2
|
|
||||||
|
|
||||||
|
|
||||||
class Capability():
|
class Capability():
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|||||||
+35
-23
@@ -5,38 +5,50 @@ from keystone import Ks, KS_ARCH_X86, KS_MODE_64
|
|||||||
from capstone import Cs, CS_ARCH_X86, CS_MODE_64
|
from capstone import Cs, CS_ARCH_X86, CS_MODE_64
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from model import *
|
||||||
|
from helper import *
|
||||||
|
|
||||||
logger = logging.getLogger("PEHelper")
|
logger = logging.getLogger("PEHelper")
|
||||||
|
|
||||||
|
|
||||||
def get_code_section(pe):
|
def extract_code_from_exe(exe_file: FilePath) -> bytes:
|
||||||
|
pe = pefile.PE(exe_file)
|
||||||
|
section = get_code_section(pe)
|
||||||
|
logger.info("--[ Code section: {}".format(section.Name.decode().rstrip('\x00')))
|
||||||
|
data: bytes = section.get_data()
|
||||||
|
data = remove_trailing_null_bytes(data)
|
||||||
|
logger.info(" > 0x{:X} Code Size: {} (raw code section size: {})".format(
|
||||||
|
section.VirtualAddress,
|
||||||
|
len(data), section.SizeOfRawData))
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def write_code_section(exe_file: FilePath, new_data: bytes):
|
||||||
|
pe = pefile.PE(exe_file)
|
||||||
|
section = get_code_section(pe)
|
||||||
|
file_offset = section.PointerToRawData
|
||||||
|
with open(exe_file, 'r+b') as f:
|
||||||
|
f.seek(file_offset)
|
||||||
|
f.write(new_data)
|
||||||
|
|
||||||
|
|
||||||
|
def get_code_section(pe) -> pefile.SectionStructure:
|
||||||
entrypoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint
|
entrypoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint
|
||||||
|
|
||||||
for sect in pe.sections:
|
for sect in pe.sections:
|
||||||
name = sect.Name.decode()
|
|
||||||
#logger.info("Checking: {} and 0x{:x}".format(name, sect.Characteristics))
|
|
||||||
|
|
||||||
if sect.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_EXECUTE']:
|
if sect.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_EXECUTE']:
|
||||||
if entrypoint >= sect.VirtualAddress and entrypoint <= sect.VirtualAddress + sect.SizeOfRawData:
|
if entrypoint >= sect.VirtualAddress and entrypoint <= sect.VirtualAddress + sect.SizeOfRawData:
|
||||||
return sect
|
return sect
|
||||||
#else:
|
raise Exception("Code section not found")
|
||||||
# logger.info("NOOO: 0x{:x} 0x{:x} 0x{:x}".format(
|
|
||||||
# entrypoint,
|
|
||||||
# sect.VirtualAddress,
|
|
||||||
# sect.VirtualAddress + sect.SizeOfRawData,
|
|
||||||
# ))
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# RWX
|
# RWX
|
||||||
def get_rwx_section(pe):
|
def get_rwx_section(pe: pefile.PE) -> pefile.SectionStructure:
|
||||||
entrypoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint
|
entrypoint = pe.OPTIONAL_HEADER.AddressOfEntryPoint
|
||||||
for section in pe.sections:
|
for section in pe.sections:
|
||||||
if (section.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_READ'] and
|
if (section.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_READ'] and
|
||||||
section.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_WRITE'] and
|
section.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_WRITE'] and
|
||||||
section.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_EXECUTE']
|
section.Characteristics & pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_MEM_EXECUTE']
|
||||||
):
|
):
|
||||||
#name = section.Name.decode().rstrip('\x00')
|
|
||||||
if entrypoint > section.VirtualAddress and entrypoint < section.VirtualAddress + section.SizeOfRawData:
|
if entrypoint > section.VirtualAddress and entrypoint < section.VirtualAddress + section.SizeOfRawData:
|
||||||
return section
|
return section
|
||||||
return None
|
return None
|
||||||
@@ -44,7 +56,7 @@ def get_rwx_section(pe):
|
|||||||
|
|
||||||
# keystone/capstone stuff
|
# keystone/capstone stuff
|
||||||
|
|
||||||
def assemble_and_disassemble_jump(current_address, destination_address):
|
def assemble_and_disassemble_jump(current_address: int, destination_address: int) -> bytes:
|
||||||
#logger.info(" Make jmp from 0x{:X} to 0x{:X}".format(
|
#logger.info(" Make jmp from 0x{:X} to 0x{:X}".format(
|
||||||
# current_address, destination_address
|
# current_address, destination_address
|
||||||
#))
|
#))
|
||||||
@@ -67,7 +79,7 @@ def assemble_and_disassemble_jump(current_address, destination_address):
|
|||||||
|
|
||||||
# IAT Stuff
|
# IAT Stuff
|
||||||
|
|
||||||
def extract_iat(pe):
|
def extract_iat(pe: pefile.PE):
|
||||||
iat = {}
|
iat = {}
|
||||||
|
|
||||||
# If the PE file was loaded using the fast_load=True argument, we will need to parse the data directories:
|
# If the PE file was loaded using the fast_load=True argument, we will need to parse the data directories:
|
||||||
@@ -109,10 +121,10 @@ def resolve_iat_capabilities(needed_capabilities, inject_exe):
|
|||||||
cap.addr = get_addr_for(iat, cap.name)
|
cap.addr = get_addr_for(iat, cap.name)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
## Utils
|
||||||
pe = pefile.PE(sys.argv[1])
|
|
||||||
iat = extract_iat(pe)
|
|
||||||
|
|
||||||
|
def remove_trailing_null_bytes(data: bytes) -> bytes:
|
||||||
if __name__ == "__main__":
|
for i in range(len(data) - 1, -1, -1):
|
||||||
main()
|
if data[i] != b'\x00'[0]: # Check for a non-null byte
|
||||||
|
return data[:i + 1]
|
||||||
|
return b'' # If the entire sequence is null bytes
|
||||||
|
|||||||
+13
-16
@@ -8,37 +8,34 @@ from config import config
|
|||||||
from observer import observer
|
from observer import observer
|
||||||
from project import project
|
from project import project
|
||||||
from helper import *
|
from helper import *
|
||||||
|
from pehelper import *
|
||||||
|
|
||||||
logger = logging.getLogger("Assembler")
|
logger = logging.getLogger("Assembler")
|
||||||
|
|
||||||
def make_shc_from_asm(asm_file, exe_file, shc_file):
|
|
||||||
logger.info("--[ Assemble to exe: {} -> {} -> {}".format(asm_file, exe_file, shc_file))
|
|
||||||
|
|
||||||
logger.info("---[ Assemble ASM to EXE: {} -> {}".format(asm_file, exe_file))
|
def asm_to_shellcode(asm_in: FilePath, build_exe: FilePath, shellcode_out: FilePath):
|
||||||
|
"""Takes ASM source file asm_in, compiles it into build_exe, extracts its code section and write into shellcode_out"""
|
||||||
|
logger.info("--[ Assemble to exe: {} -> {} -> {}".format(asm_in, build_exe, shellcode_out))
|
||||||
run_process_checkret([
|
run_process_checkret([
|
||||||
config.get("path_ml64"),
|
config.get("path_ml64"),
|
||||||
asm_file,
|
asm_in,
|
||||||
"/link",
|
"/link",
|
||||||
"/OUT:{}".format(exe_file),
|
"/OUT:{}".format(build_exe),
|
||||||
"/entry:AlignRSP"
|
"/entry:AlignRSP"
|
||||||
])
|
])
|
||||||
if not os.path.isfile(exe_file):
|
if not os.path.isfile(build_exe):
|
||||||
logger.error("Error")
|
logger.error("Error")
|
||||||
return
|
return
|
||||||
|
code = extract_code_from_exe(build_exe)
|
||||||
logger.info("---[ EXE to SHC: {} -> {} ".format(exe_file, shc_file))
|
with open(shellcode_out, 'wb') as f:
|
||||||
code = get_code_section_data(exe_file)
|
|
||||||
with open(shc_file, 'wb') as f:
|
|
||||||
f.write(code)
|
f.write(code)
|
||||||
|
|
||||||
return code
|
return code
|
||||||
#logger.info("---[ Shellcode from {} written to: {} (size: {}) ".format(exe_file, shc_file, len(code)))
|
|
||||||
|
|
||||||
|
|
||||||
def merge_loader_payload(main_shc_file):
|
def merge_loader_payload(shellcode_in: FilePath, shellcode_out: FilePath, payload: FilePath, decoder_style: DecoderStyle):
|
||||||
logger.info("--[ Merge stager: {} + {} -> {}".format(
|
logger.info("--[ Merge stager: {} + {} -> {}".format(
|
||||||
main_shc_file, project.payload, main_shc_file))
|
shellcode_in, project.payload, shellcode_out))
|
||||||
with open(main_shc_file, 'rb') as input1:
|
with open(shellcode_in, 'rb') as input1:
|
||||||
data_stager = input1.read()
|
data_stager = input1.read()
|
||||||
with open(project.payload, 'rb') as input2:
|
with open(project.payload, 'rb') as input2:
|
||||||
data_payload = input2.read()
|
data_payload = input2.read()
|
||||||
@@ -53,7 +50,7 @@ def merge_loader_payload(main_shc_file):
|
|||||||
logger.info("---[ Size: Stager: {} and Payload: {} Sum: {} ".format(
|
logger.info("---[ Size: Stager: {} and Payload: {} Sum: {} ".format(
|
||||||
len(data_stager), len(data_payload), len(data_stager)+len(data_payload)))
|
len(data_stager), len(data_payload), len(data_stager)+len(data_payload)))
|
||||||
|
|
||||||
with open(main_shc_file, 'wb') as output:
|
with open(shellcode_out, 'wb') as output:
|
||||||
data = data_stager + data_payload
|
data = data_stager + data_payload
|
||||||
output.write(data)
|
output.write(data)
|
||||||
observer.add_code("final_shellcode", data)
|
observer.add_code("final_shellcode", data)
|
||||||
|
|||||||
+4
-3
@@ -1,10 +1,11 @@
|
|||||||
from helper import *
|
|
||||||
from config import config
|
|
||||||
import os
|
import os
|
||||||
import pprint
|
import pprint
|
||||||
from observer import observer
|
|
||||||
import logging
|
import logging
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
from helper import *
|
||||||
|
from config import config
|
||||||
|
from observer import observer
|
||||||
from project import project
|
from project import project
|
||||||
from model import *
|
from model import *
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -2,6 +2,7 @@ from helper import *
|
|||||||
import shutil
|
import shutil
|
||||||
import pprint
|
import pprint
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
from pehelper import *
|
from pehelper import *
|
||||||
from model import *
|
from model import *
|
||||||
@@ -36,7 +37,7 @@ def inject_exe(shc_file: FilePath):
|
|||||||
# and re-implant it
|
# and re-implant it
|
||||||
if project.source_style == SourceStyle.iat_reuse:
|
if project.source_style == SourceStyle.iat_reuse:
|
||||||
# get code section of exe_out
|
# get code section of exe_out
|
||||||
code = get_code_section_data(exe_out)
|
code = extract_code_from_exe(exe_out)
|
||||||
for cap in exe_capabilities.get_all().values():
|
for cap in exe_capabilities.get_all().values():
|
||||||
if not cap.id in code:
|
if not cap.id in code:
|
||||||
logger.error("Capability ID {} not found, abort".format(cap.id))
|
logger.error("Capability ID {} not found, abort".format(cap.id))
|
||||||
@@ -58,16 +59,16 @@ def inject_exe(shc_file: FilePath):
|
|||||||
def verify_injected_exe(exefile):
|
def verify_injected_exe(exefile):
|
||||||
logger.info("---[ Verify infected exe: {} ".format(exefile))
|
logger.info("---[ Verify infected exe: {} ".format(exefile))
|
||||||
# remove indicator file
|
# remove indicator file
|
||||||
pathlib.Path(verify_filename).unlink(missing_ok=True)
|
pathlib.Path(project.verify_filename).unlink(missing_ok=True)
|
||||||
|
|
||||||
run_process_checkret([
|
run_process_checkret([
|
||||||
exefile,
|
exefile,
|
||||||
], check=False)
|
], check=False)
|
||||||
time.sleep(SHC_VERIFY_SLEEP)
|
time.sleep(SHC_VERIFY_SLEEP)
|
||||||
if os.path.isfile(verify_filename):
|
if os.path.isfile(project.verify_filename):
|
||||||
logger.info("---> Verify OK. Infected exe works (file was created)")
|
logger.info("---> Verify OK. Infected exe works (file was created)")
|
||||||
# better to remove it immediately
|
# better to remove it immediately
|
||||||
os.remove(verify_filename)
|
os.remove(project.verify_filename)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logger.error("---> Verify FAIL. Infected exe does not work (no file created)")
|
logger.error("---> Verify FAIL. Infected exe does not work (no file created)")
|
||||||
|
|||||||
+4
-1
@@ -1,5 +1,5 @@
|
|||||||
from model import *
|
from model import *
|
||||||
|
from defs import *
|
||||||
|
|
||||||
class Project():
|
class Project():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -32,5 +32,8 @@ class Project():
|
|||||||
self.generate_asm_from_c: bool = True
|
self.generate_asm_from_c: bool = True
|
||||||
self.generate_shc_from_asm: bool = True
|
self.generate_shc_from_asm: bool = True
|
||||||
|
|
||||||
|
self.verify_filename = r'C:\Temp\a'
|
||||||
|
self.build_dir = "build"
|
||||||
|
|
||||||
|
|
||||||
project = Project()
|
project = Project()
|
||||||
|
|||||||
+22
-14
@@ -1,14 +1,15 @@
|
|||||||
import shutil
|
import shutil
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from helper import *
|
|
||||||
import argparse
|
import argparse
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
import pickle
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
|
from defs import *
|
||||||
from model import *
|
from model import *
|
||||||
|
from helper import *
|
||||||
from config import config
|
from config import config
|
||||||
from pehelper import *
|
|
||||||
import phases.templater
|
import phases.templater
|
||||||
import phases.compiler
|
import phases.compiler
|
||||||
import phases.assembler
|
import phases.assembler
|
||||||
@@ -16,10 +17,10 @@ import phases.injector
|
|||||||
from observer import observer
|
from observer import observer
|
||||||
from project import project
|
from project import project
|
||||||
|
|
||||||
main_c_file = os.path.join(build_dir, "main.c")
|
main_c_file = os.path.join(project.build_dir, "main.c")
|
||||||
main_asm_file = os.path.join(build_dir, "main.asm")
|
main_asm_file = os.path.join(project.build_dir, "main.asm")
|
||||||
main_exe_file = os.path.join(build_dir, "main.exe")
|
main_exe_file = os.path.join(project.build_dir, "main.exe")
|
||||||
main_shc_file = os.path.join(build_dir, "main.bin")
|
main_shc_file = os.path.join(project.build_dir, "main.bin")
|
||||||
|
|
||||||
|
|
||||||
# ANSI escape sequences for colors
|
# ANSI escape sequences for colors
|
||||||
@@ -178,7 +179,10 @@ def start():
|
|||||||
|
|
||||||
# Convert: ASM -> Shellcode
|
# Convert: ASM -> Shellcode
|
||||||
if project.generate_shc_from_asm:
|
if project.generate_shc_from_asm:
|
||||||
code = phases.assembler.make_shc_from_asm(main_asm_file, main_exe_file, main_shc_file)
|
code = phases.assembler.asm_to_shellcode(
|
||||||
|
asm_in = main_asm_file,
|
||||||
|
build_exe = main_exe_file,
|
||||||
|
shellcode_out = main_shc_file)
|
||||||
observer.add_code("generate_shc_from_asm", code)
|
observer.add_code("generate_shc_from_asm", code)
|
||||||
|
|
||||||
# Try: Starting the shellcode (rarely useful)
|
# Try: Starting the shellcode (rarely useful)
|
||||||
@@ -187,7 +191,11 @@ def start():
|
|||||||
|
|
||||||
# Merge shellcode/loader with payload
|
# Merge shellcode/loader with payload
|
||||||
if project.dataref_style == DataRefStyle.APPEND:
|
if project.dataref_style == DataRefStyle.APPEND:
|
||||||
phases.assembler.merge_loader_payload(main_shc_file)
|
phases.assembler.merge_loader_payload(
|
||||||
|
shellcode_in = main_shc_file,
|
||||||
|
shellcode_out = main_shc_file,
|
||||||
|
payload = project.payload,
|
||||||
|
decoder_style = project.decoder_style)
|
||||||
|
|
||||||
if project.verify and project.source_style == SourceStyle.peb_walk:
|
if project.verify and project.source_style == SourceStyle.peb_walk:
|
||||||
logger.info("--[ Verify final shellcode")
|
logger.info("--[ Verify final shellcode")
|
||||||
@@ -275,21 +283,21 @@ def verify_shellcode(shc_name):
|
|||||||
logger.info("---[ Verify shellcode: {}".format(shc_name))
|
logger.info("---[ Verify shellcode: {}".format(shc_name))
|
||||||
|
|
||||||
# check if directory exists
|
# check if directory exists
|
||||||
if not os.path.exists(os.path.dirname(verify_filename)):
|
if not os.path.exists(os.path.dirname(project.verify_filename)):
|
||||||
logger.info("Error, directory does not exist for: {}".format(verify_filename))
|
logger.info("Error, directory does not exist for: {}".format(project.verify_filename))
|
||||||
return
|
return
|
||||||
|
|
||||||
# remove indicator file
|
# remove indicator file
|
||||||
pathlib.Path(verify_filename).unlink(missing_ok=True)
|
pathlib.Path(project.verify_filename).unlink(missing_ok=True)
|
||||||
|
|
||||||
run_process_checkret([
|
run_process_checkret([
|
||||||
config.get("path_runshc"),
|
config.get("path_runshc"),
|
||||||
"{}".format(shc_name),
|
"{}".format(shc_name),
|
||||||
], check=False)
|
], check=False)
|
||||||
time.sleep(SHC_VERIFY_SLEEP)
|
time.sleep(SHC_VERIFY_SLEEP)
|
||||||
if os.path.isfile(verify_filename):
|
if os.path.isfile(project.verify_filename):
|
||||||
logger.info("---> Verify OK. Shellcode works (file was created)")
|
logger.info("---> Verify OK. Shellcode works (file was created)")
|
||||||
os.remove(verify_filename)
|
os.remove(project.verify_filename)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logger.info("---> Verify FAIL. Shellcode doesnt work (file was not created)")
|
logger.info("---> Verify FAIL. Shellcode doesnt work (file was not created)")
|
||||||
|
|||||||
Reference in New Issue
Block a user