{"id":19430256,"url":"https://github.com/8dcc/libsigscan","last_synced_at":"2025-04-24T18:33:27.658Z","repository":{"id":230769036,"uuid":"780033991","full_name":"8dcc/libsigscan","owner":"8dcc","description":"Single-header C/C++ library for signature scanning on Linux.","archived":false,"fork":false,"pushed_at":"2024-04-21T22:56:43.000Z","size":38,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-22T02:25:59.906Z","etag":null,"topics":["c","c-library","cpp","game-hacking","hacking","library","signature-scanning","sigscan"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/8dcc.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-03-31T14:10:36.000Z","updated_at":"2024-04-23T12:42:36.476Z","dependencies_parsed_at":"2024-03-31T20:26:29.362Z","dependency_job_id":"3286233d-957b-4981-b632-d0584e666a6c","html_url":"https://github.com/8dcc/libsigscan","commit_stats":null,"previous_names":["8dcc/libsigscan"],"tags_count":1,"template":false,"template_full_name":"8dcc/c-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8dcc%2Flibsigscan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8dcc%2Flibsigscan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8dcc%2Flibsigscan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/8dcc%2Flibsigscan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/8dcc","download_url":"https://codeload.github.com/8dcc/libsigscan/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223963187,"owners_count":17232613,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","c-library","cpp","game-hacking","hacking","library","signature-scanning","sigscan"],"created_at":"2024-11-10T14:24:09.050Z","updated_at":"2024-11-10T14:24:09.730Z","avatar_url":"https://github.com/8dcc.png","language":"C","readme":"#+title: libsigscan\n#+options: toc:nil\n#+startup: showeverything\n#+author: 8dcc\n\n#+TOC: headlines 2\n\n*Simple C/C++ library for signature scanning on Linux.*\n\nThis library is for matching byte patterns (signatures) in the memory of a\nprocess. It's able to scan the memory of the current process, or an external\nprocess using the =process_vm_readv= function.\n\nIt only supports linux, since it parses the =/proc/PID/maps= file to get the start\nand end addresses of the loaded modules.\n\nThe library asumes all signatures are in [[https://hex-rays.com/ida-pro/][IDA]] (=DE AD ? EF=) or [[https://x64dbg.com/][x64Dbg]]\n(=DE AD ?? EF=) format. See also the [[https://github.com/ajkhoury/SigMaker-x64][sigmaker]] plugin.\n\nFor more information on signature scanning and on how this library works, check\nout my [[https://8dcc.github.io/programming/signature-scanning.html][Signature scanning in C]] blog entry.\n\n* Building the example\n\nTo try the example, simply clone the repository, compile it, and run\n=libsigscan-test.out=. Please see [[file:src/main.c][src/main.c]] and the /Usage/ section for an example\non how to use it.\n\n#+begin_src console\n$ git clone https://github.com/8dcc/libsigscan\n$ cd libsigscan\n$ make\n$ ./libsigscan-test.out\n#+end_src\n\nIf you want to try the external example, run the following two commands in\nseparate terminals after compiling.\n\n#+begin_src console\n$ ./libsigscan-test-external.out  # Simulates target process, keep it open\n$ sudo ./libsigscan-test.out      # Scans the other process, needs root\n#+end_src\n\n* Usage\n** Including in a project\n\nIf you want to use this library, simply copy the detour source and headers to\nyour project, =#include= the header in your source files and compile the\n=libsigscan.c= source with the rest of your code.\n\nFor a full example, see [[file:src/main.c][src/main.c]]. For more information on how to compile it,\nsee the [[file:Makefile][Makefile]].\n\n** Public functions\n\nThe library is pretty simple and consists of one main function for signature\nscanning, and some wrappers for it. There are also some utilities that may be\nused independently. All the functions are documented in [[file:src/libsigscan.h][the header]], but I will\nexplain them here as well.\n\n*** =sigscan_pidof=\n\nThis utility function can be used to get the PID of a process by name.\n\n#+begin_src C\n#include \"libsigscan.h\"\n\nint pid = sigscan_pidof(\"my-test.out\");\n#+end_src\n\n*** =sigscan_pid_module=\n\nThis is the main function of the library. It scans all the modules loaded by the\nprocess with the specified =pid=, whose name matches the specified =regex=.\n\nIt uses POSIX [[https://www.gnu.org/software/sed/manual/html_node/ERE-syntax.html][Extended Regular Expression]] (ERE) syntax, so keep that in mind\nbefore escaping certain characters like =+=, =?=, etc. See also [[https://www.gnu.org/software/sed/manual/html_node/BRE-vs-ERE.html][BRE vs. ERE]].\n\nAlso note that it skips modules starting with =[= in =/proc/PID/maps=, like heap,\nstack, etc.\n\n#+begin_src C\n#include \"libsigscan.h\"\n\n#define MODULE_REGEX \".+/libc\\\\.so\\\\.6\"\n#define SIGNATURE    \"DE AD BE EF ? ? CA FE\"\n\n/*\n ,* Search for a signature in the modules loaded by \"my-test.out\" whose name\n ,* matches the regex.\n ,*/\nint pid     = sigscan_pidof(\"my-test.out\");\nvoid* match = sigscan_pid_module(pid, MODULE_REGEX, SIGNATURE);\n#+end_src\n\n*** =sigscan_pid=, =sigscan_module= and =sigscan=\n\nThese functions are just wrappers for =sigscan_pid_module=.\n\nThe =sigscan_pid= function can be used to search for a pattern in *all modules*\nloaded by the process with the specified PID. Same as using =NULL= as the second\nparameter of =sigscan_pid_module=.\n\nThe =sigscan_module= function can be used to search for a pattern in the modules\nloaded by *the current process*, whose name matches a regex. Same as using\n=SIGSCAN_PID_SELF= as the first parameter of =sigscan_pid_module=.\n\nThe =sigscan= function can be used to search for a pattern in *all modules* loaded\nby *the current process*. Same as using =SIGSCAN_PID_SELF= and =NULL= as the first and\nsecond parameters of =sigscan_pid_module=.\n\n*** =sigscan_get_module_bounds= and =sigscan_free_module_bounds=\n\nThese functions are used internally by the library when calling\n=sigscan_pid_module=. They are exposed, so the user can call them whenever\nnecessary.\n\nThe =sigscan_get_module_bounds= function parses the =/proc/PID/maps= file (see\n[[https://man.cx/proc(5)][proc(5)]]) to get the start and end addresses of the modules loaded by the process\nwith the specified PID, whose name matches the specified regex. Similarly to\n=sigscan_pid_module=, it accepts =SIGSCAN_PID_SELF= as its first parameter, and =NULL=\nas its second parameter.\n\nIt returns a linked list of =SigscanModuleBounds= structures, and each element\ncontains the start and end addresses of a readable memory chunk. The caller is\nresponsible for freeing this linked list by calling =sigscan_free_module_bounds=.\n\n* Troubleshooting\n\nIf you are having any unexpected problems with this library (e.g. it's not able\nto find a signature that you know to be there), try compiling the =libsigscan.c=\nsource with =LIBSIGSCAN_DEBUG= defined. You can easily do this by adding the\nfollowing compilation option to your =CFLAGS=.\n\n#+begin_src diff\n-CFLAGS=-std=gnu99 -Wall -Wextra -Wpedantic\n+CFLAGS=-std=gnu99 -Wall -Wextra -Wpedantic -DLIBSIGSCAN_DEBUG\n#+end_src\n\nNow the library will print some useful information to =stderr=. For example:\n\n#+begin_example\nmy-user-program: Searching in all modules matching regex \"^.*module\\.o$\"...\nlibsigscan: Couldn't get any module bounds matching regex \"^.*module\\.o$\" in /proc/364195/maps\n#+end_example\n\nIn that example, you might want to look at the output of =cat /proc/self/maps= and\nsee if, for example, the =module.o= line ends with =(deleted)=. In that case, you\nshould remove the =$= from the regex.\n\nIf any other unexpected errors occur, please [[https://github.com/8dcc/libsigscan/issues][report them]] with as much\ninformation as possible.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F8dcc%2Flibsigscan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F8dcc%2Flibsigscan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F8dcc%2Flibsigscan/lists"}