Selaa lähdekoodia

simple_tests

master
aaaaaa aaaaaaa 6 vuotta sitten
vanhempi
commit
815a98c688
7 muutettua tiedostoa jossa 12179 lisäystä ja 0 poistoa
  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 Näytä tiedosto

@@ -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
Näytä tiedosto


+ 12
- 0
hook_tests/hook_tests.vcxproj Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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…
Peruuta
Tallenna