├── IDA.md ├── LICENSE ├── README.md ├── WINDOWS.md ├── doc ├── COMPILE_OPTIONS.md ├── COMPILE_WINDOWS.md ├── DEBUG.md ├── TESTS.md └── syntax_highlighting.md ├── examples ├── analyze_backspace.py ├── backspace_4ee.grapp ├── backspace_4ee00c46da143ba70f7e6270960823be_exact.grapp ├── backspace_4ee00c46da143ba70f7e6270960823be_loop.grapp ├── backspace_call_push.grapp ├── backspace_decrypt_algos.grapp ├── backspace_samples.md └── upx.grapp ├── patterns ├── basic_block_loop.grapp ├── bb_xor_loop.grapp ├── crypto │ ├── aes_libressl_v0.1.grapp │ ├── arx_crypto.grapp │ ├── generator_md5_libressl_crypto.py │ └── md5_libressl_crypto.grapp ├── popular.grapp ├── trick_PEB.grapp ├── trick_PEparsing.grapp ├── trick_call5.grapp ├── trick_cpuid.grapp ├── trick_pushret.grapp ├── trick_vmware_detection.grapp └── unprotect │ ├── unprotect_sandbox-evasion_CPUID.grapp │ └── unprotect_sandbox-evasion_IO-VMWare.grapp ├── releases ├── changelogs │ ├── v1.2.0 │ ├── v1.2.1 │ ├── v1.3.0 │ └── v1.3.1 ├── grap_1-1-0_ida695_windows │ ├── grap_1-1-0_ida695_windows.zip.SHA256 │ └── grap_1-1-0_ida695_windows │ │ └── README.txt ├── grap_1-1-0_ida700_windows │ ├── grap_1-1-0_ida700_windows.zip.SHA256 │ └── grap_1-1-0_ida700_windows │ │ └── README.txt ├── grap_1-2-1_ida7_windows_64 │ ├── grap_1-2-1_ida7_windows_64.SHA256 │ └── grap_1-2-1_ida7_windows_64 │ │ └── README.txt ├── grap_1-3-0_ida7_windows_64 │ ├── grap_1-3-0_ida7_windows_64.SHA256 │ └── grap_1-3-0_ida7_windows_64 │ │ └── README.txt └── grap_1-3-1_ida7_windows64 │ └── grap_1-3-1_ida7_windows64.SHA256 └── src ├── .clang-format ├── CMakeLists.txt ├── IDA └── grap │ ├── grap.py │ └── idagrap │ ├── __init__.py │ ├── analysis │ ├── Analysis.py │ └── __init__.py │ ├── config │ ├── General.py │ ├── Instruction.py │ └── __init__.py │ ├── core │ ├── ColorCore.py │ ├── CryptoIdentifier.py │ ├── PatternGenerator.py │ └── __init__.py │ ├── error │ ├── Exceptions.py │ └── __init__.py │ ├── graph │ ├── Graph.py │ ├── Node.py │ └── __init__.py │ ├── modules │ ├── Module.py │ ├── Pattern.py │ └── __init__.py │ ├── patterns │ ├── Modules.py │ ├── __init__.py │ ├── compression │ │ ├── ModulesCompression.py │ │ └── __init__.py │ ├── cryptography │ │ ├── ModulesCrypto.py │ │ ├── __init__.py │ │ ├── block │ │ │ ├── ModulesCryptoBlock.py │ │ │ └── __init__.py │ │ ├── hash │ │ │ ├── ModulesCryptoHash.py │ │ │ └── __init__.py │ │ ├── mode │ │ │ ├── ModulesCryptoMode.py │ │ │ └── __init__.py │ │ └── stream │ │ │ ├── ModulesCryptoStream.py │ │ │ ├── __init__.py │ │ │ └── rc4 │ │ │ ├── RC4.py │ │ │ ├── __init__.py │ │ │ └── set_key │ │ │ ├── RC4SetKey.py │ │ │ ├── __init__.py │ │ │ ├── loop1.dot │ │ │ └── loop2.dot │ └── test │ │ ├── ModulesTest.py │ │ ├── __init__.py │ │ └── misc │ │ ├── ModulesTestMisc.py │ │ ├── __init__.py │ │ └── files │ │ ├── .gitkeep │ │ ├── basic_block_loop.grapp │ │ ├── bb_xor_loop.grapp │ │ ├── crypto │ │ ├── aes_libressl_v0.1.grapp │ │ ├── arx_crypto.grapp │ │ ├── generator_md5_libressl_crypto.py │ │ └── md5_libressl_crypto.grapp │ │ ├── popular.grapp │ │ ├── trick_PEB.grapp │ │ ├── trick_PEparsing.grapp │ │ ├── trick_call5.grapp │ │ ├── trick_cpuid.grapp │ │ ├── trick_pushret.grapp │ │ └── trick_vmware_detection.grapp │ └── ui │ ├── IDAgrapForm.py │ ├── __init__.py │ ├── helpers │ ├── ClassCollection.py │ ├── QtGrapSyntax.py │ ├── QtShim.py │ └── __init__.py │ ├── icons │ ├── circle.png │ ├── coloring.png │ ├── crypto.png │ ├── generate.png │ ├── graphic.png │ ├── icons8-add-file.png │ ├── icons8-asterisk-24.png │ ├── icons8-color-palette.png │ ├── icons8-delete.png │ ├── icons8-edit-property-52.png │ ├── icons8-eye-50.png │ ├── icons8-fingerprint-scan.png │ ├── icons8-function-mac-32.png │ ├── icons8-info.png │ ├── icons8-mind-map.png │ ├── icons8-plus.png │ ├── icons8-python-50.png │ ├── icons8-save-as-50.png │ ├── icons8-search.png │ ├── icons8-workflow.png │ ├── reset.png │ └── scan_graph.png │ └── widgets │ ├── AboutScriptingWidget.py │ ├── AboutWidget.py │ ├── CryptoIdentificationWidget.py │ ├── EditorWidget.py │ ├── PatternGenerationWidget.py │ ├── __init__.py │ ├── about.html │ ├── pygmentize.css │ └── scripting.html ├── bindings ├── CMakeLists.txt └── python │ ├── CMakeLists.txt │ ├── dot_writer.py │ ├── ida_helper.py │ └── pygrap.i ├── cmake-modules └── ListCombinations.cmake ├── compiled ├── _pygrap.pyd └── pygrap.py ├── libs ├── CMakeLists.txt ├── common │ ├── CMakeLists.txt │ ├── ga_types.hpp │ ├── my_alloc.cpp │ ├── my_alloc.hpp │ └── my_assert.hpp ├── dotparser │ ├── CMakeLists.txt │ ├── Expression.cpp │ ├── Expression.hpp │ ├── Lexer.l │ ├── Parser.y │ ├── graphParser.cpp │ └── graphParser.hpp ├── libgraph │ ├── CMakeLists.txt │ ├── graph.cpp │ ├── graph.hpp │ ├── graphIO.cpp │ ├── graphIO.hpp │ ├── node.cpp │ ├── node.hpp │ ├── nodeIO.cpp │ ├── nodeIO.hpp │ ├── node_list.cpp │ └── node_list.hpp └── node_info │ ├── CMakeLists.txt │ ├── node_info.cpp │ └── node_info.hpp ├── libsGTSI ├── CMakeLists.txt ├── Traversal │ ├── CMakeLists.txt │ ├── Traversal.cpp │ └── Traversal.hpp ├── utils-gtsi.cpp └── utils-gtsi.hpp ├── syntax └── vim │ └── grap.vim ├── tests_graphs ├── test0 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test1 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test10 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test11 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test12 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test13 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test14 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test15 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test16 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test17 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test18 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test19 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test2 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test20 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test21 │ ├── expected │ ├── pattern_0.dot │ ├── pattern_1.dot │ └── test.dot ├── test22 │ ├── expected │ ├── pattern_0.dot │ ├── pattern_1.dot │ └── test.dot ├── test23 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test24 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test25 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test26 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test27 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test28 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test29 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test3 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test30 │ ├── expected │ ├── pattern_0.dot │ ├── pattern_1.dot │ └── test.dot ├── test31 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test32 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test33 │ ├── expected │ ├── pattern_0.dot │ ├── test │ └── test.dot ├── test34 │ ├── expected │ ├── pattern_0.dot │ ├── test │ └── test.dot ├── test35 │ ├── expected │ ├── pattern_0.dot │ ├── pattern_1.dot │ ├── pattern_2.dot │ └── test.dot ├── test36 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test37 │ ├── .expected.un~ │ ├── .pattern_0.dot.un~ │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test38 │ ├── .expected.un~ │ ├── .pattern_0.dot.un~ │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test39 │ ├── .expected.un~ │ ├── .pattern_0.dot.un~ │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test4 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test40 │ ├── .expected.un~ │ ├── .pattern_0.dot.un~ │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test41 │ ├── expected │ ├── pattern_0.dot │ ├── test.dot │ └── wildcard ├── test42 │ ├── expected │ ├── pattern_0.dot │ ├── test.dot │ └── wildcard ├── test43 │ ├── expected │ ├── pattern_0.dot │ ├── test.dot │ └── wildcard ├── test44 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test45 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test46 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test5 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test6 │ ├── expected │ ├── pattern_0.dot │ ├── pattern_1.dot │ ├── pattern_2.dot │ ├── pattern_3.dot │ └── test.dot ├── test7 │ ├── expected │ ├── pattern_0.dot │ └── test.dot ├── test8 │ ├── expected │ ├── pattern_0.dot │ └── test.dot └── test9 │ ├── expected │ ├── pattern_0.dot │ └── test.dot └── tools ├── CMakeLists.txt ├── grap-match ├── CMakeLists.txt ├── grap-match.cpp ├── grap-match.hpp └── grap-match.py ├── grap ├── CMakeLists.txt └── grap.py ├── grap_disassembler ├── __init__.py └── disassembler.py ├── setup.py ├── tests ├── CMakeLists.txt ├── test_all.py ├── tests.cpp └── tests.hpp └── todot ├── CMakeLists.txt ├── todot.cpp ├── todot.hpp └── todot.py /IDA.md: -------------------------------------------------------------------------------- 1 | # Requirements 2 | You will need to have grap installed (see [WINDOWS.md](WINDOWS.md) for Windows, and [README.md](README.md) for GNU/Linux). 3 | 4 | # IDA plugin installation 5 | You need to copy the following file and folder into IDA's plugin folder: 6 | 7 | - grap.py into (IDA_folder)\plugins\ 8 | - idagrap/ into (IDA_folder)\plugins\ 9 | 10 | These files can be found either in the pre-compiled binaries or in the repository in folder [src/IDA/grap/](src/IDA/grap/). 11 | 12 | ## Linux 13 | You can make symbolic links to the grap repository: 14 | 15 | - ln -s ~/grap/src/IDA/grap/grap.py ~/ida-7.1/plugins/ 16 | - ln -s ~/grap/src/IDA/grap/idagrap/ ~/ida-7.1/plugins/ 17 | 18 | 19 | ## Windows 20 | For instance for IDA 7 on Windows: 21 | 22 | - Copy grap.py into C:\Program Files\IDA 7.0\plugins\ 23 | - Copy idagrap/ into C:\Program Files\IDA 7.0\plugins\ 24 | 25 | # Usage 26 | You can activate the plugin within IDA with the menu (Edit -> Plugins -> IDAgrap) or with Shift+G. 27 | 28 | It opens a new tab with four panels. 29 | 30 | * The first panel is made for detection and has two buttons: one for launching detection, the other for coloring matched nodes. 31 | * Some patterns are already available 32 | * You can modify them and add your own in the folder C:\Program Files\IDA 7.0\plugins\idagrap\patterns\test\misc\files 33 | 34 | * The second panel will assist the creation of new patterns within IDA: 35 | * Click "Load the control flow graph" 36 | * In IDA View (main panel), click right on the instruction you want to define as the root of your pattern , select "[grap] set root node" 37 | * Define additional nodes with right click + "[grap] Add target node" 38 | * Use the plugin buttons to generate the pattern 39 | 40 | * A "Scripting" panel with script examples on how to use grap's python bindings 41 | 42 | * An "About" panel 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Inria 4 | Copyright (c) 2015-2017 Cassidian CyberSecurity SAS 5 | Copyright (c) 2018-2019 QuoScient GmbH 6 | Copyright (c) 2020 QuoSec GmbH 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | -------------------------------------------------------------------------------- /WINDOWS.md: -------------------------------------------------------------------------------- 1 | We recommand you to not compile grap yourself on Windows because it can be tedious (see [COMPILE_WINDOWS.md](doc/COMPILE_WINDOWS.md) if you wish to compile it yourself) . 2 | 3 | This document explains how to use pre-compiled version of grap and its bindings on Windows. 4 | 5 | # Requirements 6 | 7 | - If you only intend to use the IDA plugin, you will only need to install capstone: within a cmd.exe admin prompt, run `pip install capstone-windows` (you might need to change directory to where pip is, for instance C:\python27-x64\Scripts) 8 | - If you want to use grap as a standalone tool, you will need also need pefile and pyelftools (install them with pip) 9 | 10 | # grap, python bindings and IDA plugin 11 | You will find compiled files (grap\_1-3-1\_ida7_windows64.zip for instance) in the release panel. You can find release information (SHA256SUM) in the [releases/](releases/) folder. 12 | 13 | - Extract the .zip file 14 | - Follow the instructions in the README.txt (you will need to copy 4 files / folders) 15 | 16 | # grap-match.exe and grap.py 17 | You may use the compiled grap-match.exe and grap.py with the -nt option since multi-threading does not work on Windows for now (please update the path to match your setup): 18 | 19 | - grap-match.exe (in binaries\ folder) may be directly used within a cmd.exe prompt: 20 | ``` 21 | E:\windows_compiled_1_0_0\binaries\grap-match.exe -nt pattern.dot test.dot 22 | ``` 23 | - The grap.py wrapper (and disassembler) can be used but the path of the grap-match.exe binary should be specified: 24 | ``` 25 | python E:\windows_compiled_1_0_0\binaries\grap.py -nt -b E:\windows_compiled_1_0_0\binaries\grap-match.exe pattern.dot test.dot 26 | ``` 27 | 28 | # IDA plugin 29 | Read [IDA.md](IDA.md) for addtionnal usage instruction of the IDA plugin. 30 | -------------------------------------------------------------------------------- /doc/COMPILE_OPTIONS.md: -------------------------------------------------------------------------------- 1 | # Compilation options 2 | Compilation options are chosen with cmake (`cmake -DSECCOMP=1 ../src` for instance): 3 | 4 | - TOOLS: build tools (grap-match, todot and test binaries), default 5 | - PYTHON_BINDING: build python bindings, default 6 | - SECCOMP: enable support of the grap-match binary for privilege drop through seccomp, **not default** 7 | 8 | On GNU/Linux enabling seccomp on grap-match restricts the number of system calls available to the binary for security purposes. 9 | In particular the "open" syscall is mostly unavailable after the initial argument parsing. 10 | 11 | Note that seccomp is only implemented within the `grap-match` binary and its wrapper (grap and grap.py scripts), and **not** within the bindings (hence not within the IDA plugin). 12 | 13 | The seccomp filters have only been testing against the latest Ubuntu LTS (18.04.1). 14 | -------------------------------------------------------------------------------- /doc/DEBUG.md: -------------------------------------------------------------------------------- 1 | # Build types 2 | The default build type is "Release", the others can be obtained through cmake options (such as `cmake -DCMAKE_BUILD_TYPE=Debug -DSECCOMP=0 ../src`): 3 | 4 | - Release: best performance, default 5 | - Debug: with debug information and address sanitizer 6 | - Valgrind: with debug information, good to use when debugging with valgrind 7 | - Errall: all gcc warnings activated, all warnings are fatal to build 8 | 9 | Note that for debug builds it may be mandatory to disable seccomp (otherwise it will crash). 10 | 11 | ## Valgrind 12 | This command will work to try the ./test binary against Valgrind: 13 | 14 | - `valgrind --max-stackframe=2000344 --leak-check=full --track-origins=yes --show-reachable=yes ./tests` 15 | 16 | -------------------------------------------------------------------------------- /doc/TESTS.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | Note that grap is a python script that will: 3 | 4 | - Use the python disassembler to create DOT files from binaries 5 | - Call the installed C++ binary grap-match to match patterns to the DOT files 6 | 7 | Some examples of pattern files and test files are given in the src/tests_graphs/ directory. 8 | For troubleshooting purposes you can test them all. 9 | 10 | - `./tests` will use the C++ library to test them against expected values, `./tests -h` gives information about each test. 11 | - `make test` will use `test_all.py` (in the build/ directory) and test the C++ library, the grap-match binary, grap-match.py and python bindings for disassembly and matching. It needs bindings to be built and installed 12 | - `grap` or `grap-match` can be used to test them individually 13 | 14 | `test_all.py` takes options: 15 | 16 | - -nt: no threads 17 | - -nc: no colors 18 | - -t tests_path, -gm grap_match_path, -gmpy grap_match_py_path, -g grap_path: specifies where those binaries and scripts are found 19 | - -v: verbose 20 | - -l log.txt: log output 21 | 22 | On GNU/Linux, once grap is installed you may call directly either `make test` or `test_all.py` with no options. 23 | 24 | On Windows, the following command is recommended: 25 | ``` 26 | test_all.py -l log.txt -nt -nc -t Release\tests.exe -gm Release\grap-match.exe -gmpy ..\src\tools\grap-match\grap-match.py -g ..\src\tools\grap\grap.py 27 | ``` 28 | 29 | It is normal and expected that some WARNING will show. 30 | 31 | More options for debug can be found in [doc/DEBUG.md](doc/DEBUG.md). 32 | 33 | -------------------------------------------------------------------------------- /doc/syntax_highlighting.md: -------------------------------------------------------------------------------- 1 | # grap syntax highlighting 2 | ## Vim syntax file 3 | Here is a vim syntax highlighting file: [../src/syntax/vim/grap.vim](../src/syntax/vim/grap.vim) 4 | 5 | It can be used by **either** : 6 | * Copying it to ~/.vim/ftdetect/ 7 | * Loading it from ~/.vimrc with a line such as: 8 | ``` 9 | source ~/grap/src/syntax/vim/grap.vim 10 | ``` 11 | -------------------------------------------------------------------------------- /examples/backspace_4ee.grapp: -------------------------------------------------------------------------------- 1 | digraph decrypt_sample_4ee{ 2 | A [label="mov eax, ??", cond="opcode is mov and arg1 is eax", getid=A] 3 | B [label="add eax, ecx", cond="opcode is add and arg1 is eax and arg2 is ecx", getid=B] 4 | C [label="mov ??, [eax]", cond="opcode is mov and arg2 contains [eax]", getid=C] 5 | D [label="xor ??, 0x11", cond="opcode is xor and (arg2 is 0x11 or arg2 is 11h)", getid=D] 6 | E [label="sub ??, 0x25", cond="opcode is sub and (arg2 is 0x25 or arg2 is 25h)", getid=E] 7 | F [label="inc ecx", cond="opcode is inc and arg1 is ecx", getid=F] 8 | G [label="cmp ecx, ??", cond="opcode is cmp and arg1 is ecx", getid=G] 9 | H [label="mov [eax], ??", cond="opcode is mov and arg1 contains [eax]", getid=H] 10 | I [label="j* ??", cond="opcode beginswith j", getid=I] 11 | J [label="*", cond=true, getid=J] 12 | 13 | A -> B [label=1] 14 | B -> C [label=1] 15 | C -> D [label=1] 16 | D -> E [label=1] 17 | E -> F [label=1] 18 | F -> G [label=1] 19 | G -> H [label=1] 20 | H -> I [label=1] 21 | I -> J [label=1, child_number=1] 22 | I -> A [label=2, child_number=2] 23 | } 24 | 25 | -------------------------------------------------------------------------------- /examples/backspace_4ee00c46da143ba70f7e6270960823be_exact.grapp: -------------------------------------------------------------------------------- 1 | digraph decrypt_sample_4ee00c46da143ba70f7e6270960823be_exact{ 2 | A [label="mov eax, ??", cond="opcode is mov and arg1 is eax"] 3 | B [label="add eax, ??", cond="opcode is add and arg1 is eax"] 4 | C [label="mov ??, [eax]", cond="opcode is mov and arg2 contains [eax]"] 5 | D [label="xor ??, 0x11", cond="opcode is xor and arg2 is 0x11"] 6 | E [label="sub ??, 0x25", cond="opcode is sub and arg2 is 0x25"] 7 | F [label="inc ??", cond="opcode is inc"] 8 | G [label="cmp ??, ??", cond="opcode is cmp"] 9 | H [label="mov [eax], ??", cond="opcode is mov and arg1 contains [eax]"] 10 | I [label="j* ??", cond="opcode beginswith j"] 11 | J [label="*", cond=true] 12 | 13 | A -> B [label=1] 14 | B -> C [label=1] 15 | C -> D [label=1] 16 | D -> E [label=1] 17 | E -> F [label=1] 18 | F -> G [label=1] 19 | G -> H [label=1] 20 | H -> I [label=1] 21 | I -> J [label=1, child_number=1] 22 | I -> A [label=2, child_number=2] 23 | } 24 | 25 | -------------------------------------------------------------------------------- /examples/backspace_4ee00c46da143ba70f7e6270960823be_loop.grapp: -------------------------------------------------------------------------------- 1 | digraph decrypt_sample_4ee00c46da143ba70f7e6270960823be_loop{ 2 | A [label="?? (x3)", cond=true, repeat=3] 3 | B [label="xor ??, 0x11", cond="opcode is xor and arg2 is 0x11"] 4 | C [label="sub ??, 0x25", cond="opcode is sub and arg2 is 0x25"] 5 | D [label="?? (x3)", cond=true, repeat=3] 6 | E [label="j*", cond="opcode beginswith j and nchildren == 2"] 7 | 8 | A -> B 9 | B -> C 10 | C -> D 11 | D -> E 12 | E -> A [label=2, childnumber=2] 13 | } 14 | 15 | -------------------------------------------------------------------------------- /examples/backspace_call_push.grapp: -------------------------------------------------------------------------------- 1 | digraph push_calls{ 2 | 0 [label="pop or push", cond="opcode is pop or opcode is push"] 3 | A [label="push1 (x2)", cond="opcode is push", repeat=2] 4 | B [label="call1", cond="opcode is call"] 5 | C [label="push2 (x2)", cond="opcode is push", repeat=2] 6 | D [label="call2", cond="opcode is call"] 7 | E [label="push3 (x2)", cond="opcode is push", repeat=2] 8 | F [label="call2", cond="opcode is call"] 9 | G [label="push4 (x2)", cond="opcode is push", repeat=2] 10 | H [label="call3", cond="opcode is call"] 11 | 12 | 13 | Pre [label="Pre", cond=true, maxrepeat=4] 14 | Loop [label="Loop", cond=true, minrepeat=3, maxrepeat=12, getid="loop"] 15 | End [label="End", cond=true, minrepeat=0, maxrepeat=2, lazyrepeat=true] 16 | Ret[label="Ret", cond="opcode beginswith ret"] 17 | 18 | 0 -> A 19 | A -> B 20 | B -> C 21 | C -> D 22 | D -> E 23 | E -> F 24 | F -> G 25 | G -> H 26 | 27 | B -> Pre [childnumber=2] 28 | D -> Pre [childnumber=2] 29 | F -> Pre [childnumber=2] 30 | H -> Pre [childnumber=2] 31 | 32 | Pre -> Loop [childnumber=1] 33 | Pre -> End [childnumber=2] 34 | Loop -> End [childnumber=1] 35 | Loop -> Loop [childnumber=2] 36 | End -> Ret 37 | } 38 | -------------------------------------------------------------------------------- /examples/backspace_decrypt_algos.grapp: -------------------------------------------------------------------------------- 1 | digraph decrypt_xor_sub { 2 | A [label="A", cond="opcode is xor and arg2 is 0x11", getid=A] 3 | B [label="B", cond="opcode is sub and arg2 is 0x25"] 4 | 5 | A -> B 6 | } 7 | 8 | digraph decrypt_sub_xor_sub { 9 | A [label="A", cond="opcode is sub", getid=A] 10 | B [label="B", cond="opcode is xor and arg2 is 0xb"] 11 | C [label="C", cond="opcode is sub and arg2 is 0x12"] 12 | 13 | A -> B 14 | B -> C 15 | } 16 | 17 | digraph decrypt_sub_xor_add { 18 | A [label="A", cond="opcode is sub", getid=A] 19 | B [label="B", cond="opcode is xor and arg2 is 0x19"] 20 | C [label="C", cond="opcode is add and arg2 is 0x13"] 21 | 22 | A -> B 23 | B -> C 24 | } 25 | 26 | digraph decrypt_xor_sub_sub { 27 | A [label="A", cond="opcode is xor and arg2 is 0x17", getid=A] 28 | B [label="B", cond="opcode is sub"] 29 | C [label="C", cond="opcode is add and arg2 is 0x13"] 30 | 31 | A -> B 32 | B -> C 33 | } 34 | 35 | digraph decrypt_sub_add1 { 36 | A [label="A", cond="opcode is 'or' and arg2 is 0xff", getid=A] 37 | B [label="B", cond="opcode is sub"] 38 | C [label="C", cond="opcode is add"] 39 | D [label="D", cond="opcode is mov and arg1 contains ["] 40 | 41 | A -> B 42 | B -> C 43 | C -> D 44 | } 45 | 46 | digraph decrypt_sub_add2 { 47 | A [label="A", cond="opcode is 'or' and arg2 is 0xff", getid=A] 48 | B [label="B", cond="opcode is add"] 49 | C [label="C", cond="opcode is sub"] 50 | D [label="D", cond="opcode is add and arg1 contains ["] 51 | 52 | A -> B 53 | B -> C 54 | C -> D 55 | } 56 | 57 | digraph decrypt_sub { 58 | A [label="A", cond="opcode is sub and arg1 contains eax", getid=A] 59 | B [label="B", cond="opcode is add and arg1 contains [eax]"] 60 | 61 | A -> B 62 | } 63 | -------------------------------------------------------------------------------- /examples/backspace_samples.md: -------------------------------------------------------------------------------- 1 | We tested those patterns on 100 Backspace samples. 2 | 3 | # Download the samples 4 | 5 | Disclaimer: 6 | 7 | - These are live Windows malware 8 | - Download them only if you know what you are doing 9 | - Do not execute them on a (non sandboxed) machine 10 | 11 | You can find them here: [https://drive.google.com/open?id=1jmMsjOFUsez2gsAc9S6MF7MPKkry4qgL](https://drive.google.com/open?id=1jmMsjOFUsez2gsAc9S6MF7MPKkry4qgL). 12 | 13 | The .zip password is: PonaeR4oihei 14 | 15 | # MD5 list 16 | 17 | - 010ca5e1de980f5f45f9d82027e1606c 18 | - 0570066887f44bc6c82ebe033cad0451 19 | - 062fe1336459a851bd0ea271bb2afe35 20 | - 07bb30a2a42423e54f70af61e20edca3 21 | - 08f299c2d8cfe1ae64d71dfb15fe6e8d 22 | - 09010917cd00dc8ddd21aeb066877aa2 23 | - 0a4fdacde69a566f53833500a0d53a35 24 | - 0cdc35ffc222a714ee138b57d29c8749 25 | - 0fcb4ffe2eb391421ec876286c9ddb6c 26 | - 10aa368899774463a355f1397e6e5151 27 | - 1133fe501fa4691b7f52e53706c80df9 28 | - 12e1dcd71693b6f875a98aefbd4ec91a 29 | - 139158fe63a0e46639cc20b754a7c38c 30 | - 1dbb584e19499e26398fb0a7aa2a01b7 31 | - 1f64afa4069036513604cbf651e53e0d 32 | - 29395c528693b69233c1c12bef8a64b3 33 | - 2a2b22aa94a59575ca1dea8dd489d2eb 34 | - 2d75de9e1bb58fe61fd971bb720a49b7 35 | - 310a4a62ba3765cbf8e8bbb9f324c503 36 | - 3166baffecccd0934bdc657c01491094 37 | - 37e568bed4ae057e548439dc811b4d3a 38 | - 40601cf29c1bbfe0942d1ac914d8ce27 39 | - 414854a9b40f7757ed7bfc6a1b01250f 40 | - 428fc53c84e921ac518e54a5d055f54a 41 | - 44992068aab25daa1decae93b25060af 42 | - 49ee6365618b2a5819d36a48131e280c 43 | - 4a41c422e9eb29f5d722700b060bca11 44 | - 4b8531d294c020d5f856b58a5a23b238 45 | - 4c10a1efed25b828e4785d9526507fbc 46 | - 4c6b21e98ca03e0ef0910e07cef45dac 47 | - 4e5c116d874bbaaf7d6dadec7be926f5 48 | - 4ee00c46da143ba70f7e6270960823be 49 | - 550459b31d8dabaad1923565b7e50242 50 | - 572c9cd4388699347c0b2edb7c6f5e25 51 | - 59e055cee87d8faf6f701293e5830b5a 52 | - 5ae51243647b7d03a5cb20dccbc0d561 53 | - 5b590798da581c894d8a87964763aa8b 54 | - 5ddbd80720997f7a8ff53396e8e8b920 55 | - 62e5d5e244059dc02654f497401615cc 56 | - 646e2cfa6aa457013769e2b89454acf7 57 | - 65232a8d555d7c4f7bc0d7c5da08c593 58 | - 65b984b198359003a5a3b8aaf91af234 59 | - 6791254f160e98ac1f46b4d506b695ad 60 | - 6f931c15789d234881be8ae8ccfe33f4 61 | - 71f25831681c19ea17b2f2a84a41bbfb 62 | - 78c4fcee5b7fdbabf3b9941225d95166 63 | - 7b111e1054b6b929de071c4f48386415 64 | - 8022a4136a6200580962da94f3cdb905 65 | - 8214b0e18fbcd5db6b008884e7685f2c 66 | - 853a20f5fc6d16202828df132c41a061 67 | - 8c713117af4ca6bbd69292a78069e75b 68 | - 8c9db773d387bf9b3f2b6a532e4c937c 69 | - 8da9373fc5b8320fb04d6202ca1eb6f1 70 | - 8ff473bedbcc77df2c49a91167b1abeb 71 | - 948a53450e1d7dc7535ea52ca7d5bddd 72 | - 95bfe940816a89f168cacbc340eb4a5f 73 | - 9c0cad1560cd0ffe2aa570621ef7d0a0 74 | - 9c31551cd8087072d08c9004c0ce76c5 75 | - 9cbcc68c9b913a5fda445fbc7558c658 76 | - 9e3ef98abcfffcf3205261e09e06cba6 77 | - a5ca2c5b4d8c0c1bc93570ed13dcab1a 78 | - a813eba27b2166620bd75029cc1f04b0 79 | - a9e8e402a7ee459e4896d0ba83543684 80 | - ab153afbfbcfc8c67cf055b0111f0003 81 | - acb2ba25ef225d820ac8a5923b746cb8 82 | - ad044dc0e2e1eaa19cf031dbcff9d770 83 | - af1c1c5d8031c4942630b6a10270d8f4 84 | - b2138a57f723326eda5a26d2dec56851 85 | - b5546842e08950bc17a438d785b5a019 86 | - b590c15499448639c2748ff9e0d214b2 87 | - b7b282c9e3eca888cbdb5a856e07e8bd 88 | - ba80e3ad617e6998f3c4b003397db840 89 | - c4dec6d69d8035d481e4f2c86f580e81 90 | - c6e388ee5269239070e5ad7336d0bf59 91 | - c90f798ccfbedb4bbe6c4568e0f05b68 92 | - c9484902c7f1756b26244d6d644c9dd5 93 | - c95cd106c1fecbd500f4b97566d8dc96 94 | - cb1087b2add3245418257d648ac9e9a7 95 | - cc06815e8d8c0083263651877decb44b 96 | - cd1aa1c8cdf4a4ba8dc4309ce30ec263 97 | - d28d67b4397b7ce1508d10bf3054ffe5 98 | - d38e02eac7e3b299b46ff2607dd0f288 99 | - d55514d8b97999453621a8614090cbf0 100 | - d8248be5ed0f2f8f9787be331a18c36b 101 | - d8e68db503f4155ed1aeba95d1f5e3e4 102 | - d93026b1c6c828d0905a0868e4cbc55f 103 | - da92b863095ee730aef6c6c541ab7697 104 | - db3e5c2f2ce07c2d3fa38d6fc1ceb854 105 | - dc95b0e8ecb22ad607fc912219a640c1 106 | - df1799845b51300b03072c6569ab96d5 107 | - e26a2afaaddfb09d9ede505c6f1cc4e3 108 | - e3ae3cbc024e39121c87d73e87bb2210 109 | - e62a63307deead5c9fcca6b9a2d51fb0 110 | - ebf42e8b532e2f3b19046b028b5dfb23 111 | - ec3905d8e100644ae96ad9b51d701a7f 112 | - ed151602dea80f39173c2f7b1dd58e06 113 | - f4a648a2382c51ca367be87d05628cff 114 | - f97ec83d68362e4dff4756ed1101fea8 115 | - fe211c7a081c1dac46e3935f7c614549 116 | - ff00682b0b8c8d13b797d722d9048ea2 117 | -------------------------------------------------------------------------------- /examples/upx.grapp: -------------------------------------------------------------------------------- 1 | digraph upx_loop1 { 2 | A [cond="opcode is mov and arg2 contains [edx]"] 3 | B [cond="opcode is inc and arg1 contains edx"] 4 | C [cond="opcode is mov and arg1 contains [edi]"] 5 | D [cond="opcode is inc and arg1 contains edi"] 6 | E [cond="opcode is dec"] 7 | F [cond="nchildren == 2"] 8 | 9 | A -> B 10 | B -> C 11 | C -> D 12 | D -> E 13 | E -> F 14 | F -> A [childnumber=2] 15 | } 16 | 17 | digraph upx_loop2 { 18 | A [cond="opcode is mov and arg2 contains [edx]"] 19 | B [cond="opcode is add and arg1 contains edx"] 20 | C [cond="opcode is mov and arg1 contains [edi]"] 21 | D [cond="opcode is add and arg1 contains edi"] 22 | E [cond="opcode is sub and arg1 contains ecx"] 23 | F [cond="nchildren == 2"] 24 | 25 | A -> B 26 | B -> C 27 | C -> D 28 | D -> E 29 | E -> F 30 | F -> A [childnumber=2] 31 | } 32 | -------------------------------------------------------------------------------- /patterns/basic_block_loop.grapp: -------------------------------------------------------------------------------- 1 | digraph bb_loop{ 2 | A [label="A: (*)+", shape="box", cond=true, minrepeat=1, maxrepeat=none, getid="A"] 3 | A -> A [label=2, childnumber=2] 4 | } 5 | -------------------------------------------------------------------------------- /patterns/bb_xor_loop.grapp: -------------------------------------------------------------------------------- 1 | digraph bb_xor_loop{ 2 | A [label="A: (^xor)*", shape="box", cond=true, repeat="*", lazyrepeat=true, maxchildren=1, getid="A"] 3 | B [label="B: (xor)+", shape="box", cond="opcode is xor", repeat="+",maxchildren=1, getid="B"] 4 | C [label="C: (*)*", shape="box", cond="true", repeat="*", getid="C"] 5 | 6 | A -> B 7 | B -> C 8 | C -> A [label=2, childnumber=2] 9 | } 10 | -------------------------------------------------------------------------------- /patterns/crypto/aes_libressl_v0.1.grapp: -------------------------------------------------------------------------------- 1 | digraph LibreSSL_AES_common{ 2 | Ro [cond="opcode is shl and arg2 is 0x10", getid="LibreSSL_AES_common"] 3 | A [cond=true, lazyrepeat=true, repeat=*] 4 | B [cond="opcode is shl and arg2 is 0x18"] 5 | C [cond=true, lazyrepeat=true, repeat=*] 6 | D [cond="opcode is shl and arg2 is 0x10"] 7 | E [cond=true, lazyrepeat=true, repeat=*] 8 | F [cond="opcode is shl and arg2 is 0x18"] 9 | G [cond=true, repeat=*] 10 | 11 | H [cond="nfathers == 2"] 12 | I [cond=true, lazyrepeat=true, repeat=*] 13 | J [cond="opcode is shr and arg2 is 0x18"] 14 | K [cond=true, lazyrepeat=true, repeat=*] 15 | L [cond="opcode is shr and arg2 is 0x10"] 16 | M [cond=true, lazyrepeat=true, repeat=*] 17 | N [cond="opcode is shr and arg2 is 0x18"] 18 | O [cond=true, lazyrepeat=true, repeat=*] 19 | P [cond="opcode is shr and arg2 is 0x10"] 20 | Q [cond=true, lazyrepeat=true, repeat=*] 21 | R [cond="opcode beginswith j and nchildren == 2"] 22 | 23 | S [cond=true, lazyrepeat=true, repeat=*] 24 | T [cond="opcode is shr and arg2 is 0x18"] 25 | U [cond=true, lazyrepeat=true, repeat=*] 26 | V [cond="opcode is 'and' and arg2 is 0xff000000"] 27 | 28 | X [cond=true, lazyrepeat=true, repeat=*] 29 | Y [cond="opcode is shr and arg2 is 0x18"] 30 | Z [cond=true, lazyrepeat=true, repeat=*] 31 | a [cond="opcode is shr and arg2 is 0x10"] 32 | b [cond=true, lazyrepeat=true, repeat=*] 33 | c [cond="opcode is shr and arg2 is 0x18"] 34 | d [cond=true, lazyrepeat=true, repeat=*] 35 | e [cond="opcode is shr and arg2 is 0x10"] 36 | f [cond=true, lazyrepeat=true, repeat=*] 37 | g [cond="basicblockend"] 38 | 39 | Ro -> A 40 | A -> B 41 | B -> C 42 | C -> D 43 | D -> E 44 | E -> F 45 | F -> G 46 | 47 | G -> H [childnumber=*] 48 | H -> I 49 | I -> J 50 | J -> K 51 | K -> L 52 | L -> M 53 | M -> N 54 | N -> O 55 | O -> P 56 | P -> Q 57 | Q -> R 58 | 59 | R -> S [childnumber=*] 60 | S -> T 61 | T -> U 62 | U -> V 63 | 64 | R -> X [childnumber=*] 65 | X -> Y 66 | Y -> Z 67 | Z -> a 68 | a -> b 69 | b -> c 70 | c -> d 71 | d -> e 72 | e -> f 73 | f -> g 74 | g -> H [childnumber=*] 75 | } 76 | 77 | digraph LibreSSL_AES_compact{ 78 | Ro [cond="opcode is shl", getid="LibreSSL_AES_compact"] 79 | A [cond="opcode is shl", repeat=2] 80 | B [cond="opcode is xor", repeat=3] 81 | C [cond=true, lazyrepeat=true, repeat=*] 82 | D [cond="opcode is shl and arg2 is 0x18"] 83 | E [cond=true, lazyrepeat=true, repeat=*] 84 | F [cond="opcode beginswith j and nchildren == 2"] 85 | 86 | G [cond="opcode is xor"] 87 | H [cond=true, lazyrepeat=true, repeat=*] 88 | I [cond="basicblockend"] 89 | 90 | K [cond=true, lazyrepeat=true, repeat=*] 91 | L [cond="opcode is 'and' and arg2 is 0x80808080", repeat=2] 92 | M [cond=true, lazyrepeat=true, repeat=*] 93 | N [cond="opcode is 'and' and arg2 is 0xfefefefe", repeat=2] 94 | O [cond=true, lazyrepeat=true, repeat=*] 95 | P [cond="opcode is 'and' and arg2 is 0x1b1b1b1b", repeat=2] 96 | Q [cond=true, lazyrepeat=true, repeat=*] 97 | R [cond="opcode beginswith j"] 98 | 99 | Ro -> A 100 | A -> B 101 | B -> C 102 | C -> D 103 | D -> E 104 | E -> F 105 | 106 | F -> G [childnumber=*] 107 | G -> H 108 | H -> I 109 | 110 | F -> K [childnumber=*] 111 | K -> L 112 | L -> M 113 | M -> N 114 | N -> O 115 | O -> P 116 | P -> Q 117 | Q -> R 118 | } 119 | 120 | digraph AES_NI{ 121 | Ro [cond="opcode is aesenc or opcode is aesenclast or opcode is aesdec or opcode is aesdeclast", getid="LibreSSL_AES_NI"] 122 | } 123 | -------------------------------------------------------------------------------- /patterns/crypto/arx_crypto.grapp: -------------------------------------------------------------------------------- 1 | digraph ARX_crypto{ 2 | Op1 [cond="opcode is add" repeat=+ lazyrepeat=true getid="ARX_crypto"] 3 | Op1M [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 4 | Op2 [cond="opcode is xor" repeat=+ lazyrepeat=true] 5 | Op2M [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 6 | Op3 [cond="opcode is rol" repeat=+ lazyrepeat=true] 7 | Op3M [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 8 | 9 | Op1_A [cond="opcode is add" repeat=+ lazyrepeat=true] 10 | Op1M_A [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 11 | Op2_A [cond="opcode is xor" repeat=+ lazyrepeat=true] 12 | Op2M_A [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 13 | Op3_A [cond="opcode is rol" repeat=+ lazyrepeat=true] 14 | Op3M_A [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 15 | 16 | Op1_B [cond="opcode is add" repeat=+ lazyrepeat=true] 17 | Op1M_B [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 18 | Op2_B [cond="opcode is xor" repeat=+ lazyrepeat=true] 19 | Op2M_B [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 20 | Op3_B [cond="opcode is rol" repeat=+ lazyrepeat=true] 21 | Op3M_B [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 22 | 23 | Op1_C [cond="opcode is add" repeat=+ lazyrepeat=true] 24 | Op1M_C [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 25 | Op2_C [cond="opcode is xor" repeat=+ lazyrepeat=true] 26 | Op2M_C [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 27 | Op3_C [cond="opcode is rol" repeat=+ lazyrepeat=true] 28 | Op3M_C [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 29 | 30 | Op1 -> Op1M 31 | Op1M -> Op2 32 | Op2 -> Op2M 33 | Op2M -> Op3 34 | Op3 -> Op3M 35 | 36 | Op3M -> Op1_A 37 | Op1_A -> Op1M_A 38 | Op1M_A -> Op2_A 39 | Op2_A -> Op2M_A 40 | Op2M_A -> Op3_A 41 | Op3_A -> Op3M_A 42 | 43 | Op3M_A -> Op1_B 44 | Op1_B -> Op1M_B 45 | Op1M_B -> Op2_B 46 | Op2_B -> Op2M_B 47 | Op2M_B -> Op3_B 48 | Op3_B -> Op3M_B 49 | 50 | Op3M_B -> Op1_C 51 | Op1_C -> Op1M_C 52 | Op1M_C -> Op2_C 53 | Op2_C -> Op2M_C 54 | Op2M_C -> Op3_C 55 | Op3_C -> Op3M_C 56 | } 57 | -------------------------------------------------------------------------------- /patterns/popular.grapp: -------------------------------------------------------------------------------- 1 | digraph popular{ 2 | A [cond="nfathers>=10", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /patterns/trick_PEB.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_PEB { 2 | 0x2000b [cond="opcode is 'mov' and arg2 contains 'dword ptr fs:' and arg2 contains '0x30'"] 3 | } 4 | -------------------------------------------------------------------------------- /patterns/trick_PEparsing.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_PEparsing { 2 | magic [cond="arg1 is 0x5a4d or arg2 is 0x5a4d or arg1 is 0x4550 or arg2 is 0x4550"] 3 | } 4 | -------------------------------------------------------------------------------- /patterns/trick_call5.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_call5 { 2 | call [cond="opcode is 'call'"] 3 | child [cond=true] 4 | call -> child [childnumber=1] 5 | call -> child [childnumber=2] 6 | } 7 | -------------------------------------------------------------------------------- /patterns/trick_cpuid.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_cpuid { 2 | cpuid [cond="opcode is 'cpuid'"] 3 | } 4 | -------------------------------------------------------------------------------- /patterns/trick_pushret.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_pushret { 2 | 0x2032a [cond="opcode is 'push'"] 3 | 0x2032b [cond="opcode beginswith 'ret'"] 4 | 5 | 0x2032a -> 0x2032b [childnumber=1] 6 | } 7 | -------------------------------------------------------------------------------- /patterns/trick_vmware_detection.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_vmware_detection_cmp { 2 | 0x403e82 [cond="opcode is 'cmp' and arg2 is '0x564d5868'"] 3 | } 4 | 5 | digraph trick_vmware_detection_v1 { 6 | 0x406d7f [cond="opcode is 'mov' and arg1 is 'eax' and arg2 is '0x564d5868'"] 7 | 0x406d84 [cond="opcode is 'mov' and arg1 is 'ecx' and arg2 is '0xa'"] 8 | 0x406d89 [cond="opcode is 'mov' and arg1 is 'dx' and arg2 is '0x5658'"] 9 | 0x406d8d [cond="opcode is 'in'"] 10 | 11 | 0x406d7f -> 0x406d84 [childnumber=1] 12 | 0x406d84 -> 0x406d89 [childnumber=1] 13 | 0x406d89 -> 0x406d8d [childnumber=1] 14 | } 15 | 16 | digraph trick_vmware_detection_magic { 17 | 1_magic [cond="inst regex '.*0x564d5868.*'"] 18 | 2_other [cond="true", minrepeat=0, maxrepeat=5, lazyrepeat=true] 19 | 3_in [cond="opcode is 'in'"] 20 | 21 | 1_magic -> 2_other [childnumber=1] 22 | 2_other -> 3_in [childnumber=1] 23 | } 24 | -------------------------------------------------------------------------------- /patterns/unprotect/unprotect_sandbox-evasion_CPUID.grapp: -------------------------------------------------------------------------------- 1 | // https://search.unprotect.it/map/sandbox-evasion/cpuid/ 2 | 3 | digraph "unprotect.sandbox-evasion.CPUID" { 4 | CPUID [cond="opcode is 'cpuid'"] 5 | } 6 | -------------------------------------------------------------------------------- /patterns/unprotect/unprotect_sandbox-evasion_IO-VMWare.grapp: -------------------------------------------------------------------------------- 1 | // https://search.unprotect.it/map/sandbox-evasion/input-output-communication-port/ 2 | 3 | digraph "unprotect.sandbox-evasion.IO-VMWare.cmp" { 4 | 0x403e82 [cond="opcode is 'cmp' and arg2 is '0x564d5868'"] 5 | } 6 | 7 | digraph ""unprotect.sandbox-evasion.IO-VMWare.v1" { 8 | 0x406d7f [cond="opcode is 'mov' and arg1 is 'eax' and arg2 is '0x564d5868'"] 9 | 0x406d84 [cond="opcode is 'mov' and arg1 is 'ecx' and arg2 is '0xa'"] 10 | 0x406d89 [cond="opcode is 'mov' and arg1 is 'dx' and arg2 is '0x5658'"] 11 | 0x406d8d [cond="opcode is 'in'"] 12 | 13 | 0x406d7f -> 0x406d84 [childnumber=1] 14 | 0x406d84 -> 0x406d89 [childnumber=1] 15 | 0x406d89 -> 0x406d8d [childnumber=1] 16 | } 17 | 18 | digraph "unprotect.sandbox-evasion.IO-VMWare.magic" { 19 | 1_magic [cond="inst regex '.*0x564d5868.*'"] 20 | 2_other [cond="true", minrepeat=0, maxrepeat=5, lazyrepeat=true] 21 | 3_in [cond="opcode is 'in'"] 22 | 23 | 1_magic -> 2_other [childnumber=1] 24 | 2_other -> 3_in [childnumber=1] 25 | } 26 | -------------------------------------------------------------------------------- /releases/changelogs/v1.2.0: -------------------------------------------------------------------------------- 1 | New features: 2 | - IDA pattern generation: possible to chose granularity for condition (opcode, opcode with arg1...) of each pattern node 3 | - IDA pattern generation: added quick pattern generation 4 | - IDA: Easier access and documentation of the python bindings 5 | - CLI: -nd option (no disassembly) 6 | 7 | New patterns: 8 | - MD5 LibreSSL 9 | - Tricks patterns: 10 | - PEB handling (fs:[30]) 11 | - push ret 12 | - call +5 13 | 14 | Various improvements and bugfixes: 15 | - MISC: added vim syntax files for grap 16 | - grap-match: updated seccomp filter against Ubuntu 18.04 LTS 17 | - Disassembly: improved disassembly for ELF files 18 | - Disassembly: improved function detection (prologues) 19 | - IDA pattern generation: fixed multiple issues with lazyrepeat 20 | 21 | -------------------------------------------------------------------------------- /releases/changelogs/v1.2.1: -------------------------------------------------------------------------------- 1 | Changed behavior: 2 | - seccomp is now disabled by default (can be enabled with cmake -DSECCOMP=1 ../src) 3 | 4 | Various improvements and bugfixes: 5 | - IDA pattern search: now follows symbolic links 6 | - Fixed compiling errors on Windows (removed non-existing "dirent.h" include) 7 | -------------------------------------------------------------------------------- /releases/changelogs/v1.3.0: -------------------------------------------------------------------------------- 1 | Modifications: 2 | - Migrated from python2 to python3 (CLI and IDA plugin) 3 | - Various bug fixes 4 | 5 | New features for the IDA plugin: 6 | - Generate pattern for whole function 7 | - Embedded pattern editor (new text editor widget) 8 | 9 | -------------------------------------------------------------------------------- /releases/changelogs/v1.3.1: -------------------------------------------------------------------------------- 1 | Modifications: 2 | - Various bugfix related to python3 migration 3 | - New default patterns 4 | - Added parser helper function "parse_first_address" 5 | -------------------------------------------------------------------------------- /releases/grap_1-1-0_ida695_windows/grap_1-1-0_ida695_windows.zip.SHA256: -------------------------------------------------------------------------------- 1 | 5fe1995c97719dbfebddfceff11ca68d5eb90ecaa63095822a1423092f9cfc39 grap_1-1-0_ida695_windows.zip 2 | -------------------------------------------------------------------------------- /releases/grap_1-1-0_ida695_windows/grap_1-1-0_ida695_windows/README.txt: -------------------------------------------------------------------------------- 1 | If you want to use the IDA plugin only: 2 | - Copy pygrap\pygrap.py into C:\Python27\Lib\site-packages\ 3 | - Copy pygrap\_pygrap.pyd into C:\Python27\Lib\site-packages\ 4 | - Copy IDA\grap.py into C:\Program Files (x86)\IDA\plugins\ 5 | - Copy folder IDA\idagrap\ into C:\Program Files (x86)\IDA\plugins\ 6 | - In an administrative prompt (cmd.exe), perform: 7 | - pip install capstone-windows 8 | - (you may need to run it from directory C:\Python27\Scripts) 9 | 10 | If you want to use grap as a standalone tool: 11 | - Perform the previous steps 12 | - Install python2.7 (32 bits) and ask the installation wizard to add python to path 13 | - Open an administrative prompt (cmd.exe) and perform: 14 | - pip install pefile 15 | - pip install pyelftools 16 | - pip install capstone-windows 17 | 18 | Please refer to https://github.com/AirbusCyber/grap/ for further information: 19 | - IDA plugin usage (IDA.md) 20 | - grap binaries usage (WINDOWS.md) 21 | 22 | -------------------------------------------------------------------------------- /releases/grap_1-1-0_ida700_windows/grap_1-1-0_ida700_windows.zip.SHA256: -------------------------------------------------------------------------------- 1 | a18a5623d7b1c083a05e7a3a9c8423f5a00f07ae2b386f6e579c5defaa8d9bb6 grap_1-1-0_ida700_windows.zip 2 | -------------------------------------------------------------------------------- /releases/grap_1-1-0_ida700_windows/grap_1-1-0_ida700_windows/README.txt: -------------------------------------------------------------------------------- 1 | If you want to use the IDA plugin only: 2 | - If you use the normal (64 bits) version of IDA (>=7): 3 | - Copy pygrap\x64\pygrap.py into C:\python27-x64\Lib\site-packages\ 4 | - Copy pygrap\x64\_pygrap.pyd into C:\python27-x64\Lib\site-packages\ 5 | - Copy IDA\grap.py into C:\Program Files\IDA 7.0\plugins\ 6 | - Copy folder IDA\idagrap\ into C:\Program Files\IDA 7.0\plugins\ 7 | - If you use the legacy (32 bits) version of IDA (>=7): 8 | - Copy pygrap\x32\pygrap.py into C:\Python27\Lib\site-packages\ 9 | - Copy pygrap\x32\_pygrap.pyd into C:\Python27\Lib\site-packages\ 10 | - Copy IDA\grap.py into C:\Program Files (x86)\IDA 7.0\plugins\ 11 | - Copy folder IDA\idagrap\ into C:\Program Files (x86)\IDA 7.0\plugins\ 12 | - In an administrative prompt (cmd.exe), perform: 13 | - pip install capstone-windows 14 | - (you may need to run it from directory C:\Python27-x64\Scripts or C:\Python27\Scripts) 15 | 16 | If you want to use grap as a standalone tool: 17 | - Perform the previous steps 18 | - If it is not installed, install python2.7 (64 or 32 bits) and ask the installation wizard to add python to path 19 | - Open an administrative prompt (cmd.exe) and perform: 20 | - pip install pefile 21 | - pip install pyelftools 22 | - pip install capstone-windows 23 | 24 | Please refer to https://github.com/AirbusCyber/grap/ for further information: 25 | - IDA plugin usage (IDA.md) 26 | - grap binaries usage (WINDOWS.md) 27 | 28 | -------------------------------------------------------------------------------- /releases/grap_1-2-1_ida7_windows_64/grap_1-2-1_ida7_windows_64.SHA256: -------------------------------------------------------------------------------- 1 | 275bf00fadd423eedbba153f71cc11affe093cfb563771ea1ea5798734814194 grap_1-2-1_ida7_windows_64.zip 2 | -------------------------------------------------------------------------------- /releases/grap_1-2-1_ida7_windows_64/grap_1-2-1_ida7_windows_64/README.txt: -------------------------------------------------------------------------------- 1 | If you want to use the IDA plugin only: 2 | - If you use the normal (64 bits) version of IDA (>=7): 3 | - Copy pygrap\x64\pygrap.py into C:\python27-x64\Lib\site-packages\ 4 | - Copy pygrap\x64\_pygrap.pyd into C:\python27-x64\Lib\site-packages\ 5 | - Copy IDA\grap.py into C:\Program Files\IDA 7.0\plugins\ 6 | - Copy folder IDA\idagrap\ into C:\Program Files\IDA 7.0\plugins\ 7 | - In an administrative prompt (cmd.exe), perform: 8 | - pip install capstone-windows 9 | - (you may need to run it from directory C:\Python27-x64\Scripts or C:\Python27\Scripts) 10 | 11 | If you want to use grap as a standalone tool: 12 | - Perform the previous steps 13 | - If it is not installed, install python2.7 (64 bits) and ask the installation wizard to add python to path 14 | - Open an administrative prompt (cmd.exe) and perform: 15 | - pip install pefile 16 | - pip install pyelftools 17 | - pip install capstone-windows 18 | 19 | Please refer to https://github.com/QuoScient/grap/ for further information: 20 | - IDA plugin usage (IDA.md) 21 | - grap binaries usage (WINDOWS.md) 22 | 23 | -------------------------------------------------------------------------------- /releases/grap_1-3-0_ida7_windows_64/grap_1-3-0_ida7_windows_64.SHA256: -------------------------------------------------------------------------------- 1 | 05f9150db8e4e68d8b90fe0358a3feb0dd0ec58a0603badd37437b0453055848 /home/ath/grap/WIP/V1.2.1/zip/grap_1-3-0_ida7_windows_64.zip 2 | -------------------------------------------------------------------------------- /releases/grap_1-3-0_ida7_windows_64/grap_1-3-0_ida7_windows_64/README.txt: -------------------------------------------------------------------------------- 1 | If you want to use the IDA plugin only: 2 | - If you use the normal (64 bits) version of IDA (>=7): 3 | - Copy pygrap\x64\pygrap.py into C:\python27-x64\Lib\site-packages\ 4 | - Copy pygrap\x64\_pygrap.pyd into C:\python27-x64\Lib\site-packages\ 5 | - Copy IDA\grap.py into C:\Program Files\IDA 7.0\plugins\ 6 | - Copy folder IDA\idagrap\ into C:\Program Files\IDA 7.0\plugins\ 7 | - In an administrative prompt (cmd.exe), perform: 8 | - pip install capstone-windows 9 | - (you may need to run it from directory C:\Python27-x64\Scripts or C:\Python27\Scripts) 10 | 11 | If you want to use grap as a standalone tool: 12 | - Perform the previous steps 13 | - If it is not installed, install python2.7 (64 bits) and ask the installation wizard to add python to path 14 | - Open an administrative prompt (cmd.exe) and perform: 15 | - pip install pefile 16 | - pip install pyelftools 17 | - pip install capstone-windows 18 | 19 | Please refer to https://github.com/QuoScient/grap/ for further information: 20 | - IDA plugin usage (IDA.md) 21 | - grap binaries usage (WINDOWS.md) 22 | 23 | -------------------------------------------------------------------------------- /releases/grap_1-3-1_ida7_windows64/grap_1-3-1_ida7_windows64.SHA256: -------------------------------------------------------------------------------- 1 | e124acf488a533cc91a81d68d16038e6252da553679ef9a1c4cdcc1e2ab540da grap_1-3-1_ida7_windows64.zip 2 | -------------------------------------------------------------------------------- /src/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: LLVM 3 | BreakBeforeBraces: Stroustrup 4 | ColumnLimit: 80 5 | BreakBeforeBinaryOperators: NonAssignment 6 | AllowShortIfStatementsOnASingleLine: true 7 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(grap) 3 | CMAKE_POLICY(SET CMP0015 NEW) 4 | set (GRAP_VERSION "1.3.1") 5 | 6 | # Default build type: Release 7 | if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 8 | message(STATUS "No build type selected, default to Release") 9 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Release)" FORCE) 10 | endif() 11 | 12 | 13 | # Options 14 | set (SECCOMP OFF CACHE BOOL "Seccomp") 15 | if(${SECCOMP}) 16 | add_definitions(-DSECCOMP) 17 | endif() 18 | 19 | # Cmake Modules------------------------------------------------------------- 20 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake-modules") 21 | include(ListCombinations) 22 | 23 | # Variables----------------------------------------------------------------- 24 | # Describe property 25 | define_property(GLOBAL PROPERTY SRCS_BINDING 26 | BRIEF_DOCS "Bindings sources" 27 | FULL_DOCS "Bindings sources") 28 | 29 | set_property(GLOBAL PROPERTY SRCS_BINDING "") 30 | 31 | # Macros-------------------------------------------------------------------- 32 | macro(binding_add_srcs var) 33 | set_property(GLOBAL APPEND PROPERTY SRCS_BINDING "${var}") 34 | endmacro(binding_add_srcs) 35 | 36 | # Compiler------------------------------------------------------------------ 37 | if(${MSVC}) 38 | # Don't include uinstd.h in Lexer.h 39 | add_definitions(-DYY_NO_UNISTD_H) 40 | 41 | # Increase stack size 42 | set(CMAKE_EXE_LINKER_FLAGS "/STACK:1000000000") 43 | set(CMAKE_CXX_FLAGS_RELEASE "/MT") 44 | set(CMAKE_CXX_FLAGS_DEBUG "/MTd -DDEBUG") 45 | else() 46 | # Less warnings in C in order to avoid warnings about flex/bison code 47 | set(CMAKE_CXX_FLAGS " -D__STDC_FORMAT_MACROS -std=gnu++11 -D_hypot=hypot -pedantic -Wall -Wno-write-strings -Wextra -Wcast-align -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Woverloaded-virtual -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused") 48 | 49 | set(CMAKE_CXX_FLAGS_VALGRIND " -g") 50 | set(CMAKE_C_FLAGS_VALGRIND " -g") 51 | 52 | set(CMAKE_CXX_FLAGS_DEBUG " -g -fsanitize=address -DDEBUG") 53 | set(CMAKE_C_FLAGS_DEBUG " -g -fsanitize=address -DDEBUG") 54 | 55 | set(CMAKE_CXX_FLAGS_ERRALL " -g -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused") 56 | 57 | set(CMAKE_C_FLAGS_ERRALL " -g -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused") 58 | 59 | endif() 60 | 61 | 62 | # Boost package 63 | if(${MSVC}) 64 | set(Boost_USE_STATIC_LIBS ON) 65 | else() 66 | set(Boost_USE_STATIC_LIBS OFF) 67 | endif() 68 | 69 | find_package(Boost REQUIRED COMPONENTS regex system filesystem) 70 | 71 | include_directories( 72 | ./ 73 | libs/common/ 74 | libs/libgraph/ 75 | libs/dotparser/ 76 | libsGTSI/ 77 | libsGTSI/Traversal/ 78 | libs/node_info/ 79 | ${CMAKE_BINARY_DIR}/libs/dotparser/ 80 | ${Boost_INCLUDE_DIR} 81 | ) 82 | 83 | # Libraries----------------------------------------------------------------- 84 | # Libs 85 | add_subdirectory(libs) 86 | 87 | # GTSI 88 | add_subdirectory(libsGTSI) 89 | 90 | # Executables--------------------------------------------------------------- 91 | add_subdirectory(tools) 92 | 93 | # Bindings------------------------------------------------------------------ 94 | add_subdirectory(bindings) 95 | -------------------------------------------------------------------------------- /src/IDA/grap/grap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """This file is a part of the IDAgrap project.""" 3 | 4 | import sys 5 | 6 | from pygrap import graph_free 7 | 8 | import idaapi 9 | from idagrap.analysis.Analysis import PatternsAnalysis 10 | from idagrap.graph.Graph import CFG 11 | from idagrap.patterns.Modules import MODULES 12 | from idagrap.ui.helpers import QtShim 13 | from idagrap.ui.IDAgrapForm import IDAgrapForm 14 | try: 15 | from idc import auto_wait 16 | except: 17 | from idc import Wait 18 | 19 | # Initialization of useful objects for PySide/PyQt 20 | QtGui = QtShim.get_QtGui() 21 | QtCore = QtShim.get_QtCore() 22 | QtWidgets = QtShim.get_QtWidgets() 23 | 24 | # Recursion limit 25 | sys.setrecursionlimit(400000000) 26 | 27 | def PLUGIN_ENTRY(): 28 | """Plugin entry point.""" 29 | return IDAgrapPlugin() 30 | 31 | 32 | class IDAgrapPlugin(idaapi.plugin_t): 33 | """Grap plugin.""" 34 | 35 | flags = idaapi.PLUGIN_PROC 36 | comment = "IDA Grap" 37 | help = "IDA Grap" 38 | wanted_name = "IDAgrap" 39 | wanted_hotkey = "Shift+G" 40 | 41 | def init(self): 42 | """Initialization of the IDAgrap plugin.""" 43 | return idaapi.PLUGIN_KEEP 44 | 45 | def term(self): 46 | """Exit of the IDAgrap plugin.""" 47 | pass 48 | 49 | def run(self, arg): 50 | """Core of the IDAgrap plugin. 51 | 52 | Args: 53 | arg: Plugin argument. 54 | """ 55 | # Wait for the end of autoanalysis 56 | try: 57 | auto_wait() 58 | except: 59 | Wait() 60 | 61 | # Create form 62 | form = IDAgrapForm() 63 | 64 | # Show the form 65 | form.Show() 66 | 67 | return 68 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/analysis/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/analysis/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/config/General.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from os.path import abspath, dirname 4 | import os 5 | 6 | # Project root 7 | ROOT = dirname(abspath(__file__)) 8 | 9 | 10 | # Config 11 | config = { 12 | "patterns_path": ROOT + os.path.sep + ".." + os.path.sep + "patterns" + os.path.sep, 13 | "icons_path": ROOT + os.path.sep + ".." + os.path.sep + "ui" + os.path.sep + "icons" + os.path.sep, 14 | "about_path": ROOT + os.path.sep + ".." + os.path.sep + "ui" + os.path.sep + "widgets" + os.path.sep + "about.html", 15 | "pygmentize_css_path": ROOT + os.path.sep + ".." + os.path.sep + "ui" + os.path.sep + "widgets" + os.path.sep + "pygmentize.css", 16 | "scripting_path": ROOT + os.path.sep + ".." + os.path.sep + "ui" + os.path.sep + "widgets" + os.path.sep + "scripting.html", 17 | "version": "1.3.1", 18 | "name": "IDAgrap" 19 | } 20 | 21 | try: 22 | if os.name == "nt": 23 | appdata_path = os.getenv("APPDATA") 24 | user_grap_path = appdata_path + os.path.sep + "IDAgrap" 25 | if not os.path.exists(user_grap_path): 26 | os.makedirs(user_grap_path) 27 | config["user_patterns_path"] = user_grap_path + os.path.sep + "patterns" 28 | if not os.path.exists(config["user_patterns_path"]): 29 | os.makedirs(config["user_patterns_path"]) 30 | except Exception as e: 31 | print("WARNING:", e) 32 | 33 | # Patterns Definitions 34 | MIN_THRESHOLD = 0.0 35 | MAX_THRESHOLD = 1.0 36 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/config/Instruction.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import idaapi 4 | 5 | # 6 | # Types of instructions 7 | # 8 | 9 | # Jump instructions 10 | JMPS = ( 11 | idaapi.NN_jmp, # Jump 12 | idaapi.NN_jmpfi, # Indirect Far Jump 13 | idaapi.NN_jmpni, # Indirect Near Jump 14 | idaapi.NN_jmpshort # Jump Short (not used) 15 | ) 16 | 17 | # Conditional jump instructions 18 | CJMPS = ( 19 | idaapi.NN_ja, # Jump if Above (CF=0 & ZF=0) 20 | idaapi.NN_jae, # Jump if Above or Equal (CF=0) 21 | idaapi.NN_jb, # Jump if Below (CF=1) 22 | idaapi.NN_jbe, # Jump if Below or Equal (CF=1 | ZF=1) 23 | idaapi.NN_jc, # Jump if Carry (CF=1) 24 | idaapi.NN_jcxz, # Jump if CX is 0 25 | idaapi.NN_jecxz, # Jump if ECX is 0 26 | idaapi.NN_jrcxz, # Jump if RCX is 0 27 | idaapi.NN_je, # Jump if Equal (ZF=1) 28 | idaapi.NN_jg, # Jump if Greater (ZF=0 & SF=OF) 29 | idaapi.NN_jge, # Jump if Greater or Equal (SF=OF) 30 | idaapi.NN_jl, # Jump if Less (SF!=OF) 31 | idaapi.NN_jle, # Jump if Less or Equal (ZF=1 | SF!=OF) 32 | idaapi.NN_jna, # Jump if Not Above (CF=1 | ZF=1) 33 | idaapi.NN_jnae, # Jump if Not Above or Equal (CF=1) 34 | idaapi.NN_jnb, # Jump if Not Below (CF=0) 35 | idaapi.NN_jnbe, # Jump if Not Below or Equal (CF=0 & ZF=0) 36 | idaapi.NN_jnc, # Jump if Not Carry (CF=0) 37 | idaapi.NN_jne, # Jump if Not Equal (ZF=0) 38 | idaapi.NN_jng, # Jump if Not Greater (ZF=1 | SF!=OF) 39 | idaapi.NN_jnge, # Jump if Not Greater or Equal (ZF=1) 40 | idaapi.NN_jnl, # Jump if Not Less (SF=OF) 41 | idaapi.NN_jnle, # Jump if Not Less or Equal (ZF=0 & SF=OF) 42 | idaapi.NN_jno, # Jump if Not Overflow (OF=0) 43 | idaapi.NN_jnp, # Jump if Not Parity (PF=0) 44 | idaapi.NN_jns, # Jump if Not Sign (SF=0) 45 | idaapi.NN_jnz, # Jump if Not Zero (ZF=0) 46 | idaapi.NN_jo, # Jump if Overflow (OF=1) 47 | idaapi.NN_jp, # Jump if Parity (PF=1) 48 | idaapi.NN_jpe, # Jump if Parity Even (PF=1) 49 | idaapi.NN_jpo, # Jump if Parity Odd (PF=0) 50 | idaapi.NN_js, # Jump if Sign (SF=1) 51 | idaapi.NN_jz, # Jump if Zero (ZF=1) 52 | idaapi.NN_loopw, # Loop while ECX != 0 53 | idaapi.NN_loop, # Loop while CX != 0 54 | idaapi.NN_loopd, # Loop while ECX != 0 55 | idaapi.NN_loopq, # Loop while RCX != 0 56 | idaapi.NN_loopwe, # Loop while CX != 0 and ZF=1 57 | idaapi.NN_loope, # Loop while rCX != 0 and ZF=1 58 | idaapi.NN_loopde, # Loop while ECX != 0 and ZF=1 59 | idaapi.NN_loopqe, # Loop while RCX != 0 and ZF=1 60 | idaapi.NN_loopwne, # Loop while CX != 0 and ZF=0 61 | idaapi.NN_loopne, # Loop while rCX != 0 and ZF=0 62 | idaapi.NN_loopdne, # Loop while ECX != 0 and ZF=0 63 | idaapi.NN_loopqne # Loop while RCX != 0 and ZF=0 64 | ) 65 | 66 | # Return instructions 67 | RETS = ( 68 | idaapi.NN_retn, # Return Near from Procedure 69 | idaapi.NN_retf, # Return Far from Procedure 70 | idaapi.NN_retnw, 71 | idaapi.NN_retnd, 72 | idaapi.NN_retnq, 73 | idaapi.NN_retfw, 74 | idaapi.NN_retfd, 75 | idaapi.NN_retfq 76 | ) 77 | 78 | # Call Instructions 79 | CALLS = ( 80 | idaapi.NN_call, # Call Procedure 81 | idaapi.NN_callfi, # Indirect Call Far Procedure 82 | idaapi.NN_callni # Indirect Call Near Procedure 83 | ) 84 | 85 | # 86 | # Types of operands 87 | # 88 | 89 | # Memory types 90 | OP_MEM = ( 91 | idaapi.o_near, 92 | idaapi.o_far 93 | ) 94 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/config/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/core/ColorCore.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class ColorCore: 4 | @staticmethod 5 | def rgb_to_int(rgb): 6 | """Convert a rgb tuple to an int. 7 | 8 | Arguments: 9 | rgb (tuple): Rgb color. 10 | 11 | Returns: 12 | (int): The return value is an rgb color. 13 | """ 14 | r = int(rgb[0] * 255) << 16 15 | g = int(rgb[1] * 255) << 8 16 | b = int(rgb[2] * 255) 17 | 18 | return r | g | b 19 | 20 | @staticmethod 21 | def rgb_to_bgr(rgb): 22 | """Convert a RGB -> BGR. 23 | 24 | Arguments: 25 | rgb (int): RGB color. 26 | 27 | Returns: 28 | (int): The return value is an BGR color. 29 | """ 30 | r = (rgb & 0xFF0000) >> 16 31 | g = (rgb & 0xFF00) 32 | b = (rgb & 0xFF) << 16 33 | 34 | return b | g | r 35 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/core/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/error/Exceptions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | class NodeException(Exception): 4 | pass 5 | 6 | class CodeException(NodeException): 7 | pass 8 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/error/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/error/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/graph/Node.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from pygrap import NodeInfo, node_t 4 | 5 | try: 6 | from idaapi import is_code, get_flags, print_insn_mnem, generate_disasm_line, create_insn 7 | from idc import print_operand, get_bytes 8 | except: 9 | from idaapi import isCode 10 | from idc import GetDisasm, GetFlags, GetMnem, GetOpnd, GetManyBytes, MakeCode 11 | from idagrap.error.Exceptions import CodeException 12 | import capstone 13 | 14 | 15 | class Node(node_t): 16 | """Representation of a pygrap node, with useful methods. 17 | 18 | Args: 19 | ea (ea_t): Effective Address of the node. 20 | 21 | Attributs: 22 | node (node_t): Pygrap structure for a node. 23 | 24 | Raises: 25 | CodeException: If the ``ea`` is not a code instruction. 26 | """ 27 | def __init__(self, ea, cs, IDA_inst, IDA_inst_size, IDA_inst_string): 28 | """Initialization function, to disassemble with Capstone""" 29 | # Init the node structure 30 | node_t.__init__(self) 31 | 32 | # Check if it's a code instruction 33 | try: 34 | is_c = is_code(get_flags(ea)) 35 | except: 36 | is_c = isCode(GetFlags(ea)) 37 | if not is_c: 38 | raise CodeException 39 | 40 | # 41 | # fill node_t struct 42 | # 43 | 44 | # NodeInfo 45 | self.info = NodeInfo() 46 | inst_elements = [] 47 | 48 | if cs is not None: 49 | try: 50 | size = create_insn(ea) 51 | bytes = get_bytes(ea, size) 52 | except: 53 | size = MakeCode(ea) 54 | bytes = GetManyBytes(ea, size) 55 | 56 | (address, size, mnemonic, op_str) = next(cs.disasm_lite(bytes, ea, count=1)) 57 | else: 58 | address = ea 59 | size = IDA_inst_size 60 | splitted = IDA_inst_string.split(" ") 61 | mnemonic = splitted[0] 62 | op_str = " ".join(splitted[1:]) 63 | 64 | 65 | self.info.opcode = mnemonic 66 | self.info.inst_str = self.info.opcode + " " + op_str 67 | 68 | splitted = op_str.split(", ") 69 | self.info.nargs = 0 70 | 71 | if len(splitted) >= 1: 72 | self.info.arg1 = splitted[0] 73 | self.info.nargs += 1 74 | if len(splitted) >= 2: 75 | self.info.arg2 = splitted[1] 76 | self.info.nargs += 1 77 | if len(splitted) >= 3: 78 | self.info.arg3 = splitted[2] 79 | self.info.nargs += 1 80 | 81 | # No node will be root but this is acceptable for CFGs 82 | self.info.is_root = False 83 | 84 | self.info.address = ea 85 | self.info.has_address = True 86 | 87 | # node_t 88 | self.node_id = self._genid() 89 | 90 | def getid(self): 91 | """Get the node id. 92 | 93 | Returns: 94 | vsize_t: The id of the node. 95 | """ 96 | return self.node_id 97 | 98 | def _genid(self): 99 | """Generate a unique ID for the node. 100 | 101 | Returns: 102 | vsize_t: The id for the node 103 | """ 104 | return self.info.address 105 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/graph/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/graph/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/modules/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/Modules.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from .compression.ModulesCompression import COMPRESSION 4 | from .cryptography.ModulesCrypto import CRYPTO 5 | from .test.ModulesTest import TEST 6 | 7 | MODULES = { 8 | "Crypto": CRYPTO, 9 | "Compression": COMPRESSION, 10 | "Test": TEST 11 | } 12 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/compression/ModulesCompression.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | COMPRESSION = { 4 | } 5 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/compression/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/compression/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/ModulesCrypto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from .block.ModulesCryptoBlock import CRYPTO_BLOCK 4 | from .hash.ModulesCryptoHash import CRYPTO_HASH 5 | from .mode.ModulesCryptoMode import CRYPTO_MODE 6 | from .stream.ModulesCryptoStream import CRYPTO_STREAM 7 | 8 | CRYPTO = { 9 | "Stream": CRYPTO_STREAM, 10 | "Block": CRYPTO_BLOCK, 11 | "Mode": CRYPTO_MODE, 12 | "Hash": CRYPTO_HASH, 13 | } 14 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/cryptography/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/block/ModulesCryptoBlock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Tuple of block ciphers 4 | CRYPTO_BLOCK = ( 5 | ) 6 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/block/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/cryptography/block/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/hash/ModulesCryptoHash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Tuple of hashes 4 | CRYPTO_HASH = ( 5 | ) 6 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/hash/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/cryptography/hash/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/mode/ModulesCryptoMode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Tuple of modes of operation 4 | CRYPTO_MODE = ( 5 | ) 6 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/mode/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/cryptography/mode/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/ModulesCryptoStream.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from .rc4.RC4 import CRYPTO_STREAM_RC4 4 | 5 | # Tuple of stream ciphers 6 | CRYPTO_STREAM = ( 7 | # RC4 deactivated (too many false positives) 8 | # CRYPTO_STREAM_RC4, 9 | ) 10 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/cryptography/stream/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/RC4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from idagrap.modules.Module import ModuleCryptoStream 4 | 5 | from .set_key.RC4SetKey import RC4_SET_KEY 6 | 7 | CRYPTO_STREAM_RC4 = ModuleCryptoStream( 8 | patterns=[RC4_SET_KEY], 9 | name="RC4", 10 | author=["Jonathan Thieuleux"], 11 | description="RC4 Stream Cipher." 12 | ) 13 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/set_key/RC4SetKey.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from os.path import abspath, dirname, sep 4 | from idagrap.modules.Pattern import Pattern, Patterns 5 | 6 | # Definition---------------------------------------------------------------- 7 | ROOT = dirname(abspath(__file__)) 8 | 9 | # 10 | # Pattern 11 | # 12 | # RC4 set key first loop 13 | loop1 = Pattern(f=ROOT + sep + "loop1.dot", 14 | name="First Loop", 15 | description="First Initialization loop of RC4 set_key.", 16 | min_pattern=1, 17 | max_pattern=1) 18 | 19 | # RC4 set key second loop 20 | loop2 = Pattern(f=ROOT + sep + "loop2.dot", 21 | name="Second Loop", 22 | description="Second Initialization loop of RC4 set_key.", 23 | min_pattern=1, 24 | max_pattern=1) 25 | 26 | 27 | RC4_SET_KEY = Patterns( 28 | patterns=[ 29 | loop1, 30 | loop2 31 | ], 32 | threshold=1.0, 33 | name="RC4 Set_Key()", 34 | description="Initialization function of the RC4 algorithm." 35 | ) 36 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/set_key/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/set_key/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/set_key/loop1.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | A [label = "mov+", cond="opcode is mov", getid="A", repeat="+"] 3 | B [label = "add", cond="opcode is add or opcode is inc", getid="B"] 4 | C [label = "*", cond=true, getid="C", minrepeat="0", maxrepeat="3", lazyrepeat=true] 5 | D [label = "cmp", cond="opcode is cmp", getid="D"] 6 | E [label = "JCC", cond="opcode beginswith j", getid="E", minchildren="2"] 7 | 8 | A -> B 9 | B -> C 10 | C -> D 11 | D -> E 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/cryptography/stream/rc4/set_key/loop2.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | A [label = "mov", cond="opcode is mov", getid="A", minrepeat="0", maxrepeat="3", lazyrepeat=true] 3 | B [label = "mov", cond="opcode is mov", getid="B"] 4 | C [label = "*", cond=true, getid="C", minrepeat="1", maxrepeat="6"] 5 | D [label = "mov", cond="opcode is mov", getid="D"] 6 | E [label = "add", cond="opcode is add or opcode is inc", getid="E"] 7 | F [label = "*", cond=true, getid="F", minrepeat="0", maxrepeat="4", lazyrepeat=true] 8 | G [label = "cmp", cond="opcode is cmp", getid="G"] 9 | 10 | A -> B 11 | B -> C 12 | C -> D 13 | D -> E 14 | E -> F 15 | F -> G 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/ModulesTest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from .misc.ModulesTestMisc import get_test_misc 4 | 5 | TEST = { 6 | "Misc": get_test_misc(), 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/test/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/ModulesTestMisc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | from os.path import abspath, dirname, sep 5 | 6 | from idagrap.modules.Module import ModuleTestMisc 7 | from idagrap.modules.Pattern import Pattern, Patterns 8 | from idagrap.config.General import config 9 | 10 | 11 | def get_test_misc(): 12 | # Definition---------------------------------------------------------------- 13 | ROOT = dirname(abspath(__file__)) 14 | DIR = sep + "files" 15 | FULL_PATHS = [ROOT + DIR] 16 | if "user_patterns_path" in config: 17 | FULL_PATHS.append(config["user_patterns_path"]) 18 | EXT = [".grapp", ".dot"] 19 | 20 | # Tuple of stream ciphers 21 | TEST_MISC = [] 22 | 23 | # For all misc patterns 24 | for p in FULL_PATHS: 25 | rec_listdir = [(os.path.join(dp, f), f) for dp, dn, fn in os.walk(p, followlinks=True) for f in fn] 26 | for dotpath, dot in rec_listdir: 27 | ext_ok = False 28 | for e in EXT: 29 | if dot.endswith(e): 30 | ext_ok = True 31 | break 32 | if ext_ok: 33 | pattern = Pattern(f=dotpath, 34 | name=dot, 35 | description=dot + " pattern", 36 | min_pattern=1, 37 | max_pattern=10) 38 | patterns = Patterns(patterns=[pattern], 39 | threshold=1.0, 40 | name=dot + " patterns", 41 | description=dot + " patterns", 42 | perform_analysis=False) 43 | module = ModuleTestMisc( 44 | patterns=[patterns], 45 | name=dot + " module", 46 | description=dot + " module" 47 | ) 48 | 49 | TEST_MISC.append(module) 50 | return TEST_MISC 51 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/test/misc/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/patterns/test/misc/files/.gitkeep -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/basic_block_loop.grapp: -------------------------------------------------------------------------------- 1 | digraph bb_loop{ 2 | A [label="A: (*)+", shape="box", cond=true, minrepeat=1, maxrepeat=none, getid="A"] 3 | A -> A [label=2, childnumber=2] 4 | } 5 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/bb_xor_loop.grapp: -------------------------------------------------------------------------------- 1 | digraph bb_xor_loop{ 2 | A [label="A: (^xor)*", shape="box", cond=true, repeat="*", lazyrepeat=true, maxchildren=1, getid="A"] 3 | B [label="B: (xor)+", shape="box", cond="opcode is xor", repeat="+",maxchildren=1, getid="B"] 4 | C [label="C: (*)*", shape="box", cond="true", repeat="*", getid="C"] 5 | 6 | A -> B 7 | B -> C 8 | C -> A [label=2, childnumber=2] 9 | } 10 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/crypto/aes_libressl_v0.1.grapp: -------------------------------------------------------------------------------- 1 | digraph LibreSSL_AES_common{ 2 | Ro [cond="opcode is shl and arg2 is 0x10", getid="LibreSSL_AES_common"] 3 | A [cond=true, lazyrepeat=true, repeat=*] 4 | B [cond="opcode is shl and arg2 is 0x18"] 5 | C [cond=true, lazyrepeat=true, repeat=*] 6 | D [cond="opcode is shl and arg2 is 0x10"] 7 | E [cond=true, lazyrepeat=true, repeat=*] 8 | F [cond="opcode is shl and arg2 is 0x18"] 9 | G [cond=true, repeat=*] 10 | 11 | H [cond="nfathers == 2"] 12 | I [cond=true, lazyrepeat=true, repeat=*] 13 | J [cond="opcode is shr and arg2 is 0x18"] 14 | K [cond=true, lazyrepeat=true, repeat=*] 15 | L [cond="opcode is shr and arg2 is 0x10"] 16 | M [cond=true, lazyrepeat=true, repeat=*] 17 | N [cond="opcode is shr and arg2 is 0x18"] 18 | O [cond=true, lazyrepeat=true, repeat=*] 19 | P [cond="opcode is shr and arg2 is 0x10"] 20 | Q [cond=true, lazyrepeat=true, repeat=*] 21 | R [cond="opcode beginswith j and nchildren == 2"] 22 | 23 | S [cond=true, lazyrepeat=true, repeat=*] 24 | T [cond="opcode is shr and arg2 is 0x18"] 25 | U [cond=true, lazyrepeat=true, repeat=*] 26 | V [cond="opcode is 'and' and arg2 is 0xff000000"] 27 | 28 | X [cond=true, lazyrepeat=true, repeat=*] 29 | Y [cond="opcode is shr and arg2 is 0x18"] 30 | Z [cond=true, lazyrepeat=true, repeat=*] 31 | a [cond="opcode is shr and arg2 is 0x10"] 32 | b [cond=true, lazyrepeat=true, repeat=*] 33 | c [cond="opcode is shr and arg2 is 0x18"] 34 | d [cond=true, lazyrepeat=true, repeat=*] 35 | e [cond="opcode is shr and arg2 is 0x10"] 36 | f [cond=true, lazyrepeat=true, repeat=*] 37 | g [cond="basicblockend"] 38 | 39 | Ro -> A 40 | A -> B 41 | B -> C 42 | C -> D 43 | D -> E 44 | E -> F 45 | F -> G 46 | 47 | G -> H [childnumber=*] 48 | H -> I 49 | I -> J 50 | J -> K 51 | K -> L 52 | L -> M 53 | M -> N 54 | N -> O 55 | O -> P 56 | P -> Q 57 | Q -> R 58 | 59 | R -> S [childnumber=*] 60 | S -> T 61 | T -> U 62 | U -> V 63 | 64 | R -> X [childnumber=*] 65 | X -> Y 66 | Y -> Z 67 | Z -> a 68 | a -> b 69 | b -> c 70 | c -> d 71 | d -> e 72 | e -> f 73 | f -> g 74 | g -> H [childnumber=*] 75 | } 76 | 77 | digraph LibreSSL_AES_compact{ 78 | Ro [cond="opcode is shl", getid="LibreSSL_AES_compact"] 79 | A [cond="opcode is shl", repeat=2] 80 | B [cond="opcode is xor", repeat=3] 81 | C [cond=true, lazyrepeat=true, repeat=*] 82 | D [cond="opcode is shl and arg2 is 0x18"] 83 | E [cond=true, lazyrepeat=true, repeat=*] 84 | F [cond="opcode beginswith j and nchildren == 2"] 85 | 86 | G [cond="opcode is xor"] 87 | H [cond=true, lazyrepeat=true, repeat=*] 88 | I [cond="basicblockend"] 89 | 90 | K [cond=true, lazyrepeat=true, repeat=*] 91 | L [cond="opcode is 'and' and arg2 is 0x80808080", repeat=2] 92 | M [cond=true, lazyrepeat=true, repeat=*] 93 | N [cond="opcode is 'and' and arg2 is 0xfefefefe", repeat=2] 94 | O [cond=true, lazyrepeat=true, repeat=*] 95 | P [cond="opcode is 'and' and arg2 is 0x1b1b1b1b", repeat=2] 96 | Q [cond=true, lazyrepeat=true, repeat=*] 97 | R [cond="opcode beginswith j"] 98 | 99 | Ro -> A 100 | A -> B 101 | B -> C 102 | C -> D 103 | D -> E 104 | E -> F 105 | 106 | F -> G [childnumber=*] 107 | G -> H 108 | H -> I 109 | 110 | F -> K [childnumber=*] 111 | K -> L 112 | L -> M 113 | M -> N 114 | N -> O 115 | O -> P 116 | P -> Q 117 | Q -> R 118 | } 119 | 120 | digraph AES_NI{ 121 | Ro [cond="opcode is aesenc or opcode is aesenclast or opcode is aesdec or opcode is aesdeclast", getid="LibreSSL_AES_NI"] 122 | } 123 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/crypto/arx_crypto.grapp: -------------------------------------------------------------------------------- 1 | digraph ARX_crypto{ 2 | Op1 [cond="opcode is add" repeat=+ lazyrepeat=true getid="ARX_crypto"] 3 | Op1M [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 4 | Op2 [cond="opcode is xor" repeat=+ lazyrepeat=true] 5 | Op2M [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 6 | Op3 [cond="opcode is rol" repeat=+ lazyrepeat=true] 7 | Op3M [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 8 | 9 | Op1_A [cond="opcode is add" repeat=+ lazyrepeat=true] 10 | Op1M_A [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 11 | Op2_A [cond="opcode is xor" repeat=+ lazyrepeat=true] 12 | Op2M_A [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 13 | Op3_A [cond="opcode is rol" repeat=+ lazyrepeat=true] 14 | Op3M_A [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 15 | 16 | Op1_B [cond="opcode is add" repeat=+ lazyrepeat=true] 17 | Op1M_B [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 18 | Op2_B [cond="opcode is xor" repeat=+ lazyrepeat=true] 19 | Op2M_B [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 20 | Op3_B [cond="opcode is rol" repeat=+ lazyrepeat=true] 21 | Op3M_B [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 22 | 23 | Op1_C [cond="opcode is add" repeat=+ lazyrepeat=true] 24 | Op1M_C [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 25 | Op2_C [cond="opcode is xor" repeat=+ lazyrepeat=true] 26 | Op2M_C [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 27 | Op3_C [cond="opcode is rol" repeat=+ lazyrepeat=true] 28 | Op3M_C [cond="opcode is mov or opcode is lea" repeat=* lazyrepeat=true] 29 | 30 | Op1 -> Op1M 31 | Op1M -> Op2 32 | Op2 -> Op2M 33 | Op2M -> Op3 34 | Op3 -> Op3M 35 | 36 | Op3M -> Op1_A 37 | Op1_A -> Op1M_A 38 | Op1M_A -> Op2_A 39 | Op2_A -> Op2M_A 40 | Op2M_A -> Op3_A 41 | Op3_A -> Op3M_A 42 | 43 | Op3M_A -> Op1_B 44 | Op1_B -> Op1M_B 45 | Op1M_B -> Op2_B 46 | Op2_B -> Op2M_B 47 | Op2M_B -> Op3_B 48 | Op3_B -> Op3M_B 49 | 50 | Op3M_B -> Op1_C 51 | Op1_C -> Op1M_C 52 | Op1M_C -> Op2_C 53 | Op2_C -> Op2M_C 54 | Op2M_C -> Op3_C 55 | Op3_C -> Op3M_C 56 | } 57 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/popular.grapp: -------------------------------------------------------------------------------- 1 | digraph popular{ 2 | A [cond="nfathers>=10", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/trick_PEB.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_PEB { 2 | 0x2000b [cond="opcode is 'mov' and arg2 contains 'dword ptr fs:' and arg2 contains '0x30'"] 3 | } 4 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/trick_PEparsing.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_PEparsing { 2 | magic [cond="arg1 is 0x5a4d or arg2 is 0x5a4d or arg1 is 0x4550 or arg2 is 0x4550"] 3 | } 4 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/trick_call5.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_call5 { 2 | call [cond="opcode is 'call'"] 3 | child [cond=true] 4 | call -> child [childnumber=1] 5 | call -> child [childnumber=2] 6 | } 7 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/trick_cpuid.grapp: -------------------------------------------------------------------------------- 1 | // https://search.unprotect.it/map/sandbox-evasion/cpuid/ 2 | 3 | digraph trick_cpuid { 4 | cpuid [cond="opcode is 'cpuid'"] 5 | } 6 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/trick_pushret.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_pushret { 2 | 0x2032a [cond="opcode is 'push'"] 3 | 0x2032b [cond="opcode beginswith 'ret'"] 4 | 5 | 0x2032a -> 0x2032b [childnumber=1] 6 | } 7 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/patterns/test/misc/files/trick_vmware_detection.grapp: -------------------------------------------------------------------------------- 1 | digraph trick_vmware_detection_cmp { 2 | 0x403e82 [cond="opcode is 'cmp' and arg2 is '0x564d5868'"] 3 | } 4 | 5 | digraph trick_vmware_detection_v1 { 6 | 0x406d7f [cond="opcode is 'mov' and arg1 is 'eax' and arg2 is '0x564d5868'"] 7 | 0x406d84 [cond="opcode is 'mov' and arg1 is 'ecx' and arg2 is '0xa'"] 8 | 0x406d89 [cond="opcode is 'mov' and arg1 is 'dx' and arg2 is '0x5658'"] 9 | 0x406d8d [cond="opcode is 'in'"] 10 | 11 | 0x406d7f -> 0x406d84 [childnumber=1] 12 | 0x406d84 -> 0x406d89 [childnumber=1] 13 | 0x406d89 -> 0x406d8d [childnumber=1] 14 | } 15 | 16 | digraph trick_vmware_detection_magic { 17 | 1_magic [cond="inst regex '.*0x564d5868.*'"] 18 | 2_other [cond="true", minrepeat=0, maxrepeat=5, lazyrepeat=true] 19 | 3_in [cond="opcode is 'in'"] 20 | 21 | 1_magic -> 2_other [childnumber=1] 22 | 2_other -> 3_in [childnumber=1] 23 | } 24 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/IDAgrapForm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Inspired by IDAscope 3 | 4 | import idc 5 | from idaapi import PluginForm 6 | from idagrap.config.General import config 7 | 8 | from .helpers.ClassCollection import ClassCollection 9 | from .widgets.CryptoIdentificationWidget import CryptoIdentificationWidget 10 | from .widgets.PatternGenerationWidget import PatternGenerationWidget 11 | from .widgets.AboutWidget import AboutWidget 12 | from .widgets.AboutScriptingWidget import AboutScriptingWidget 13 | 14 | 15 | class IDAgrapForm(PluginForm): 16 | """IDAgrapForm class. 17 | 18 | This class is the core of the IDAgrap UI. 19 | 20 | Attributes: 21 | idagrap_widgets (QMainWindow list): List of widgets to add. 22 | cc (ClassCollection): Collection of many classes. 23 | icon (QIcon): Icon of the plugin-in. 24 | parent (QWidget): QWidget to be used by PySide/PyQt5. 25 | tabs (QTabWidget): Stack of tabbed widgets. 26 | """ 27 | 28 | def __init__(self): 29 | """Initialization.""" 30 | super(IDAgrapForm, self).__init__() 31 | 32 | self.idagrap_widgets = [] 33 | self.cc = ClassCollection() 34 | self.icon = self.cc.QIcon(config['icons_path'] + "icons8-mind-map.png") 35 | 36 | def print_banner(self): 37 | """Print the banner.""" 38 | banner = "{:#^72}\n".format('') 39 | banner += " ________ ______ ________ _______ ______ ________ ______ \n" 40 | banner += "/_______/\\/_____/\\ /_______/\\ /______/\\ /_____/\\ /_______/\\ /_____/\\ \n" 41 | banner += "\\__.::._\\/\\:::_ \\ \\\\::: _ \\ \\\\::::__\\/__\\:::_ \\ \\ \\::: _ \\ \\\\:::_ \\ \\ \n" 42 | banner += " \\::\\ \\ \\:\\ \\ \\ \\\\::(_) \\ \\\\:\\ /____/\\\\:(_) ) )_\\::(_) \\ \\\\:(_) \\ \\ \n" 43 | banner += " _\\::\\ \\__\\:\\ \\ \\ \\\\:: __ \\ \\\\:\\\\_ _\\/ \\: __ `\\ \\\\:: __ \\ \\\\: ___\\/ \n" 44 | banner += " /__\\::\\__/\\\\:\\/.:| |\\:.\\ \\ \\ \\\\:\\_\\ \\ \\ \\ \\ `\\ \\ \\\\:.\\ \\ \\ \\\\ \\ \\ \n" 45 | banner += " \\________\\/ \\____/_/ \\__\\/\\__\\/ \\_____\\/ \\_\\/ \\_\\/ \\__\\/\\__\\/ \\_\\/ \n\n" 46 | banner += "{:#^72}\n".format('') 47 | 48 | print(banner) 49 | 50 | def setupWidgets(self): 51 | """ 52 | Setup IDAgrap widgets. 53 | """ 54 | 55 | #print "[/] setting up widgets..." 56 | 57 | # Initialization of the widgets 58 | self.idagrap_widgets.append(CryptoIdentificationWidget(self)) 59 | self.idagrap_widgets.append(PatternGenerationWidget(self)) 60 | self.idagrap_widgets.append(AboutScriptingWidget(self)) 61 | self.idagrap_widgets.append(AboutWidget(self)) 62 | self.setupIDAgrapForm() 63 | 64 | #print "[\\] end widgets" 65 | 66 | def setupIDAgrapForm(self): 67 | """ 68 | Orchestrate the already initialized widgets in tabs on the main 69 | window. 70 | """ 71 | self.tabs = self.cc.QTabWidget() 72 | self.tabs.setTabsClosable(False) 73 | self.tabs.setMovable(True) 74 | 75 | # Add all the widgets 76 | for widget in self.idagrap_widgets: 77 | self.tabs.addTab(widget, widget.icon, widget.name) 78 | 79 | # Lines up widgets 80 | layout = self.cc.QVBoxLayout() 81 | layout.addWidget(self.tabs) 82 | 83 | # Set layout in QWidget 84 | self.parent.setLayout(layout) 85 | 86 | def OnCreate(self, form): 87 | """OnCreate of IDAgrap. 88 | 89 | This event is called when the plugin form is created. 90 | 91 | Arguments: 92 | form (TForm*): Plug-in form. 93 | """ 94 | self.print_banner() 95 | 96 | # compatibility with IDA < 6.9 97 | # Convert TForm* for PyQt or PySide 98 | try: 99 | self.parent = self.FormToPySideWidget(form) 100 | except Exception: 101 | self.parent = self.FormToPyQtWidget(form) 102 | 103 | self.parent.setWindowIcon(self.icon) 104 | self.setupWidgets() 105 | 106 | def Show(self): 107 | """ 108 | Creates the form and brings it to the front. 109 | """ 110 | 111 | try: 112 | input_md5 = idc.retrieve_input_file_md5() 113 | except: 114 | input_md5 = idc.GetInputMD5() 115 | 116 | if input_md5 is None: 117 | return 118 | else: 119 | name = "{}".format(config['name']) 120 | 121 | try: 122 | options = PluginForm.WCLS_CLOSE_LATER |\ 123 | PluginForm.WCLS_SAVE |\ 124 | PluginForm.WOPN_RESTORE 125 | except: 126 | options = PluginForm.FORM_CLOSE_LATER |\ 127 | PluginForm.FORM_SAVE |\ 128 | PluginForm.FORM_RESTORE 129 | 130 | return PluginForm.Show(self, name, options=options) 131 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/helpers/ClassCollection.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Inspired by https://bitbucket.org/daniel_plohmann/simplifire.idascope/raw/438a8f8a83b8ef7599b72c78cd2d843aa23c407c/idascope/core/helpers/ClassCollection.py 4 | ######################################################################## 5 | # Copyright (c) 2016 6 | # Daniel Plohmann gmailcom> 7 | # Alexander Hanel gmailcom> 8 | # All rights reserved. 9 | ######################################################################## 10 | # 11 | # This file is part of IDAscope 12 | # 13 | # IDAscope is free software: you can redistribute it and/or modify it 14 | # under the terms of the GNU General Public License as published by 15 | # the Free Software Foundation, either version 3 of the License, or 16 | # (at your option) any later version. 17 | # 18 | # This program is distributed in the hope that it will be useful, but 19 | # WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU General Public License 24 | # along with this program. If not, see 25 | # . 26 | # 27 | ######################################################################## 28 | 29 | 30 | # helpers 31 | import idagrap.ui.helpers.QtShim as QtShim 32 | from idagrap.core.CryptoIdentifier import CryptoColor, CryptoIdentifier 33 | from idagrap.core.PatternGenerator import PatternGenerator 34 | from idagrap.graph.Graph import CFG 35 | 36 | 37 | class ClassCollection(): 38 | """Collection of classes. 39 | 40 | This class is a collection of many classes. The goal of this 41 | ClassCollection is to simplify the access to Qt and personal classes. 42 | """ 43 | 44 | def __init__(self): 45 | """Initialization.""" 46 | # python imports 47 | # PySide / PyQt imports 48 | self.QtShim = QtShim 49 | self.QtGui = self.QtShim.get_QtGui() 50 | self.QtCore = self.QtShim.get_QtCore() 51 | self.QIcon = self.QtShim.get_QIcon() 52 | self.QWidget = self.QtShim.get_QWidget() 53 | self.QVBoxLayout = self.QtShim.get_QVBoxLayout() 54 | self.QHBoxLayout = self.QtShim.get_QHBoxLayout() 55 | self.QSplitter = self.QtShim.get_QSplitter() 56 | self.QStyleFactory = self.QtShim.get_QStyleFactory() 57 | self.QLabel = self.QtShim.get_QLabel() 58 | self.QTableWidget = self.QtShim.get_QTableWidget() 59 | self.QAbstractItemView = self.QtShim.get_QAbstractItemView() 60 | self.QTableWidgetItem = self.QtShim.get_QTableWidgetItem() 61 | self.QPushButton = self.QtShim.get_QPushButton() 62 | self.QScrollArea = self.QtShim.get_QScrollArea() 63 | self.QSizePolicy = self.QtShim.get_QSizePolicy() 64 | self.QLineEdit = self.QtShim.get_QLineEdit() 65 | self.QTextEdit = self.QtShim.get_QTextEdit() 66 | self.QMainWindow = self.QtShim.get_QMainWindow() 67 | self.QSlider = self.QtShim.get_QSlider() 68 | self.QCompleter = self.QtShim.get_QCompleter() 69 | self.QTextBrowser = self.QtShim.get_QTextBrowser() 70 | self.QStringListModel = self.QtShim.get_QStringListModel() 71 | self.QDialog = self.QtShim.get_QDialog() 72 | self.QGroupBox = self.QtShim.get_QGroupBox() 73 | self.QRadioButton = self.QtShim.get_QRadioButton() 74 | self.QComboBox = self.QtShim.get_QComboBox() 75 | self.QCheckBox = self.QtShim.get_QCheckBox() 76 | self.QAction = self.QtShim.get_QAction() 77 | self.QColor = self.QtShim.get_QColor() 78 | self.QBrush = self.QtShim.get_QBrush() 79 | self.QTreeWidget = self.QtShim.get_QTreeWidget() 80 | self.QTreeWidgetItem = self.QtShim.get_QTreeWidgetItem() 81 | self.QStyle = self.QtShim.get_QStyle() 82 | self.QPainter = self.QtShim.get_QPainter() 83 | self.QApplication = self.QtShim.get_QApplication() 84 | self.QStyleOptionSlider = self.QtShim.get_QStyleOptionSlider() 85 | self.QTabWidget = self.QtShim.get_QTabWidget() 86 | self.QFileDialog = self.QtShim.get_QFileDialog() 87 | self.DescendingOrder = self.QtShim.get_DescendingOrder() 88 | 89 | # IDAgrap 90 | graph = CFG() 91 | self.CryptoIdentifier = CryptoIdentifier(graph) 92 | self.CryptoColor = CryptoColor() 93 | 94 | self.PatternGenerator = PatternGenerator(graph) 95 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/helpers/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/circle.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/coloring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/coloring.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/crypto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/crypto.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/generate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/generate.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/graphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/graphic.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-add-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-add-file.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-asterisk-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-asterisk-24.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-color-palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-color-palette.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-delete.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-edit-property-52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-edit-property-52.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-eye-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-eye-50.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-fingerprint-scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-fingerprint-scan.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-function-mac-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-function-mac-32.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-info.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-mind-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-mind-map.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-plus.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-python-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-python-50.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-save-as-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-save-as-50.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-search.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/icons8-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/icons8-workflow.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/reset.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/icons/scan_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/icons/scan_graph.png -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/widgets/AboutScriptingWidget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Inspired by IDAscope. 3 | 4 | 5 | import idagrap.ui.helpers.QtShim as QtShim 6 | import idc 7 | import idaapi 8 | from idagrap.config.General import config 9 | from idagrap.patterns.Modules import MODULES 10 | 11 | QMainWindow = QtShim.get_QMainWindow() 12 | 13 | 14 | class AboutScriptingWidget(QMainWindow): 15 | def __init__(self, parent): 16 | """Initialization.""" 17 | # Initialization 18 | self.cc = parent.cc 19 | self.cc.QMainWindow.__init__(self) 20 | #print "[|] loading AboutScriptingWidget" 21 | 22 | # Enable access to shared IDAscope modules 23 | self.parent = parent 24 | self.name = "Scripting" 25 | self.icon = self.cc.QIcon(config['icons_path'] + "icons8-python-50.png") 26 | self.color = False 27 | 28 | # This widget relies on the crypto identifier 29 | self.central_widget = self.cc.QWidget() 30 | self.setCentralWidget(self.central_widget) 31 | self._createGui() 32 | 33 | 34 | def _createGui(self): 35 | """ 36 | Setup function for the full GUI of this widget. 37 | """ 38 | 39 | # Text pattern 40 | self._createTextWidget() 41 | 42 | # Layout and fill the widget 43 | generation_layout = self.cc.QVBoxLayout() 44 | generation_layout.addWidget(self.text_widget) 45 | 46 | self.central_widget.setLayout(generation_layout) 47 | 48 | def _createTextWidget(self): 49 | self.text_widget = self.cc.QTextEdit() 50 | self.text_widget.setReadOnly(True) 51 | self.text_widget.setFontFamily("Monospace") 52 | 53 | css_text = open(config['pygmentize_css_path'], "r").read() 54 | if css_text is not None: 55 | self.text_widget.document().setDefaultStyleSheet(css_text) 56 | 57 | html_text = open(config['scripting_path'], "r").read() 58 | if html_text is not None: 59 | self.text_widget.setHtml(html_text.replace("TODO_GRAPVERSION", config["version"])) 60 | else: 61 | self.text_widget.setText("Error: scripting.html not found") 62 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/widgets/AboutWidget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Inspired by IDAscope. 3 | 4 | 5 | import idagrap.ui.helpers.QtShim as QtShim 6 | import idc 7 | import idaapi 8 | from idagrap.config.General import config 9 | from idagrap.patterns.Modules import MODULES 10 | 11 | QMainWindow = QtShim.get_QMainWindow() 12 | 13 | 14 | class AboutWidget(QMainWindow): 15 | def __init__(self, parent): 16 | """Initialization.""" 17 | # Initialization 18 | self.cc = parent.cc 19 | self.cc.QMainWindow.__init__(self) 20 | #print "[|] loading AboutWidget" 21 | 22 | # Enable access to shared IDAscope modules 23 | self.parent = parent 24 | self.name = "About" 25 | self.icon = self.cc.QIcon(config['icons_path'] + "icons8-info.png") 26 | self.color = False 27 | 28 | # This widget relies on the crypto identifier 29 | self.central_widget = self.cc.QWidget() 30 | self.setCentralWidget(self.central_widget) 31 | self._createGui() 32 | 33 | 34 | def _createGui(self): 35 | """ 36 | Setup function for the full GUI of this widget. 37 | """ 38 | 39 | # Text pattern 40 | self._createTextWidget() 41 | 42 | # Layout and fill the widget 43 | generation_layout = self.cc.QVBoxLayout() 44 | generation_layout.addWidget(self.text_widget) 45 | 46 | self.central_widget.setLayout(generation_layout) 47 | 48 | def _createTextWidget(self): 49 | self.text_widget = self.cc.QTextEdit() 50 | self.text_widget.setReadOnly(True) 51 | self.text_widget.setFontFamily("Monospace") 52 | 53 | 54 | html_text = open(config['about_path'], "r").read() 55 | if html_text is not None: 56 | self.text_widget.setHtml(html_text.replace("TODO_GRAPVERSION", config["version"])) 57 | else: 58 | self.text_widget.setText("Error: about.html not found") 59 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/widgets/EditorWidget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Inspired by IDAscope. 3 | 4 | 5 | import idagrap.ui.helpers.QtShim as QtShim 6 | import idc 7 | import idaapi 8 | from idagrap.config.General import config 9 | from idagrap.patterns.Modules import MODULES 10 | import idagrap.ui.helpers.QtGrapSyntax as syntax 11 | from PyQt5.QtWidgets import QMessageBox 12 | 13 | QMainWindow = QtShim.get_QMainWindow() 14 | 15 | class EditorWidget(QMainWindow): 16 | def __init__(self, parent, file_path=None): 17 | """Initialization.""" 18 | # Initialization 19 | self.file_path = file_path 20 | self.saved_text = None 21 | self.cc = parent.cc 22 | self.cc.QMainWindow.__init__(self) 23 | # print("[|] loading EditorWidget") 24 | 25 | # Enable access to shared IDAscope modules 26 | self.parent = parent 27 | self.name = "Pattern Editor" 28 | #self.icon = self.cc.QIcon(config['icons_path'] + "icons8-align-text-left-50.png") 29 | self.icon = self.cc.QIcon(config['icons_path'] + "icons8-edit-property-52.png") 30 | self.color = False 31 | 32 | # This widget relies on the crypto identifier 33 | self.central_widget = self.cc.QWidget() 34 | self.setCentralWidget(self.central_widget) 35 | self._createGui() 36 | 37 | self.textPath.setText(self.file_path) 38 | self.load_file() 39 | 40 | def _createGui(self): 41 | """ 42 | Setup function for the full GUI of this widget. 43 | """ 44 | 45 | # Toolbar 46 | self._createToolbar() 47 | 48 | # Text pattern 49 | self._createTextWidget() 50 | 51 | # Layout and fill the widget 52 | generation_layout = self.cc.QVBoxLayout() 53 | generation_layout.addWidget(self.text_widget) 54 | 55 | self.central_widget.setLayout(generation_layout) 56 | 57 | def _createToolbar(self): 58 | """ 59 | Creates the toolbar, containing buttons to control the widget. 60 | """ 61 | self.toolbar = self.addToolBar('Pattern Editor Toolbar') 62 | self.toolbar.setMovable(False) 63 | 64 | #self._createOpenAction() 65 | #self.toolbar.addAction(self.openAction) 66 | 67 | self._createSaveAction() 68 | self.toolbar.addAction(self.saveAction) 69 | 70 | self._createTextPath() 71 | self.toolbar.addWidget(self.textPath) 72 | 73 | self._createCloseAction() 74 | self.toolbar.addAction(self.closeAction) 75 | 76 | def _createCloseAction(self): 77 | """ 78 | Create an action for the close button of the toolbar and connect it. 79 | """ 80 | # Action 81 | self.closeAction = self.cc.QAction( 82 | self.cc.QIcon(config['icons_path'] + "icons8-delete.png"), 83 | "Quit editor", 84 | self 85 | ) 86 | 87 | self.closeAction.triggered.connect(self._onCloseClicked) 88 | 89 | def _onCloseClicked(self): 90 | text = self.text_widget.toPlainText() 91 | if text != self.saved_text: 92 | msg_box = QMessageBox(self) 93 | r = msg_box.question(self, 'Warning', ('The pattern has not been saved to file, close the editor anyway?'), QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel) 94 | if r != QMessageBox.Yes: 95 | return 96 | 97 | index = self.parent.tabs.indexOf(self) 98 | self.parent.tabs.removeTab(index) 99 | 100 | def _createSaveAction(self): 101 | """ 102 | Create an action for the save button of the toolbar and connect it. 103 | """ 104 | # Action 105 | self.saveAction = self.cc.QAction( 106 | self.cc.QIcon(config['icons_path'] + "icons8-save-as-50.png"), 107 | "Save file", 108 | self 109 | ) 110 | 111 | self.saveAction.triggered.connect(self._onSaveClicked) 112 | 113 | def _onSaveClicked(self): 114 | text = self.text_widget.toPlainText() 115 | 116 | try: 117 | f = open(self.file_path, "w") 118 | f.write(text) 119 | f.close() 120 | self.saved_text = text 121 | except Exception as e: 122 | print("WARNING:", e) 123 | 124 | def _createTextPath(self): 125 | self.textPath = self.cc.QLineEdit() 126 | self.textPath.setReadOnly(True) 127 | self.textPath.setFrame(False) 128 | 129 | def _createTextWidget(self): 130 | self.text_widget = self.cc.QTextEdit() 131 | self.text_widget.setReadOnly(False) 132 | self.text_widget.setFontFamily("Monospace") 133 | self.highlight = syntax.PythonHighlighter(self.text_widget.document()) 134 | 135 | 136 | def load_file(self): 137 | if self.file_path: 138 | try: 139 | f = open(self.file_path, "r") 140 | text = f.read() 141 | f.close() 142 | self.text_widget.setText(text) 143 | self.saved_text = text 144 | except Exception as e: 145 | print("WARNING:", e) 146 | 147 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/widgets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/IDA/grap/idagrap/ui/widgets/__init__.py -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/widgets/about.html: -------------------------------------------------------------------------------- 1 |

