Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Enable PE hooking
* Add 'hook_function' to hook a PE imported function * Add tutorial on PE hooking (resolve #5) * Add 'PE::get_import' and 'PE::has_import' to retrieve import
- Loading branch information
1 parent
9508d22
commit 24f6b72
Showing
22 changed files
with
558 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BIN
+40.5 KB
doc/sphinx/_static/tutorial/06/06_hooking_1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
+52.8 KB
doc/sphinx/_static/tutorial/06/06_hooking_2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN
+2.64 KB
doc/sphinx/_static/tutorial/06/06_hooking_3.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
.. _02-pe-from-scratch: | ||
|
||
02 - Create a PE from scratch | ||
----------------------------- | ||
|
||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
04 - Hooking | ||
------------ | ||
04 - ELF Hooking | ||
---------------- | ||
|
||
The objective of this tutorial is to hook a library function | ||
|
||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
06 - PE Hooking | ||
--------------- | ||
|
||
The objective of this tutorial is show how we can hook imported functions | ||
|
||
Scripts and materials are available here: `materials <https://github.com/lief-project/tutorials/tree/master/06_PE_hooking>`_ | ||
|
||
------ | ||
|
||
The targeted binary is a simple ``PE64`` *HelloWorld* which prints the first argument on in the console: | ||
|
||
.. code-block:: cpp | ||
#include "stdafx.h" | ||
#include <stdio.h> | ||
int main(int argc, char** argv) { | ||
printf("Hello: %s\n", argv[1]); | ||
return 0; | ||
} | ||
.. code-block:: console | ||
$ PE64_x86-64_binary_HelloWorld.exe World | ||
$ Hello: World | ||
Using LIEF, we will replace the function that prints the message in the console with a ``MessageBox`` | ||
|
||
By disassembling the binary we can see that the *print* occurs in the function ``sub_140001030`` and it uses two | ||
external functions: ``__acrt_iob_func`` and ``__stdio_common_vfprintf``. | ||
|
||
|
||
.. figure:: ../_static/tutorial/06/06_hooking_1.png | ||
:scale: 80 % | ||
:align: center | ||
|
||
|
||
.. figure:: ../_static/tutorial/06/06_hooking_2.png | ||
:scale: 80 % | ||
:align: center | ||
|
||
Due to the Microsoft x64 calling convention, the format is located in the ``rcx`` and the input message in the ``rdx`` register. | ||
|
||
Basically the :ref:`hooking-code` replaces the ``__acrt_iob_func`` function and shows a ``MessageBox`` with the ``rdx`` message. | ||
|
||
.. code-block:: nasm | ||
:caption: hooking code | ||
:name: hooking-code | ||
add rsp, 0x48 ; Stack unwind | ||
xor rcx, rcx ; hWnd | ||
mov rdx, rdx ; Message | ||
mov r8, 0x0140009000 ; Title | ||
xor r9, r9 ; MB_OK | ||
mov rax, 0x014000A3E4 ; MessageBoxA address | ||
call [rax] ; MessageBoxA(hWnd, Message, Title, MB_OK) | ||
xor rcx, rcx ; exit value | ||
mov rax, 0x014000A3d4 ; ExitProcess address | ||
call [rax] ; ExitProcess(0) | ||
ret ; Never reached | ||
.. note:: | ||
|
||
As for tutorial :ref:`02-pe-from-scratch`, the address of ``MessageBoxA`` and ``ExitProcess`` can be found | ||
with the function: | ||
|
||
.. automethod:: lief.PE.Binary.predict_function_rva | ||
:noindex: | ||
|
||
|
||
|
||
|
||
|
||
First we create the ``.htext`` section which will hold the hooking code: | ||
|
||
.. code-block:: python | ||
section_text = lief.PE.Section(".htext") | ||
section_text.content = code | ||
section_text.virtual_address = 0x7000 | ||
section_text.characteristics = lief.PE.SECTION_CHARACTERISTICS.CNT_CODE | lief.PE.SECTION_CHARACTERISTICS.MEM_READ | lief.PE.SECTION_CHARACTERISTICS.MEM_EXECUTE | ||
section_text = pe.add_section(section_text) | ||
Then the ``.hdata`` section for the ``MessageBox`` title: | ||
|
||
.. code-block:: python | ||
title = "LIEF is awesome\0" | ||
data = list(map(ord, title)) | ||
section_data = lief.PE.Section(".hdata") | ||
section_data.content = data | ||
section_data.virtual_address = 0x8000 | ||
section_data.characteristics = lief.PE.SECTION_CHARACTERISTICS.CNT_INITIALIZED_DATA | lief.PE.SECTION_CHARACTERISTICS.MEM_READ | ||
section_data = pe.add_section(section_data) | ||
As the ASLR is enabled we will disable it to avoid to deal with relocations: | ||
|
||
.. code-block:: python | ||
binary.optional_header.dll_characteristics &= ~lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE | ||
We will also disable the ``NX`` protection: | ||
|
||
|
||
.. code-block:: python | ||
binary.optional_header.dll_characteristics &= ~lief.PE.DLL_CHARACTERISTICS.NX_COMPAT | ||
As ``ExitProcess`` is not imported in ``KERNEL32.dll`` we need to add it: | ||
|
||
.. code-block:: python | ||
kernel32 = binary.get_import("KERNEL32.dll") | ||
kernel32.add_entry("ExitProcess") | ||
The ``MessageBoxA`` function is located in the ``user32.dll`` thus we have to add it: | ||
|
||
|
||
.. code-block:: python | ||
user32 = binary.add_library("user32.dll") | ||
user32.add_entry("MessageBoxA") | ||
Then we proceed to the hook of the ``__acrt_iob_func`` function: | ||
|
||
.. code-block:: python | ||
pe.hook_function("__acrt_iob_func", binary.optional_header.imagebase + section_text.virtual_address) | ||
And finally we configure the :class:`~lief.PE.Builder` to create a new import table and to patch the original one with trampolines. | ||
|
||
.. code-block:: python | ||
builder = lief.PE.Builder(binary) | ||
builder.build_imports(True).patch_imports(True) | ||
builder.build() | ||
builder.write("lief_pe_hooking.exe") | ||
Now we can run the final executable: | ||
|
||
.. code-block:: console | ||
$ lief_pe_hooking.exe "Hooking World" | ||
.. figure:: ../_static/tutorial/06/06_hooking_3.png | ||
:scale: 80 % | ||
:align: center | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -9,6 +9,7 @@ Tutorials | ||
03_elf_change_symbols.rst | ||
04_elf_hooking.rst | ||
05_elf_infect_plt_got.rst | ||
06_pe_hooking.rst | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.