mirror of
https://github.com/d35ha/PE2Shellcode
synced 2026-06-08 13:42:58 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#include "Utils.h"
|
||||
|
||||
#pragma comment (lib, "ntdll.lib")
|
||||
|
||||
#define CONSOLE_COLOR_GREEN 0xA
|
||||
#define CONSOLE_COLOR_YELLOW 0xE
|
||||
#define CONSOLE_COLOR_RED 0xC
|
||||
#define CONSOLE_COLOR_WHITE 0x7
|
||||
|
||||
HANDLE hConsole = NULL;
|
||||
CHAR ErrorMsg[MAX_PATH] = { 0 };
|
||||
|
||||
BOOL printf_success(LPCSTR _Format, ...)
|
||||
{
|
||||
if (!hConsole) hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
va_list ArgList = NULL;
|
||||
va_start(ArgList, _Format);
|
||||
SetConsoleTextAttribute(hConsole, CONSOLE_COLOR_GREEN);
|
||||
printf("[+] ");
|
||||
vprintf(_Format, ArgList);
|
||||
SetConsoleTextAttribute(hConsole, CONSOLE_COLOR_WHITE);
|
||||
va_end(ArgList);
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
BOOL printf_info(LPCSTR _Format, ...)
|
||||
{
|
||||
if (!hConsole) hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
va_list ArgList = NULL;
|
||||
va_start(ArgList, _Format);
|
||||
SetConsoleTextAttribute(hConsole, CONSOLE_COLOR_YELLOW);
|
||||
printf("[!] ");
|
||||
vprintf(_Format, ArgList);
|
||||
SetConsoleTextAttribute(hConsole, CONSOLE_COLOR_WHITE);
|
||||
va_end(ArgList);
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
BOOL printf_error(LPCSTR _Format, ...)
|
||||
{
|
||||
if (!hConsole) hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
va_list ArgList = NULL;
|
||||
va_start(ArgList, _Format);
|
||||
SetConsoleTextAttribute(hConsole, CONSOLE_COLOR_RED);
|
||||
printf("[-] ");
|
||||
vprintf(_Format, ArgList);
|
||||
SetConsoleTextAttribute(hConsole, CONSOLE_COLOR_WHITE);
|
||||
va_end(ArgList);
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
LPCSTR GetLastErrorFormat(ULONG dwErrorCode)
|
||||
{
|
||||
if (dwErrorCode == -1) dwErrorCode = GetLastError();
|
||||
if (!FormatMessageA(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dwErrorCode,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
ErrorMsg,
|
||||
sizeof(ErrorMsg),
|
||||
NULL))
|
||||
{
|
||||
printf_error("Error at getting the last error format of code 0x%lx\n", dwErrorCode);
|
||||
sprintf_s(ErrorMsg, "0x%lx", dwErrorCode);
|
||||
};
|
||||
return ErrorMsg;
|
||||
};
|
||||
|
||||
LPCSTR GetNtStatusFormat(NTSTATUS ntCode)
|
||||
{
|
||||
ULONG dwErrorCode = RtlNtStatusToDosError(ntCode);
|
||||
if (dwErrorCode == ERROR_MR_MID_NOT_FOUND)
|
||||
{
|
||||
printf_error("Error at getting the error code of ntstatus 0x%lx\n", ntCode);
|
||||
sprintf_s(ErrorMsg, "0x%lx", dwErrorCode);
|
||||
return ErrorMsg;
|
||||
};
|
||||
return GetLastErrorFormat(dwErrorCode);
|
||||
};
|
||||
|
||||
BOOL ReportBadPE(LPCSTR lpErrorStr)
|
||||
{
|
||||
printf_error("Invalid or unsupported PE file, %s\n", lpErrorStr);
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
BOOL ReportApiError(LPCSTR szApiName, LPCSTR szMsg)
|
||||
{
|
||||
printf_error("Error at %s, %s, error code/msg = %s\n", szApiName, szMsg, GetLastErrorFormat(GetLastError()));
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
BOOL ReportNtStastus(LPCSTR szApiName, NTSTATUS NtCode, LPCSTR szMsg)
|
||||
{
|
||||
printf_error("Error at %s, %s, status code/msg = %s\n", szApiName, szMsg, GetNtStatusFormat(NtCode));
|
||||
return TRUE;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define offsetof(type, member) __builtin_offsetof (type, member)
|
||||
#endif
|
||||
|
||||
#define GET_DIRECTORY_ENTRY(lpNtHeader, dwEntry) lpNtHeader->OptionalHeader.DataDirectory[dwEntry].VirtualAddress
|
||||
#define GET_DIRECTORY_SIZE(lpNtHeader, dwEntry) lpNtHeader->OptionalHeader.DataDirectory[dwEntry].Size
|
||||
|
||||
LPCSTR GetNtStatusFormat(NTSTATUS ntCode);
|
||||
LPCSTR GetLastErrorFormat(ULONG dwErrorCode = -1);
|
||||
BOOL printf_error(LPCSTR _Format, ...);
|
||||
BOOL printf_info(LPCSTR _Format, ...);
|
||||
BOOL printf_success(LPCSTR _Format, ...);
|
||||
BOOL ReportBadPE(LPCSTR lpErrorStr);
|
||||
BOOL ReportApiError(LPCSTR szApiName, LPCSTR szMsg);
|
||||
BOOL ReportNtStastus(LPCSTR szApiName, NTSTATUS NtCode, LPCSTR szMsg);
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,159 @@
|
||||
#include "Utils/Utils.h"
|
||||
|
||||
INT main(INT argc, CHAR** argv) {
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
LPCSTR szPeFile = argv[1];
|
||||
LPCSTR szStubFile = argv[2];
|
||||
DWORD dwPid = atoi(argv[3]);
|
||||
|
||||
HANDLE hStubFile = NULL;
|
||||
if (!(hStubFile = CreateFileA(
|
||||
szStubFile,
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
)) || INVALID_HANDLE_VALUE == hStubFile)
|
||||
{
|
||||
ReportApiError("CreateFileA", "cannot open the supplied stub file");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
HANDLE hExeFile = NULL;
|
||||
if (!(hExeFile = CreateFileA(
|
||||
szPeFile,
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
)) || INVALID_HANDLE_VALUE == hExeFile)
|
||||
{
|
||||
ReportApiError("CreateFileA", "cannot open the supplied exe file");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
LARGE_INTEGER u32StubSize;
|
||||
if (!GetFileSizeEx(
|
||||
hStubFile,
|
||||
&u32StubSize
|
||||
))
|
||||
{
|
||||
ReportApiError("GetFileSizeEx", "cannot get the size of the supplied stub file");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
LARGE_INTEGER u32ExeSize;
|
||||
if (!GetFileSizeEx(
|
||||
hExeFile,
|
||||
&u32ExeSize
|
||||
))
|
||||
{
|
||||
ReportApiError("GetFileSizeEx", "cannot get the size of the supplied exe file");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
LPVOID lpShellcode = NULL;
|
||||
if (!(lpShellcode = VirtualAlloc(
|
||||
NULL,
|
||||
(SIZE_T)(u32StubSize.QuadPart + u32ExeSize.QuadPart),
|
||||
(MEM_COMMIT | MEM_RESERVE),
|
||||
PAGE_READWRITE
|
||||
)))
|
||||
{
|
||||
ReportApiError("VirtualAlloc", "cannot allocate memory for the shellcode");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
DWORD dwReadBytes = 0;
|
||||
if (!ReadFile(
|
||||
hStubFile,
|
||||
lpShellcode,
|
||||
(DWORD)u32StubSize.QuadPart,
|
||||
&dwReadBytes,
|
||||
NULL
|
||||
) || dwReadBytes != u32StubSize.QuadPart)
|
||||
{
|
||||
ReportApiError("ReadFile", "cannot read the stub file");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
if (!ReadFile(
|
||||
hExeFile,
|
||||
#if defined(_M_X64) || defined(__amd64__)
|
||||
(LPVOID)((ULONGLONG)lpShellcode + dwReadBytes),
|
||||
#else
|
||||
(LPVOID)((ULONGLONG)lpShellcode + dwReadBytes),
|
||||
#endif
|
||||
(DWORD)u32ExeSize.QuadPart,
|
||||
&dwReadBytes,
|
||||
NULL
|
||||
) || dwReadBytes != u32ExeSize.QuadPart)
|
||||
{
|
||||
ReportApiError("ReadFile", "cannot read the exe file");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
HANDLE hProcess = NULL;
|
||||
if (!(hProcess = OpenProcess(
|
||||
PROCESS_ALL_ACCESS,
|
||||
FALSE,
|
||||
dwPid
|
||||
)))
|
||||
{
|
||||
ReportApiError("OpenProcess", "cannot open the target pid");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
LPVOID lpAllocatedBase = NULL;
|
||||
if (!(lpAllocatedBase = VirtualAllocEx(
|
||||
hProcess,
|
||||
NULL,
|
||||
(SIZE_T)(u32StubSize.QuadPart + u32ExeSize.QuadPart),
|
||||
(MEM_COMMIT | MEM_RESERVE),
|
||||
PAGE_EXECUTE_READWRITE
|
||||
)))
|
||||
{
|
||||
ReportApiError("VirtualAllocEx", "cannot allocate at the remote process for the shellcode");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
SIZE_T stWrittenBytes = 0;
|
||||
if (!WriteProcessMemory(
|
||||
hProcess,
|
||||
lpAllocatedBase,
|
||||
lpShellcode,
|
||||
(SIZE_T)(u32StubSize.QuadPart + u32ExeSize.QuadPart),
|
||||
&stWrittenBytes
|
||||
) || stWrittenBytes != u32StubSize.QuadPart + u32ExeSize.QuadPart)
|
||||
{
|
||||
ReportApiError("WriteProcessMemory", "cannot write at the remote process");
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
if (!CreateRemoteThread(
|
||||
hProcess,
|
||||
NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE)lpAllocatedBase,
|
||||
NULL,
|
||||
0,
|
||||
NULL
|
||||
))
|
||||
{
|
||||
ReportApiError("CreateRemoteThread", "cannot create a new thread at the remote process");
|
||||
return FALSE;
|
||||
};
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s [exe] [stub] [pid]\n", argv[0]);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
nasm -o stub_X32.bin -f bin stub_x32.asm
|
||||
nasm -o stub_X64.bin -f bin stub_x64.asm
|
||||
@@ -0,0 +1,258 @@
|
||||
bits 32
|
||||
%include "stub_x32.inc"
|
||||
|
||||
Init:
|
||||
fs mov eax, dword [TEB_PPEB_OFFSET]
|
||||
mov eax, dword [eax + PEB_PLDR_OFFSET]
|
||||
mov esi, dword [eax + LDR_PIN_ORDER_MOD_LIST_OFFSET]
|
||||
lodsd
|
||||
xchg eax, esi
|
||||
lodsd
|
||||
mov ebp, dword [eax + LDR_MODULE_BASE_OFFSET]
|
||||
mov eax, dword [ebp + IMAGE_DOS_HEADER_LFANEW_OFFSET]
|
||||
mov ebx, dword [ebp + eax + IMAGE_NT_HEADER_ENTRY_EXPORT_OFFSET]
|
||||
add ebx, ebp
|
||||
mov esi, [ebx + EXPORT_TABLE_ADDR_OF_NAMES_OFFSET]
|
||||
add esi, ebp
|
||||
xor ecx, ecx
|
||||
FindGetProcAddr:
|
||||
inc ecx
|
||||
lodsd
|
||||
add eax, ebp
|
||||
cmp dword [eax], STRING_OF_GETP
|
||||
jnz FindGetProcAddr
|
||||
cmp dword [eax + 0x4], STRING_OF_ROCA
|
||||
jnz FindGetProcAddr
|
||||
cmp dword [eax + 0x8], STRING_OF_DDRE
|
||||
jnz FindGetProcAddr
|
||||
mov esi, [ebx + EXPORT_TABLE_ADDR_OF_ORDINALS_OFFSET]
|
||||
add esi, ebp
|
||||
mov cx, [esi + ecx*2]
|
||||
dec ecx
|
||||
mov esi, [ebx + EXPORT_TABLE_ADDR_OF_FUNCTIONS_OFFSET]
|
||||
add esi, ebp
|
||||
mov edi, [esi + ecx*4]
|
||||
add edi, ebp
|
||||
jmp GetPERawBase
|
||||
PERawBase:
|
||||
mov esi, [esp]
|
||||
add esi, dword [esi + IMAGE_DOS_HEADER_LFANEW_OFFSET]
|
||||
call VirtualAlloc
|
||||
db 'VirtualAlloc', 0h
|
||||
VirtualAlloc:
|
||||
push ebp
|
||||
call edi
|
||||
push eax
|
||||
push PAGE_EXECUTE_READWRITE
|
||||
push MEM_COMMIT | MEM_RESERVE
|
||||
push dword [esi + IMAGE_NT_HEADER_SIZE_OF_IMAGE_OFFSET]
|
||||
push dword [esi + IMAGE_NT_HEADER_BASE_OF_IMAGE_OFFSET]
|
||||
call eax
|
||||
pop ecx
|
||||
mov ebx, eax
|
||||
test eax, eax
|
||||
jnz BuildIAT
|
||||
push PAGE_EXECUTE_READWRITE
|
||||
push MEM_COMMIT | MEM_RESERVE
|
||||
push dword [esi + IMAGE_NT_HEADER_SIZE_OF_IMAGE_OFFSET]
|
||||
push 0
|
||||
call ecx
|
||||
mov ebx, eax
|
||||
jmp RelocatePE
|
||||
Rva2Offset:
|
||||
push ebx
|
||||
push edx
|
||||
push ebp
|
||||
push edi
|
||||
push ecx
|
||||
mov ecx, esi
|
||||
add ecx, SIZE_OF_IMAGE_NT_HEADER
|
||||
xor ebp, ebp
|
||||
mov bp, [esi + IMAGE_NT_HEADER_NUMBER_OF_SECTIONS_OFFSET]
|
||||
push ebp
|
||||
xor ebp, ebp
|
||||
Rva2OffsetLoop:
|
||||
cmp ebp, dword [esp]
|
||||
je Rva2OffsetEndLoop
|
||||
mov edx, dword [ecx + IMAGE_SECTION_HEADER_VIRTUAL_ADDR_OFFSET]
|
||||
mov ebx, dword [ecx + IMAGE_SECTION_HEADER_VIRTUAL_SIZE_OFFSET]
|
||||
mov edi, dword [ecx + IMAGE_SECTION_HEADER_POINTER_TO_RAW_DATA_OFFSET]
|
||||
add ebx, edx
|
||||
add ecx, SIZE_OF_IMAGE_SECTION_HEADER
|
||||
inc ebp
|
||||
cmp eax, edx
|
||||
jl Rva2OffsetLoop
|
||||
cmp eax, ebx
|
||||
jge Rva2OffsetLoop
|
||||
add eax, edi
|
||||
sub eax, edx
|
||||
Rva2OffsetEndLoop:
|
||||
add esp, 4h
|
||||
pop ecx
|
||||
pop edi
|
||||
pop ebp
|
||||
pop edx
|
||||
pop ebx
|
||||
ret
|
||||
RelocatePE:
|
||||
push ebp
|
||||
push edi
|
||||
mov eax, dword [esi + IMAGE_NT_HEADER_ENTRY_RELOCS_OFFSET]
|
||||
call Rva2Offset
|
||||
add eax, [esp + 8h]
|
||||
mov ebp, eax
|
||||
xor ecx, ecx
|
||||
RelocationLoop:
|
||||
cmp ecx, dword [esi + IMAGE_NT_HEADER_ENTRY_RELOCS_OFFSET + 4h]
|
||||
je RelocationLoopEnd
|
||||
mov edx, ebp
|
||||
add edx, 8h
|
||||
push ecx
|
||||
mov edi, dword [ebp + 4h]
|
||||
sub edi, 8h
|
||||
shr edi, 1h
|
||||
xor ecx, ecx
|
||||
BlocksLoop:
|
||||
cmp ecx, edi
|
||||
je BlocksLoopEnd
|
||||
xor eax, eax
|
||||
mov ax, [edx]
|
||||
test eax, eax
|
||||
jz EscapeBlock
|
||||
and ax, 0fffh
|
||||
add eax, dword [ebp]
|
||||
call Rva2Offset
|
||||
add eax, dword [esp + 0ch]
|
||||
push ecx
|
||||
mov ecx, dword [esi + IMAGE_NT_HEADER_BASE_OF_IMAGE_OFFSET]
|
||||
sub dword [eax], ecx
|
||||
add dword [eax], ebx
|
||||
pop ecx
|
||||
EscapeBlock:
|
||||
inc ecx
|
||||
add edx, 2h
|
||||
jmp BlocksLoop
|
||||
BlocksLoopEnd:
|
||||
pop ecx
|
||||
add ecx, dword [ebp + 4h]
|
||||
add ebp, dword [ebp + 4h]
|
||||
jmp RelocationLoop
|
||||
RelocationLoopEnd:
|
||||
pop edi
|
||||
pop ebp
|
||||
BuildIAT:
|
||||
call LoadLibrary
|
||||
db 'LoadLibraryA', 0h
|
||||
LoadLibrary:
|
||||
push ebp
|
||||
call edi
|
||||
mov edx, eax
|
||||
mov eax, dword [esi + IMAGE_NT_HEADER_ENTRY_IMPORT_OFFSET]
|
||||
call Rva2Offset
|
||||
add eax, [esp]
|
||||
mov ecx, eax
|
||||
DescriptorsLoop:
|
||||
mov eax, dword [ecx + IMAGE_IMPORT_DESCRIPTOR_NAME_OFFSET]
|
||||
test eax, eax
|
||||
jz DescriptorsLoopEnd
|
||||
call Rva2Offset
|
||||
add eax, [esp]
|
||||
push ecx
|
||||
push edx
|
||||
push eax
|
||||
call edx
|
||||
pop edx
|
||||
pop ecx
|
||||
push edx
|
||||
push ebx
|
||||
push ebp
|
||||
mov ebp, eax
|
||||
mov eax, dword [ecx + IMAGE_IMPORT_DESCRIPTOR_FIRST_THUNK_OFFSET]
|
||||
call Rva2Offset
|
||||
add eax, [esp + 0ch]
|
||||
mov edx, eax
|
||||
cmp dword [ecx + IMAGE_IMPORT_DESCRIPTOR_TIME_STAMP_OFFSET], 0
|
||||
je NotBoundedImport
|
||||
mov eax, dword [ecx]
|
||||
call Rva2Offset
|
||||
add eax, [esp + 0ch]
|
||||
mov ebx, eax
|
||||
jmp ThunkArraysLoop
|
||||
NotBoundedImport:
|
||||
mov ebx, edx
|
||||
ThunkArraysLoop:
|
||||
mov eax, [ebx]
|
||||
test eax, eax
|
||||
jz ThunkArraysLoopEnd
|
||||
bt eax, 1fh
|
||||
jc ImportByOrdinal
|
||||
call Rva2Offset
|
||||
add eax, [esp + 0ch]
|
||||
add eax, 2h
|
||||
jmp GetApiAddr
|
||||
ImportByOrdinal:
|
||||
and eax, 0ffffh
|
||||
GetApiAddr:
|
||||
push ecx
|
||||
push edx
|
||||
push eax
|
||||
push ebp
|
||||
call edi
|
||||
pop edx
|
||||
pop ecx
|
||||
mov dword [edx], eax
|
||||
add ebx, SIZE_OF_IMAGE_THUNK_DATA
|
||||
add edx, SIZE_OF_IMAGE_THUNK_DATA
|
||||
jmp ThunkArraysLoop
|
||||
ThunkArraysLoopEnd:
|
||||
pop ebp
|
||||
pop ebx
|
||||
pop edx
|
||||
add ecx, SIZE_OF_IMAGE_IMPORT_DESCRIPTOR
|
||||
jmp DescriptorsLoop
|
||||
DescriptorsLoopEnd:
|
||||
push edi
|
||||
push ebp
|
||||
mov ecx, esi
|
||||
add ecx, SIZE_OF_IMAGE_NT_HEADER
|
||||
xor eax, eax
|
||||
xor edx, edx
|
||||
mov dx, word [esi + IMAGE_NT_HEADER_NUMBER_OF_SECTIONS_OFFSET]
|
||||
MapSectionLoop:
|
||||
cmp eax, edx
|
||||
je MapSectionLoopEnd
|
||||
mov edi, ebx
|
||||
mov ebp, esi
|
||||
mov esi, [esp + 8h]
|
||||
add esi, dword [ecx + IMAGE_SECTION_HEADER_POINTER_TO_RAW_DATA_OFFSET]
|
||||
add edi, dword [ecx + IMAGE_SECTION_HEADER_VIRTUAL_ADDR_OFFSET]
|
||||
push dword [ecx + IMAGE_SECTION_HEADER_SIZE_OF_RAW_DATA_OFFSET]
|
||||
xchg ecx, [esp]
|
||||
rep movsb
|
||||
pop ecx
|
||||
mov esi, ebp
|
||||
inc eax
|
||||
add ecx, SIZE_OF_IMAGE_SECTION_HEADER
|
||||
jmp MapSectionLoop
|
||||
MapSectionLoopEnd:
|
||||
pop ebp
|
||||
pop edi
|
||||
mov eax, dword [esi + IMAGE_NT_HEADER_ADDR_OF_ENTRY_POINT_OFFSET]
|
||||
add eax, ebx
|
||||
mov dword [esp], eax
|
||||
call VirtualFree
|
||||
db 'VirtualFree', 0h
|
||||
VirtualFree:
|
||||
push ebp
|
||||
call edi
|
||||
pop esi
|
||||
push MEM_RELEASE
|
||||
push 0
|
||||
call PushShellcodeBase
|
||||
PushShellcodeBase:
|
||||
sub dword [esp], PushShellcodeBase
|
||||
push esi
|
||||
push eax
|
||||
ret
|
||||
GetPERawBase:
|
||||
call PERawBase
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
TEB_PPEB_OFFSET equ 30h
|
||||
PEB_PLDR_OFFSET equ 0ch
|
||||
LDR_PIN_ORDER_MOD_LIST_OFFSET equ 0ch
|
||||
LDR_MODULE_BASE_OFFSET equ 18h
|
||||
IMAGE_DOS_HEADER_LFANEW_OFFSET equ 3ch
|
||||
|
||||
IMAGE_NT_HEADER_ENTRY_EXPORT_OFFSET equ 78h
|
||||
IMAGE_NT_HEADER_ENTRY_IMPORT_OFFSET equ 80h
|
||||
IMAGE_NT_HEADER_ENTRY_RELOCS_OFFSET equ 0a0h
|
||||
|
||||
EXPORT_TABLE_ADDR_OF_NAMES_OFFSET equ 20h
|
||||
EXPORT_TABLE_ADDR_OF_ORDINALS_OFFSET equ 24h
|
||||
EXPORT_TABLE_ADDR_OF_FUNCTIONS_OFFSET equ 1ch
|
||||
|
||||
STRING_OF_GETP equ 50746547h
|
||||
STRING_OF_ROCA equ 41636f72h
|
||||
STRING_OF_DDRE equ 65726464h
|
||||
|
||||
MEM_COMMIT equ 1000h
|
||||
MEM_RESERVE equ 2000h
|
||||
MEM_RELEASE equ 8000h
|
||||
|
||||
PAGE_EXECUTE_READWRITE equ 40h
|
||||
|
||||
IMAGE_NT_HEADER_SIZE_OF_IMAGE_OFFSET equ 50h
|
||||
IMAGE_NT_HEADER_BASE_OF_IMAGE_OFFSET equ 34h
|
||||
IMAGE_SECTION_HEADER_VIRTUAL_SIZE_OFFSET equ 8h
|
||||
IMAGE_SECTION_HEADER_VIRTUAL_ADDR_OFFSET equ 0ch
|
||||
IMAGE_NT_HEADER_NUMBER_OF_SECTIONS_OFFSET equ 6h
|
||||
IMAGE_NT_HEADER_ADDR_OF_ENTRY_POINT_OFFSET equ 28h
|
||||
IMAGE_SECTION_HEADER_POINTER_TO_RAW_DATA_OFFSET equ 14h
|
||||
IMAGE_SECTION_HEADER_SIZE_OF_RAW_DATA_OFFSET equ 10h
|
||||
SIZE_OF_IMAGE_IMPORT_DESCRIPTOR equ 14h
|
||||
|
||||
SIZE_OF_IMAGE_THUNK_DATA equ 4h
|
||||
SIZE_OF_IMAGE_NT_HEADER equ 0F8h
|
||||
SIZE_OF_IMAGE_SECTION_HEADER equ 28h
|
||||
|
||||
IMAGE_IMPORT_DESCRIPTOR_TIME_STAMP_OFFSET equ 4h
|
||||
IMAGE_IMPORT_DESCRIPTOR_NAME_OFFSET equ 0ch
|
||||
IMAGE_IMPORT_DESCRIPTOR_FIRST_THUNK_OFFSET equ 10h
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
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
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
TEB_PPEB_OFFSET equ 60h
|
||||
PEB_PLDR_OFFSET equ 18h
|
||||
LDR_PIN_ORDER_MOD_LIST_OFFSET equ 10h
|
||||
LDR_MODULE_BASE_OFFSET equ 30h
|
||||
IMAGE_DOS_HEADER_LFANEW_OFFSET equ 3ch
|
||||
|
||||
IMAGE_NT_HEADER_ENTRY_EXPORT_OFFSET equ 88h
|
||||
IMAGE_NT_HEADER_ENTRY_IMPORT_OFFSET equ 90h
|
||||
IMAGE_NT_HEADER_ENTRY_RELOCS_OFFSET equ 0b0h
|
||||
|
||||
EXPORT_TABLE_ADDR_OF_NAMES_OFFSET equ 20h
|
||||
EXPORT_TABLE_ADDR_OF_ORDINALS_OFFSET equ 24h
|
||||
EXPORT_TABLE_ADDR_OF_FUNCTIONS_OFFSET equ 1ch
|
||||
|
||||
STRING_OF_GETP equ 50746547h
|
||||
STRING_OF_ROCA equ 41636f72h
|
||||
STRING_OF_DDRE equ 65726464h
|
||||
|
||||
MEM_COMMIT equ 1000h
|
||||
MEM_RESERVE equ 2000h
|
||||
MEM_RELEASE equ 8000h
|
||||
|
||||
PAGE_EXECUTE_READWRITE equ 40h
|
||||
|
||||
IMAGE_NT_HEADER_SIZE_OF_IMAGE_OFFSET equ 50h
|
||||
IMAGE_NT_HEADER_BASE_OF_IMAGE_OFFSET equ 30h
|
||||
IMAGE_SECTION_HEADER_VIRTUAL_SIZE_OFFSET equ 8h
|
||||
IMAGE_SECTION_HEADER_VIRTUAL_ADDR_OFFSET equ 0ch
|
||||
IMAGE_NT_HEADER_NUMBER_OF_SECTIONS_OFFSET equ 6h
|
||||
IMAGE_NT_HEADER_ADDR_OF_ENTRY_POINT_OFFSET equ 28h
|
||||
IMAGE_SECTION_HEADER_POINTER_TO_RAW_DATA_OFFSET equ 14h
|
||||
IMAGE_SECTION_HEADER_SIZE_OF_RAW_DATA_OFFSET equ 10h
|
||||
SIZE_OF_IMAGE_IMPORT_DESCRIPTOR equ 14h
|
||||
|
||||
SIZE_OF_IMAGE_THUNK_DATA equ 8h
|
||||
SIZE_OF_IMAGE_NT_HEADER equ 108h
|
||||
SIZE_OF_IMAGE_SECTION_HEADER equ 28h
|
||||
|
||||
IMAGE_IMPORT_DESCRIPTOR_TIME_STAMP_OFFSET equ 4h
|
||||
IMAGE_IMPORT_DESCRIPTOR_NAME_OFFSET equ 0ch
|
||||
IMAGE_IMPORT_DESCRIPTOR_FIRST_THUNK_OFFSET equ 10h
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user