Browse Source

simple_tests

master
aaaaaa aaaaaaa 6 years ago
parent
commit
815a98c688
7 changed files with 12179 additions and 0 deletions
  1. +31
    -0
      hook_tests/README.md
  2. +12012
    -0
      hook_tests/catch.hpp
  3. +12
    -0
      hook_tests/hook_tests.vcxproj
  4. +22
    -0
      hook_tests/hook_tests.vcxproj.filters
  5. +17
    -0
      hook_tests/main.cpp
  6. +54
    -0
      hook_tests/simple_tests.asm
  7. +31
    -0
      hook_tests/simple_tests.h

+ 31
- 0
hook_tests/README.md View 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
- 0
hook_tests/catch.hpp
File diff suppressed because it is too large
View File


+ 12
- 0
hook_tests/hook_tests.vcxproj View File

@@ -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">

+ 22
- 0
hook_tests/hook_tests.vcxproj.filters View File

@@ -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
- 0
hook_tests/main.cpp View 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
- 0
hook_tests/simple_tests.asm View 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
- 0
hook_tests/simple_tests.h View 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);
};

Loading…
Cancel
Save