simple_tests
This commit is contained in:
31
hook_tests/README.md
Normal file
31
hook_tests/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
This project aims to give a simple overview on how good various x64 hooking
|
||||
engines (on windows) are. I'll try to write various functions, that are hard to
|
||||
patch and then see how each hooking engine does.
|
||||
|
||||
I'll test:
|
||||
* [EasyHook]()
|
||||
* [PolyHook]()
|
||||
|
||||
(I'd like to test detours, but I'm not willing to pay for it. So that isn't
|
||||
tested :( )
|
||||
|
||||
There are multiple things that make hooking difficult. Maybe you want to patch
|
||||
while the application is running -- in that case you might get race conditions,
|
||||
as the application is executing your half finished hook. Maybe the software has
|
||||
some self protection features (or other software on the system provides that,
|
||||
e.g. Trustee Rapport)
|
||||
|
||||
Evaluating how the hooking engines stack up against that is not the goal here.
|
||||
This is just about the challenges the function to be hooked itself poses.
|
||||
|
||||
Namely:
|
||||
* Are jumps relocated?
|
||||
* What about RIP adressing?
|
||||
* If it's a tail recurisve function, does the hooking engine handle it?
|
||||
* How good is the dissassembler, how many instructions does it know?
|
||||
|
||||
Test cases
|
||||
==========
|
||||
12012
hook_tests/catch.hpp
Normal file
12012
hook_tests/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -146,6 +146,18 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="catch.hpp" />
|
||||
<ClInclude Include="simple_tests.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" />
|
||||
<None Include="simple_tests.asm" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="simple_tests.obj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -14,4 +14,26 @@
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="catch.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="simple_tests.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="simple_tests.asm">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="README.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="simple_tests.obj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
17
hook_tests/main.cpp
Normal file
17
hook_tests/main.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
||||
#include "simple_tests.h"
|
||||
|
||||
TEST_CASE("Functions work as expected, unhooked") {
|
||||
REQUIRE(_small() == 0);
|
||||
|
||||
REQUIRE(_branch(1) == 0);
|
||||
REQUIRE(_branch(0) == 0);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
REQUIRE(_rip_relative() == rand());
|
||||
}
|
||||
}
|
||||
54
hook_tests/simple_tests.asm
Normal file
54
hook_tests/simple_tests.asm
Normal file
@@ -0,0 +1,54 @@
|
||||
format ms64 coff
|
||||
|
||||
section '.text' code readable writeable executable
|
||||
|
||||
use64
|
||||
|
||||
public _small
|
||||
_small:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
public _rip_relative
|
||||
_rip_relative:
|
||||
mov eax, [seed]
|
||||
mov ecx, 214013
|
||||
mul ecx
|
||||
add eax, 2531011
|
||||
mov [seed], eax
|
||||
|
||||
shr eax, 16
|
||||
and eax, 0x7FFF
|
||||
ret
|
||||
|
||||
seed dd 1
|
||||
|
||||
public _branch
|
||||
_branch:
|
||||
and rax, 1
|
||||
jz @branch_ret
|
||||
xor rax, rax
|
||||
|
||||
nop ; Just some padding, so the function can't be copied entirely into the
|
||||
nop ; trampoline
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
@branch_ret:
|
||||
ret
|
||||
|
||||
31
hook_tests/simple_tests.h
Normal file
31
hook_tests/simple_tests.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
extern "C" {
|
||||
/**
|
||||
* A small function, that always returns 0
|
||||
*/
|
||||
uint64_t _small(void);
|
||||
|
||||
/**
|
||||
* This function checks if the parameter is even or odd, and then
|
||||
* always returns 0.
|
||||
*
|
||||
* The check is done with a branch, so the hooking engine has to take that
|
||||
* into account.
|
||||
*
|
||||
* @param Number to be checked
|
||||
*/
|
||||
uint64_t _branch(uint64_t);
|
||||
|
||||
/**
|
||||
* Replicates the MSVCRT rand().
|
||||
*
|
||||
* This function is used to check whether the hooking engine correctly fixes
|
||||
* rip relative addressing.
|
||||
*
|
||||
* @internal:
|
||||
* static seed = 1;
|
||||
* return( ((seed = seed * 214013L
|
||||
* + 2531011L) >> 16) & 0x7fff );
|
||||
*/
|
||||
uint64_t _rip_relative(void);
|
||||
};
|
||||
Reference in New Issue
Block a user