EndProject | EndProject | ||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tester", "tester\tester.vcxproj", "{8182D1BA-E651-4668-9EC1-A3023AAFD5AC}" | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tester", "tester\tester.vcxproj", "{8182D1BA-E651-4668-9EC1-A3023AAFD5AC}" | ||||
ProjectSection(ProjectDependencies) = postProject | ProjectSection(ProjectDependencies) = postProject | ||||
{0E055CAF-C68B-42CB-A302-F775CA5A917F} = {0E055CAF-C68B-42CB-A302-F775CA5A917F} | |||||
{8C444ABC-D25C-4B44-8F27-081B464D9AE4} = {8C444ABC-D25C-4B44-8F27-081B464D9AE4} | {8C444ABC-D25C-4B44-8F27-081B464D9AE4} = {8C444ABC-D25C-4B44-8F27-081B464D9AE4} | ||||
EndProjectSection | EndProjectSection | ||||
EndProject | EndProject |
class AbstractHookEngine { | class AbstractHookEngine { | ||||
private: | private: | ||||
const char* name_; | const char* name_; | ||||
public: | |||||
/* boolean for each hook test case, which are set by the hooks */ | |||||
struct { | |||||
bool small_; | |||||
bool branch; | |||||
bool rip_relative; | |||||
}; | |||||
public: | public: | ||||
AbstractHookEngine(const char* name) : name_(name) { | AbstractHookEngine(const char* name) : name_(name) { | ||||
virtual bool hook_all() = 0; | virtual bool hook_all() = 0; | ||||
virtual bool unhook_all() = 0; | virtual bool unhook_all() = 0; | ||||
virtual bool all_hooked() = 0; | |||||
bool all_hooked() { | |||||
return small_ && branch && rip_relative; | |||||
} | |||||
const char* name() { | const char* name() { | ||||
return name_; | return name_; |
#include "abstracthook.h" | #include "abstracthook.h" | ||||
#include "mhook.h" | #include "mhook.h" | ||||
#pragma comment(lib, "..\\x64\\release\\test_cases.lib") | |||||
#pragma comment(lib, "..\\x64\\debug\\test_cases.lib") | |||||
extern AbstractHookEngine* g_mhook; | extern AbstractHookEngine* g_mhook; | ||||
}; | }; | ||||
for(auto&& x : engines) { | for(auto&& x : engines) { | ||||
x->hook_all(); | |||||
if (!x->hook_all()) { | |||||
std::cerr << x->name() << " can't hook\n"; | |||||
x->unhook_all(); | |||||
continue; | |||||
} | |||||
SelfTest(); | SelfTest(); | ||||
std::cout << x->name() << ':' << x->all_hooked() << '\n'; | std::cout << x->name() << ':' << x->all_hooked() << '\n'; | ||||
x->unhook_all(); | x->unhook_all(); |
#pragma comment(lib, "..\\x64\\debug\\test_cases.lib") | #pragma comment(lib, "..\\x64\\debug\\test_cases.lib") | ||||
static TypeSmall trueSmall = &_small; | static TypeSmall trueSmall = &_small; | ||||
static TypeBranch trueBranch = &_branch; | |||||
static TypeRip_relative trueRip_Relative = &_rip_relative; | |||||
AbstractHookEngine* g_mhook = new MHook(); | AbstractHookEngine* g_mhook = new MHook(); | ||||
static uint64_t hookSmall(void) { | |||||
uint64_t MHook_Hooks::hookSmall(void) { | |||||
g_mhook->small_ = true; | |||||
return trueSmall(); | return trueSmall(); | ||||
} | } | ||||
bool MHook::hook_all(void) { | |||||
return Mhook_SetHook((PVOID*)&trueSmall, hookSmall); | |||||
uint64_t MHook_Hooks::hookBranch(uint64_t x) { | |||||
g_mhook->branch = true; | |||||
return trueBranch(x); | |||||
} | } | ||||
bool MHook::unhook_all() { | |||||
return Mhook_Unhook((PVOID*)&trueSmall); | |||||
uint64_t MHook_Hooks::hookRip_relative(void) { | |||||
g_mhook->rip_relative = true; | |||||
return trueRip_Relative(); | |||||
} | } | ||||
bool MHook::all_hooked() { | |||||
return true; | |||||
bool MHook::hook_all(void) { | |||||
bool ret = Mhook_SetHook((PVOID*)&trueSmall, &MHook_Hooks::hookSmall); | |||||
ret |= Mhook_SetHook((PVOID*)&trueBranch, &MHook_Hooks::hookBranch); | |||||
ret |= Mhook_SetHook((PVOID*)&trueRip_Relative, &MHook_Hooks::hookRip_relative); | |||||
return ret; | |||||
} | |||||
bool MHook::unhook_all() { | |||||
return Mhook_Unhook((PVOID*)&trueSmall) && | |||||
Mhook_Unhook((PVOID*)&trueBranch) && | |||||
Mhook_Unhook((PVOID*)&trueRip_Relative); | |||||
} | } |
#pragma once | #pragma once | ||||
namespace MHook_Hooks { | |||||
uint64_t hookSmall(void); | |||||
uint64_t hookBranch(uint64_t); | |||||
uint64_t hookRip_relative(void); | |||||
}; | |||||
class MHook : public AbstractHookEngine { | class MHook : public AbstractHookEngine { | ||||
public: | public: | ||||
bool hook_all(); | bool hook_all(); | ||||
bool unhook_all(); | bool unhook_all(); | ||||
bool all_hooked(); | |||||
MHook() : AbstractHookEngine("MHook") { | MHook() : AbstractHookEngine("MHook") { | ||||
} | } | ||||
friend uint64_t MHook_Hooks::hookSmall(void); | |||||
friend uint64_t MHook_Hooks::hookBranch(uint64_t); | |||||
friend uint64_t MHook_Hooks::hookRip_relative(void); | |||||
}; | }; |
<Link> | <Link> | ||||
<SubSystem>Console</SubSystem> | <SubSystem>Console</SubSystem> | ||||
<GenerateDebugInformation>true</GenerateDebugInformation> | <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> | |||||
</Link> | </Link> | ||||
</ItemDefinitionGroup> | </ItemDefinitionGroup> | ||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Object Include="..\x64\Debug\mhook.obj" /> | <Object Include="..\x64\Debug\mhook.obj" /> | ||||
<Object Include="..\x64\Debug\disasm.obj" /> | |||||
<Object Include="..\x64\Debug\disasm_x86.obj" /> | |||||
<Object Include="..\x64\Debug\misc.obj" /> | <Object Include="..\x64\Debug\misc.obj" /> | ||||
<Object Include="..\x64\Debug\disasm_x86.obj" /> | |||||
<Object Include="..\x64\Debug\disasm.obj" /> | |||||
<Object Include="..\x64\Debug\cpu.obj" /> | <Object Include="..\x64\Debug\cpu.obj" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
</Project> | </Project> |
#pragma once | #pragma once | ||||
#include "../test_cases/test_cases.h" | #include "../test_cases/test_cases.h" | ||||
typedef uint64_t(*TypeSmall)(void); | |||||
typedef uint64_t(*TypeSmall)(void); | |||||
typedef uint64_t (*TypeBranch)(uint64_t); | |||||
typedef uint64_t (*TypeRip_relative)(void); |