Skip to content

Commit

Permalink
[BUGFIX] Fixed missing system check before applying the patch. Flush …
Browse files Browse the repository at this point in the history
…cache after
  • Loading branch information
hasherezade committed Feb 7, 2025
1 parent 900a22a commit 78df8f1
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 20 deletions.
3 changes: 2 additions & 1 deletion run_pe/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#include <tchar.h>
#include "run_pe.h"

LPCTSTR version = TEXT("0.1.9");
LPCTSTR version = TEXT("0.2");

bool g_PatchRequired = false;

bool isWindows1124H2OrLater()
Expand Down
37 changes: 20 additions & 17 deletions run_pe/patch_ntdll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,27 @@ bool patch_NtManageHotPatch32(HANDLE hProcess)
if (!_NtManageHotPatch) {
return false;
}
ULONG_PTR stub_ptr = (ULONG_PTR)_NtManageHotPatch;
LPVOID stub_ptr = (LPVOID)_NtManageHotPatch;

if (!VirtualProtectEx(hProcess, (LPVOID)stub_ptr, stub_size, PAGE_READWRITE, &oldProtect)) {
if (!VirtualProtectEx(hProcess, stub_ptr, stub_size, PAGE_READWRITE, &oldProtect)) {
return false;
}
BYTE stub_buffer_orig[stub_size] = { 0 };
SIZE_T out_bytes = 0;
if (!ReadProcessMemory(hProcess, (LPVOID)stub_ptr, stub_buffer_orig, stub_size, &out_bytes) || out_bytes != stub_size) {
if (!ReadProcessMemory(hProcess, stub_ptr, stub_buffer_orig, stub_size, &out_bytes) || out_bytes != stub_size) {
return false;
}
// confirm it is a valid syscall stub:
if (stub_buffer_orig[0] != 0xB8) {
return false;
}
if (!WriteProcessMemory(hProcess, (LPVOID)stub_ptr, hotpatch_patch, sizeof(hotpatch_patch), &out_bytes) || out_bytes != sizeof(hotpatch_patch)) {
if (!WriteProcessMemory(hProcess, stub_ptr, hotpatch_patch, sizeof(hotpatch_patch), &out_bytes) || out_bytes != sizeof(hotpatch_patch)) {
return false;
}
if (!VirtualProtectEx(hProcess, (LPVOID)stub_ptr, stub_size, oldProtect, &oldProtect)) {
if (!VirtualProtectEx(hProcess, stub_ptr, stub_size, oldProtect, &oldProtect)) {
return false;
}
FlushInstructionCache(hProcess, stub_ptr, sizeof(hotpatch_patch));
return true;
}

Expand Down Expand Up @@ -65,26 +66,27 @@ bool patch_NtManageHotPatch64(HANDLE hProcess)
if (!_NtManageHotPatch) {
return false;
}
ULONG_PTR stub_ptr = (ULONG_PTR)_NtManageHotPatch;
LPVOID stub_ptr = (LPVOID)_NtManageHotPatch;

if (!VirtualProtectEx(hProcess, (LPVOID)stub_ptr, stub_size, PAGE_READWRITE, &oldProtect)) {
if (!VirtualProtectEx(hProcess, stub_ptr, stub_size, PAGE_READWRITE, &oldProtect)) {
return false;
}
BYTE stub_buffer_orig[stub_size] = { 0 };
SIZE_T out_bytes = 0;
if (!ReadProcessMemory(hProcess, (LPVOID)stub_ptr, stub_buffer_orig, stub_size, &out_bytes) || out_bytes != stub_size) {
if (!ReadProcessMemory(hProcess, stub_ptr, stub_buffer_orig, stub_size, &out_bytes) || out_bytes != stub_size) {
return false;
}
// confirm it is a valid syscall stub:
if (::memcmp(stub_buffer_orig, syscall_fill_pattern, syscall_pattern_start) != 0) {
return false;
}
if (!WriteProcessMemory(hProcess, (LPVOID)stub_ptr, hotpatch_patch, sizeof(hotpatch_patch), &out_bytes) || out_bytes != sizeof(hotpatch_patch)) {
if (!WriteProcessMemory(hProcess, stub_ptr, hotpatch_patch, sizeof(hotpatch_patch), &out_bytes) || out_bytes != sizeof(hotpatch_patch)) {
return false;
}
if (!VirtualProtectEx(hProcess, (LPVOID)stub_ptr, stub_size, oldProtect, &oldProtect)) {
if (!VirtualProtectEx(hProcess, stub_ptr, stub_size, oldProtect, &oldProtect)) {
return false;
}
FlushInstructionCache(hProcess, stub_ptr, sizeof(hotpatch_patch));
return true;
}

Expand All @@ -104,9 +106,9 @@ bool patch_ZwQueryVirtualMemory(HANDLE hProcess, LPVOID module_ptr)
if (!_ZwQueryVirtualMemory || _ZwQueryVirtualMemory < pos) {
return false;
}
ULONG_PTR stub_ptr = (ULONG_PTR)_ZwQueryVirtualMemory - pos;
LPVOID stub_ptr = (LPVOID)((ULONG_PTR)_ZwQueryVirtualMemory - pos);

if (!VirtualProtectEx(hProcess, (LPVOID)stub_ptr, stub_size, PAGE_READWRITE, &oldProtect)) {
if (!VirtualProtectEx(hProcess, stub_ptr, stub_size, PAGE_READWRITE, &oldProtect)) {
return false;
}
LPVOID patch_space = VirtualAllocEx(hProcess, 0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
Expand All @@ -115,7 +117,7 @@ bool patch_ZwQueryVirtualMemory(HANDLE hProcess, LPVOID module_ptr)
}
BYTE stub_buffer_orig[stub_size] = { 0 };
SIZE_T out_bytes = 0;
if (!ReadProcessMemory(hProcess, (LPVOID)stub_ptr, stub_buffer_orig, stub_size, &out_bytes) || out_bytes != stub_size) {
if (!ReadProcessMemory(hProcess, stub_ptr, stub_buffer_orig, stub_size, &out_bytes) || out_bytes != stub_size) {
return false;
}
const BYTE nop_pattern[] = {0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
Expand Down Expand Up @@ -169,18 +171,19 @@ bool patch_ZwQueryVirtualMemory(HANDLE hProcess, LPVOID module_ptr)

const SIZE_T trampoline_full_size = stub_size + pos + syscall_pattern_full + sizeof(jump_to_contnue);

if (!WriteProcessMemory(hProcess, (LPVOID)stub_ptr, stub_buffer_patched, stub_size, &out_bytes) || out_bytes != stub_size) {
if (!WriteProcessMemory(hProcess, stub_ptr, stub_buffer_patched, stub_size, &out_bytes) || out_bytes != stub_size) {
return false;
}
if (!VirtualProtectEx(hProcess, (LPVOID)stub_ptr, stub_size, oldProtect, &oldProtect)) {
if (!VirtualProtectEx(hProcess, stub_ptr, stub_size, oldProtect, &oldProtect)) {
return false;
}
if (!WriteProcessMemory(hProcess, (LPVOID)patch_space, stub_buffer_trampoline, trampoline_full_size, &out_bytes) || out_bytes != trampoline_full_size) {
if (!WriteProcessMemory(hProcess, patch_space, stub_buffer_trampoline, trampoline_full_size, &out_bytes) || out_bytes != trampoline_full_size) {
return false;
}
if (!VirtualProtectEx(hProcess, (LPVOID)patch_space, stub_size, PAGE_EXECUTE_READ, &oldProtect)) {
if (!VirtualProtectEx(hProcess, patch_space, stub_size, PAGE_EXECUTE_READ, &oldProtect)) {
return false;
}
FlushInstructionCache(hProcess, stub_ptr, stub_size);
return true;
#endif
}
6 changes: 4 additions & 2 deletions run_pe/run_pe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,13 @@ bool run_pe(IN LPCTSTR payloadPath, IN LPCTSTR targetPath, IN LPCTSTR cmdLine)
free_pe_buffer(loaded_pe, payloadImageSize);
return false;
}
if (g_PatchRequired) {
#ifndef _WIN64
patch_NtManageHotPatch32(pi.hProcess);
patch_NtManageHotPatch32(pi.hProcess);
#else
patch_NtManageHotPatch64(pi.hProcess);
patch_NtManageHotPatch64(pi.hProcess);
#endif
}
//3. Perform the actual RunPE:
bool isOk = _run_pe(loaded_pe, payloadImageSize, pi, is32bit_payload);
//4. Cleanup:
Expand Down

0 comments on commit 78df8f1

Please sign in to comment.