Single-header C library for signature scanning on Linux.
This library is for matching byte patterns (signatures) in the memory of a
process. By default, this library only scans the current process, but there is
an external-scanning branch that is able to read external memory using
process_vm_readv
.
It only supports linux, since it parses the /proc/PID/maps
file to get the start
and end addresses of the loaded modules.
The library asumes all signatures are in IDA (DE AD ? EF
) or x64Dbg
(DE AD ?? EF
) format. See also the sigmaker plugin.
For more information on signature scanning and on how this library works, check out my Signature scanning in C blog entry.
To try the example, simply clone the repository, compile it, and run
libsigscan-test.out
. Please see src/main.c and the Usage section for an example
on how to use it.
$ git clone https://github.com/8dcc/libsigscan
$ cd libsigscan
$ make
$ ./libsigscan-test.out
Since this is a simple single-header library, you just need to copy the
libsigscan.h
file and #include
it on your sources.
For a full example, see src/main.c.
The library consists of just 2 functions: sigscan_module()
and sigscan()
.
This function scans all the memory blocks whose name matches the regex
parameter. It uses the Extended Regular Expression (ERE) syntax, so keep that in
mind before escaping certain characters like +
, ?
, etc. See also BRE vs. ERE.
#include "libsigscan.h"
#define MODULE_REGEX ".+/libc\\.so\\.6"
#define SIGNATURE "DE AD BE EF ? ? CA FE"
/* Search only in this module. */
void* match = sigscan_module(MODULE_REGEX, SIGNATURE);
This function scans the whole memory being used by the process (except the
regions that start with [
in /proc/PID/maps
, like heap, stack, etc.). Keep in
mind that depending on the memory being used by the process, it might take a few
seconds, so it’s better to filter the module name whenever possible.
This function is just a wrapper, and calling it is the same as passing NULL
as
the first parameter to sigscan_module
.
#include "libsigscan.h"
#define SIGNATURE "DE AD BE EF ? ? CA FE"
/* Look for those bytes in all loaded modules. */
void* match = sigscan(SIGNATURE);
If you are having any unexpected problems with this library (e.g. it’s not able
to find a signature that you know to be there), try defining LIBSIGSCAN_DEBUG
before including the header.
#define LIBSIGSCAN_DEBUG
#include "libsigscan.h"
void* match = sigscan("DE AD BE EF ? ? CA FE");
That will print some useful information to stdout
. For example:
my-user-program: Searching in all modules matching regex "^.*module\.o$"... libsigscan: Couldn't get any module bounds matching regex "^.*module\.o$" in /proc/self/maps
In that example, you might want to look at the output of cat /proc/self/maps
and
see if, for example, the module.o
line ends with (deleted)
. In that case, you
should remove the $
from the regex.
If any other unexpected errors occur, please report them with as much information as possible.