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>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<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>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<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>
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</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>
|
</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