grap TODO_GRAPVERSION

2 | grap matches user-defined graph patterns within binaries. 3 |
4 | It exists as a stand-alone CLI application (with a Capstone-based disassembler), as python bindings and as this IDA plugin. 5 |
6 | https://github.com/QuoSecGmbH/grap/ 7 | 8 |

Pattern Search

9 |
    10 |
  • Within the Pattern Search tab, you can match existing patterns against the state of the binary being analyzed
  • 11 |
  • Since the Control Flow Graph (CFG) is created from the current IDA database, you might want to do it again later in the analysis process
  • 12 |
13 | 14 | Patterns files should have the .grapp extension and may be located: 15 |
    16 |
  • (Windows Only) in %APPDATA%\IDAgrap\patterns: user defined patterns
  • 17 |
  • In an IDA plugin folder (for instance C:\Program Files\IDA 7.0\plugins\idagrap\patterns\test\misc\files): default patterns
  • 18 |
19 | 20 |

Pattern Generation

21 |
    22 |
  • Within the Pattern Generation tab, first parse the CFG with the "Load CFG" button
  • 23 |
  • Then, within IDA View, add a root node and target nodes (with a right click)
  • 24 |
  • Intermediate nodes are automatically colored and the pattern text field is filled
  • 25 |
  • Alternatively you can disable the "Auto update" option and click on "Generate a pattern" to generate a pattern
  • 26 |
  • You can save the generated pattern to a file
  • 27 |
  • The created pattern file can be matched from the Pattern Search tab
  • 28 |
