Bläddra i källkod

simple_tests

master
aaaaaa aaaaaaa 7 år sedan
förälder
incheckning
815a98c688
7 ändrade filer med 12179 tillägg och 0 borttagningar
  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 Visa fil

@@ -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
Filskillnaden har hållits tillbaka eftersom den är för stor
Visa fil


+ 12
- 0
hook_tests/hook_tests.vcxproj Visa fil

@@ -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 Visa fil

@@ -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 Visa fil

@@ -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 Visa fil

@@ -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 Visa fil

@@ -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);
};

Laddar…
Avbryt
Spara