-
Notifications
You must be signed in to change notification settings - Fork 13
/
vectored_handler.hpp
93 lines (79 loc) · 2.48 KB
/
vectored_handler.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright (C) 2010-2015 Joshua Boyce
// See the file COPYING for copying permission.
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <windows.h>
#include <hadesmem/config.hpp>
#include <hadesmem/process.hpp>
#include <hadesmem/error.hpp>
#include <hadesmem/find_pattern.hpp>
#include <hadesmem/detail/winternl.hpp>
#include <hadesmem/detail/trace.hpp>
// It would be better to use data structures already available
// from 3rd part libraries that hadesmem already includes in order
// to provide the x86 instruction encodings.
namespace hadesmem
{
namespace detail
{
#pragma pack(push, 1)
struct x86AddInstruction
{
std::int16_t Opcode;
std::int32_t Operand;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct x64LeaInstruction
{
std::uint8_t SecondaryOpcode;
std::uint8_t PrimaryOpcode;
std::uint8_t Register;
std::uint32_t Operand;
};
#pragma pack(pop)
inline winternl::PVECTORED_HANDLER_ENTRY
GetVectoredEhPointer(hadesmem::Process const& process)
{
#if defined(HADESMEM_DETAIL_ARCH_X86)
using InstructionPtrT = x86AddInstruction;
std::wstring const kInstructionPattern{L"81 C3 ?? ?? ?? ?? 53 89 46 0C"};
#elif defined(HADESMEM_DETAIL_ARCH_X64)
using InstructionPtrT = x64LeaInstruction;
std::wstring const kInstructionPattern{
L"48 8D 05 ?? ?? ?? ?? 48 8D ?? ?? 48 8B ??"};
#else
#error "[HadesMem] Unsupported architecture."
#endif
if (process.GetId() != ::GetCurrentProcessId())
{
HADESMEM_DETAIL_THROW_EXCEPTION(
Error{} << ErrorString{
"This feature is only supported on the local process."});
}
auto instruction_ptr = static_cast<InstructionPtrT*>(
hadesmem::Find(process,
L"ntdll.dll",
kInstructionPattern,
hadesmem::PatternFlags::kThrowOnUnmatch,
0U));
HADESMEM_DETAIL_TRACE_FORMAT_A(
"process=%d, instruction=%p", process.GetId(), instruction_ptr);
winternl::PVECTORED_HANDLER_LIST vectored_handler_list = nullptr;
#if defined(HADESMEM_DETAIL_ARCH_X86)
vectored_handler_list = reinterpret_cast<winternl::PVECTORED_HANDLER_LIST>(
instruction_ptr->Operand);
#elif defined(HADESMEM_DETAIL_ARCH_X64)
// Because of x64 RIP relative addressing.
vectored_handler_list = reinterpret_cast<winternl::PVECTORED_HANDLER_LIST>(
reinterpret_cast<std::uint8_t*>(instruction_ptr) +
instruction_ptr->Operand + sizeof(InstructionPtrT));
#else
#error "[HadesMem] Unsupported architecture."
#endif
return vectored_handler_list->First;
}
}
}