Skip to content

Find start addresses of unique arm64 instruction sequences in loaded macho images at runtime

Notifications You must be signed in to change notification settings

doraorak/simplePatchFinder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Info

This is a c/cpp library that uses capstone (https://www.capstone-engine.org) to find start addresses of an unique sequence of instruction mnemonics in a given image (main executable, dylib or a framework).

The search is done in terms of mnemonics (instruction strings like "mov", "str" etc).

You can also compare operands on specific mnemonics with this format "mov x1", "mov x2 x18", "mov x1 #0x4", "mov * x2".

* will ignore that operand but still match other operands. "mov x1" will only match first operand to x1 but will not match second operand. Per capstones formatting hex addresses need to have a leading '#' (i.e #0x192e39000). Square bracket operands need to be formatted as such: [sp, #-0x10]!

see simplePatchFinder-Test for an example of this format.

When looking for target sequences in binaries; in order to match instructions generated by our capstone to those generated by a standalone disassembler, its recommended to use radare2 (https://github.com/radareorg/radare2) because radare2's disassembly engine is also capstone.

API

std::vector<uint64_t> image_findInstructions(const struct mach_header_64* mh, std::vector<const char*> targetSequence)
  • mh: image (mach header) to look for the target sequence in. You can pass NULL to search in the main executable.

  • targetSequence: cpp vector of c strings that contains an exact sequence (so the order matters) of string representations (mnemonics) of arm64 instructions. For example "mov" or "bl".

  • return: cpp vector containing start addresses of the found target sequences of instructions (these addresses take ASLR slide into account, so they should be ready for use).

extern "C" const struct mach_header_64* image_getFromBinaryName(const char* binaryName)
  • binaryName: binary name of the loaded image. For example just "AppKit" for /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit or "libobjc.A.dylib" for /usr/lib/libobjc.A.dylib.

  • return: mach header pointer for the target loaded image.

C binding

The library exposes the c function below so it can be used without cpp.

uint64_t* image_findInstructions(const struct mach_header_64* mh, char** targetSequence, size_t size, size_t* outCount)
  • mh: image (mach header) to look for the target sequence in. You can pass NULL to search in the main executable.

  • targetSequence: c array of c strings that contains an exact sequence (so the order matters) of string representations (mnemonics) of arm64 instructions. For example "mov" or "bl".

  • size: count of how many instructions there are in targetSequence.

  • outCount: address of a size_t variable, the variable will be the count of address entries the return array contains after this call.

  • return: c array (caller is responsible for freeing) containing start addresses of the found target sequences of instructions (these addresses take ASLR slide into account, so they should be ready for use).

Dependencies

Depends on capstone library, you can install it via brew install capstone for more information see https://www.capstone-engine.org.

The binaries in the releases page are statically linked to capstone so it should work standalone without any dependencies.

Usage

  1. download the prebuilt library in the releases page.
  2. #include "simplePatchFinder.h".
  3. add the dylib to your projects Libraries & Frameworks section.
  4. see Example for code snippet.

Example

see simplePatchFinder-Test.

#include "simplePatchFinder.h"
const struct mach_header_64* mh = image_getFromBinaryName("libobjc.A.dylib");
std::vector<uint64_t> addresses = image_findInstructions(mh, {"pacibsp", "stp", "stp"});
//for each address entry in `addresses`, first 3 instructions are "pacibsp", "stp", "stp"

About

Find start addresses of unique arm64 instruction sequences in loaded macho images at runtime

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages