mirror of
https://github.com/d35ha/PE2Shellcode
synced 2026-06-08 13:42:58 +00:00
265 lines
7.2 KiB
NASM
265 lines
7.2 KiB
NASM
bits 64
|
|
%include "stub_x64.inc"
|
|
|
|
Init:
|
|
sub rsp, 28h
|
|
gs mov rax, qword [TEB_PPEB_OFFSET]
|
|
mov rax, qword [rax + PEB_PLDR_OFFSET]
|
|
mov rsi, qword [rax + LDR_PIN_ORDER_MOD_LIST_OFFSET]
|
|
lodsq
|
|
xchg rax, rsi
|
|
lodsq
|
|
mov rbp, qword [rax + LDR_MODULE_BASE_OFFSET]
|
|
mov eax, dword [rbp + IMAGE_DOS_HEADER_LFANEW_OFFSET]
|
|
mov ebx, dword [rbp + rax + IMAGE_NT_HEADER_ENTRY_EXPORT_OFFSET]
|
|
add rbx, rbp
|
|
mov esi, [rbx + EXPORT_TABLE_ADDR_OF_NAMES_OFFSET]
|
|
add rsi, rbp
|
|
xor rcx, rcx
|
|
FindGetProcAddr:
|
|
inc rcx
|
|
lodsd
|
|
add rax, rbp
|
|
cmp dword [rax], STRING_OF_GETP
|
|
jnz FindGetProcAddr
|
|
cmp dword [rax + 0x4], STRING_OF_ROCA
|
|
jnz FindGetProcAddr
|
|
cmp dword [rax + 0x8], STRING_OF_DDRE
|
|
jnz FindGetProcAddr
|
|
mov esi, [rbx + EXPORT_TABLE_ADDR_OF_ORDINALS_OFFSET]
|
|
add rsi, rbp
|
|
mov cx, [rsi + rcx*2]
|
|
dec rcx
|
|
mov esi, [rbx + EXPORT_TABLE_ADDR_OF_FUNCTIONS_OFFSET]
|
|
add rsi, rbp
|
|
mov edi, [rsi + rcx*4]
|
|
add rdi, rbp
|
|
jmp GetPERawBase
|
|
PERawBase:
|
|
pop r15
|
|
mov rsi, r15
|
|
mov eax, dword [rsi + IMAGE_DOS_HEADER_LFANEW_OFFSET]
|
|
add rsi, rax
|
|
call VirtualAlloc
|
|
db 'VirtualAlloc', 0h
|
|
VirtualAlloc:
|
|
pop rdx
|
|
mov rcx, rbp
|
|
call rdi
|
|
mov r12, rax
|
|
mov r9, PAGE_EXECUTE_READWRITE
|
|
mov r8, MEM_COMMIT | MEM_RESERVE
|
|
mov edx, dword [rsi + IMAGE_NT_HEADER_SIZE_OF_IMAGE_OFFSET]
|
|
mov rcx, qword [rsi + IMAGE_NT_HEADER_BASE_OF_IMAGE_OFFSET]
|
|
call rax
|
|
mov rbx, rax
|
|
test rax, rax
|
|
jnz BuildIAT
|
|
mov r9, PAGE_EXECUTE_READWRITE
|
|
mov r8, MEM_COMMIT | MEM_RESERVE
|
|
mov edx, dword [rsi + IMAGE_NT_HEADER_SIZE_OF_IMAGE_OFFSET]
|
|
mov rcx, 0
|
|
call r12
|
|
mov rbx, rax
|
|
jmp RelocatePE
|
|
Rva2Offset:
|
|
push r8
|
|
push r9
|
|
push r10
|
|
push r11
|
|
push r12
|
|
push r13
|
|
mov r12, rsi
|
|
add r12, SIZE_OF_IMAGE_NT_HEADER
|
|
xor r13, r13
|
|
mov r13w, [rsi + IMAGE_NT_HEADER_NUMBER_OF_SECTIONS_OFFSET]
|
|
xor r10, r10
|
|
Rva2OffsetLoop:
|
|
cmp r10, r13
|
|
je Rva2OffsetEndLoop
|
|
mov r9d, dword [r12 + IMAGE_SECTION_HEADER_VIRTUAL_ADDR_OFFSET]
|
|
mov r8d, dword [r12 + IMAGE_SECTION_HEADER_VIRTUAL_SIZE_OFFSET]
|
|
mov r11d, dword [r12 + IMAGE_SECTION_HEADER_POINTER_TO_RAW_DATA_OFFSET]
|
|
add r8, r9
|
|
add r12, SIZE_OF_IMAGE_SECTION_HEADER
|
|
inc r10
|
|
cmp rax, r9
|
|
jl Rva2OffsetLoop
|
|
cmp rax, r8
|
|
jge Rva2OffsetLoop
|
|
add rax, r11
|
|
sub rax, r9
|
|
Rva2OffsetEndLoop:
|
|
pop r13
|
|
pop r12
|
|
pop r11
|
|
pop r10
|
|
pop r9
|
|
pop r8
|
|
ret
|
|
RelocatePE:
|
|
mov r8, rbp
|
|
mov r9, rdi
|
|
mov eax, dword [rsi + IMAGE_NT_HEADER_ENTRY_RELOCS_OFFSET]
|
|
call Rva2Offset
|
|
add rax, r15
|
|
mov rbp, rax
|
|
xor rcx, rcx
|
|
RelocationLoop:
|
|
cmp ecx, dword [rsi + IMAGE_NT_HEADER_ENTRY_RELOCS_OFFSET + 4h]
|
|
je RelocationLoopEnd
|
|
mov rdx, rbp
|
|
add rdx, 8h
|
|
mov r14, rcx
|
|
mov edi, dword [rbp + 4h]
|
|
sub rdi, 8h
|
|
shr rdi, 1h
|
|
xor rcx, rcx
|
|
BlocksLoop:
|
|
cmp rcx, rdi
|
|
je BlocksLoopEnd
|
|
xor rax, rax
|
|
mov ax, [rdx]
|
|
test rax, rax
|
|
jz EscapeBlock
|
|
and ax, 0fffh
|
|
add eax, dword [rbp]
|
|
call Rva2Offset
|
|
add rax, r15
|
|
mov r10, qword [rsi + IMAGE_NT_HEADER_BASE_OF_IMAGE_OFFSET]
|
|
sub qword [rax], r10
|
|
add qword [rax], rbx
|
|
EscapeBlock:
|
|
inc rcx
|
|
add rdx, 2h
|
|
jmp BlocksLoop
|
|
BlocksLoopEnd:
|
|
mov rcx, r14
|
|
add ecx, dword [rbp + 4h]
|
|
mov r14d, dword [rbp + 4h]
|
|
add rbp, r14
|
|
jmp RelocationLoop
|
|
RelocationLoopEnd:
|
|
mov rbp, r8
|
|
mov rdi, r9
|
|
BuildIAT:
|
|
call LoadLibrary
|
|
db 'LoadLibraryA', 0h
|
|
LoadLibrary:
|
|
pop rdx
|
|
mov rcx, rbp
|
|
call rdi
|
|
mov rdx, rax
|
|
mov eax, dword [rsi + IMAGE_NT_HEADER_ENTRY_IMPORT_OFFSET]
|
|
call Rva2Offset
|
|
add rax, r15
|
|
mov rcx, rax
|
|
DescriptorsLoop:
|
|
mov eax, dword [rcx + IMAGE_IMPORT_DESCRIPTOR_NAME_OFFSET]
|
|
test eax, eax
|
|
jz DescriptorsLoopEnd
|
|
call Rva2Offset
|
|
add rax, r15
|
|
mov r12, rcx
|
|
mov r13, rdx
|
|
mov rcx, rax
|
|
call rdx
|
|
mov rcx, r12
|
|
mov rdx, r13
|
|
mov r12, rdx
|
|
mov r13, rbx
|
|
mov r14, rbp
|
|
mov rbp, rax
|
|
mov eax, dword [rcx + IMAGE_IMPORT_DESCRIPTOR_FIRST_THUNK_OFFSET]
|
|
call Rva2Offset
|
|
add rax, r15
|
|
mov rdx, rax
|
|
cmp dword [rcx + IMAGE_IMPORT_DESCRIPTOR_TIME_STAMP_OFFSET], 0
|
|
je NotBoundedImport
|
|
mov eax, dword [rcx]
|
|
call Rva2Offset
|
|
add rax, r15
|
|
mov rbx, rax
|
|
jmp ThunkArraysLoop
|
|
NotBoundedImport:
|
|
mov rbx, rdx
|
|
ThunkArraysLoop:
|
|
mov rax, [rbx]
|
|
test rax, rax
|
|
jz ThunkArraysLoopEnd
|
|
bt rax, 3fh
|
|
jc ImportByOrdinal
|
|
call Rva2Offset
|
|
add rax, r15
|
|
add rax, 2h
|
|
jmp GetApiAddr
|
|
ImportByOrdinal:
|
|
and rax, 0ffffh
|
|
GetApiAddr:
|
|
xchg rcx, [rsp + 30h]
|
|
xchg rdx, [rsp + 38h]
|
|
mov rdx, rax
|
|
mov rcx, rbp
|
|
call rdi
|
|
xchg rcx, [rsp + 30h]
|
|
xchg rdx, [rsp + 38h]
|
|
mov qword [rdx], rax
|
|
add rbx, SIZE_OF_IMAGE_THUNK_DATA
|
|
add rdx, SIZE_OF_IMAGE_THUNK_DATA
|
|
jmp ThunkArraysLoop
|
|
ThunkArraysLoopEnd:
|
|
mov rdx, r12
|
|
mov rbx, r13
|
|
mov rbp, r14
|
|
add rcx, SIZE_OF_IMAGE_IMPORT_DESCRIPTOR
|
|
jmp DescriptorsLoop
|
|
DescriptorsLoopEnd:
|
|
mov r12, rdi
|
|
mov r13, rbp
|
|
mov rcx, rsi
|
|
add rcx, SIZE_OF_IMAGE_NT_HEADER
|
|
xor rax, rax
|
|
xor rdx, rdx
|
|
mov dx, word [rsi + IMAGE_NT_HEADER_NUMBER_OF_SECTIONS_OFFSET]
|
|
MapSectionLoop:
|
|
cmp rax, rdx
|
|
je MapSectionLoopEnd
|
|
mov rdi, rbx
|
|
mov rbp, rsi
|
|
mov rsi, r15
|
|
mov r14d, dword [rcx + IMAGE_SECTION_HEADER_POINTER_TO_RAW_DATA_OFFSET]
|
|
add rsi, r14
|
|
mov r14d, dword [rcx + IMAGE_SECTION_HEADER_VIRTUAL_ADDR_OFFSET]
|
|
add rdi, r14
|
|
mov r14, rcx
|
|
mov ecx, dword [rcx + IMAGE_SECTION_HEADER_SIZE_OF_RAW_DATA_OFFSET]
|
|
rep movsb
|
|
mov rcx, r14
|
|
mov rsi, rbp
|
|
inc rax
|
|
add rcx, SIZE_OF_IMAGE_SECTION_HEADER
|
|
jmp MapSectionLoop
|
|
MapSectionLoopEnd:
|
|
mov rdi, r12
|
|
mov rbp, r13
|
|
mov eax, dword [rsi + IMAGE_NT_HEADER_ADDR_OF_ENTRY_POINT_OFFSET]
|
|
add rax, rbx
|
|
mov rsi, rax
|
|
call VirtualFree
|
|
db 'VirtualFree', 0h
|
|
VirtualFree:
|
|
pop rdx
|
|
mov rcx, rbp
|
|
call rdi
|
|
mov r8, MEM_RELEASE
|
|
xor rdx, rdx
|
|
call PushShellcodeBase
|
|
PushShellcodeBase:
|
|
pop rcx
|
|
sub rcx, PushShellcodeBase
|
|
add rsp, 28h
|
|
push rsi
|
|
push rax
|
|
ret
|
|
GetPERawBase:
|
|
call PERawBase |