Skip to content

Commit

Permalink
added readme and added more error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
user committed May 8, 2024
1 parent 0912947 commit c9ba515
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 8 deletions.
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
## Gadgify

Gadgify is a fast and simplified gadget enumeration tool for x86_64
binaries with flexible functionality to make filtering for specific gadgets
a breeze. Gadgify can be used to find ROP, JOP, COP, and COOP gadgets by querying
for sequences of instructions using a simplified regex based search.

## Features
- Supports x86-64 Portable Executables (PE)
- Supports raw x86-64 files (e.g. a dumped .text section, JIT'd code, etc)
- Intuitive query functionality

## Building
Gadgify can be built cross-platform using cmake which can be acheived using the following commands:
```
cmake -S . build -D CMAKE_BUILD_TYPE=Release
cmake --build build --config Release
```

## Usage
```
Usage: Gadgify [--help] [--version] [--gap VAR] --pattern VAR [--raw] binaryPath
Positional arguments:
binaryPath Path of the file to search for gadgets. e.g. C:\Windows\System32\ntdll.dll [required]
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
-g, --gap The gap between instructions specified in the pattern e.g. searching for the 'mov r*, r1*;call r*;sub *' pattern with a gap of '3' will result in gadgets that can have up to 3 instructions that do not match the pattern between each instruction in the pattern provided. [nargs=0..1] [default: 3]
-p, --pattern The pattern to search for. [required]
-r, --raw Treat the binary as raw executable code and not as a PE.
```

## Usage examples
- Search for ROP gadgets but ensure up to 5 random instructions preceded the return instruction:
```
gadgify.exe -p "ret;" -g 5 C:\Windows\System32\ntdll.dll
*SNIP*
0x0011b1df: mov eax, 0x80000022; mov rbx, [rsp+0x40]; add rsp, 0x30; pop rdi; ret;
0x0011b236: mov eax, 0x01; ret;
0x0011b23c: int3; sbb eax, eax; ret;
0x0011b2b0: pop r14; ret;
0x0011b353: pop r15; pop r14; pop r12; ret;
0x0011b3a0: add rsp, 0x38; ret;
0x0011b3ef: mov eax, ebx; add rsp, 0x20; pop rbx; ret;
*SNIP*
```
- Search for COP gadgets that perform some addition but ensure only 2 random instructions are between the ADD and CALL:
```
gadgify.exe -p "add *; call r*;" -g 2 "C:\Program Files (x86)\Microsoft\Edge\Application\124.0.2478.80\msedge.dll"
*SNIP*
0x007938be: add rcx, r12; call r13;
0x00aa6659: add [r14+0x10], r13; mov rcx, r15; call r12;
0x00aa6698: add [r14+0x18], r13; mov rcx, r15; call r12;
*SNIP*
```

12 changes: 8 additions & 4 deletions src/Gadgify.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "Gadgify.h"

#include <utility>

Gadgify::Gadgify(std::string peFile) {
PEFile::GetSections([&](IMAGE_SECTION_HEADER sectionHeader, const std::vector<char>& sectionContents)
{
Expand Down Expand Up @@ -60,7 +58,6 @@ bool Gadgify::SearchGadgets(const std::function<void(uint64_t, std::string)> &ca
std::vector<std::string> gadget;
uint32_t gapCounter = 0;
uint32_t matches = 0;

ZyanU64 runtime_address = 0;
ZyanUSize offset = 0;
ZydisDisassembledInstruction instruction;
Expand Down Expand Up @@ -109,7 +106,7 @@ bool Gadgify::SearchGadgets(const std::function<void(uint64_t, std::string)> &ca
instruction.info.mnemonic == ZYDIS_MNEMONIC_JRCXZ ||
instruction.info.mnemonic == ZYDIS_MNEMONIC_JS ||
instruction.info.mnemonic == ZYDIS_MNEMONIC_JZ
)
)
{
gapCounter = 0;
matches = 0;
Expand Down Expand Up @@ -185,5 +182,12 @@ std::vector<std::regex> Gadgify::ConstructRegexes(const std::string& pattern) {

currentRegex.push_back(i);
}

if (regexes.empty() || !currentRegex.empty())
{
std::cout << "Failed to construct query. Ensure each instruction always ends with a semi-colon e.g. "
"\"-p 'mov r1*; sub *; ret;'\" NOT \"-p 'ret' etc" << std::endl;
regexes.clear();
}
return regexes;
}
1 change: 1 addition & 0 deletions src/Gadgify.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <cstdint>
#include <functional>
#include <map>
#include <iostream>
#include <regex>
#include <Zydis/Zydis.h>
#include "PEFile.h"
Expand Down
1 change: 1 addition & 0 deletions src/PEFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ bool PEFile::GetSections(const std::function<void(IMAGE_SECTION_HEADER sectionHe

if (!pe.IsValid())
{
std::cout << "The file provided is not a valid Portable Executable (PE)." << std::endl;
return false;
}

Expand Down
1 change: 1 addition & 0 deletions src/PEFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <vector>
#include <functional>
#include <cstring>
#include <iostream>
#include "File.h"
#include "WindowsTypes.h"

Expand Down
15 changes: 11 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

int main(int argc, char *argv[]) {
argparse::ArgumentParser program("Gadgify");
uint32_t gap = 0;
uint32_t gap = 3;
program.add_argument("-g", "--gap")
.help("The gap between instructions specified in the pattern e.g. searching for the pattern"
"'mov r*, r1*;call r*;sub *' with a gap of '3' will result in gadgets that can have up to 3"
.help("The gap between instructions specified in the pattern e.g. searching for the "
"'mov r*, r1*;call r*;sub *' pattern with a gap of '3' will result in gadgets that can have up to 3 "
"instructions that do not match the pattern between each instruction in the pattern provided.")
.scan<'u', uint32_t>()
.default_value(gap);
Expand Down Expand Up @@ -62,7 +62,14 @@ int main(int argc, char *argv[]) {
);
}

std::cout << results.str() << std::endl;
if (results.str().empty())
{
std::cout << "No gadgets found that matched your query." << std::endl;
}
else
{
std::cout << results.str() << std::endl;
}

return 0;
}

0 comments on commit c9ba515

Please sign in to comment.