GithubHelp home page GithubHelp logo

kweatherman / sigmakerex Goto Github PK

View Code? Open in Web Editor NEW
302.0 5.0 42.0 1.33 MB

Enhanced IDA Pro signature generator plugin.

License: MIT License

Python 4.88% C++ 89.66% C 5.46%
game-hacking reverse-engineering ida-plugin

sigmakerex's Introduction

SigMakerEx

Enhanced IDA Pro signature generator plugin.

Installation

Copy IDA_SigMaker32.dLL and IDA_SigMaker64.dLL to your IDA plugins directory.

The default IDA hot key is "Ctrl-Alt-S", but can be set to another using key your IDA "plugins.cfg". Since "Ctrl-Alt-S" now combo conflicts with an IDA default, to avoid getting warning messages, edit your "idagui.cfg" and make the "StackTrace" entry like: "StackTrace" = 0 // "Ctrl-Alt-S" // open stack trace window (the '0' disables the key).

Requires IDA Pro version 7.6'ish.

Using

Invoke the plugin via its hotkey or via the IDA Edit/Plugin menu.

main

There are three signature generation operations:

  1. Function: Used to create a unique function entry point, a minimal function signature w/offset, or a whole-body signature depending on the Options config (see below).

    First select any address inside the target function. If the selected function is not unique (for the entry point, or the minimal option) then a signature for a unique function cross-reference scan will be attempted.

    Typical use cases: Signatures to locate functions at run time in target memory, to locate functions in IDA after executable updates, or to help locate known libraries by signature, etc.

  1. At address: Attempts to find a unique signature at the selected address. Typical use case: For locating a particular offset at runtime to hook, or making Cheat Engine script signatures for this purpose, etc.
  1. From address range: Generates a signature from the selected address range, not checking for uniqueness. Special use case for when one of the other actions won't work. Like wanting to ignore the uniqueness of a signature, etc.

Example signature output: minimal_func_example

Signature results are pushed to the Windows clipboard for easy CTRL+V pasting into source code, etc.

Options

options

Output format: IDA: The default hex binary search format that IDA and some other tools support, using spaced hex bytes and "??" wildcards. Example: C1 6C E8 ?? ?? ?? ?? 8B 50 08 Code style: Escape coded hex string and a separate mask string where 'x' are keeper bytes, and '?' are wildcard bytes. Example: "\xC1\x6C\xE8\xCC\xCC\xCC\xCC\x8B\x50\x08", "xxx????xxx" Inline byte: A minimalist C style array of bytes with wildcard bytes included format. Example: {0xC1,0x6C,0xE8,0xAE,0xAE,0xAE,0xAE,0x8B,0x50,0x08}; Use the "mask byte" edit box to change the default "Inline byte" mask byte. The default mask byte is 0xAE, one of the least used code bytes (see "Ideal mask byte" below).

Function sigs:

The criteria for "Function" signature generation. Entry point: Will attempt to generate a minimal byte sized function entry point signature when possible. Minimal byte size: Will attempt to generate a minimal, with least wildcards count, byte sized (five are greater) instruction boundary aligned signature inside of the selected function body. Full function body: Will attempt to generate a unique full function body signature.

For any of these three options, if the function is not unique, an attempt will be made to locate the smallest unique cross-reference signature instead. If you wish to make a full or partial function signature for a non-unique function then use the "From address range" option instead.

Message level: Set to "Verbose" for internal signature generation message output to the IDA log window.

Max function scan refs: Limit how many function cross-references to search when a direct "Function" action signature can't be found. Normally this should be '0' for unlimited search, but for problem cases where there are so many references that it causes a slowdown, this can be set to some reasonable limit like 16 or 100 to increase the scanning speed.

For the relatively rare case of functions that have their chunks spread over multiple address ranges, the tool will attempt to use just the first chunk. If wishing to make a signature in one of the disjointed chunks, try using the "At address" method. If all else fails, try a "From address range" sig (which might take some manual searching for uniqueness).

Max function entry point signature bytes: When using the "Function" option, and the "Entry point" criteria is configured, optionally limit the maximum entry point signature byte size. The default is '0', for unlimited (which can be up to the entire selected function body byte size) . If this limit is exceeded, a cross-reference signature will be looked for instead.

