Compare commits
2 Commits
75cf1e7f71
...
9fd9e66340
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fd9e66340 | |||
| 8f73fcf829 |
@@ -7,7 +7,7 @@ draft: false
|
||||
I wanted to get back into ARM assembler so I wrote my own strlen. And then I looked at the strlen() glibc uses and did not understand
|
||||
a single thing. So I sat down and figured it out.
|
||||
|
||||
XXX IMG HERE XXX
|
||||

|
||||
|
||||
On the left you see a flow diagram of the building blocks of my naive implementation. On the right you see glibc's. You might
|
||||
notice that it is more complex. (How much faster it is, and which optimization exactly makes it fast is an interesting topic.
|
||||
@@ -22,7 +22,7 @@ The first thing I noticed about the inner loop is that it is unrolled. That is a
|
||||
because strlen does not clearly unroll as the input is cleanly divisible by word size. So on the end of every basic block there
|
||||
is a check which skips out of the loop and to the end where the result is calculated and returned.
|
||||
|
||||
XXX IMG HERE XXX
|
||||

|
||||
|
||||
The basic blocks are basically identical. First the registers r2 and r3 are populated with the next two words to be checked for
|
||||
the null byte. Now r2 and r3 each contain one word (i.e. 4 bytes). How do you check whether there is a null byte *somewhere* in them?
|
||||
|
||||
71
content/projects/hookengs.md
Normal file
71
content/projects/hookengs.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: "Hooking Engine Deatmatch"
|
||||
description: "Evaluating various hooking engines, putting them against pathologically hard to hook functions"
|
||||
date: 2020-02-26T22:00:00+01:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
For the full code see the [git repo](https://vcs.wacked.codes/wacked/hook_tests).
|
||||
|
||||
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](https://easyhook.github.io/)
|
||||
* [PolyHook](https://github.com/stevemk14ebr/PolyHook)
|
||||
* [MinHook](https://www.codeproject.com/Articles/44326/MinHook-The-Minimalistic-x-x-API-Hooking-Libra)
|
||||
* [Mhook](http://codefromthe70s.org/mhook24.aspx)
|
||||
|
||||
(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.
|
||||
Neither are non-functional criteria, like how fast it is or how much memory it
|
||||
needs for each hook. This is just about the challenges the function to be
|
||||
hooked itself poses.
|
||||
|
||||
Namely:
|
||||
|
||||
* Are jumps relocated?
|
||||
* What about RIP adressing?
|
||||
* If there's a loop at the beginning / if it's a tail recurisve function, does
|
||||
the hooking engine handle it?
|
||||
* How good is the dissassembler, how many instructions does it know?
|
||||
* Can it hook already hooked functions?
|
||||
|
||||
At first I will give a short walk through of the architecture, then quickly go
|
||||
over the test cases. After that come the results and an evaluation for each
|
||||
engine.
|
||||
|
||||
I think I found a flaw in all of them; I'll publish a small POC which should at
|
||||
least detect the existence of problematic code.
|
||||
|
||||
**A word of caution**: my results are worse than expected, so do assume I have
|
||||
made a mistake in using the libraries. I went into this expecting that some
|
||||
engines at least would try to detect e.g. the loops back into the first few
|
||||
bytes. But none did? That's gotta be wrong.
|
||||
|
||||
**Another word of caution**: parts of this are rushed and/or ugly. Please
|
||||
double check parts that seem suspicious. And I'd love to get patches, even for
|
||||
the most trivial things -- spelling mistakes? Yes please.
|
||||
|
||||
|
||||
Result
|
||||
========
|
||||
|
||||
| Name|Small|Branch|RIP Relative|AVX|RDRAND|Loop|TailRec|
|
||||
|----------|-----|------|------------|---|------|----|-------|
|
||||
| PolyHook| X | X | X | X | | | |
|
||||
| MinHook| X | X | X | | | | X |
|
||||
| MHook| | | X | | | | |
|
||||
|
||||
BIN
static/img/arm-glibc-strlen/strlen-loop.png
Normal file
BIN
static/img/arm-glibc-strlen/strlen-loop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
static/img/arm-glibc-strlen/strlen-side-by-side.png
Normal file
BIN
static/img/arm-glibc-strlen/strlen-side-by-side.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
Reference in New Issue
Block a user