29 | 30 |

Credits

31 | grap is an open source project. 32 | 33 |

License

34 | grap is licensed under the MIT license. 35 |
36 | The full license text should have been distributed with the software. 37 | It can be also found in the file LICENSE on the repository. 38 | 39 |

Icons

40 | Most of the icons used in the IDA plugin (those named icons8-* in the ui/icons/ folder): 41 | 45 | -------------------------------------------------------------------------------- /src/IDA/grap/idagrap/ui/widgets/pygmentize.css: -------------------------------------------------------------------------------- 1 | .hll { background-color: #ffffcc } 2 | .c { color: #408080; font-style: italic } /* Comment */ 3 | .err { border: 1px solid #FF0000 } /* Error */ 4 | .k { color: #008000; font-weight: bold } /* Keyword */ 5 | .o { color: #666666 } /* Operator */ 6 | .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ 7 | .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 8 | .cp { color: #BC7A00 } /* Comment.Preproc */ 9 | .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ 10 | .c1 { color: #408080; font-style: italic } /* Comment.Single */ 11 | .cs { color: #408080; font-style: italic } /* Comment.Special */ 12 | .gd { color: #A00000 } /* Generic.Deleted */ 13 | .ge { font-style: italic } /* Generic.Emph */ 14 | .gr { color: #FF0000 } /* Generic.Error */ 15 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 16 | .gi { color: #00A000 } /* Generic.Inserted */ 17 | .go { color: #888888 } /* Generic.Output */ 18 | .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 19 | .gs { font-weight: bold } /* Generic.Strong */ 20 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 21 | .gt { color: #0044DD } /* Generic.Traceback */ 22 | .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ 23 | .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ 24 | .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ 25 | .kp { color: #008000 } /* Keyword.Pseudo */ 26 | .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ 27 | .kt { color: #B00040 } /* Keyword.Type */ 28 | .m { color: #666666 } /* Literal.Number */ 29 | .s { color: #BA2121 } /* Literal.String */ 30 | .na { color: #7D9029 } /* Name.Attribute */ 31 | .nb { color: #008000 } /* Name.Builtin */ 32 | .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 33 | .no { color: #880000 } /* Name.Constant */ 34 | .nd { color: #AA22FF } /* Name.Decorator */ 35 | .ni { color: #999999; font-weight: bold } /* Name.Entity */ 36 | .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 37 | .nf { color: #0000FF } /* Name.Function */ 38 | .nl { color: #A0A000 } /* Name.Label */ 39 | .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 40 | .nt { color: #008000; font-weight: bold } /* Name.Tag */ 41 | .nv { color: #19177C } /* Name.Variable */ 42 | .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 43 | .w { color: #bbbbbb } /* Text.Whitespace */ 44 | .mb { color: #666666 } /* Literal.Number.Bin */ 45 | .mf { color: #666666 } /* Literal.Number.Float */ 46 | .mh { color: #666666 } /* Literal.Number.Hex */ 47 | .mi { color: #666666 } /* Literal.Number.Integer */ 48 | .mo { color: #666666 } /* Literal.Number.Oct */ 49 | .sa { color: #BA2121 } /* Literal.String.Affix */ 50 | .sb { color: #BA2121 } /* Literal.String.Backtick */ 51 | .sc { color: #BA2121 } /* Literal.String.Char */ 52 | .dl { color: #BA2121 } /* Literal.String.Delimiter */ 53 | .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ 54 | .s2 { color: #BA2121 } /* Literal.String.Double */ 55 | .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 56 | .sh { color: #BA2121 } /* Literal.String.Heredoc */ 57 | .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 58 | .sx { color: #008000 } /* Literal.String.Other */ 59 | .sr { color: #BB6688 } /* Literal.String.Regex */ 60 | .s1 { color: #BA2121 } /* Literal.String.Single */ 61 | .ss { color: #19177C } /* Literal.String.Symbol */ 62 | .bp { color: #008000 } /* Name.Builtin.Pseudo */ 63 | .fm { color: #0000FF } /* Name.Function.Magic */ 64 | .vc { color: #19177C } /* Name.Variable.Class */ 65 | .vg { color: #19177C } /* Name.Variable.Global */ 66 | .vi { color: #19177C } /* Name.Variable.Instance */ 67 | .vm { color: #19177C } /* Name.Variable.Magic */ 68 | .il { color: #666666 } /* Literal.Number.Integer.Long */ 69 | 70 | -------------------------------------------------------------------------------- /src/bindings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Python binding 2 | add_subdirectory(python) 3 | -------------------------------------------------------------------------------- /src/bindings/python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Variables----------------------------------------------------------------- 2 | set(PYTHON_BINDING ON CACHE BOOL "Python bindings") 3 | 4 | # Removes the use of 'pythonxx_d.lib' 5 | if(${MSVC}) 6 | add_definitions("-DSWIG_PYTHON_INTERPRETER_NO_DEBUG") 7 | endif(${MSVC}) 8 | 9 | if(PYTHON_BINDING) 10 | 11 | # Variables 12 | set(SWIG_FILE pygrap.i) 13 | get_property(SRCS GLOBAL PROPERTY SRCS_BINDING) 14 | 15 | # Dependencies 16 | set(SWIG_MODULE_pygrap_EXTRA_DEPS dot_writer.py) 17 | set(SWIG_MODULE_pygrap_EXTRA_DEPS ../../tools/grap_disassembler/disassembler.py) 18 | 19 | # SWIG 20 | FIND_PACKAGE(SWIG REQUIRED) 21 | 22 | if(SWIG_FOUND AND Boost_FOUND) 23 | INCLUDE(${SWIG_USE_FILE}) 24 | 25 | # Python 26 | FIND_PACKAGE(PythonInterp 3 REQUIRED) 27 | FIND_PACKAGE(PythonLibs 3 REQUIRED) 28 | 29 | if(PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) 30 | 31 | # Environement 32 | EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} 33 | -c "from sys import stdout; from distutils import sysconfig; stdout.write(sysconfig.get_python_lib())" 34 | OUTPUT_VARIABLE PYTHON_LIB_DIR) 35 | 36 | IF (NOT PYTHON_SITE_DIR) 37 | SET (PYTHON_SITE_DIR ${PYTHON_LIB_DIR}) 38 | ENDIF (NOT PYTHON_SITE_DIR) 39 | 40 | # Print information 41 | MESSAGE(STATUS "Python executable: ${PYTHON_EXECUTABLE}") 42 | MESSAGE(STATUS "Python inc dir: ${PYTHON_INCLUDE_PATH}") 43 | MESSAGE(STATUS "Python lib dir: ${PYTHON_LIB_DIR}") 44 | MESSAGE(STATUS "Python libraries: ${PYTHON_LIBRARIES}") 45 | MESSAGE(STATUS "Python site dir: ${PYTHON_SITE_DIR}") 46 | 47 | # Includes 48 | INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) 49 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) 50 | 51 | SET_SOURCE_FILES_PROPERTIES(${SWIG_FILE} PROPERTIES CPLUSPLUS ON) 52 | SET_SOURCE_FILES_PROPERTIES(${SWIG_FILE} PROPERTIES SWIG_FLAGS "-builtin") 53 | # Forcing the generation of the parser and lexer 54 | SET_SOURCE_FILES_PROPERTIES(${SRCS} PROPERTIES GENERATED TRUE) 55 | 56 | # Generation 57 | SWIG_ADD_MODULE(pygrap python ${SWIG_FILE} ${SRCS}) 58 | 59 | # Removed warnings for the binding 60 | SET_SOURCE_FILES_PROPERTIES(${SRCS} PROPERTIES COMPILE_FLAGS "-w") 61 | SET_SOURCE_FILES_PROPERTIES(${swig_generated_file_fullname} PROPERTIES 62 | COMPILE_FLAGS "-w" 63 | GENERATED TRUE) 64 | 65 | SWIG_LINK_LIBRARIES(pygrap ${PYTHON_LIBRARIES} ${Boost_REGEX_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${BOOST_FILESYSTEM_LIBRARY}) 66 | 67 | # Install 68 | install(TARGETS ${SWIG_MODULE_pygrap_REAL_NAME} LIBRARY DESTINATION ${PYTHON_SITE_DIR}) 69 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pygrap.py DESTINATION ${PYTHON_SITE_DIR}) 70 | 71 | endif(PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND) 72 | endif(SWIG_FOUND AND Boost_FOUND) 73 | 74 | endif(PYTHON_BINDING) 75 | -------------------------------------------------------------------------------- /src/bindings/python/ida_helper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | import imp 6 | 7 | cfg = None 8 | is_cfg_from_idagrap = False 9 | 10 | def ida_get_cfg_raw(existing_cfg=None): 11 | if "idaapi" not in sys.modules: 12 | print("ERROR: idaapi not loaded") 13 | return None 14 | 15 | import idaapi 16 | tw = idaapi.find_widget("IDAgrap") 17 | if tw is not None: 18 | import idagrap 19 | # Get CFG from existing loaded IDAgrap 20 | w = idaapi.PluginForm.FormToPyQtWidget(tw) 21 | pgw=w.findChild(idagrap.ui.widgets.PatternGenerationWidget.PatternGenerationWidget) 22 | cfg = pgw.cc.PatternGenerator.graph 23 | return cfg, True 24 | else: 25 | # If necessary, load grap and creates new CFG object 26 | if existing_cfg is None: 27 | fp, pathname, description = imp.find_module("grap") 28 | _mod = imp.load_module("grap", fp, pathname, description) 29 | cfg = _mod.CFG() 30 | return cfg, False 31 | return existing_cfg, False 32 | 33 | 34 | def ida_get_cfg(): 35 | global cfg, is_cfg_from_idagrap 36 | 37 | if "idaapi" in sys.modules: 38 | # Within IDA 39 | if cfg is None or not is_cfg_from_idagrap: 40 | cfg, is_cfg_from_idagrap = ida_get_cfg_raw(cfg) 41 | if not cfg.graph: 42 | cfg.extract() 43 | return cfg 44 | else: 45 | print("ERROR: idaapi not loaded") 46 | return None 47 | 48 | def ida_match(pattern_arg, getids=True, print_matches=True): 49 | cfg = ida_get_cfg() 50 | if (type(pattern_arg) is list or (type(pattern_arg) is str and pattern_arg != "")) and cfg is not None: 51 | matches = match_graph(pattern_arg, cfg.graph) 52 | if print_matches: 53 | print(matches_tostring(matches, getids)) 54 | return matches 55 | else: 56 | print("ERROR: pattern_arg is empty string or not a list, or cfg is None") 57 | return None 58 | 59 | 60 | def ida_quick_match(str_in, pattern_name="quick_pattern", getids=True, print_pattern=False, print_matches=True): 61 | pattern_str = quick_pattern(str_in, pattern_name) 62 | if print_pattern: 63 | print("Generated the following pattern:") 64 | print(pattern_str) 65 | return ida_match(pattern_str, getids, print_matches) 66 | 67 | -------------------------------------------------------------------------------- /src/cmake-modules/ListCombinations.cmake: -------------------------------------------------------------------------------- 1 | # - Combine lists of prefixes and suffixes in all combinations 2 | # 3 | # list_combinations(var PREFIXES listitems... SUFFIXES listitems...) - 4 | # where var is the name of your desired output variable and PREFIXES 5 | # and SUFFIXES are special arguments that indicate the start of your 6 | # list of prefixes or suffixes respectively. 7 | # 8 | # Original Author: 9 | # 2009-2010 Ryan Pavlik 10 | # http://academic.cleardefinition.com 11 | # Iowa State University HCI Graduate Program/VRAC 12 | # 13 | # Copyright Iowa State University 2009-2010. 14 | # Distributed under the Boost Software License, Version 1.0. 15 | # (See accompanying file LICENSE_1_0.txt or copy at 16 | # http://www.boost.org/LICENSE_1_0.txt) 17 | 18 | if(__list_combinations) 19 | return() 20 | endif() 21 | set(__list_combinations YES) 22 | 23 | function(list_combinations var) 24 | # Parse arguments 25 | set(_prefixes) 26 | set(_suffixes) 27 | set(_nowhere) 28 | set(_curdest _nowhere) 29 | foreach(_element ${ARGN}) 30 | if("${_element}" STREQUAL "PREFIXES") 31 | set(_curdest _prefixes) 32 | elseif("${_element}" STREQUAL "SUFFIXES") 33 | set(_curdest _suffixes) 34 | else() 35 | list(APPEND ${_curdest} "${_element}") 36 | endif() 37 | endforeach() 38 | if(_nowhere) 39 | message(STATUS "_prefixes ${_prefixes}") 40 | message(STATUS "_prefixes ${_suffixes}") 41 | message(STATUS "_prefixes ${_nowhere}") 42 | message(FATAL_ERROR "Syntax error in use of ${CMAKE_CURRENT_LIST_FILE}") 43 | endif() 44 | 45 | foreach(_prefix ${_prefixes}) 46 | foreach(_suffix ${_suffixes}) 47 | list(APPEND _out "${_prefix}${_suffix}") 48 | endforeach() 49 | endforeach() 50 | 51 | set(${var} "${_out}" PARENT_SCOPE) 52 | endfunction() 53 | -------------------------------------------------------------------------------- /src/compiled/_pygrap.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/compiled/_pygrap.pyd -------------------------------------------------------------------------------- /src/libs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # dotparser 2 | add_subdirectory(dotparser) 3 | 4 | # node_info 5 | add_subdirectory(node_info) 6 | 7 | # common 8 | add_subdirectory(common) 9 | 10 | # graph 11 | add_subdirectory(libgraph) 12 | 13 | 14 | # libgraph 15 | add_library(graph 16 | $ 17 | $ 18 | $ 19 | ${BISON_Parser_OUTPUTS} 20 | ${FLEX_Scanner_OUTPUTS} 21 | ) 22 | -------------------------------------------------------------------------------- /src/libs/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # sources 2 | set(SRCS_COMMON 3 | my_alloc.cpp 4 | ga_types.hpp 5 | my_alloc.hpp 6 | my_assert.hpp 7 | ) 8 | 9 | # common object-library 10 | add_library(common-obj OBJECT ${SRCS_COMMON}) 11 | 12 | # common types and functions (alloc_or_quit for instance) 13 | add_library(common $) 14 | 15 | # Bindings 16 | list_combinations(SRCS_COMMON_BINDING 17 | PREFIXES ${CMAKE_CURRENT_SOURCE_DIR}/ 18 | SUFFIXES ${SRCS_COMMON}) 19 | binding_add_srcs("${SRCS_COMMON_BINDING}") 20 | -------------------------------------------------------------------------------- /src/libs/common/ga_types.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GA_TYPES_HPP 2 | #define GA_TYPES_HPP 3 | 4 | /*! 5 | @file ga_types.hpp 6 | @brief Define all basic types that will be used in the whole project. 7 | And custom typed allocator, allowing stronger type checking. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | /*! 15 | @brief Type of memory pointers. 16 | */ 17 | typedef size_t vsize_t; 18 | 19 | #include "my_assert.hpp" 20 | #include "my_alloc.hpp" 21 | #endif 22 | -------------------------------------------------------------------------------- /src/libs/common/my_alloc.cpp: -------------------------------------------------------------------------------- 1 | #include "my_alloc.hpp" 2 | 3 | void* malloc_or_quit(size_t s){ 4 | void *v = malloc(s); 5 | RELEASE_ASSERT(v != 0); 6 | return v; 7 | } 8 | 9 | void* calloc_or_quit(size_t n, size_t s){ 10 | void *v = calloc(n, s); 11 | RELEASE_ASSERT(v != 0); 12 | return v; 13 | } 14 | 15 | void* realloc_or_quit(void* p, size_t s){ 16 | void *v = realloc(p, s); 17 | RELEASE_ASSERT(s == 0 or v != 0); 18 | return v; 19 | } -------------------------------------------------------------------------------- /src/libs/common/my_alloc.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MY_ALLOC_HPP 2 | #define MY_ALLOC_HPP 3 | 4 | #include "ga_types.hpp" 5 | #include 6 | 7 | void* malloc_or_quit(size_t s); 8 | void* calloc_or_quit(size_t n, size_t s); 9 | void* realloc_or_quit(void* p, size_t s); 10 | 11 | #endif -------------------------------------------------------------------------------- /src/libs/common/my_assert.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MY_ASSERT_H 2 | #define MY_ASSERT_H 3 | 4 | #ifndef NDEBUG 5 | #define ENABLE_ASSERT 6 | #endif 7 | 8 | #include 9 | 10 | #ifndef unlikely 11 | # ifdef _MSC_VER 12 | # define unlikely(x) (x) 13 | # else 14 | # define unlikely(x) __builtin_expect(!!(x), 0) 15 | #endif 16 | #endif 17 | 18 | #define AssertStream stderr 19 | 20 | #define AssertActionMsg(...) \ 21 | do { \ 22 | fprintf(AssertStream,__VA_ARGS__); \ 23 | fprintf(AssertStream,"\n"); \ 24 | exit(EXIT_FAILURE); \ 25 | }while(0) 26 | 27 | #ifdef ENABLE_ASSERT 28 | #define AssertActionMsgContinue(...) \ 29 | do { \ 30 | fprintf(AssertStream,__VA_ARGS__); \ 31 | fprintf(AssertStream,"\n"); \ 32 | }while(0) 33 | 34 | #define ASSERT_MSG(cond, ...) \ 35 | do { \ 36 | if(unlikely(!(cond))) \ 37 | AssertActionMsg(__VA_ARGS__); \ 38 | } while(0) 39 | 40 | #define ASSERT_MSG_CONTINUE(cond, ...) \ 41 | do { \ 42 | if(unlikely(!(cond))) \ 43 | AssertActionMsgContinue(__VA_ARGS__); \ 44 | } while(0) 45 | #else /* ENABLE_ASSERT */ 46 | 47 | #define ASSERT_MSG(cond, ...) 48 | #define ASSERT_MSG_CONTINUE(cond, ...) 49 | 50 | #endif /* ENABLE_ASSERT */ 51 | 52 | #define RELEASE_ASSERT(cond) \ 53 | do { \ 54 | if(unlikely(!(cond))) \ 55 | AssertActionMsg("Fatal error."); \ 56 | } while(0) 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/libs/dotparser/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Dot parser 2 | # Create custom command for flex/lex 3 | find_package(BISON REQUIRED) 4 | find_package(FLEX REQUIRED) 5 | 6 | if (BISON_FOUND) 7 | 8 | # Creation of the Parser 9 | BISON_TARGET(Parser 10 | Parser.y 11 | ${CMAKE_CURRENT_BINARY_DIR}/Parser.cpp 12 | DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/Parser.hpp 13 | COMPILE_FLAGS "-y" 14 | ) 15 | 16 | if(FLEX_FOUND) 17 | 18 | # Creation of the Lexer 19 | FLEX_TARGET(Scanner 20 | Lexer.l 21 | ${CMAKE_CURRENT_BINARY_DIR}/Lexer.cpp 22 | COMPILE_FLAGS "--header-file=${CMAKE_CURRENT_BINARY_DIR}/Lexer.hpp" 23 | ) 24 | 25 | ADD_FLEX_BISON_DEPENDENCY(Scanner Parser) 26 | else() 27 | message("[-] Flex issues") 28 | endif() 29 | else() 30 | message("[-] Bison issues") 31 | endif() 32 | 33 | 34 | # sources 35 | set(SRCS_DOTPARSER 36 | graphParser.cpp 37 | graphParser.hpp 38 | Expression.cpp 39 | Expression.hpp 40 | ) 41 | 42 | set(SRCS_BISON 43 | ${FLEX_Scanner_OUTPUTS} 44 | ${BISON_Parser_OUTPUTS} 45 | ) 46 | 47 | # Removed warnings for the parser and lexer 48 | SET_SOURCE_FILES_PROPERTIES(${SRCS_BISON} PROPERTIES 49 | COMPILE_FLAGS "-w" 50 | GENERATED TRUE) 51 | 52 | # Bindings 53 | list_combinations(SRCS_DOTPARSER_BINDING 54 | PREFIXES ${CMAKE_CURRENT_SOURCE_DIR}/ 55 | SUFFIXES ${SRCS_DOTPARSER}) 56 | 57 | binding_add_srcs("${SRCS_DOTPARSER_BINDING}") 58 | binding_add_srcs("${SRCS_BISON}") 59 | 60 | # dotparser object-library 61 | add_library(dotparser-obj OBJECT ${SRCS_DOTPARSER} ${SRCS_BISON}) 62 | 63 | -------------------------------------------------------------------------------- /src/libs/dotparser/Expression.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Expression.h 3 | * Definition of the structure used to build the syntax tree. 4 | */ 5 | #ifndef __EXPRESSION_H__ 6 | #define __EXPRESSION_H__ 7 | 8 | #include "graph.hpp" 9 | #include "graphIO.hpp" 10 | #include "node_info.hpp" 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | typedef struct GraphList 20 | { 21 | vsize_t size; 22 | graph_t** graphes; 23 | } GraphList; 24 | 25 | typedef struct Couple 26 | { 27 | vsize_t x; 28 | vsize_t y; 29 | bool is_numbered; 30 | bool is_wildcard; 31 | bool is_child1; 32 | } Couple; 33 | 34 | typedef struct CoupleList 35 | { 36 | vsize_t size; 37 | Couple** couples; 38 | } CoupleList; 39 | 40 | typedef struct Option 41 | { 42 | char* id; 43 | char* value; 44 | } Option; 45 | 46 | typedef struct OptionList 47 | { 48 | vsize_t size; 49 | Option** options; 50 | } OptionList; 51 | 52 | vsize_t hash_func(char* s); 53 | 54 | void debug_print(char* s); 55 | 56 | GraphList* createGraphList(); 57 | GraphList* addGraphToInput(graph_t* g, GraphList* gl); 58 | typedef std::list GraphCppList; 59 | void freeGraphList(GraphList* gl, bool freeGraphs, bool free_info); 60 | void freeGraphList(GraphCppList gl, bool freeGraphs, bool free_info); 61 | GraphCppList MakeGraphList(GraphList* gl); 62 | 63 | CoupleList* createEdgeList(); 64 | void freeEdgeList(CoupleList* cl); 65 | char *removeQuotes(char *s); 66 | 67 | CoupleList* addEdgeToList(Couple* c, CoupleList* cl); 68 | 69 | Couple* createEdge(char* f, char* c, OptionList* ol); 70 | 71 | graph_t* addEdgesToGraph(char* name, CoupleList* cl, graph_t* g); 72 | 73 | node_t* updateNode(OptionList* ol, node_t* n); 74 | 75 | OptionList* createOptionList(); 76 | 77 | OptionList* addOptionToList(Option* o, OptionList* ol); 78 | 79 | Option* createOption(char* I, char* V); 80 | 81 | /** 82 | * @brief It creates a node 83 | * @param value The name of the node 84 | * @return The graph or NULL in case of no memory 85 | */ 86 | node_t *createNode(char* value); 87 | 88 | graph_t *createGraph(); 89 | 90 | graph_t* addNodeToGraph(node_t* n, graph_t* g); 91 | 92 | void freeOption(Option* o); 93 | void freeOptionList(OptionList* ol); 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/libs/dotparser/Lexer.l: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | /* 4 | * Lexer.l file 5 | * To generate the lexical analyzer run: "flex Lexer.l" 6 | */ 7 | 8 | #include "Expression.hpp" 9 | #include "Parser.hpp" 10 | 11 | #include 12 | 13 | /* IDS: simple labels (aaa, 7ffs) 14 | * IDC: labels with quotes ("hello", "z97(e,e)", "xor eax, eax") 15 | * IDV: labels with comparisons ("inst >= xor", "opcode==add", "inst == xor eax, eax") 16 | */ 17 | 18 | %} 19 | 20 | %option warn nodefault 21 | 22 | %option reentrant noyywrap never-interactive nounistd 23 | %option bison-bridge 24 | 25 | DIGRAPH_HEADER [dD]igraph 26 | COMMENT_SINGLE_LINE " "*"//".*[\r\n] 27 | IGNORE "labeljust=r" 28 | IDS [a-zA-Z0-9*+._?]+ 29 | IDC \"[a-zA-Z0-9*+-._:;@\\(),?\[\]]*\" 30 | IDV \"[a-zA-Z0-9*+-._:;@ \\(),\[\]=!<>^$?|{}']*\" 31 | LENS "{" 32 | RENS "}" 33 | LCRO "[" 34 | RCRO "]" 35 | EQ "=" 36 | VIRG "," 37 | ARROW "->" 38 | 39 | WS [ \r\n\t]* 40 | 41 | %% 42 | 43 | {IGNORE} { } 44 | {WS} { } 45 | {COMMENT_SINGLE_LINE} { } 46 | 47 | {DIGRAPH_HEADER} { debug_print((char *) "digraph header!\n"); return TOKEN_DIGRAPH_HEADER; } 48 | {IDS} { yylval->type_string = strdup(yytext); debug_print((char *) "ids: "); debug_print(yytext); debug_print((char *) "\n"); return TOKEN_ID; } 49 | {IDC} { yylval->type_string = strdup(yytext); debug_print((char *) "idc: "); debug_print(yytext); debug_print((char *) "\n"); return TOKEN_ID; } 50 | {IDV} { yylval->type_string = strdup(yytext); debug_print((char *) "idv: "); debug_print(yytext); debug_print((char *) "\n"); return TOKEN_IDV; } 51 | {LENS} { debug_print((char *) "lens!\n"); return TOKEN_LENS; } 52 | {RENS} { debug_print((char *) "rens!\n"); return TOKEN_RENS; } 53 | {LCRO} { debug_print((char *) "lcro!\n"); return TOKEN_LCRO; } 54 | {RCRO} { debug_print((char *) "rcro!\n"); return TOKEN_RCRO; } 55 | {EQ} { debug_print((char *) "eq!\n"); return TOKEN_EQ; } 56 | {VIRG} { debug_print((char *) "virg!\n"); return TOKEN_VIRG; } 57 | {ARROW} { debug_print((char *) "arrow!\n"); return TOKEN_ARROW; } 58 | . { } 59 | 60 | %% 61 | 62 | void yyerror (char *msg) { 63 | fprintf(stderr, "Error while parsing dot file. Exiting. Error message: %s.\n", msg); 64 | RELEASE_ASSERT(false); 65 | } 66 | -------------------------------------------------------------------------------- /src/libs/dotparser/Parser.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | /* 4 | * Parser.y file 5 | * To generate the parser run: "bison Parser.y" 6 | */ 7 | 8 | #include "Expression.hpp" 9 | #include "Parser.hpp" 10 | #include "Lexer.hpp" 11 | 12 | #define YYINITDEPTH 200000 13 | #define YYMAXDEPTH 1000000 14 | 15 | int yyerror(GraphList **SgraphList, yyscan_t scanner, const char *msg) { 16 | // Add error handling routine as needed 17 | std::cerr << "WARNING: An error occurred while parsing a DOT file." << std::endl; 18 | return 0; 19 | } 20 | 21 | %} 22 | 23 | %code requires { 24 | #ifndef YY_TYPEDEF_YY_SCANNER_T 25 | #define YY_TYPEDEF_YY_SCANNER_T 26 | typedef void* yyscan_t; 27 | #endif 28 | } 29 | %error-verbose 30 | 31 | %define api.pure 32 | 33 | %lex-param { yyscan_t scanner } 34 | %parse-param { GraphList** SgraphList } 35 | %parse-param { yyscan_t scanner } 36 | 37 | %union { 38 | char* type_string; 39 | int value; 40 | GraphList* SgraphList; 41 | graph_t* Sgraph; 42 | node_t* Snode; 43 | Option* Soption; 44 | OptionList* SoptionList; 45 | Couple* Sedge; 46 | CoupleList* SedgeList; 47 | } 48 | 49 | 50 | %token TOKEN_DIGRAPH_HEADER 51 | %token TOKEN_ID 52 | %token TOKEN_IDV 53 | %token OPTION_ID 54 | %token TOKEN_OPTION_STR 55 | %type option_value 56 | %token TOKEN_LENS 57 | %token TOKEN_RENS 58 | %token TOKEN_LCRO 59 | %token TOKEN_RCRO 60 | %token TOKEN_EQ 61 | %token TOKEN_VIRG 62 | %token TOKEN_ARROW 63 | %token TOKEN_NUMBER 64 | 65 | %type graph_list 66 | %type graph 67 | %type node_list 68 | %type node 69 | %type node_id 70 | %type edge 71 | %type edge_list 72 | %type option 73 | %type option_list 74 | 75 | %% 76 | 77 | input 78 | : graph_list { *SgraphList = $1;} 79 | ; 80 | 81 | graph_list 82 | : 83 | {$$ = createGraphList();} 84 | | graph_list[GL] graph[G] { $$ = addGraphToInput($G, $GL); } 85 | | graph_list[GL] error { $$ = $GL; } 86 | ; 87 | 88 | graph 89 | : 90 | TOKEN_DIGRAPH_HEADER TOKEN_LENS node_list[G] edge_list[E] TOKEN_RENS { $$ = addEdgesToGraph(NULL , $E, $G); } 91 | | TOKEN_DIGRAPH_HEADER TOKEN_ID[id] TOKEN_LENS node_list[G] edge_list[E] TOKEN_RENS {$$ = addEdgesToGraph($id , $E, $G); } 92 | ; 93 | 94 | node_list 95 | : 96 | {$$ = createGraph();} 97 | | node_list[G] node[nG] { $$ = addNodeToGraph($nG, $G); } 98 | | node_list[G] error { fprintf(stderr, "WARNING: Error parsing a node_list.\n"); $$ = $G; } 99 | ; 100 | 101 | node 102 | : 103 | node_id[N] TOKEN_LCRO option_list[O] TOKEN_RCRO { $$ = updateNode($O, $N); } 104 | ; 105 | 106 | node_id 107 | : 108 | TOKEN_ID { $$ = createNode($1); } 109 | | error { fprintf(stderr, "WARNING: Error parsing a node_id.\n"); $$ = NULL; } 110 | ; 111 | 112 | option_list 113 | : 114 | {$$ = createOptionList();} 115 | | option[O] option_list[L] { $$ = addOptionToList($O, $L); } 116 | | option[O] TOKEN_VIRG option_list[L] { $$ = addOptionToList($O, $L); } 117 | | error option_list[L] { $$ = $L; } 118 | ; 119 | 120 | option_value 121 | : 122 | TOKEN_ID[V] { $$ = $V; } 123 | | TOKEN_IDV[V] { $$ = $V; } 124 | | error { fprintf(stderr, "WARNING: Error parsing an option_value.\n"); $$ = NULL; } 125 | ; 126 | 127 | option 128 | : 129 | TOKEN_ID[I] TOKEN_EQ option_value[V] { $$ = createOption($I, $V); } 130 | | error { fprintf(stderr, "WARNING: Error parsing an option.\n"); $$ = NULL; } 131 | ; 132 | 133 | edge_list 134 | : 135 | {$$ = createEdgeList();} 136 | | edge[E] edge_list[L] { $$ = addEdgeToList($E, $L); } 137 | | error edge_list[L] { fprintf(stderr, "WARNING: Error parsing an edge_list.\n"); $$ = $L; } 138 | ; 139 | 140 | edge 141 | : 142 | TOKEN_ID[F] TOKEN_ARROW TOKEN_ID[C] TOKEN_LCRO option_list[L] TOKEN_RCRO { $$ = createEdge($F, $C, $L); } 143 | | TOKEN_ID[F] TOKEN_ARROW TOKEN_ID[C] { $$ = createEdge($F, $C, NULL); } 144 | ; 145 | 146 | %% 147 | -------------------------------------------------------------------------------- /src/libs/dotparser/graphParser.cpp: -------------------------------------------------------------------------------- 1 | #include "graphParser.hpp" 2 | 3 | GraphList *getGraphList (const char *expr) { 4 | GraphList* gl; 5 | yyscan_t scanner; 6 | YY_BUFFER_STATE state; 7 | 8 | if (yylex_init (&scanner)) { 9 | // couldn't initialize 10 | return NULL; 11 | } 12 | 13 | state = yy_scan_string (expr, scanner); 14 | 15 | if (yyparse (&gl, scanner)) { 16 | // error parsing 17 | return NULL; 18 | } 19 | 20 | yy_delete_buffer (state, scanner); 21 | 22 | yylex_destroy (scanner); 23 | 24 | return gl; 25 | } 26 | 27 | GraphList *getGraphListFromFile (FILE * f) { 28 | GraphList* gl; 29 | yyscan_t scanner; 30 | YY_BUFFER_STATE state; 31 | 32 | // TODO: fseek+ftell should NOT be used to compute file size (unreliable on regular files) 33 | fseek (f, 0, SEEK_END); 34 | size_t fsize = (size_t) ftell (f); 35 | fseek (f, 0, SEEK_SET); 36 | 37 | char *buf = (char *) malloc (fsize + 1); 38 | size_t read = fread (buf, 1, fsize, f); 39 | RELEASE_ASSERT(read == fsize); 40 | 41 | buf[fsize] = 0; 42 | 43 | if (yylex_init (&scanner)) { 44 | // couldn't initialize 45 | std::cerr << "ERROR: Couldn't initialize yylex." << std::endl; 46 | return NULL; 47 | } 48 | 49 | state = yy_scan_string (buf, scanner); 50 | if (yyparse (&gl, scanner)) { 51 | // error parsing 52 | std::cerr << "ERROR: Parsing failed." << std::endl; 53 | return NULL; 54 | } 55 | 56 | yy_delete_buffer (state, scanner); 57 | free (buf); 58 | yylex_destroy (scanner); 59 | 60 | return gl; 61 | } 62 | 63 | GraphList *getGraphListFromPath (const char *path) { 64 | FILE *f = fopen (path, "rb"); 65 | if (f != NULL) { 66 | GraphList* gl = getGraphListFromFile (f); 67 | fclose(f); 68 | return gl; 69 | } 70 | else return NULL; 71 | } 72 | 73 | graph_t *getGraph (const char *expr) { 74 | return popfreeFirstGraph(getGraphList(expr)); 75 | } 76 | 77 | graph_t *getGraphFromFile (FILE * f) { 78 | return popfreeFirstGraph(getGraphListFromFile(f)); 79 | } 80 | 81 | graph_t *getGraphFromPath (const char *path) { 82 | return popfreeFirstGraph(getGraphListFromPath(path)); 83 | } 84 | 85 | graph_t* popfreeFirstGraph(GraphList* gl){ 86 | graph_t* gr; 87 | if (gl != NULL and gl->size >= 1){ 88 | gr = gl->graphes[0]; 89 | } 90 | else{ 91 | gr = nullptr; 92 | } 93 | 94 | if (gl != NULL){ 95 | vsize_t i; 96 | for (i = 1; i < gl->size; i++){ 97 | graph_free(gl->graphes[i], true); 98 | } 99 | } 100 | 101 | if (gl != NULL){ 102 | freeGraphList(gl, false, false); 103 | } 104 | return gr; 105 | } 106 | -------------------------------------------------------------------------------- /src/libs/dotparser/graphParser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHPARSER_H 2 | #define GRAPHPARSER_H 3 | 4 | #include "Expression.hpp" 5 | #include "Parser.hpp" 6 | #include "Lexer.hpp" 7 | 8 | #include "graph.hpp" 9 | #include "graphIO.hpp" 10 | 11 | #include 12 | 13 | GraphList* getGraphList(const char *expr); 14 | graph_t *getGraph (const char *expr); 15 | GraphList* getGraphListFromPath(const char* path); 16 | graph_t* getGraphFromPath(const char* path); 17 | GraphList* getGraphListFromFile(FILE* f); 18 | graph_t* getGraphFromFile(FILE* f); 19 | graph_t* popfreeFirstGraph(GraphList* gl); 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /src/libs/libgraph/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # sources 2 | set(SRCS_GRAPH 3 | graph.cpp 4 | graph.hpp 5 | graphIO.cpp 6 | graphIO.hpp 7 | node.cpp 8 | node.hpp 9 | node_list.cpp 10 | node_list.hpp 11 | nodeIO.cpp 12 | nodeIO.hpp 13 | ) 14 | 15 | # graph object-library 16 | add_library(graph-obj OBJECT ${SRCS_GRAPH}) 17 | 18 | # Bindings 19 | list_combinations(SRCS_GRAPH_BINDING 20 | PREFIXES ${CMAKE_CURRENT_SOURCE_DIR}/ 21 | SUFFIXES ${SRCS_GRAPH}) 22 | binding_add_srcs("${SRCS_GRAPH_BINDING}") 23 | -------------------------------------------------------------------------------- /src/libs/libgraph/graph.cpp: -------------------------------------------------------------------------------- 1 | #include "graph.hpp" 2 | 3 | graph_t* graph_alloc(vsize_t max_size) { 4 | graph_t* graph; 5 | 6 | graph = new graph_t(); 7 | node_list_build(&graph->nodes, max_size); 8 | graph->root = NULL; 9 | graph->has_wildcards = false; 10 | return graph; 11 | } 12 | 13 | void graph_free(graph_t* graph, bool free_info) { 14 | if(graph) { 15 | node_list_free(&(graph->nodes), free_info); 16 | delete graph; 17 | } 18 | } 19 | 20 | void update_children_fathers_number(graph_t* graph){ 21 | vsize_t k; 22 | for (k = 0; k < graph->nodes.size; k++){ 23 | graph->nodes.storage[k]->info->childrenNumber = graph->nodes.storage[k]->children_nb; 24 | graph->nodes.storage[k]->info->fathersNumber = graph->nodes.storage[k]->fathers_nb; 25 | } 26 | } -------------------------------------------------------------------------------- /src/libs/libgraph/graph.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GRAPH_H 2 | #define GRAPH_H 3 | 4 | /*! 5 | @file graph.h 6 | @brief Structure and methods for rooted and directed graphs support. 7 | A graph is seen as a list of node with a root. 8 | */ 9 | 10 | #include "node.hpp" 11 | #include "node_list.hpp" 12 | 13 | /*! 14 | @brief Define a structure for rooted and directed graphs 15 | */ 16 | typedef struct graph_t { 17 | /*! 18 | @brief Nodes of the graph. 19 | @see node_list.h 20 | */ 21 | node_list_t nodes; 22 | 23 | /*! 24 | @brief Root of the graph. 25 | @see node.h 26 | */ 27 | node_t* root; 28 | 29 | std::string name; 30 | 31 | bool has_wildcards; 32 | } graph_t; 33 | 34 | /*! 35 | @brief Graph construction procedure. 36 | @return A pointer to the newly allocated graph. 37 | */ 38 | graph_t* graph_alloc(vsize_t max_size); 39 | 40 | /*! 41 | @brief Graph freeing procedure. 42 | @param graph The graph to free. 43 | @param free_info Wether to free nodes' info, be sure that they are not used elsewhere (Parcours). 44 | */ 45 | void graph_free(graph_t* graph, bool free_info); 46 | 47 | /*! 48 | @brief Updates children and fathers numbers in nodes' nodeinfo struct from the node fields 49 | @param graph The graph to update. 50 | */ 51 | void update_children_fathers_number(graph_t* graph); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/libs/libgraph/graphIO.cpp: -------------------------------------------------------------------------------- 1 | #include "graphIO.hpp" 2 | 3 | void graph_fprint(FILE* fp, graph_t* graph) { 4 | struct node_list_iterator_t *node_it; 5 | 6 | if (graph != nullptr){ 7 | fprintf(fp, "Digraph G {\n"); 8 | 9 | size_t i; 10 | 11 | for (i=0; inodes.count; i++){ 12 | node_t* node = graph->nodes.storage[i]; 13 | node_to_dot(node,(node_t*)&graph->root->node_id, i, fp); 14 | } 15 | 16 | for (i=0; inodes.count; i++){ 17 | node_t* node = graph->nodes.storage[i]; 18 | node_edges_to_dot(node, fp); 19 | } 20 | 21 | 22 | fprintf(fp, "}\n"); 23 | } 24 | } 25 | 26 | void graph_save_to_path(std::string path, graph_t * graph){ 27 | FILE* fp = fopen(path.c_str(), "wb"); 28 | if (fp != nullptr){ 29 | graph_fprint(fp, graph); 30 | fclose(fp); 31 | } 32 | } -------------------------------------------------------------------------------- /src/libs/libgraph/graphIO.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHIO_H 2 | #define GRAPHIO_H 3 | 4 | #define GRAPHBINMAGIC "GRAPHBIN" 5 | #define GRAPHBINMAGIC_LEN 8 6 | 7 | #include "nodeIO.hpp" 8 | 9 | /*! 10 | @file graphIO.h 11 | @brief Structure and methods for rooted and directed graphs input/output support. 12 | */ 13 | #include 14 | 15 | #include "graph.hpp" 16 | 17 | /*! 18 | @brief Print a a graph. 19 | @param graph The graph to print. 20 | @param fp The file to print the graph to. 21 | */ 22 | void graph_fprint (FILE * fp, graph_t * graph); 23 | 24 | void graph_save_to_path(std::string path, graph_t * graph); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/libs/libgraph/node.cpp: -------------------------------------------------------------------------------- 1 | #include "node.hpp" 2 | 3 | node_t *node_alloc () { 4 | node_t *node = (node_t*) calloc_or_quit (1, sizeof(node_t)); 5 | 6 | return node; 7 | } 8 | 9 | node_t *node_copy (node_t * node1, const node_t * node2) { 10 | /* free tables of fathers/children */ 11 | free(node1->fathers); 12 | 13 | memcpy (node1, node2, sizeof (node_t)); 14 | 15 | /* copy fathers */ 16 | if (node2->fathers_nb > 0) { 17 | node1->fathers = (node_t**) malloc_or_quit(node2->fathers_nb * sizeof(node_t*)); 18 | memcpy (node1->fathers, node2->fathers, node1->fathers_nb * sizeof (node_t *)); 19 | } 20 | 21 | /* copy children */ 22 | if (node1->children_nb > 0) { 23 | node1->has_child1 = node2->has_child1; 24 | node1->child1 = node2->child1; 25 | node1->has_child2 = node2->has_child2; 26 | node1->child2 = node2->child2; 27 | } 28 | return node1; 29 | } 30 | 31 | void node_free (node_t * node, bool free_info) { 32 | free(node->fathers); 33 | 34 | if (free_info){ 35 | // be careful, node info and node conditions are also used in Parcours and ParcoursNode 36 | delete(node->info); 37 | node->info = NULL; 38 | if (node->condition != NULL){ 39 | CondNode::freeCondition(node->condition); 40 | } 41 | } 42 | 43 | free(node); 44 | } 45 | 46 | void node_link (node_t * node, node_t * child, bool is_wildcard, bool is_child1) { 47 | if (is_child1){ 48 | if (not node->has_child1) { 49 | node->children_nb++; 50 | node->has_child1 = true; 51 | } 52 | else{ 53 | std::cerr << "WARNING: Overwriting existing node child." << std::endl; 54 | } 55 | node->child1 = child; 56 | } 57 | else { 58 | if (not node->has_child2) { 59 | node->children_nb++; 60 | node->has_child2 = true; 61 | } 62 | else{ 63 | std::cerr << "WARNING: Overwriting existing node child." << std::endl; 64 | } 65 | node->child2 = child; 66 | } 67 | 68 | if (is_wildcard){ 69 | node->children_are_wildcards = true; 70 | } 71 | 72 | child->fathers_nb++; 73 | child->fathers = (node_t**) realloc_or_quit(child->fathers, child->fathers_nb * sizeof(node_t*)); 74 | child->fathers[child->fathers_nb - 1] = node; 75 | } 76 | 77 | node_t *node_father (node_t * node, size_t index) { 78 | if (index >= node->fathers_nb) 79 | return NULL; 80 | return node->fathers[index]; 81 | } 82 | 83 | void node_remove_father (node_t * node, node_t * to_remove) { 84 | vsize_t i, shift; 85 | 86 | shift = 0; 87 | for (i = 0; i < node->fathers_nb; ++i) { 88 | node_t *current = node_father (node, i); 89 | if (current == to_remove){ 90 | ++shift; 91 | } 92 | else{ 93 | node->fathers[i - shift] = current; 94 | } 95 | } 96 | node->fathers_nb = i - shift; 97 | node->fathers = (node_t**) realloc_or_quit(node->fathers, node->fathers_nb * sizeof(node_t*)); 98 | } 99 | 100 | void node_remove_child (node_t * node, node_t * to_remove) { 101 | if (node->has_child1){ 102 | if (node->child1 == to_remove){ 103 | node->has_child1 = false; 104 | node->children_nb--; 105 | } 106 | } 107 | 108 | if (node->has_child2){ 109 | if (node->child1 == to_remove){ 110 | node->has_child2 = false; 111 | node->children_nb--; 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/libs/libgraph/node.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NODE_H 2 | #define NODE_H 3 | 4 | /*! 5 | @file node.h 6 | @brief Structures and routines for nodes of a graph. 7 | */ 8 | 9 | #include 10 | #include 11 | 12 | #include "ga_types.hpp" 13 | #include "node_info.hpp" 14 | 15 | struct node_t; 16 | /*! 17 | @brief Structure describing a node in a graph. 18 | */ 19 | typedef struct node_t { 20 | /*! 21 | @brief Id of the node. 22 | 23 | For statically extraction code address is chosen (begin or maybe end of 24 | block). 25 | */ 26 | std::string str_id; 27 | vsize_t node_id; 28 | 29 | NodeInfo* info; 30 | 31 | // Only for patterns 32 | // TODO: differentiate parsing of pattern and test graphs, fill has_condition 33 | // bool has_condition; 34 | CondNode* condition; 35 | 36 | /*! 37 | @brief Number of fathers. 38 | */ 39 | vsize_t fathers_nb; 40 | 41 | /*! 42 | Number of children. 43 | */ 44 | vsize_t children_nb; 45 | 46 | /*! 47 | @brief Table of pointers to the predecessors of the node. 48 | 49 | To retrieve the i-th father use node_father(). 50 | @see node_father() 51 | */ 52 | struct node_t** fathers; 53 | 54 | bool children_are_wildcards; 55 | 56 | bool has_child1; 57 | node_t* child1; 58 | 59 | bool has_child2; 60 | node_t* child2; 61 | 62 | // id of the node in the nodelist 63 | vsize_t list_id; 64 | 65 | 66 | } node_t; 67 | 68 | /*! 69 | @brief Allocate a node. 70 | @return The newly malloc'ed node. 71 | */ 72 | node_t* node_alloc(); 73 | 74 | /*! 75 | @brief Overwrite a node with an other. 76 | 77 | Internal structures of node1 are free'd. 78 | @param node1 Pointer on the node to overwrite. 79 | @param node2 Pointer on the node to copy. 80 | @return node1 81 | */ 82 | node_t* node_copy(node_t* node1, const node_t* node2); 83 | 84 | /*! 85 | @brief Free the node. 86 | @param node The node to free. 87 | */ 88 | void node_free(node_t* node, bool free_info); 89 | 90 | /*! 91 | @brief Add a child to the node children list. 92 | @param node the node we add a child to. 93 | @param child the child node. 94 | @see node_new_child() node_child() 95 | */ 96 | void node_link(node_t* node, node_t* child, bool is_wildcard, bool is_child1); 97 | 98 | /*! 99 | @brief Get the i-th father of a node. 100 | @param node The node from which to get the father. 101 | @param index The index of the father to get. 102 | @return The i-th father of a node if i is valid, otherwise it returns a NULL 103 | pointer. 104 | */ 105 | node_t* node_father(node_t* node, size_t index); 106 | 107 | /*! 108 | @brief Remove all instances of a node from the fathers node list of a node. 109 | @param node The node from which remove the father. 110 | @param to_remove The father to remove. 111 | */ 112 | void node_remove_father(node_t* node, node_t* to_remove); 113 | 114 | /*! 115 | @brief Remove all instances of a node from the children node list of a node. 116 | @param node The node from which remove the child. 117 | @param to_remove The child to remove. 118 | */ 119 | void node_remove_child(node_t* node, node_t* to_remove); 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /src/libs/libgraph/nodeIO.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NODEIO_H 2 | #define NODEIO_H 3 | 4 | /*! 5 | @file nodeIO.h 6 | @brief Input/Output support for nodes. 7 | */ 8 | 9 | #include 10 | #include "node.hpp" 11 | 12 | /*! 13 | @brief Print a node in format .dot. 14 | @param node Source node. 15 | @param node Root node. 16 | @param fp Destination file. 17 | @return Number of written bytes. 18 | */ 19 | size_t node_to_dot(const node_t* node, const node_t* root, size_t, FILE* fp); 20 | 21 | /*! 22 | @brief Print all edges going out of a node in format .dot. 23 | @param node Source node. 24 | @param fp Destination file. 25 | @return Number of written bytes. 26 | */ 27 | size_t node_edges_to_dot(const node_t* node, FILE* fp); 28 | 29 | int printVK(FILE * fp, char *key, char *value, char virg); 30 | int printVKint(FILE * fp, char *key, int value, char virg); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/libs/libgraph/node_list.cpp: -------------------------------------------------------------------------------- 1 | #include "node_list.hpp" 2 | 3 | 4 | void node_list_build(node_list_t * list, vsize_t max_size) { 5 | list->size = max_size; 6 | list->count = 0; 7 | list->storage = NULL; 8 | list->nodes_map = new std::map < vsize_t, node_t * >(); 9 | } 10 | 11 | void node_list_add(node_list_t * list, node_t* node) { 12 | std::map< vsize_t, node_t * >::iterator id_it = list->nodes_map->find(node->node_id); 13 | 14 | if (id_it == list->nodes_map->end()){ 15 | // node_id not found: node is a new node in list 16 | list->size++; 17 | list->storage = (node_t**) realloc_or_quit(list->storage , list->size * sizeof(node_t*)); 18 | 19 | list->storage[list->size-1] = node; 20 | list->storage[list->size-1]->list_id = list->count; 21 | list->count++; 22 | 23 | list->nodes_map->insert(std::pair< vsize_t, node_t * >(node->node_id, node)); 24 | } 25 | else { 26 | // node already exists 27 | std::cerr << "WARNING: Node already exists in graph (it was not duplicated)." << std::endl; 28 | } 29 | } 30 | 31 | void node_list_free(node_list_t * list, bool free_info) { 32 | vsize_t i; 33 | 34 | for (i = 0; i < list->size; i++) { 35 | node_free(list->storage[i], free_info); 36 | } 37 | 38 | free(list->storage); 39 | delete list->nodes_map; 40 | } 41 | 42 | node_t * node_list_item(const node_list_t * list, vsize_t index) { 43 | return list->storage[index]; 44 | } 45 | 46 | vsize_t node_list_size(const node_list_t * list) { 47 | return list->count; 48 | } 49 | 50 | node_t* node_list_append(node_list_t * list, vsize_t node_id) { 51 | node_t *new_node; 52 | 53 | new_node = list->storage[list->count]; 54 | new_node->node_id = node_id; 55 | new_node->list_id = list->count; 56 | list->count++; 57 | 58 | list->nodes_map->insert(std::pair< vsize_t, node_t * >(node_id, new_node)); 59 | 60 | return new_node; 61 | } 62 | 63 | node_t* node_list_find(node_list_t * list, vsize_t node_id) { 64 | node_t item; 65 | item.node_id = node_id; 66 | 67 | std::map< vsize_t, node_t * >::iterator id_it = list->nodes_map->find(node_id); 68 | if (id_it == list->nodes_map->end()){ 69 | return NULL; 70 | } 71 | else{ 72 | return id_it->second; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/libs/libgraph/node_list.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NODE_LIST_H 2 | #define NODE_LIST_H 3 | 4 | #include "node.hpp" 5 | #include 6 | 7 | /*! 8 | @file node_list.h 9 | @brief Wrapper preventing from using dv_t for node list. 10 | 11 | Now node pointers list has it own type, different from dv_t. 12 | Help to make a clear distinction between arrays of node_t (in graph_t) and 13 | arrays of node_t*. 14 | 15 | @see node_ptr_list.h 16 | */ 17 | struct _dv_t; 18 | struct node_list_iterator_t; 19 | 20 | /*! 21 | @brief The node list structure. 22 | */ 23 | typedef struct node_list_t { 24 | /*! 25 | @brief Array for storing nodes. 26 | 27 | We can't use dv_t because node stores pointers to children and father, and 28 | a realloc would break them. If we really want to use dv_t, we must never add 29 | or remove any node after creating edges. This is too dangerous, so we use a 30 | static array. 31 | */ 32 | node_t **storage; 33 | 34 | /*! 35 | @brief Size of the node array. 36 | */ 37 | vsize_t size; 38 | 39 | /*! 40 | @brief Number of node allocated in the node array. 41 | */ 42 | vsize_t count; 43 | 44 | /*! 45 | @brief Map used when loading graph from dot file 46 | */ 47 | std::map < vsize_t, node_t * >* nodes_map; 48 | } node_list_t; 49 | 50 | /*! 51 | @brief Initialize the list. 52 | @param list The list to initialize. 53 | */ 54 | void node_list_build(node_list_t * list, vsize_t max_size); 55 | 56 | void node_list_add(node_list_t * list, node_t* node); 57 | 58 | /*! 59 | @brief Free all internal structures used. 60 | @param list The list to free. 61 | */ 62 | void node_list_free(node_list_t * list, bool free_info); 63 | 64 | /*! 65 | @brief Reset the list. 66 | @param list The list to reset. 67 | */ 68 | // void node_list_reset(node_list_t * list); 69 | 70 | /*! 71 | @brief Get the i-th node of the node_list. 72 | @param list The node list. 73 | @param index The index i. 74 | */ 75 | node_t * node_list_item(const node_list_t * list, vsize_t index); 76 | 77 | /*! 78 | @brief Get the number of nodes in the list. 79 | @param list The node list. 80 | @return Number of nodes. 81 | */ 82 | vsize_t node_list_size(const node_list_t * list); 83 | 84 | /*! 85 | @brief Add an empty node to the list at index node_id. 86 | Node index must not already exist ! 87 | @param list The node list. 88 | @param node_id The unique index of the new node. 89 | @return Created node in the list. 90 | */ 91 | node_t* node_list_append(node_list_t * list, vsize_t node_id); 92 | 93 | /*! 94 | @brief Find the node with node_id inside node list 95 | Node index must not already exist ! 96 | @param list The node list. 97 | @param node_id The unique id of the searched node. 98 | @return Pointer to found node or NULL 99 | */ 100 | node_t* node_list_find(node_list_t * list, vsize_t node_id); 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/libs/node_info/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # sources 2 | set(SRCS_NODEINFO 3 | node_info.cpp 4 | node_info.hpp 5 | ) 6 | 7 | # nodeinfo library 8 | add_library(nodeinfo ${SRCS_NODEINFO}) 9 | target_link_libraries(nodeinfo ${Boost_REGEX_LIBRARY}) 10 | 11 | # Bindings 12 | list_combinations(SRCS_NODEINFO_BINDING 13 | PREFIXES ${CMAKE_CURRENT_SOURCE_DIR}/ 14 | SUFFIXES ${SRCS_NODEINFO}) 15 | binding_add_srcs("${SRCS_NODEINFO_BINDING}") 16 | -------------------------------------------------------------------------------- /src/libsGTSI/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(SRCS_LIBGTSI 2 | utils-gtsi.cpp 3 | utils-gtsi.hpp 4 | ) 5 | 6 | # Traversal directory 7 | add_subdirectory(Traversal) 8 | 9 | # utils-GTSI object-library 10 | add_library(utils-GTSI OBJECT ${SRCS_LIBGTSI}) 11 | 12 | # libGTSI library 13 | add_library(GTSI 14 | $ 15 | $ 16 | ) 17 | 18 | # Bindings 19 | list_combinations(SRCS_LIBGTSI_BINDING 20 | PREFIXES ${CMAKE_CURRENT_SOURCE_DIR}/ 21 | SUFFIXES ${SRCS_LIBGTSI}) 22 | binding_add_srcs("${SRCS_LIBGTSI_BINDING}") 23 | -------------------------------------------------------------------------------- /src/libsGTSI/Traversal/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SET(SRCS_TRAVERSAL 2 | Traversal.cpp 3 | Traversal.hpp 4 | ) 5 | 6 | # Traversal object-library 7 | add_library(Traversal OBJECT ${SRCS_TRAVERSAL}) 8 | 9 | # Bindings 10 | list_combinations(SRCS_TRAVERSAL_BINDING 11 | PREFIXES ${CMAKE_CURRENT_SOURCE_DIR}/ 12 | SUFFIXES ${SRCS_TRAVERSAL}) 13 | binding_add_srcs("${SRCS_TRAVERSAL_BINDING}") 14 | -------------------------------------------------------------------------------- /src/libsGTSI/Traversal/Traversal.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TRAVERSAL_HPP 2 | #define TRAVERSAL_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "utils-gtsi.hpp" 15 | #include 16 | #include 17 | #include 18 | using namespace std; 19 | 20 | #include "graph.hpp" 21 | #include "nodeIO.hpp" 22 | #include "node_info.hpp" 23 | 24 | 25 | enum TypeMotParcours { 26 | TYPE_M1, 27 | TYPE_M2 28 | }; 29 | 30 | class MotParcours { 31 | public: 32 | MotParcours* duplicate(); 33 | 34 | TypeMotParcours type; 35 | bool has_symbol; 36 | vsize_t i; 37 | bool alpha_is_R; 38 | bool children_are_wildcards; 39 | uint8_t k; 40 | MotParcours(); 41 | string toString(); 42 | bool matchesSymbol(node_t * n, bool); 43 | bool matchesCF(node_t * n); 44 | bool matchesC(node_t * n); 45 | bool matchesF(node_t * n); 46 | bool equals(MotParcours * m, bool checkLabels); 47 | bool sameSymbol(MotParcours * m, bool); 48 | bool sameRepeatAndCF(MotParcours * m); 49 | 50 | NodeInfo* info; 51 | CondNode* condition; 52 | }; 53 | 54 | CondNode* computeCond(node_t* n); 55 | 56 | typedef std::map < string, std::list < node_t * >*> Match; 57 | typedef std::list MatchList; 58 | typedef std::map < std::string, MatchList*> PatternsMatches; 59 | 60 | 61 | Match* clone_match(Match* m); 62 | 63 | class Parcours { 64 | public: 65 | bool complete; 66 | vsize_t size; 67 | MotParcours **mots; 68 | string name; 69 | 70 | Parcours(); 71 | string toString(); 72 | void addMot(MotParcours * m); 73 | typedef std::pair < bool, Match*> RetourParcoursDepuisSommet; 74 | RetourParcoursDepuisSommet parcourirDepuisSommet(graph_t *, vsize_t root, vsize_t W, bool checkLabels, bool printFound, bool printAllMatches); 75 | std::pair parcoursUnmatchedNode(bool checkLabels, bool returnFound, MotParcours* m, node_t* node, node_t* current_node, set < node_t * >* matched_nodes, std::pair < node_t *, node_t * >*numbers, vsize_t max_numbered, Match* found_nodes, bool printAllMatches); 76 | typedef std::pair < vsize_t, MatchList*> RetourParcours; 77 | RetourParcours parcourir(graph_t * gr, vsize_t W, bool checkLabels, bool countAllMatches, bool getId, bool printAllMatches); 78 | bool equals(Parcours *, bool checkLabels); 79 | void freeParcours(bool free_mots); 80 | }; 81 | 82 | void freeMatch(std::map < string, std::list < node_t * >*>*); 83 | void freeRetourParcoursDepuisSommet(Parcours::RetourParcoursDepuisSommet rt, bool getid); 84 | void freePatternsMatches(PatternsMatches* patterns_matches, bool freeMatches); 85 | 86 | typedef std::tuple < node_t *, uint8_t, node_t * >TupleQueue; 87 | 88 | vsize_t parcoursProfondeurRec(Parcours *p, bool has_father, vsize_t father_number, node_t * s, bool i_wildcard, vsize_t i, set < node_t * >* explored, std::map * node_ids, vsize_t W); 89 | Parcours* parcoursProfondeur(graph_t * graph, vsize_t vroot, vsize_t W); 90 | Parcours *parcoursLargeur(graph_t * graph, vsize_t root, vsize_t W); 91 | Parcours* parcoursGen(graph_t * graph, vsize_t root, vsize_t W); 92 | 93 | std::set < Parcours * >parcoursFromGraph(graph_t *, vsize_t, bool); 94 | 95 | class ParcoursNode { 96 | public: 97 | vsize_t id; 98 | bool feuille; 99 | MotParcours *mot; 100 | std::list < ParcoursNode * >fils; 101 | string name; 102 | 103 | ParcoursNode(); 104 | ParcoursNode(std::list < ParcoursNode * >fils, MotParcours * mot, uint64_t id); 105 | bool addGraphFromNode(graph_t* gr, node_t* r, vsize_t W, bool checkLabels); 106 | bool addParcours(Parcours * p, vsize_t index, bool checkLabels); 107 | void saveParcoursNodeToDot(string path); 108 | string toDotPartiel(); 109 | string toDot(); 110 | string toString(); 111 | 112 | typedef std::pair < vsize_t, PatternsMatches*> RetourParcourir; 113 | RetourParcourir parcourir(graph_t * gr, vsize_t W, bool checkLabels, bool returnFound, bool printAllMatches); 114 | PatternsMatches* parcourirDepuisSommetRec(bool racine, graph_t * gr, node_t * r, std::pair < node_t *, node_t * >*numeros, vsize_t max_numeros, std::set < node_t * > matched_nodes, bool checkLabels, Match* current_match, bool returnFound, bool printAllMatches); 115 | PatternsMatches* parcourirDepuisSommet(graph_t *, vsize_t r, vsize_t W, bool checkLabels, bool printFound, bool printAllMatches); 116 | typedef std::tuple < bool, node_t *, std::pair < node_t *, node_t * >*, vsize_t, set < node_t * >>RetourEtape; 117 | std::tuple > etapeUnmatchedNode(bool checkLabels, bool returnFound, MotParcours* m, node_t* node, node_t* current_node, set < node_t * > matched_nodes, std::pair < node_t *, node_t * >*numbers, vsize_t max_numbered, Match*, bool printAllMatches); 118 | RetourEtape etape(MotParcours* m, node_t* s, graph_t* gr, std::pair< node_t*, node_t* >* numbers, vsize_t max_numbered, std::set< node_t* > matched_nodes, bool checkLabels, Match* current_match, bool returnFound, bool printAllMatches); 119 | vsize_t countLeaves(); 120 | vsize_t countFinal(); 121 | void freeParcoursNode(); 122 | void merge_patternsmatches(PatternsMatches* leaves_to_matches, PatternsMatches* leaves_to_matches_rec); 123 | }; 124 | 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/libsGTSI/utils-gtsi.cpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_CPP 2 | #define UTILS_CPP 3 | 4 | #include "utils-gtsi.hpp" 5 | #include 6 | 7 | 8 | string b2s(bool b){ 9 | return b ? "true" : "false"; 10 | } 11 | 12 | string h2s(uint64_t a){ 13 | string str; 14 | char* buff = (char*) calloc_or_quit(16, sizeof(char)); 15 | sprintf(buff, "%lx", (long int) a); 16 | str += buff; 17 | free(buff); 18 | return str; 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/libsGTSI/utils-gtsi.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_GTSI_H 2 | #define UTILS_GTSI_H 3 | 4 | #include 5 | #include "my_alloc.hpp" 6 | 7 | using namespace std; 8 | 9 | string b2s(bool b); 10 | string h2s(uint64_t a); 11 | 12 | #endif -------------------------------------------------------------------------------- /src/tests_graphs/test0/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test0/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test0/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test1/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test1/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test1/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "D" [label = "INST"] 6 | "A" -> "B" [label = "1"] 7 | "A" -> "C" [label = "2"] 8 | "B" -> "D" [label = "1"] 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test10/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test10/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="xor", shape="box", inst="xor"] 3 | B [label="A: *", shape="box", cond=true, getid="A"] 4 | C [label="inc", shape="box", inst="inc"] 5 | D [label="cmp", shape="box", inst="cmp"] 6 | E [label="jb", shape="box", inst="jb"] 7 | F [label="*", shape="box", cond=true] 8 | 9 | A -> B 10 | B -> C 11 | C -> D 12 | D -> E 13 | E -> B 14 | E -> F 15 | } 16 | -------------------------------------------------------------------------------- /src/tests_graphs/test11/expected: -------------------------------------------------------------------------------- 1 | 12 2 | 12 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test11/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="A: *", shape="box", cond=true, getid="A"] 3 | B [label="B: (*)+", shape="box", cond=true, repeat="+", getid="B"] 4 | F [label="C: *", shape="box", cond=true, getid="C"] 5 | 6 | A -> B 7 | B -> B 8 | B -> F 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test12/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test12/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="xor eax, eax", shape="box", inst="xor eax, eax"] 3 | B [label="add [eax + ebx], al", shape="box", inst="add byte ptr [eax + ebx], al"] 4 | C [label="inc eax", shape="box", inst="inc eax"] 5 | D [label="cmp eax, esi", shape="box", inst="cmp eax, esi"] 6 | E [label="jb", shape="box", inst="jb"] 7 | F [label="*", shape="box", cond=true] 8 | 9 | A -> B 10 | B -> C 11 | C -> D 12 | D -> E 13 | E -> F 14 | E -> B 15 | } 16 | -------------------------------------------------------------------------------- /src/tests_graphs/test13/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test13/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="xor", shape="box", cond="opcode is xor"] 3 | B [label="A: *", shape="box", cond=true, getid="A"] 4 | C [label="inc", shape="box", cond="opcode is inc"] 5 | D [label="cmp", shape="box", cond="opcode is cmp"] 6 | E [label="jb", shape="box", cond="opcode is jb"] 7 | F [label="*", shape="box", cond=true] 8 | 9 | A -> B 10 | B -> C 11 | C -> D 12 | D -> E 13 | E -> F 14 | E -> B 15 | } 16 | -------------------------------------------------------------------------------- /src/tests_graphs/test14/expected: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test14/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="A: *", shape="box", cond=true, getid="A"] 3 | B [label="B: (*)+", shape="box", cond=true, repeat="+", getid="B"] 4 | F [label="C: *", shape="box", cond=true, getid="C"] 5 | 6 | A -> B 7 | B -> F 8 | B -> B 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test15/expected: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test15/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="A: *", shape="box", cond=true, getid=A] 3 | B [label="B: *", shape="box", cond=true, getid="B"] 4 | C [label="C: *", shape="box", cond=true, getid=C] 5 | D [label="D: *", shape="box", cond=true, getid=D] 6 | E [label="E: *", shape="box", cond=true, getid=E] 7 | F [label="F: *", shape="box", cond=true, getid=F] 8 | 9 | A -> B 10 | B -> C 11 | C -> D 12 | D -> E 13 | E -> B 14 | E -> F 15 | } 16 | -------------------------------------------------------------------------------- /src/tests_graphs/test15/test.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="A: *", shape="box", inst="A", getid=A] 3 | B [label="B: *", shape="box", inst="B", getid=B] 4 | C [label="C: *", shape="box", inst="C", getid=C] 5 | D [label="D: *", shape="box", inst="D", getid=D] 6 | E [label="E: *", shape="box", inst="E", getid=E] 7 | F [label="F: *", shape="box", inst="F", getid=F] 8 | 9 | 10 | A -> B 11 | B -> C 12 | C -> D 13 | D -> E 14 | E -> A 15 | E -> F 16 | } 17 | -------------------------------------------------------------------------------- /src/tests_graphs/test16/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test16/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "add", cond="opcode is add", root=true] 3 | "B" [label = "*", cond=true, minrepeat=0, maxrepeat=3, lazyrepeat=true] 4 | "C" [label = "cmp", cond="opcode is cmp"] 5 | "A" -> "B" [label = "1"] 6 | "B" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test16/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "add", inst="add", root=true] 3 | "C" [label = "cmp", inst="cmp"] 4 | "A" -> "C" [label = "1"] 5 | } 6 | -------------------------------------------------------------------------------- /src/tests_graphs/test17/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test17/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "add", inst="add", root=true] 3 | "B" [label = "*", cond=true, minrepeat=0, maxrepeat=3, lazyrepeat=true] 4 | "C" [label = "cmp", inst="cmp"] 5 | "A" -> "B" [label = "1"] 6 | "B" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test17/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "add", inst="add", root=true] 3 | "B" [label = "xor", inst="xor"] 4 | "C" [label = "cmp", inst="cmp"] 5 | "A" -> "B" [label = "1"] 6 | "B" -> "C" [label = "1"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test18/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test18/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="opcode is JCC", root=true] 3 | "B" [label = "B", cond="inst contains INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test18/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test19/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test19/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="xor", shape="box", cond = "inst contains xor"] 3 | B [label="A: *", shape="box", cond = "*", getid="A"] 4 | C [label="inc", shape="box", cond = "inst contains inc"] 5 | D [label="cmp", shape="box", cond = "opcode is cmp"] 6 | E [label="jb", shape="box", cond = "opcode is jb"] 7 | F [label="*", shape="box", cond = true] 8 | 9 | A -> B 10 | B -> C 11 | C -> D 12 | D -> E 13 | E -> F 14 | E -> B 15 | } 16 | -------------------------------------------------------------------------------- /src/tests_graphs/test2/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test2/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test2/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | "B" -> "C" [label = "1"] 8 | } 9 | -------------------------------------------------------------------------------- /src/tests_graphs/test20/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test20/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="inst contains INST and addr >= 401500 and addr <= 401505"] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test20/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true, addr = 0x401500] 3 | "B" [label = "INST", address=0x401503] 4 | "C" [label = "INST", addr="401506"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test21/expected: -------------------------------------------------------------------------------- 1 | 5 2 | 7 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test21/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond = "nfathers == 1", getid=A , root=true] 3 | "B" [label = "B", cond = "nchildren >= 2", getid=B] 4 | "A" -> "B" 5 | } 6 | -------------------------------------------------------------------------------- /src/tests_graphs/test21/pattern_1.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond = true, getid=A, root=true] 3 | "B" [label = "B", cond = "nfathers >= 2", getid=B] 4 | "A" -> "B" 5 | } 6 | -------------------------------------------------------------------------------- /src/tests_graphs/test21/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | 1 [label = "JCC" , root=true] 3 | 2 [label = "INST"] 4 | 3 [label = "CALL"] 5 | 4 [label = "INST"] 6 | 5 [label = "JCC"] 7 | 6 [label = "RET"] 8 | 7 [label = "INST"] 9 | 8 [label = "JMP"] 10 | 9 [label = "RET"] 11 | 1 -> 2 12 | 1 -> 7 13 | 2 -> 3 14 | 3 -> 4 15 | 3 -> 9 16 | 4 -> 5 17 | 5 -> 6 18 | 5 -> 1 19 | 7 -> 8 20 | 8 -> 3 21 | } 22 | -------------------------------------------------------------------------------- /src/tests_graphs/test22/expected: -------------------------------------------------------------------------------- 1 | 4 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test22/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="opcode beginswith xor or opcode contains ne and not opcode beginswith j", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test22/pattern_1.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="not (not (true))", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test22/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "jne C" , root=true, addr = "0x401500"] 3 | "B" [label = "next", opcode = "xor", address="0x401503"] 4 | "C" [label = "cmp ecx, 3", addr="401506"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test23/expected: -------------------------------------------------------------------------------- 1 | 2 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test23/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="inst regex '.*(x)?or.*|.*[cmp]+.*'", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test23/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "jne C" , root=true, addr = "0x401500"] 3 | "B" [label = "xor eax, eax", address="0x401503"] 4 | "C" [label = "cmp ecx, 3", addr="401506"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test24/expected: -------------------------------------------------------------------------------- 1 | 2 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test24/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="arg1 regex e.x and not arg1 contains , and not arg2 contains ,", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test24/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "jne C" , root=true, addr = "0x401500"] 3 | "B" [label = "xor eax, eax", address="0x401503"] 4 | "C" [label = "cmp ecx, 3", addr="401506"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test25/expected: -------------------------------------------------------------------------------- 1 | 2 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test25/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="nargs == 2 and arg1 regex e.x and not arg1 contains , and not arg2 contains ,", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test25/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "jne C" , root=true, addr = "0x401500"] 3 | "B" [label = "xor ERR", arg1 = eax, arg2 = eax, address="0x401503"] 4 | "C" [label = "cmp ERR", arg1 = ecx, arg2 = 3, addr="401506"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test26/expected: -------------------------------------------------------------------------------- 1 | 6 2 | 8 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test26/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="A: *", shape="box", cond=true, getid="A"] 3 | B [label="B: (^xor)*", shape="box", cond=true, repeat="*", lazyrepeat=true, maxchildren=1, getid="B"] 4 | C [label="C: (xor)+", shape="box", cond="opcode is xor", repeat="+", maxchildren=1, getid="C"] 5 | D [label="D: (*)*", shape="box", cond="true", repeat="*", getid="D"] 6 | E [label="E: *", shape="box", cond=true, getid="E"] 7 | 8 | A -> B 9 | B -> C 10 | C -> D 11 | D -> E 12 | D -> B 13 | } 14 | -------------------------------------------------------------------------------- /src/tests_graphs/test27/expected: -------------------------------------------------------------------------------- 1 | 6 2 | 8 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test27/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="A: (^xor)*", shape="box", cond=true, repeat="*", lazyrepeat=true, maxchildren=1, getid="A"] 3 | B [label="B: (xor)+", shape="box", cond="opcode is xor", repeat="+",maxchildren=1, getid="B"] 4 | C [label="C: (*)*", shape="box", cond="true", repeat="*", getid="C"] 5 | D [label="D: *", shape="box", cond=true, getid="D"] 6 | 7 | A -> B 8 | B -> C 9 | C -> D 10 | C -> A 11 | } 12 | -------------------------------------------------------------------------------- /src/tests_graphs/test28/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test28/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "A", cond="opcode is xor and nargs >= 2 and arg1 is _arg2", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test28/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "jne C" , root=true, addr = "0x401500"] 3 | "B" [label = "xor ERR", arg1 = eax, arg2 = eax, address="0x401503"] 4 | "C" [label = "cmp ERR", arg1 = ecx, arg2 = 3, addr="401506"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test29/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test29/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "jcc" , root=true, getid=A] 3 | "B" [label = "xor", getid=B] 4 | "C" [label = "mov", getid=C] 5 | "A" -> "B" [label = "2", childnumber=2] 6 | "A" -> "C" [label = "1", childnumber=1] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test29/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "jcc" , root=true] 3 | "B" [label = "mov"] 4 | "C" [label = "xor"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test3/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test3/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test3/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "D" [label = "INST"] 6 | "A" -> "B" [label = "1"] 7 | "A" -> "C" [label = "2"] 8 | "B" -> "D" [label = "1"] 9 | "C" -> "A" [label = "1"] 10 | } 11 | -------------------------------------------------------------------------------- /src/tests_graphs/test30/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test30/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "xor eax, eax" , root=true, getid=A] 3 | "B" [label = "add eax, 1", getid=B] 4 | "C" [label = "sub eax, 3", getid=C] 5 | "D" [label = "ret", getid=D] 6 | A -> B 7 | B -> C 8 | C -> D 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test30/pattern_1.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "xor eax, eax" , root=true, getid=A] 3 | "B" [label = "add eax, 1", getid=B] 4 | "C" [label = "sub eax, 3", getid=C] 5 | A -> B 6 | B -> C 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test30/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "xor eax, eax" , root=true, getid=A] 3 | "B" [label = "add eax, 1", getid=B] 4 | "C" [label = "sub eax, 3", getid=C] 5 | A -> B 6 | B -> C 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test31/expected: -------------------------------------------------------------------------------- 1 | 2 2 | 10 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test31/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph pattern0 { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "D" [label = "CALL"] 6 | "A" -> "B" 7 | "A" -> "C" 8 | "B" -> "D" 9 | } 10 | Digraph pattern1 { 11 | "A" [label = "JCC" , root=true] 12 | "B" [label = "JCC"] 13 | "C" [label = "INST"] 14 | "D" [label = "CALL"] 15 | "A" -> "B" 16 | "B" -> "C" 17 | "C" -> "D" 18 | } 19 | Digraph pattern2 { 20 | "A" [label = "JMP" , root=true] 21 | "B" [label = "CALL"] 22 | "C" [label = "INST"] 23 | "D" [label = "RET"] 24 | "A" -> "B" 25 | "B" -> "C" 26 | "B" -> "D" 27 | } 28 | Digraph pattern3 { 29 | "A" [label = "INST" , root=true] 30 | "B" [label = "JCC"] 31 | "C" [label = "JCC"] 32 | "D" [label = "RET"] 33 | "A" -> "B" 34 | "B" -> "C" 35 | "B" -> "D" 36 | } 37 | -------------------------------------------------------------------------------- /src/tests_graphs/test31/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | 1 [label = "JCC" , root=true] 3 | 2 [label = "INST"] 4 | 3 [label = "CALL"] 5 | 4 [label = "INST"] 6 | 5 [label = "JCC"] 7 | 6 [label = "RET"] 8 | 7 [label = "INST"] 9 | 8 [label = "JMP"] 10 | 9 [label = "RET"] 11 | 1 -> 2 12 | 1 -> 7 13 | 2 -> 3 14 | 3 -> 4 15 | 3 -> 9 16 | 4 -> 5 17 | 5 -> 6 18 | 5 -> 1 19 | 7 -> 8 20 | 8 -> 3 21 | } 22 | -------------------------------------------------------------------------------- /src/tests_graphs/test32/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test32/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph ghost{ 2 | A [label="A", cond="true"] 3 | B [label="B?", cond="true", minrepeat=0, maxrepeat=1, lazyrepeat=true] 4 | C [label="C", cond="opcode is mov"] 5 | 6 | A -> B [childnumber=2] 7 | A -> B [childnumber=1] 8 | B -> C [childnumber=1] 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test32/test.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="Pre", inst="add"] 3 | B [label="Loop", inst="mov"] 4 | 5 | A -> B [childnumber=1] 6 | A -> B [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test33/expected: -------------------------------------------------------------------------------- 1 | 19 2 | 19 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test33/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph bb_loop{ 2 | A [label="A: (*)+", shape="box", cond=true, minrepeat=1, maxrepeat=none, getid="A"] 3 | A -> A [label=2, childnumber=2] 4 | } 5 | -------------------------------------------------------------------------------- /src/tests_graphs/test33/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test33/test -------------------------------------------------------------------------------- /src/tests_graphs/test34/expected: -------------------------------------------------------------------------------- 1 | 8 2 | 8773 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test34/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph popular{ 2 | A [cond="nfathers>=10", getid=A] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test34/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test34/test -------------------------------------------------------------------------------- /src/tests_graphs/test35/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test35/pattern_0.dot: -------------------------------------------------------------------------------- 1 | graph G B { 2 | "A" [cond="opcode is jne"] 3 | "B" [cond="opcode is xor and arg1 is eax"] 4 | "C" [cond="opcode is push"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test35/pattern_1.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [cond="opcodee is jne"] 3 | "B" [cond="opcode sameas xor and arg1 is eax"] 4 | "C" [cond="opcode is push"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test35/pattern_2.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [cond="opcode is jne"] 3 | "B" [cond="opcode is xor and arg1 is eax"] 4 | "C" [cond="opcode is push"] 5 | "A" -> "B" [childnumber==1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test35/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [inst = "jne C" , root=true] 3 | "B" [inst = "xor eax, eax"] 4 | "C" [inst = "push ebp"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test36/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test36/pattern_0.dot: -------------------------------------------------------------------------------- 1 | graph G B { 2 | "A" [cond="opcode is jne"] 3 | "B" [cond="opcode is xor and arg1 is eax"] 4 | "C" [cond="opcode is push"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | 9 | Digraph G { 10 | "A" [cond="opcodee is jne"] 11 | "B" [cond="opcode sameas xor and arg1 is eax"] 12 | "C" [cond="opcode is push"] 13 | "A" -> "B" [childnumber=1] 14 | "A" -> "C" [childnumber=2] 15 | } 16 | 17 | Digraph G { 18 | "A" [cond="opcode is jne"] 19 | "B" [cond="opcode is xor and arg1 is eax"] 20 | "C" [cond="opcode is push"] 21 | "A" -> "B" [childnumber==1] 22 | "A" -> "C" [childnumber=2] 23 | } 24 | -------------------------------------------------------------------------------- /src/tests_graphs/test36/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [inst = "jne C" , root=true] 3 | "B" [inst = "xor eax, eax"] 4 | "C" [inst = "push ebp"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test37/.expected.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test37/.expected.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test37/.pattern_0.dot.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test37/.pattern_0.dot.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test37/expected: -------------------------------------------------------------------------------- 1 | 0 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test37/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test37 { 2 | "A" [cond="opcode is xor and not arg1 is ebx and arg2 is ecx"] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test37/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [inst = "jne C" , root=true] 3 | "B" [inst = "xor eax, eax"] 4 | "C" [inst = "push ebp"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test38/.expected.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test38/.expected.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test38/.pattern_0.dot.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test38/.pattern_0.dot.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test38/expected: -------------------------------------------------------------------------------- 1 | 0 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test38/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test37 { 2 | "A" [cond="opcode is xor and (not arg1 is ebx) and arg2 is ecx"] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test38/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [inst = "jne C" , root=true] 3 | "B" [inst = "xor eax, eax"] 4 | "C" [inst = "push ebp"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test39/.expected.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test39/.expected.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test39/.pattern_0.dot.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test39/.pattern_0.dot.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test39/expected: -------------------------------------------------------------------------------- 1 | 0 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test39/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test37 { 2 | "A" [cond="opcode is xor and not (arg1 is ebx) and arg2 is ecx"] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test39/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [inst = "jne C" , root=true] 3 | "B" [inst = "xor eax, eax"] 4 | "C" [inst = "push ebp"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test4/expected: -------------------------------------------------------------------------------- 1 | 0 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test4/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test4/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "JCC"] 5 | "D" [label = "INST"] 6 | "A" -> "B" [label = "1"] 7 | "A" -> "C" [label = "2"] 8 | "B" -> "D" [label = "1"] 9 | "C" -> "A" [label = "1"] 10 | } 11 | -------------------------------------------------------------------------------- /src/tests_graphs/test40/.expected.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test40/.expected.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test40/.pattern_0.dot.un~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test40/.pattern_0.dot.un~ -------------------------------------------------------------------------------- /src/tests_graphs/test40/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test40/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test37 { 2 | "A" [cond="opcode is xor and not (arg1 is ebx and arg2 is ecx)"] 3 | } 4 | -------------------------------------------------------------------------------- /src/tests_graphs/test40/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [inst = "jne C" , root=true] 3 | "B" [inst = "xor eax, eax"] 4 | "C" [inst = "push ebp"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test41/expected: -------------------------------------------------------------------------------- 1 | 2 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test41/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test41 { 2 | A [cond=true] 3 | B [cond="inst contains eax"] 4 | 5 | A -> B [childnumber=*] 6 | } 7 | -------------------------------------------------------------------------------- /src/tests_graphs/test41/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [inst = "jne C" , root=true] 3 | "B" [inst = "xor eax, eax"] 4 | "C" [inst = "push eax"] 5 | "A" -> "B" [childnumber=1] 6 | "A" -> "C" [childnumber=2] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test41/wildcard: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test41/wildcard -------------------------------------------------------------------------------- /src/tests_graphs/test42/expected: -------------------------------------------------------------------------------- 1 | 4 2 | 4 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test42/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test42 { 2 | A [cond=true] 3 | B [cond=true] 4 | C [cond=true] 5 | 6 | A -> B [childnumber=*] 7 | B -> C [childnumber=*] 8 | } 9 | -------------------------------------------------------------------------------- /src/tests_graphs/test42/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | A [root=true] 3 | B [label=B] 4 | C [label=C] 5 | D [label=D] 6 | E [label=E] 7 | F [label=F] 8 | 9 | A -> B [childnumber=1] 10 | B -> C [childnumber=2] 11 | C -> D [childnumber=2] 12 | 13 | A -> E [childnumber=2] 14 | E -> F [childnumber=1] 15 | E -> A [childnumber=2] 16 | } 17 | -------------------------------------------------------------------------------- /src/tests_graphs/test42/wildcard: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test42/wildcard -------------------------------------------------------------------------------- /src/tests_graphs/test43/expected: -------------------------------------------------------------------------------- 1 | 3 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test43/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test43 { 2 | A [cond=true] 3 | B [cond=true, repeat=*] 4 | 5 | A -> B [childnumber=*] 6 | B -> A [childnumber=*] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test43/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | A [root=true] 3 | B [label=B] 4 | C [label=C] 5 | D [label=D] 6 | E [label=E] 7 | F [label=F] 8 | 9 | A -> B [childnumber=1] 10 | B -> C [childnumber=1] 11 | C -> D [childnumber=1] 12 | D -> A [childnumber=1] 13 | 14 | A -> E [childnumber=2] 15 | E -> F [childnumber=1] 16 | E -> A [childnumber=2] 17 | } 18 | -------------------------------------------------------------------------------- /src/tests_graphs/test43/wildcard: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tests_graphs/test43/wildcard -------------------------------------------------------------------------------- /src/tests_graphs/test44/expected: -------------------------------------------------------------------------------- 1 | 3 2 | 0 -------------------------------------------------------------------------------- /src/tests_graphs/test44/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test44 { 2 | "A" [cond="opcode is xor", getid="A"] 3 | "B" [cond="opcode is xor", lazyrepeat=true, repeat=*] 4 | "C" [cond="basicblockend"] 5 | 6 | "D" [cond="opcode is xor", lazyrepeat=true, repeat=*, getid="D"] 7 | "E" [cond="basicblockend"] 8 | 9 | "F" [cond="opcode is xor", lazyrepeat=true, repeat=*, getid="F"] 10 | "f" [cond="basicblockend"] 11 | 12 | "G" [cond="opcode is xor", lazyrepeat=true, repeat=*, getid="G"] 13 | "g" [cond="basicblockend"] 14 | 15 | "A" -> "B" 16 | "B" -> "C" 17 | "C" -> "D" [childnumber=2] 18 | 19 | "D" -> "E" 20 | "E" -> "F" [childnumber=2] 21 | "E" -> "G" [childnumber=1] 22 | 23 | "F" -> "f" 24 | "f" -> "D" 25 | 26 | "G" -> "g" 27 | } -------------------------------------------------------------------------------- /src/tests_graphs/test44/test.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | "A" [label = "xor eax, eax" , root=true] 3 | "B" [label = "xor eax, eax"] 4 | "C" [label = "xor eax, eax"] 5 | "D" [label = "jmp 0x1"] 6 | 7 | "E" [label = "xor eax, ebx"] 8 | "F" [label = "xor eax, eax"] 9 | "G" [label = "xor eax, eax"] 10 | "H" [label = "je 0x1"] 11 | 12 | "I" [label = "xor eax, ecx"] 13 | "a" [label = "xor eax, eax"] 14 | "b" [label = "mov eax, eax"] 15 | 16 | "J" [label = "xor eax, edx"] 17 | "c" [label = "xor eax, eax"] 18 | "d" [label = "xor eax, eax"] 19 | "e" [label = "xor eax, eax"] 20 | "f" [label = "xor eax, eax"] 21 | "g" [label = "xor eax, eax"] 22 | "h" [label = "ret"] 23 | 24 | "A" -> "B" [childnumber=1] 25 | "B" -> "C" [childnumber=1] 26 | "C" -> "D" [childnumber=1] 27 | 28 | "D" -> "E" [childnumber=2] 29 | "E" -> "F" [childnumber=1] 30 | "F" -> "G" [childnumber=1] 31 | "G" -> "H" [childnumber=1] 32 | 33 | "H" -> "I" [childnumber=2] 34 | "I" -> "a" [childnumber=1] 35 | "a" -> "b" [childnumber=1] 36 | "b" -> "E" [childnumber=1] 37 | 38 | "H" -> "J" [childnumber=1] 39 | "J" -> "c" [childnumber=1] 40 | "c" -> "d" [childnumber=1] 41 | "d" -> "e" [childnumber=1] 42 | "e" -> "f" [childnumber=1] 43 | "f" -> "g" [childnumber=1] 44 | "g" -> "h" [childnumber=1] 45 | } 46 | -------------------------------------------------------------------------------- /src/tests_graphs/test45/expected: -------------------------------------------------------------------------------- 1 | 4 2 | 18 -------------------------------------------------------------------------------- /src/tests_graphs/test45/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph test45 { 2 | "A" [cond="basicblockend"] 3 | } -------------------------------------------------------------------------------- /src/tests_graphs/test45/test.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | "A" [label = "xor eax, eax" , root=true] 3 | "B" [label = "xor eax, eax"] 4 | "C" [label = "xor eax, eax"] 5 | "D" [label = "jmp 0x1"] 6 | 7 | "E" [label = "xor eax, ebx"] 8 | "F" [label = "xor eax, eax"] 9 | "G" [label = "xor eax, eax"] 10 | "H" [label = "je 0x1"] 11 | 12 | "I" [label = "xor eax, ecx"] 13 | "a" [label = "xor eax, eax"] 14 | "b" [label = "mov eax, eax"] 15 | "c" [label = "ret"] 16 | 17 | "J" [label = "xor eax, edx"] 18 | "d" [label = "xor eax, eax"] 19 | "e" [label = "xor eax, eax"] 20 | "f" [label = "xor eax, eax"] 21 | "g" [label = "xor eax, eax"] 22 | "h" [label = "xor eax, eax"] 23 | 24 | "A" -> "B" [childnumber=1] 25 | "B" -> "C" [childnumber=1] 26 | "C" -> "D" [childnumber=1] 27 | 28 | "D" -> "E" [childnumber=2] 29 | "E" -> "F" [childnumber=1] 30 | "F" -> "G" [childnumber=1] 31 | "G" -> "H" [childnumber=1] 32 | 33 | "H" -> "I" [childnumber=2] 34 | "I" -> "a" [childnumber=1] 35 | "a" -> "b" [childnumber=1] 36 | "b" -> "c" [childnumber=1] 37 | 38 | "H" -> "J" [childnumber=1] 39 | "J" -> "d" [childnumber=1] 40 | "d" -> "e" [childnumber=1] 41 | "e" -> "f" [childnumber=1] 42 | "f" -> "g" [childnumber=1] 43 | "g" -> "h" [childnumber=1] 44 | "h" -> "E" [childnumber=1] 45 | } 46 | -------------------------------------------------------------------------------- /src/tests_graphs/test46/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test46/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 0 [cond="opcode is zero"] 3 | A [cond=true, repeat="*", lazyrepeat=true] 4 | D [cond=true] 5 | E [cond="opcode is ahah"] 6 | 0 -> A [childnumber=1] 7 | A -> D [childnumber=1] 8 | D -> E [childnumber=1] 9 | E -> D [childnumber=2] 10 | } 11 | -------------------------------------------------------------------------------- /src/tests_graphs/test46/test.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 0 [inst = "zero", opcode="zero", root=true] 3 | A [inst = "xor"] 4 | B [inst = "xor"] 5 | C [inst = "xor"] 6 | D [inst = "xor"] 7 | E [inst = "ahah", opcode="ahah"] 8 | 0 -> A [childnumber=1] 9 | A -> B [childnumber=1] 10 | B -> C [childnumber=1] 11 | C -> D [childnumber=1] 12 | D -> E [childnumber=1] 13 | E -> D [childnumber=2] 14 | } 15 | -------------------------------------------------------------------------------- /src/tests_graphs/test5/expected: -------------------------------------------------------------------------------- 1 | 0 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test5/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | } 8 | -------------------------------------------------------------------------------- /src/tests_graphs/test5/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "JCC"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "A" -> "C" [label = "2"] 7 | "B" -> "A" [label = "1"] 8 | "B" -> "C" [label = "2"] 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test6/expected: -------------------------------------------------------------------------------- 1 | 2 2 | 10 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test6/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "D" [label = "CALL"] 6 | "A" -> "B" 7 | "A" -> "C" 8 | "B" -> "D" 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test6/pattern_1.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "JCC"] 4 | "C" [label = "INST"] 5 | "D" [label = "CALL"] 6 | "A" -> "B" 7 | "B" -> "C" 8 | "C" -> "D" 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test6/pattern_2.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JMP" , root=true] 3 | "B" [label = "CALL"] 4 | "C" [label = "INST"] 5 | "D" [label = "RET"] 6 | "A" -> "B" 7 | "B" -> "C" 8 | "B" -> "D" 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test6/pattern_3.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "INST" , root=true] 3 | "B" [label = "JCC"] 4 | "C" [label = "JCC"] 5 | "D" [label = "RET"] 6 | "A" -> "B" 7 | "B" -> "C" 8 | "B" -> "D" 9 | } 10 | -------------------------------------------------------------------------------- /src/tests_graphs/test6/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | 1 [label = "JCC" , root=true] 3 | 2 [label = "INST"] 4 | 3 [label = "CALL"] 5 | 4 [label = "INST"] 6 | 5 [label = "JCC"] 7 | 6 [label = "RET"] 8 | 7 [label = "INST"] 9 | 8 [label = "JMP"] 10 | 9 [label = "RET"] 11 | 1 -> 2 12 | 1 -> 7 13 | 2 -> 3 14 | 3 -> 4 15 | 3 -> 9 16 | 4 -> 5 17 | 5 -> 6 18 | 5 -> 1 19 | 7 -> 8 20 | 8 -> 3 21 | } 22 | -------------------------------------------------------------------------------- /src/tests_graphs/test7/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test7/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC", root=true] 3 | "B" [label = "INST", repeat="*"] 4 | "C" [label = "INST"] 5 | "A" -> "B" [label = "1"] 6 | "B" -> "C" [label = "1"] 7 | "A" -> "C" [label = "2"] 8 | } 9 | -------------------------------------------------------------------------------- /src/tests_graphs/test7/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "INST"] 5 | "D" [label = "INST"] 6 | "E" [label = "INST"] 7 | "F" [label = "INST"] 8 | "G" [label = "INST"] 9 | "A" -> "B" [label = "1"] 10 | "B" -> "D" [label = "1"] 11 | "D" -> "E" [label = "1"] 12 | "E" -> "F" [label = "1"] 13 | "F" -> "G" [label = "1"] 14 | "G" -> "C" [label = "1"] 15 | "A" -> "C" [label = "2"] 16 | } 17 | -------------------------------------------------------------------------------- /src/tests_graphs/test8/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test8/pattern_0.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC", root=true] 3 | "B" [label = "INST", repeat="*"] 4 | "C" [label = "INST", cond=true, getid="joined"] 5 | "A" -> "B" [label = "1"] 6 | "B" -> "C" [label = "1"] 7 | "A" -> "C" [label = "2"] 8 | } 9 | -------------------------------------------------------------------------------- /src/tests_graphs/test8/test.dot: -------------------------------------------------------------------------------- 1 | Digraph G { 2 | "A" [label = "JCC" , root=true] 3 | "B" [label = "INST"] 4 | "C" [label = "RET"] 5 | "D" [label = "INST"] 6 | "E" [label = "INST"] 7 | "F" [label = "INST"] 8 | "G" [label = "INST"] 9 | "A" -> "B" [label = "1"] 10 | "B" -> "D" [label = "1"] 11 | "D" -> "E" [label = "1"] 12 | "E" -> "F" [label = "1"] 13 | "F" -> "G" [label = "1"] 14 | "G" -> "C" [label = "1"] 15 | "A" -> "C" [label = "2"] 16 | } 17 | -------------------------------------------------------------------------------- /src/tests_graphs/test9/expected: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -------------------------------------------------------------------------------- /src/tests_graphs/test9/pattern_0.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | A [label="xor eax, eax", shape="box", inst="xor eax, eax"] 3 | B [label="add [eax + ebx], al", shape="box", inst="add byte [eax + ebx], al"] 4 | C [label="inc eax", shape="box", inst="inc eax"] 5 | D [label="cmp eax, esi", shape="box", instruction="cmp eax, esi"] 6 | E [label="jb", shape="box", cond="inst contains jb"] 7 | F [label="*", shape="box", cond=true] 8 | 9 | A -> B 10 | B -> C 11 | C -> D 12 | D -> E 13 | E -> B 14 | E -> F 15 | } 16 | -------------------------------------------------------------------------------- /src/tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Change the location of executables 2 | set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) 3 | set (TOOLS ON CACHE BOOL "Tools") 4 | 5 | if(${TOOLS}) 6 | # grap-match 7 | add_subdirectory(grap-match) 8 | 9 | # grap 10 | add_subdirectory(grap) 11 | 12 | # tests 13 | add_subdirectory(tests) 14 | 15 | # todot 16 | add_subdirectory(todot) 17 | 18 | # disassembler 19 | # On Windows the disassembler is not installer with setup.py, it is only available through bindings 20 | find_program(PYTHON "python") 21 | if (PYTHON) 22 | set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py") 23 | set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py") 24 | if(NOT "${MSVC}") 25 | set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/grap_disassembler/__init__.py") 26 | endif() 27 | set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/setup_timestamp") 28 | 29 | if(NOT "${MSVC}") 30 | configure_file(${SETUP_PY_IN} ${SETUP_PY}) 31 | 32 | add_custom_command(OUTPUT ${OUTPUT} 33 | COMMAND ${PYTHON} ${SETUP_PY} build 34 | COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT} 35 | DEPENDS ${DEPS}) 36 | 37 | add_custom_target(target ALL DEPENDS ${OUTPUT}) 38 | 39 | install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install)") 40 | endif() 41 | endif() 42 | 43 | endif(${TOOLS}) 44 | -------------------------------------------------------------------------------- /src/tools/grap-match/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # sources 2 | set(SRCS_GRAP-MATCH 3 | grap-match.cpp 4 | grap-match.hpp 5 | ) 6 | 7 | add_executable(grap-match ${SRCS_GRAP-MATCH}) 8 | 9 | if("${MSVC}" OR "${MSYS}") 10 | target_link_libraries(grap-match common GTSI graph nodeinfo) 11 | target_link_libraries(grap-match ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY}) 12 | else() 13 | target_link_libraries(grap-match seccomp common GTSI graph nodeinfo pthread) 14 | target_link_libraries(grap-match ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY}) 15 | endif() 16 | configure_file(grap-match.py ${CMAKE_BINARY_DIR}/grap-match.py COPYONLY) 17 | 18 | if(NOT "${MSVC}" AND NOT "${MSYS}") 19 | install (TARGETS grap-match DESTINATION /usr/local/bin) 20 | endif() 21 | -------------------------------------------------------------------------------- /src/tools/grap-match/grap-match.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GRAP_MATCH_HPP 2 | #define GRAP_MATCH_HPP 3 | 4 | #include "Traversal.hpp" 5 | #include "graphParser.hpp" 6 | #include 7 | #include 8 | #include 9 | 10 | #include "boost/filesystem.hpp" 11 | #include 12 | 13 | #ifndef _WIN32 14 | #include 15 | #include 16 | #endif 17 | 18 | void printUsage(); 19 | 20 | #ifndef _WIN32 21 | #ifdef SECCOMP 22 | void drop_initial_privileges(); 23 | void drop_privileges(); 24 | #endif 25 | #endif 26 | 27 | int main(int argc, char *argv[]); 28 | bool filter_path(boost::filesystem::path p, bool option_filter, string extension_filter); 29 | std::list list_files(string path, bool recursive, bool option_filter, string extension_filter); 30 | typedef std::tuple , bool, bool, vsize_t> ArgsMatchPatternToTest; 31 | void worker_queue(list< ArgsMatchPatternToTest >* args_queue, mutex* queue_mutex, mutex* cout_mutex, bool use_tree); 32 | void matchPatternToTest(bool optionVerbose, bool optionQuiet, bool optionDebug, bool optionShowAll, bool checkLabels, bool multipleTestFiles, Parcours* pattern_parcours, string pathTest, FILE* fileTest, bool printNoMatches, bool printAllMatches, vsize_t maxSiteSize, mutex* cout_mutex); 33 | void matchTreeToTest(bool optionVerbose, bool optionQuiet, bool optionDebug, bool optionShowAll, bool checkLabels, bool multipleTestFiles, ParcoursNode* tree, Parcours* pattern_parcours, string pathTest, FILE* fileTest, bool printNoMatches, bool printAllMatches, vsize_t maxSiteSize, mutex* cout_mutex); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/tools/grap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # grap 2 | if(NOT "${MSVC}" AND NOT "${MSYS}") 3 | install(FILES grap.py 4 | RENAME grap 5 | PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 6 | DESTINATION /usr/local/bin) 7 | endif() 8 | -------------------------------------------------------------------------------- /src/tools/grap_disassembler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuoSecGmbH/grap/ef40f5e302aa80edcd798bbb27dba807bbc7e97e/src/tools/grap_disassembler/__init__.py -------------------------------------------------------------------------------- /src/tools/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from distutils.core import setup 5 | 6 | setup(name="pygrap", 7 | version='1.3.1', 8 | package_dir={ '': '${CMAKE_CURRENT_SOURCE_DIR}' }, 9 | packages=['grap_disassembler']) 10 | -------------------------------------------------------------------------------- /src/tools/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # sources 2 | set(SRCS_TESTS 3 | tests.cpp 4 | tests.hpp 5 | ) 6 | 7 | # tests 8 | add_executable(tests ${SRCS_TESTS}) 9 | configure_file(test_all.py ${CMAKE_BINARY_DIR}/test_all.py COPYONLY) 10 | 11 | if("${MSVC}" OR "${MSYS}") 12 | target_link_libraries(tests common GTSI graph nodeinfo) 13 | else() 14 | target_link_libraries(tests seccomp common GTSI graph nodeinfo) 15 | endif() 16 | 17 | add_custom_target(test COMMAND python3 ${CMAKE_BINARY_DIR}/test_all.py WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) 18 | -------------------------------------------------------------------------------- /src/tools/tests/tests.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TESTS_H 2 | #define TESTS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "node_info.hpp" 9 | #include "graphIO.hpp" 10 | #include "graphParser.hpp" 11 | #include "Traversal.hpp" 12 | #include "my_alloc.hpp" 13 | 14 | #ifndef _WIN32 15 | #include 16 | #endif 17 | 18 | char optionFuncs; 19 | 20 | #ifndef _WIN32 21 | #ifdef SECCOMP 22 | void drop_privileges(); 23 | #endif 24 | #endif 25 | 26 | int main(int argc, char *argv[]); 27 | vsize_t print_leaf_result(bool r, string, bool); 28 | vsize_t test_NodeInfo(); 29 | void printDescription (); 30 | vsize_t test_match (graph_t ** grPattern, size_t nPattern, graph_t * grTest, size_t expected, bool checkLabels, std::string desc, bool exportTree, string treePath); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/tools/todot/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # sources 2 | set(SRCS_TODOT 3 | todot.cpp 4 | todot.hpp 5 | ) 6 | 7 | # todot 8 | add_executable(todot ${SRCS_TODOT}) 9 | target_link_libraries(todot common graph nodeinfo) 10 | -------------------------------------------------------------------------------- /src/tools/todot/todot.cpp: -------------------------------------------------------------------------------- 1 | #include "todot.hpp" 2 | 3 | int main(int argc, char* argv[]){ 4 | if (argc <= 2){ 5 | std::cout << "Usage: ./todot (in.dot) (out.dot)\n"; 6 | } 7 | 8 | std::cerr << "WARNING: ./todot is deprecated, conditions are not exported." << std::endl; 9 | 10 | char* pathIn = argv[1]; 11 | char* pathOut = argv[2]; 12 | 13 | graph_t* gr; 14 | 15 | FILE* fpIn; 16 | FILE* fpOut; 17 | 18 | fpIn = fopen(pathIn, "rb"); 19 | fpOut = fopen(pathOut, "wb"); 20 | 21 | if (fpIn == NULL || fpOut == NULL){ 22 | return 1; 23 | } 24 | 25 | gr = getGraphFromFile(fpIn); 26 | fclose(fpIn); 27 | 28 | if (gr != NULL){ 29 | graph_fprint(fpOut, gr); 30 | } 31 | fclose(fpOut); 32 | } 33 | -------------------------------------------------------------------------------- /src/tools/todot/todot.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TODOT_H 2 | #define TODOT_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "graphIO.hpp" 9 | #include "graphParser.hpp" 10 | 11 | #endif -------------------------------------------------------------------------------- /src/tools/todot/todot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | from pygrap import * 4 | 5 | def main(): 6 | """ 7 | main 8 | """ 9 | if len(sys.argv) <= 2: 10 | print("Usage: ./todot (in.dot) (out.dot)\n") 11 | exit(-1) 12 | 13 | pathin = sys.argv[1] 14 | pathout = sys.argv[2] 15 | 16 | gr = getGraphFromFile(pathin) 17 | 18 | if gr is not None: 19 | graph_fprint(pathout, gr) 20 | 21 | if __name__ == '__main__': 22 | main() 23 | --------------------------------------------------------------------------------