Set to a practical limit like '16' or '32', for preferred typically smaller xref signatures vs potentially very large entry point signatures.

Original SigMaker vs SigMakerEx

  1. SigMakerEx ("EX") overall generates smaller and tighter function signatures by using better instruction analysis. Example: SigMaker ("SM") wildcards the operand bytes of instruction sub esp, 90h (as "81 EC ?? ?? ?? ??), throwing out the last four bytes unnecessarily. While EX sees it as an immediate value and keeps the whole 81 EC 90 00 00 00 byte sequence.

  2. EX is better focused on normative function body signature use cases. For SM there is only one controllable option. It will attempt to make a unique signature at wherever address you select in the function. If it can't find one there, it will look for a unique cross-reference sig instead only. For EX, since the identified typical use case is to locate function entry points, the smallest entry point signature will be generated when the "Entry point" criteria option is configured. For when the "Minimal byte size" option is selected, it will look for the smallest and least wildcard count unique signature (of minimum five bytes) within the whole function body.

  3. SM has more output criteria control over byte vs wildcard count, etc., in it's options dialog. EX assumes you want the best of both (least wildcards and smallest byte size).

  4. EX omits the "conversion" and the individual "search" functionality that SM has over a preference for a simpler and less cluttered UI.

    For searching, since EX always emits IDA format output in addition to the selected output format signatures, use the IDA binary search "Hex" option with the IDA sig string.

  5. EX is generally faster, when even doing more extensive searches, due to a technique of cloning the IDB into RAM and using an AVX2 optimized pattern scanner vs relying on the slow IDA find function for scanning.

Ideal mask byte

In my own projects for finding patterns dynamically, I prefer the "Inline byte" (for lack of a better name) format. It's the simplest, most compact, and it doesn't require a runtime transformation from an ASCII hex string. I've used this format for many projects and have yet to run into any signature collision or redundant match problems.

To minimize potential redundancy issues, it's prudent to use one of the least used code byte values for the wildcard/mask byte. To find the ideal candidates, I gathered the code byte frequency from three each large 32bit and 64bit code segments, then tabulated and sorted the results. The "ida_get_byte_frequency.py" IDA script is used the gather a byte frequency dictionary and save it to a JSON DB. The "byte_frequency_tabulate.py" script tabulates and sorts in ascending order a set of these saved JSON DBs. It's apparent the byte frequency for 32bit isn't the same as the 64bit one and tabulated independently. See "32bit.txt" and "64bit.txt". In a visual correlation of the two, 0xA2 is actually the least common denominator, then followed by 0xAE. 0xAE was chosen over 0xA2 as the default mask byte since its subjectively easier to pick out in hex visually.

Building

Built using Visual Studio 2019, on Windows 10, with the only dependency being the official IDA Pro C/C++ SDK. Setup in the project file, it looks for an environment variable _IDADIR from which it expects to find a "idasdk/include" and a "idasdk/lib" folder where the IDA SDK is located. Not using IDADIR since IDA looks for it itself and can cause a conflict if you try to use more than one installed IDA version.

Python 3.7'ish or better to run the "byte_frequency_tabulate.py" script.

Credits

Thanks to the creator of the original SigMaker tool back from the gamedeception.net days up to the current C/C++ and Python iteration authors: P4TR!CK, bobbysing, xero|hawk, ajkhoury, and zoomgod et al. Thanks to Wojciech Mula for his SIMD programming resources.

License

Released under MIT © 2022 By Kevin Weatherman

sigmakerex's People

Contributors

kweatherman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sigmakerex's Issues

Unexpected results trying to find function signature

I have built a 64-bit version of your plugin using ida pro 7.7, visual studio 2022, and windows 11. The attached file shows the output when I tried to generate function signature for a function I already have a signature for. In that file, you can see that I first used the ida search function to locate the existing signature. I then jumped to the function that existing signature corresponds to, selected the first instruction in the function, and ran your plugin to generate a function signature using the default settings. It then generated a LOT of output, but is seems to have ultimately failed. Let me know if there is something I am doing wrong, or if you need additional information to help me use this correctly. Thanks.

signature.txt

Not registering with Ida pro 7.7, Visual Studio 2022, Windows 11

I was able to build the plugin without error, and it installs itself in the ida pro plugin directory:

Build started...
1>------ Build started: Project: SigMakerEx, Configuration: Debug x64 ------
1>Signature.cpp
1>Main.cpp
1>Search.cpp
1>Utility.cpp
1>Generating Code...
1>   Creating library C:\Users\miked\Source\repos\sigmakerex\x64\Debug\IDA_SigMaker.lib and object C:\Users\miked\Source\repos\sigmakerex\x64\Debug\IDA_SigMaker.exp
1>SigMakerEx.vcxproj -> C:\Users\miked\Source\repos\sigmakerex\x64\Debug\IDA_SigMaker.dLL
1>        1 file(s) copied.
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

However, when I start ida pro, it does not appear to be loading. Let me know how I can help you debug this issue.

SigMakerEx: ** Gerneral C exception: run() ***

When I try to scan a function I get this error:

SigMakerEx: Finding function signature.
SigMakerEx: * InstToSig: Decode anomaly @ 0x000001401A560C! decodeSize: 9, itemSize: 52 *
 F: 20505C00, "FF_DWORD, FF_0OFF, FF_REF, FF_NAME, FF_DATA, FF_COMM"
 'mov     ds:0F3001A263E001A0Bh, eax; jump table for switch statement'

SigMakerEx: ** Gerneral C exception: run() ***

We have the PDB for this game, here is what it looks like:
void __fastcall cGcApplicationDeathState::Update(cGcApplicationDeathState *this, float lfTimeStep)

Failed to allocate the clone RAM buffer

Hello,

I am getting this error it's completely random sometimes the sig maker plugin works and sometimes not.

SigMakerEx: Finding function signature.
SigMakerEx: ** Failed to allocate the clone RAM buffer of size: 0xFFFFF77F80021000 ! **
SigMakerEx: * Failed to find a base or reference signature for selected function. *

Tested on IDA 7.7 and 8.3

Add test signature

Please can you add "test signature" feature to check my patterns on IDA ?

[x64] RIP Relative LEA & MOV are not Wildcarded

In x64 Assembly, it is possible to use LEA to get an address that's relative to the current instruction pointer; for example:

48 8d 05 bc 32 2a 00 lea rax,[rip+0x2a32bc]

In IDA this prints as:

48 8D 05 BC 32 2A 00 lea rax, aLabel

This form of RIP relative addressing is often used to load static values, and/or constants. These are in other segments, thus not often stored at reliable offsets, and is thus unsafe. This should be wildcarded.

Edit: Applies to RIP relative MOV too

48 89 05 2a f8 49 02 mov QWORD PTR [rip+0x249f82a],rax

Default-selected control in the signature-generating window is not `Continue`

When trying to quickly find functions in another database, when I press Ctrl+Alt+S, I get this window:
ida64_Gj0AqF3e3K

Usually in this kind of cases, the default-selected control is Ok, or in this case it would be Continue button.

In SigMaker when I press Ctrl+Alt+S and then quickly press Enter on my mouse, instead of getting the signature, this Github repo gets opened.

I think it would make sense to make the Continue button to be the default-selected control, so when you already have set your preferred settings and you're generating multiple signatures in a row, you can quickly do it by just pressing Ctrl+Alt+S > Enter.

Instruction bytes change between versions of the executable

Sigmaker generates correct byte pattern but the byte sequence for the instruction itself changes. In my case byte sequence for the instruction mov rdx, rcx changed from 48 89 CA to 48 8B D1:
ida64_1Mdcgvkuyz

And so when I generate a signature in the version on the left, Sigmaker generates 48 89 CA C1 E8 04 pattern, and it won't find it in the version on the right.

Don't know how often it happens in the wild.

An obvious fix would be to replace all bytes to ?? for instructions that can be represented by different byte sequences. Not sure if it's easy enough or possible to just ask some assembler "can this instruction be represented by multiple byte sequences?"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.