ethical.blue Magazine

// Cybersecurity clarified.

Easily Debug Shellcode for Windows x64 and x86-32

2022-06-03   Dawid Farbaniec
...
Sally (Artificial Intelligence)
The injectable code called shellcode is position independent code.

Just as pentesters, red teams and threat actors write shellcodes, in opposite malware analysts, blue teams and others responsible for cybersecurity often analyze such codes under the debugger.

The BytesLauncher solution is a handy application that allows to easily run shellcode for Windows x64 and older 32-bit (x86) architecture under the debugger. This quick solution was developed when encountering shellcode in the malware sample.

BytesLauncher for Windows x64

The program was created in MASM x64 and one can use Visual Studio to build it.

extrn ExitProcess : proc

extrn VirtualProtect : proc
extrn CreateFileA : proc
extrn ReadFile : proc
extrn CloseHandle : proc

.const
GENERIC_READ equ 080000000h
OPEN_EXISTING equ 03h
PAGE_EXECUTE_READWRITE equ 40h

.data
payload db 2048 dup (90h) ;change size if you need
oldProtect dword 0
dwReadWritten dword 0
hFile dword 0
szPath db "C:\Users\x\Desktop\dump1.bin", 0

.code
Main proc
    sub rsp, 38h
    mov qword ptr [rsp + 30h], 0
    mov qword ptr [rsp + 28h], 0
    mov qword ptr [rsp + 20h], OPEN_EXISTING
    xor r9, r9
    xor r8, r8
    mov rdx, GENERIC_READ
    mov rcx, offset szPath
    call CreateFileA

    mov hFile, eax

    mov qword ptr [rsp + 20h], 0
    mov r9, offset dwReadWritten
    mov r8, sizeof payload
    mov rdx, offset payload
    mov ecx, hFile
    call ReadFile

    mov ecx, hFile
    call CloseHandle

    mov r10, sizeof payload
    mov r9, offset oldProtect
    mov r8, PAGE_EXECUTE_READWRITE
    mov rdx, r10
    mov rcx, offset payload
    call VirtualProtect

    mov rax, offset payload
    call rax

    xor rcx, rcx
    call ExitProcess
Main endp
end

BytesLauncher for Windows x86 (legacy 32-bit)

The program was created in MASM x86 (32-bit) and one can use Visual Studio or MASM32 SDK to build it.

.686p

.model flat, stdcall
option casemap:none

ExitProcess proto stdcall :dword
VirtualProtect proto stdcall :dword,:dword,:dword,:dword
CreateFileA proto stdcall :dword, :dword, :dword, :dword, :dword, :dword, :dword
ReadFile proto stdcall :dword, :dword, :dword, :dword, :dword
CloseHandle proto stdcall :dword

.const
GENERIC_READ equ 080000000h
OPEN_EXISTING equ 03h

.data
payload db 2048 dup (90h) ;change size if you need
oldProtect dword 0
dwReadWritten dword 0
hFile dword 0
szPath db "C:\Users\x\Desktop\dump1.bin", 0

.code
Main proc
    
    push 0
    push 0
    push OPEN_EXISTING
    push 0
    push 0
    push GENERIC_READ
    push offset szPath
    call CreateFileA

    mov hFile, eax

    push 0
    push offset dwReadWritten
    push sizeof payload
    push offset payload
    push eax
    call ReadFile

    push hFile
    call CloseHandle

    push offset oldProtect
    push 40h ;PAGE_EXECUTE_READWRITE
    push sizeof payload
    push offset payload
    call VirtualProtect

    mov eax, offset payload
    call eax ;execute payload bytes

    push 0
    call ExitProcess
Main endp
end

Bibliography

https://ethical.blue/download/BytesLauncher-MASM-x64.zip [access: 2022-09-24]
https://github.com/ethicalblue/BytesLauncher [access: 2022-05-23]