Flag: Tornado! Hurricane!

Blogs >> bihariking's Blog

Created: Sunday, October 16 2011 12:23.26 CDT  
Printer Friendly ...
DLL Injection on Linux using Hotpatch
Author: bihariking # Views: 4604

Introduction to Hotpatch
=========================
Hotpatch is a library that can be used to dynamically load a shared library
(.so) file on Linux from one process into another already running process,
without affecting the execution of the target process. The API is a C API, but
also supported in C++.

The current version is 0.1.
Source code can be found on http://bit.ly/pi8fq7

The limitations, directions on how to use, and possible uses of hotpatch will be
explained in this document.

The main idea of hotpatch stems from the fact that in Linux, it is not easy to
load a library into another already running process. In Windows, there is an API
called CreateRemoteThread() that can load a library into another process very
easily with a couple of API calls. Hotpatch makes this functionality available
to Linux users and developers, with a single API call. Unlike other available
injection libraries, hotpatch restores the execution of the process to its
original state.

The user can do the following with hotpatch:
- load his/her own .so file into an already running process
- invoke a custom symbol/function in that .so file
- pass arguments to that function as long as it is serialized to the form of a
  byte buffer and length of the buffer. This shall be explained more later.

Hotpatch is available as an API with a header file called "hotpatch.h" and a
.so file called "libhotpatch.so", and also a commandline application called
"hotpatcher" which can inject .so files into processes via the commandline
itself. Hotpatch also comes with a test .so called "libhotpatchtest.so"
which can be used via the commandline "hotpatcher" application to test out
the working of hotpatch on any system. The "libhotpatchtest.so" has a symbol
"mysym" that can be invoked, and it writes to the "/tmp/hotpatchtest.log" file
with the timestamp at which the .so file was injected and anything else.

Limitations
============
NOTE: Currently if hotpatch is compiled in 64-bit mode, it can inject libraries
only in 64-bit processes, and if compiled in 32-bit mode can inject libraries
only in 32-bit processes. It cannot inject from a 64-bit to a 32-bit process or
from a 32-bit to a 64-bit process.

There are some limitations, the main being that the user can inject a library
.so file only in a process on which the user has privileges over. For example,
as the root user, hotpatch can inject libraries into any process, but as a
regular non-root user, hotpatch can inject libraries into only those processes
that hotpatch has access to, i.e. the user's processes and any other via sudo
privileges.

The other limitation is that if the user needs to compile his shared library
with the linker options "-fPIC -nostartfiles" so that hotpatch can reliably load
the .so file.

Another limitation is that injection for a particular .so file can happen only
once in the target process. Each library that is injected can be injected only
once into the target process.

Usage: API
===========

The "hotpatch.h" header file needs to be included by the user. There are 3 main
API calls that matter. Each of them have to be called in the order as shown
below in the sample program.

- hotpatch_t *hotpatch_create(pid_t pid, int verbose);

This function takes a PID of the target process, and the verbosity level
(between 0 to 6), and returns an opaque object which contains further intimate
details about the process such as current library mappings, and locations of the
important functions needed for hotpatch to do its work.

- int hotpatch_inject_library(hotpatch_t *hp,
                              const char *sofile,
                              const char *symbol,
                              const unsigned char *data,
                              size_t datalen,
                              uintptr_t *out_addr,
                              uintptr_t *out_result);

This function takes the newly created hotpatch object, along with a path to the
shared library in the variable "sofile", the optional function "symbol" to invoke,
along with the serialized arguments to the function provided in "data" and
"datalen" which are also optional. The return address of where the library was
loaded is returned in "out_addr" and the return value of the invocation of
"symbol" is returned in "out_result". On success this returns 0 and on failure
returns -1.

The verbosity levels can be adjusted accordingly from 0 to 6 to see debugging
information for investigating errors.

The usefulness of the "data" and "datalen" parameters is extremely high. Suppose
the user has a custom function they want to invoke, and the arguments of the
function is a big struct or a class. The user can then write a wrapper function
that takes a serialized buffer of this struct/class along with the length of the
buffer and invoke that wrapper function. This wrapper function can then
deserialize this buffer into the struct/class as needed and call the actual
function that the user really wanted to invoke. This functionality is only
available by the API and not by the "hotpatcher" executable.

- void hotpatch_destroy(hotpatch_t *hp);

This function cleans up memory and resources used by the hotpatch opaque object.

Sample Program
==============

#include <hotpatch.h>

int main(int argc, char **argv)
{
    pid_t pid = argc > 1 ? atoi(argv[1]) : 0;
    hotpatch_t *hp = hotpatch_create(pid, 1);
    if (hp) {
        unsigned char *data = (unsigned char *)"my custom serialized data";
        size_t datalen = strlen((char *)data) + 1;
        uintptr_t result1, result2;
        hotpatch_inject_library(hp, "libhotpatchtest.so", "mysym",
                        data, datalen, &result1, &result2);
        hotpatch_destroy(hp);
    }
    return 0;
}

Usage: Hotpatcher
==================

The commandline "hotpatcher" can be executed with the "-h" option to see the
various options that are supported.

A sample execution of "hotpatcher" into the current running shell can be done as
below:

Let's say the library libhotpatchtest.so is in the current directory.

bash> ./hotpatcher -l ./libhotpatchtest.so -s mysym -v1 $$

On success the "/tmp/hotpatchtest.log" file can be checked if it has the
timestamp of the injection.

Uses of Hotpatch
=================
Most uses of hotpatch are related to custom modifications of processes for which
the users do not have source code available.

- System administrators can use hotpatch to inject their own custom libraries in
  already running processes and change behavior as per requirement. Some such
behavior could be adding a library that creates a thread and heartbeats to a
monitoring system.

- Many software applications, that are not mission critical, are not built with
  mechanisms to update their software without having to stop the application and
restarting it. Hotpatch can help modify applications to restart and do other
fancy tricks without losing the PID and the other states such as file handles of
the applications that might be very useful or too risky to let go.

- Users can inject a library and then set up RPC service calls for the target
  application without changing any code.

- Users can inject a library and with import table modifications can instrument
  the target application for things like profiling, reverse engineering and also
debugging. This is useful as it does not necessarily need the application to be
recompiled and performance numbers can be extracted. The code to do import table
modifications is currently outside the scope of hotpatch.

- Users can create threads in other processes and make them work like a cluster
  of processes that they control.

- Users can modify another application and make it perform better by doing
  tricks in the injected code.





Blog Comments
ezln Posted: Friday, November 11 2011 19:02.52 CST
This sounds pretty cool, but it took a non-trivial amount of googling to find out where to get it:

https://github.com/vikasnkumar/hotpatch




Add New Comment
Comment:









There are 30,782 total registered users.


Recently Created Topics
How can I write olly...
Oct/05
Career: Malware Reve...
Sep/30
How to produce separ...
Sep/20
How to decompile a f...
Sep/16
How to trap mouse cl...
Sep/03
Intel pin in loaded ...
Jun/27
Going to do today wi...
Jun/27
how to create delphi...
Jun/27
enabling menu in a s...
Jun/18
How to get the Image...
Jun/17


Recent Forum Posts
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n
OOP_RE tool available?
van7hu
Should binaries be n...
Kolisar
Problem with ollydbg
nullx42
!findtrampoline Immu...
skycrack
looking for a softwa...
raxen
Documenting reversed...
raxen
.orpc section what's...
mbin


Recent Blog Entries
oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

oleavr
Apr/17
frida.re 1.2.0 is out, with...

More ...


Recent Blog Comments
djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

newlulu on:
Jun/10
Branch tracing and LBR acce...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit