Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What do you use this library for? #1

Closed
jzabroski opened this issue Mar 13, 2019 · 2 comments
Closed

What do you use this library for? #1

jzabroski opened this issue Mar 13, 2019 · 2 comments
Labels
good first issue Good for newcomers

Comments

@jzabroski
Copy link

I imagine you do some kind of software security testing? Otherwise, are there practical use cases for this? Just trying to widen my breadth and depth of knowledge as an engineer. Thank you!

@Sewer56 Sewer56 added the good first issue Good for newcomers label Mar 14, 2019
@Sewer56
Copy link
Member

Sewer56 commented Mar 15, 2019

The current readme makes an assumption that you already know the concept of function hooking but I assume that may not hold true for anyone, so allow me to make a simple (but non-short) explanation.


The main purpose of the library is to allow for the extension/modification of precompiled functions/subroutines present in external closed source applications (inside C#) where you are do not have access to the source code.

0. Preamble

Suppose that you compile a sample calculator application in a native language such as C/C++/D, with the following function:

int add(int a, int b) { return a + b; }

Under the hood, this would of course be turned into architecture specific assembly instructions to be executed directly on the processor, in x86/x86-64, such a function may become compiled as:

mov eax, [ebp + 8]
mov ecx, [ebp + 12]
add eax, ecx
ret

1. Patching with hooks.

Now let's assume there was a bug in the calculator, and for instance the actual function was:

int add(int a, int b) { return (a + b) + 1; }

And likewise, the assembly representation may look like this:

mov eax, [ebp + 8]
mov ecx, [ebp + 12]
add eax, ecx
inc eax
ret

Suppose this calculator application was last updated 10 years ago. It is prioprietary, closed source and the developer has long either stopped supporting the application or went bankrupt. You really like the calculator but with such a glaring bug, it is not comfortable to use.

With no possible means of obtaining a possible official fix, what is there that you can do? The obvious option is fix it yourself.

In this specific case you can just remove the extra instruction and call it a day. However, consider what if the bug was considerably more complex, where there is either simply not enough space before the next function or the changes required are relatively complex to do. Using a high level language would be relatively comfortable.

2. Introducing Function Hooks

So you are going to patch the function yourself. Let's pretend the bug is nontrivial to patch in assembly or you simply do not want to patch it in assembly.

You are going to do it in a high level language. While there are a few possibilities from here, though the preferred way to do this would be using a "function hook", which is what this library provides. In general terms, "hooking" covers a range of techniques alter or augment the behaviour of software (imagine "latching" to software).

In the common case, "function hooking" as you may read about it online refers to replacing a compiled assembly function in application code with your own. In effect this means that every time the game calls the original function, it will call your code instead. (Explaining how this works under the hood is beyond the scope of this post).

So how do you get started?
Suppose you reverse engineer part of the application and find the bug/faulty function in the disassembly. You note the start address of a particular function (address of first instruction in function).

The first thing you do, is you let Reloaded.Hooks know what kind of function we're dealing with. In our case, the function follows the standard Cdecl X86 calling convention (set of rules on how to call a function), where all of the parameters are passed up the stack in right to left (as in right to left written in C) order.

/* Define the function. */
[Function(CallingConventions.Cdecl)]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int AddFunction(int a, int b);

From there you can create a function hook using the Hook class, and activate the hook:

/* Define the function. */
public IHook<AddFunction> _addHook = new Hook<AddFunction>(AddImpl, (long)addPointer).Activate();

// addPointer is the address of the original Add function in memory.
// AddImpl is the new function to execute.

So what happens now? Everytime the original application will call the Add function, instead of executing its own, it will execute your C# function, AddImpl.

So, the original function now belongs to our C# code, what can we do?

Option A: Replacing Original Function

public static void Add(int a, int b) { return a + b; }

We can replace the original function outright, and do the calculation ourselves and return the result. The original function is now entirely handled by us.

Option B: Using the Original Function

public static void Add(int a, int b) { return _addHook.OriginalFunction(a,b) - 1; }

We know the original function will return a number which is 1 greater than we expect, so why not just let it run and subtract 1 from the result? Job done.

Summary

In practice, when you make function hooks, you are practically overriding virtual functions. Precompiled native functions from C#, That's all there is to it.

3. Some Common examples of hooking.

Graphics API overlays: Steam, AMD Relive, GeForce Experience, game hack overlays.
Screen Capture: OBS, XSplit etc.
Debugging: Observing behaviour of external applications. e.g. Hook NtCreateFile and intercept file accesses.
Advanced Game Modifications: Reverse engineer, replace, override and modify many game functions for desired effect. One large example would be the Grand Theft Auto modding community in particular for a large selection of mods using function hooks (whether through an interface/API or directly).

4. Why Reloaded.Hooks specifically exists.

In practice, there are many libraries providing function hooks across a multitude of languages. The main reason I originally built this library is because at the time of writing there is no other libraries supporting non-standard and/or custom calling conventions for functions.

In the modern day we have optimising compilers that will try to squeeze the most of performance possible. As a result, in reality, it is very often the case that standard calling conventions (rules) are often broken in favour of performance.

For example imagine a (x86) fastcall calling convention version of the above add function:

mov eax, edx, // Right Parameter
add eax, ecx,  // Left Parameter
ret

In this case, rather than the parameters being on the stack, they are passed through the use of registers as a performance optimisation.

Other C# libraries, for example EasyHook would not be able to support hooking such functions. In Reloaded.Hooks, this is still supported, all you need to do is modify the function definition.

[Function(CallingConventions.Fastcall)] // Set to Fastcall template here.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int AddFunction(int a, int b);

Of course the constructor with the CallingConventions.Fastcall enum is just a template. Reloaded.Hooks supports any custom arbitrary calling conventions.

// Fastcall: Accept two register parameters EDX, ECX. Return value in EAX.
// Caller fixes stack after function call.
[Function(new []{ Register.ecx, Register.edx}, Register.eax, StackCleanup.Caller)]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int AddFunction(int a, int b);

5. Extra note(s)

In order to make use of this library, your program must be in the same address space (process) as the application you want to modify. This is nothing for a bit of Dll Injection to put your DLL inside the target process and DLLExport to be able to call your C# DLL.

Originally I wrote what is in this library as part of Reloaded (Mod Loader), but as the main library (libReloaded) was getting rather huge and difficult to maintain, I decided to slowly start refactoring all of the code, improving it and republishing as small, separate modules.

@Sewer56 Sewer56 pinned this issue Mar 15, 2019
@Sewer56 Sewer56 closed this as completed Mar 15, 2019
@Sewer56
Copy link
Member

Sewer56 commented Mar 15, 2019

I imagine you do some kind of software security testing?
Forgot to answer.

At the moment I'm actually a student. My entire portfolio of knowledge regarding low level programming and reverse engineering has been acquired on my own as a hobbyist.

Aside from that, as mentioned in the footnote of the post above, mainly to tamper with games.

Kouzukii pushed a commit to Kouzukii/Reloaded.Hooks that referenced this issue Dec 11, 2023
Add support for scanning arbitrary ranges & saving compiled patterns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants