diff --git a/archive/0vercl0k/rp.txt b/archive/0vercl0k/rp.txt
new file mode 100644
index 00000000..b5b43b98
--- /dev/null
+++ b/archive/0vercl0k/rp.txt
@@ -0,0 +1,374894 @@
+Project Path: arc_0vercl0k_rp__kot9zmi
+
+Source Tree:
+
+```txt
+arc_0vercl0k_rp__kot9zmi
+├── LICENSE
+├── README.md
+├── pics
+│ ├── rp-r.gif
+│ ├── rp-shexa.gif
+│ ├── rp-sint.gif
+│ └── rp.gif
+└── src
+ ├── CMakeLists.txt
+ ├── rp
+ │ ├── arm.hpp
+ │ ├── arm64.hpp
+ │ ├── coloshell.hpp
+ │ ├── cpu.hpp
+ │ ├── disassenginewrapper.hpp
+ │ ├── elf.hpp
+ │ ├── elf_struct.hpp
+ │ ├── executable_format.hpp
+ │ ├── gadget.hpp
+ │ ├── instruction.hpp
+ │ ├── intelbeaengine.hpp
+ │ ├── macho.hpp
+ │ ├── macho_struct.hpp
+ │ ├── main.cpp
+ │ ├── options.hpp
+ │ ├── pe.hpp
+ │ ├── pe_struct.hpp
+ │ ├── platform.h
+ │ ├── program.cpp
+ │ ├── program.hpp
+ │ ├── raw.hpp
+ │ ├── ropsearch_algorithm.cpp
+ │ ├── ropsearch_algorithm.hpp
+ │ ├── rpexception.hpp
+ │ ├── safeint.hpp
+ │ ├── section.hpp
+ │ ├── toolbox.cpp
+ │ ├── toolbox.hpp
+ │ ├── x64.hpp
+ │ └── x86.hpp
+ └── third_party
+ ├── CLI11
+ │ └── CLI11.hpp
+ ├── beaengine
+ │ ├── CMakeLists.txt
+ │ ├── README.md
+ │ ├── changelog
+ │ ├── headers
+ │ │ ├── BeaEngine.h
+ │ │ ├── BeaEngineDelphi32.pas
+ │ │ ├── BeaEngineDelphi64.pas
+ │ │ ├── BeaEngineFasm32.inc
+ │ │ ├── BeaEngineFasm64.inc
+ │ │ ├── BeaEngineGoAsm32.inc
+ │ │ ├── BeaEngineGoAsm64.inc
+ │ │ ├── BeaEngineMasm32.inc
+ │ │ ├── BeaEngineMasm64.inc
+ │ │ ├── BeaEngineNasm32.inc
+ │ │ ├── BeaEngineNasm64.inc
+ │ │ ├── BeaEnginePureBasic32.pb
+ │ │ ├── BeaEnginePureBasic64.pb
+ │ │ ├── BeaEnginePython.py
+ │ │ ├── C# headers
+ │ │ │ ├── Constants.cs
+ │ │ │ ├── Engine.cs
+ │ │ │ └── Structs.cs
+ │ │ ├── Includes
+ │ │ │ ├── basic_types.h
+ │ │ │ └── export.h
+ │ │ └── __init__.py
+ │ ├── include
+ │ │ └── beaengine
+ │ │ ├── BeaEngine.h
+ │ │ ├── basic_types.h
+ │ │ ├── export.h
+ │ │ └── macros.h
+ │ ├── src
+ │ │ ├── BeaEngine.c
+ │ │ ├── CMakeLists.txt
+ │ │ ├── COPYING.LESSER.txt
+ │ │ ├── COPYING.txt
+ │ │ └── Includes
+ │ │ ├── BeaEngine.h
+ │ │ ├── BeaEngineVersion.c
+ │ │ ├── Routines_Disasm.c
+ │ │ ├── Routines_ModRM.c
+ │ │ ├── instr_set
+ │ │ │ ├── Data_opcode.h
+ │ │ │ ├── instructions_list.c
+ │ │ │ ├── opcodes_Grp1.c
+ │ │ │ ├── opcodes_Grp12.c
+ │ │ │ ├── opcodes_Grp13.c
+ │ │ │ ├── opcodes_Grp14.c
+ │ │ │ ├── opcodes_Grp15.c
+ │ │ │ ├── opcodes_Grp16.c
+ │ │ │ ├── opcodes_Grp17.c
+ │ │ │ ├── opcodes_Grp2.c
+ │ │ │ ├── opcodes_Grp3.c
+ │ │ │ ├── opcodes_Grp4.c
+ │ │ │ ├── opcodes_Grp5.c
+ │ │ │ ├── opcodes_Grp6.c
+ │ │ │ ├── opcodes_Grp7.c
+ │ │ │ ├── opcodes_Grp8.c
+ │ │ │ ├── opcodes_Grp9.c
+ │ │ │ └── opcodes_prefixes.c
+ │ │ ├── internal_datas.h
+ │ │ └── protos.h
+ │ └── tests
+ │ ├── 0f01.py
+ │ ├── 0f02.py
+ │ ├── 0f03.py
+ │ ├── 0f08.py
+ │ ├── 0f10.py
+ │ ├── 0f11.py
+ │ ├── 0f12.py
+ │ ├── 0f13.py
+ │ ├── 0f14.py
+ │ ├── 0f15.py
+ │ ├── 0f16.py
+ │ ├── 0f17.py
+ │ ├── 0f1e.py
+ │ ├── 0f28.py
+ │ ├── 0f29.py
+ │ ├── 0f2a.py
+ │ ├── 0f2b.py
+ │ ├── 0f2c.py
+ │ ├── 0f2d.py
+ │ ├── 0f2e.py
+ │ ├── 0f2f.py
+ │ ├── 0f37.py
+ │ ├── 0f3800.py
+ │ ├── 0f3801.py
+ │ ├── 0f3802.py
+ │ ├── 0f3803.py
+ │ ├── 0f3804.py
+ │ ├── 0f3805.py
+ │ ├── 0f3806.py
+ │ ├── 0f3807.py
+ │ ├── 0f3808.py
+ │ ├── 0f3809.py
+ │ ├── 0f380a.py
+ │ ├── 0f380b.py
+ │ ├── 0f380c.py
+ │ ├── 0f380d.py
+ │ ├── 0f380e.py
+ │ ├── 0f380f.py
+ │ ├── 0f3810.py
+ │ ├── 0f3811.py
+ │ ├── 0f3812.py
+ │ ├── 0f3813.py
+ │ ├── 0f3814.py
+ │ ├── 0f3815.py
+ │ ├── 0f3816.py
+ │ ├── 0f3817.py
+ │ ├── 0f3818.py
+ │ ├── 0f3819.py
+ │ ├── 0f381a.py
+ │ ├── 0f381b.py
+ │ ├── 0f381c.py
+ │ ├── 0f381d.py
+ │ ├── 0f381e.py
+ │ ├── 0f381f.py
+ │ ├── 0f3820.py
+ │ ├── 0f3821.py
+ │ ├── 0f3822.py
+ │ ├── 0f3823.py
+ │ ├── 0f3824.py
+ │ ├── 0f3825.py
+ │ ├── 0f3826.py
+ │ ├── 0f3827.py
+ │ ├── 0f3828.py
+ │ ├── 0f3829.py
+ │ ├── 0f382a.py
+ │ ├── 0f382b.py
+ │ ├── 0f382c.py
+ │ ├── 0f382d.py
+ │ ├── 0f382e.py
+ │ ├── 0f382f.py
+ │ ├── 0f3830.py
+ │ ├── 0f3831.py
+ │ ├── 0f3832.py
+ │ ├── 0f3833.py
+ │ ├── 0f3834.py
+ │ ├── 0f3835.py
+ │ ├── 0f3836.py
+ │ ├── 0f3837.py
+ │ ├── 0f3838.py
+ │ ├── 0f3839.py
+ │ ├── 0f383a.py
+ │ ├── 0f383b.py
+ │ ├── 0f383c.py
+ │ ├── 0f383d.py
+ │ ├── 0f383e.py
+ │ ├── 0f383f.py
+ │ ├── 0f3840.py
+ │ ├── 0f3841.py
+ │ ├── 0f3842.py
+ │ ├── 0f3843.py
+ │ ├── 0f3844.py
+ │ ├── 0f3845.py
+ │ ├── 0f3846.py
+ │ ├── 0f3847.py
+ │ ├── 0f3849.py
+ │ ├── 0f384b.py
+ │ ├── 0f384c.py
+ │ ├── 0f384d.py
+ │ ├── 0f384e.py
+ │ ├── 0f384f.py
+ │ ├── 0f3850.py
+ │ ├── 0f3851.py
+ │ ├── 0f3852.py
+ │ ├── 0f3853.py
+ │ ├── 0f3854.py
+ │ ├── 0f3855.py
+ │ ├── 0f3858.py
+ │ ├── 0f3859.py
+ │ ├── 0f385a.py
+ │ ├── 0f385b.py
+ │ ├── 0f385c.py
+ │ ├── 0f385e.py
+ │ ├── 0f3862.py
+ │ ├── 0f3863.py
+ │ ├── 0f3864.py
+ │ ├── 0f3865.py
+ │ ├── 0f3866.py
+ │ ├── 0f3870.py
+ │ ├── 0f3871.py
+ │ ├── 0f3872.py
+ │ ├── 0f3873.py
+ │ ├── 0f3875.py
+ │ ├── 0f3876.py
+ │ ├── 0f3877.py
+ │ ├── 0f3878.py
+ │ ├── 0f3879.py
+ │ ├── 0f387a.py
+ │ ├── 0f387b.py
+ │ ├── 0f387c.py
+ │ ├── 0f387d.py
+ │ ├── 0f387e.py
+ │ ├── 0f387f.py
+ │ ├── 0f3880.py
+ │ ├── 0f3881.py
+ │ ├── 0f3882.py
+ │ ├── 0f3883.py
+ │ ├── 0f3888.py
+ │ ├── 0f3889.py
+ │ ├── 0f388a.py
+ │ ├── 0f388b.py
+ │ ├── 0f388c.py
+ │ ├── 0f388d.py
+ │ ├── 0f388e.py
+ │ ├── 0f388f.py
+ │ ├── 0f3890.py
+ │ ├── 0f3891.py
+ │ ├── 0f3892.py
+ │ ├── 0f3893.py
+ │ ├── 0f3896.py
+ │ ├── 0f3897.py
+ │ ├── 0f3898.py
+ │ ├── 0f3899.py
+ │ ├── 0f389a.py
+ │ ├── 0f389b.py
+ │ ├── 0f389c.py
+ │ ├── 0f389d.py
+ │ ├── 0f389e.py
+ │ ├── 0f389f.py
+ │ ├── 0f38a0.py
+ │ ├── 0f38a1.py
+ │ ├── 0f38a2.py
+ │ ├── 0f38a3.py
+ │ ├── 0f38a6.py
+ │ ├── 0f38a7.py
+ │ ├── 0f38a8.py
+ │ ├── 0f38a9.py
+ │ ├── 0f38aa.py
+ │ ├── 0f38ab.py
+ │ ├── 0f38ac.py
+ │ ├── 0f38ad.py
+ │ ├── 0f38ae.py
+ │ ├── 0f38af.py
+ │ ├── 0f38b4.py
+ │ ├── 0f38b5.py
+ │ ├── 0f38b6.py
+ │ ├── 0f38b7.py
+ │ ├── 0f38b8.py
+ │ ├── 0f38b9.py
+ │ ├── 0f38ba.py
+ │ ├── 0f38bb.py
+ │ ├── 0f38bc.py
+ │ ├── 0f38bd.py
+ │ ├── 0f38be.py
+ │ ├── 0f38bf.py
+ │ ├── 0f38c4.py
+ │ ├── 0f38c8.py
+ │ ├── 0f38c9.py
+ │ ├── 0f38ca.py
+ │ ├── 0f38cb.py
+ │ ├── 0f38cc.py
+ │ ├── 0f38cd.py
+ │ ├── 0f38d8.py
+ │ ├── 0f38db.py
+ │ ├── 0f38dc.py
+ │ ├── 0f38dd.py
+ │ ├── 0f38de.py
+ │ ├── 0f38df.py
+ │ ├── 0f38f0.py
+ │ ├── 0f38f1.py
+ │ ├── 0f38f5.py
+ │ ├── 0f38f6.py
+ │ ├── 0f38f7.py
+ │ ├── 0f38fa.py
+ │ ├── 0f38fb.py
+ │ ├── 0f3a00.py
+ │ ├── 0f3a01.py
+ │ ├── 0f3a02.py
+ │ ├── 0f3a03.py
+ │ ├── 0f3a04.py
+ │ ├── 0f3a05.py
+ │ ├── 0f3a06.py
+ │ ├── 0f3a08.py
+ │ ├── 0f3a09.py
+ │ ├── 0f3a0a.py
+ │ ├── 0f3a0b.py
+ │ ├── 0f3a0c.py
+ │ ├── 0f3a0d.py
+ │ ├── 0f3a0e.py
+ │ ├── 0f3a0f.py
+ │ ├── 0f3a14.py
+ │ ├── 0f3a15.py
+ │ ├── 0f3a16.py
+ │ ├── 0f3a17.py
+ │ ├── 0f3a18.py
+ │ ├── 0f3a19.py
+ │ ├── 0f3a1a.py
+ │ ├── 0f3a1b.py
+ │ ├── 0f3a1d.py
+ │ ├── 0f3a1e.py
+ │ ├── 0f3a1f.py
+ │ ├── 0f3a20.py
+ │ ├── 0f3a21.py
+ │ ├── 0f3a22.py
+ │ ├── 0f3a23.py
+ │ ├── 0f3a25.py
+ │ ├── 0f3a26.py
+ │ ├── 0f3a27.py
+ │ ├── 0f3a30.py
+ │ ├── 0f3a31.py
+ │ ├── 0f3a32.py
+ │ ├── 0f3a33.py
+ │ ├── 0f3a38.py
+ │ ├── 0f3a39.py
+ │ ├── 0f3a3a.py
+ │ ├── 0f3a3b.py
+ │ ├── 0f3a3e.py
+ │ ├── 0f3a3f.py
+ │ ├── 0f3a40.py
+ │ ├── 0f3a41.py
+ │ ├── 0f3a42.py
+ │ ├── 0f3a43.py
+ │ ├── 0f3a44.py
+ │ ├── 0f3a46.py
+ │ ├── 0f3a4a.py
+ │ ├── 0f3a4b.py
+ │ ├── 0f3a4c.py
+ │ ├── 0f3a50.py
+ │ ├── 0f3a51.py
+ │ ├── 0f3a54.py
+ │ ├── 0f3a55.py
+ │ ├── 0f3a56.py
+ │ ├── 0f3a57.py
+ │ ├── 0f3a60.py
+ │ ├── 0f3a61.py
+ │ ├── 0f3a62.py
+ │ ├── 0f3a63.py
+ │ ├── 0f3a66.py
+ │ ├── 0f3a67.py
+ │ ├── 0f3a70.py
+ │ ├── 0f3a71.py
+ │ ├── 0f3a72.py
+ │ ├── 0f3acc.py
+ │ ├── 0f3adf.py
+ │ ├── 0f3af0.py
+ │ ├── 0f41.py
+ │ ├── 0f42.py
+ │ ├── 0f44.py
+ │ ├── 0f45.py
+ │ ├── 0f46.py
+ │ ├── 0f47.py
+ │ ├── 0f4a.py
+ │ ├── 0f4b.py
+ │ ├── 0f50.py
+ │ ├── 0f51.py
+ │ ├── 0f52.py
+ │ ├── 0f53.py
+ │ ├── 0f54.py
+ │ ├── 0f55.py
+ │ ├── 0f56.py
+ │ ├── 0f57.py
+ │ ├── 0f58.py
+ │ ├── 0f59.py
+ │ ├── 0f5a.py
+ │ ├── 0f5b.py
+ │ ├── 0f5c.py
+ │ ├── 0f5d.py
+ │ ├── 0f5e.py
+ │ ├── 0f5f.py
+ │ ├── 0f60.py
+ │ ├── 0f61.py
+ │ ├── 0f62.py
+ │ ├── 0f63.py
+ │ ├── 0f64.py
+ │ ├── 0f65.py
+ │ ├── 0f66.py
+ │ ├── 0f67.py
+ │ ├── 0f68.py
+ │ ├── 0f69.py
+ │ ├── 0f6a.py
+ │ ├── 0f6b.py
+ │ ├── 0f6c.py
+ │ ├── 0f6d.py
+ │ ├── 0f6e.py
+ │ ├── 0f6f.py
+ │ ├── 0f70.py
+ │ ├── 0f71.py
+ │ ├── 0f72.py
+ │ ├── 0f73.py
+ │ ├── 0f74.py
+ │ ├── 0f75.py
+ │ ├── 0f76.py
+ │ ├── 0f77.py
+ │ ├── 0f78.py
+ │ ├── 0f79.py
+ │ ├── 0f7a.py
+ │ ├── 0f7b.py
+ │ ├── 0f7c.py
+ │ ├── 0f7d.py
+ │ ├── 0f7f.py
+ │ ├── 0f90.py
+ │ ├── 0f91.py
+ │ ├── 0f92.py
+ │ ├── 0f93.py
+ │ ├── 0f98.py
+ │ ├── 0f99.py
+ │ ├── 0fae.py
+ │ ├── 0fc0.py
+ │ ├── 0fc1.py
+ │ ├── 0fc2.py
+ │ ├── 0fc4.py
+ │ ├── 0fc5.py
+ │ ├── 0fc6.py
+ │ ├── 0fc7.py
+ │ ├── 0fd0.py
+ │ ├── 0fd1.py
+ │ ├── 0fd2.py
+ │ ├── 0fd3.py
+ │ ├── 0fd4.py
+ │ ├── 0fd5.py
+ │ ├── 0fd6.py
+ │ ├── 0fd7.py
+ │ ├── 0fd8.py
+ │ ├── 0fd9.py
+ │ ├── 0fda.py
+ │ ├── 0fdb.py
+ │ ├── 0fdc.py
+ │ ├── 0fdd.py
+ │ ├── 0fde.py
+ │ ├── 0fdf.py
+ │ ├── 0fe0.py
+ │ ├── 0fe1.py
+ │ ├── 0fe2.py
+ │ ├── 0fe3.py
+ │ ├── 0fe4.py
+ │ ├── 0fe5.py
+ │ ├── 0fe6.py
+ │ ├── 0fe7.py
+ │ ├── 0fe8.py
+ │ ├── 0fe9.py
+ │ ├── 0fea.py
+ │ ├── 0feb.py
+ │ ├── 0fec.py
+ │ ├── 0fed.py
+ │ ├── 0fee.py
+ │ ├── 0fef.py
+ │ ├── 0ff0.py
+ │ ├── 0ff1.py
+ │ ├── 0ff2.py
+ │ ├── 0ff3.py
+ │ ├── 0ff4.py
+ │ ├── 0ff5.py
+ │ ├── 0ff6.py
+ │ ├── 0ff7.py
+ │ ├── 0ff8.py
+ │ ├── 0ff9.py
+ │ ├── 0ffa.py
+ │ ├── 0ffb.py
+ │ ├── 0ffc.py
+ │ ├── 0ffd.py
+ │ ├── 0ffe.py
+ │ ├── 0fff.py
+ │ ├── README.md
+ │ ├── REXPrefix.py
+ │ ├── VEXPrefix.py
+ │ ├── examples.py
+ │ ├── issue#2.py
+ │ ├── issue#3.py
+ │ ├── modrm.py
+ │ ├── opcode1byte.yml
+ │ ├── regopcode.py
+ │ ├── securityblock.py
+ │ ├── test.py
+ │ ├── test_prefixes.py
+ │ └── test_python_wrapper.py
+ ├── capstone
+ │ ├── CMakeLists.txt
+ │ ├── COMPILE.TXT
+ │ ├── COMPILE_CMAKE.TXT
+ │ ├── COMPILE_MSVC.TXT
+ │ ├── CREDITS.TXT
+ │ ├── ChangeLog
+ │ ├── HACK.TXT
+ │ ├── LEB128.h
+ │ ├── LICENSE.TXT
+ │ ├── LICENSE_LLVM.TXT
+ │ ├── MCDisassembler.h
+ │ ├── MCFixedLenDisassembler.h
+ │ ├── MCInst.c
+ │ ├── MCInst.h
+ │ ├── MCInstrDesc.c
+ │ ├── MCInstrDesc.h
+ │ ├── MCRegisterInfo.c
+ │ ├── MCRegisterInfo.h
+ │ ├── Makefile
+ │ ├── MathExtras.h
+ │ ├── README.md
+ │ ├── RELEASE_NOTES
+ │ ├── SPONSORS.TXT
+ │ ├── SStream.c
+ │ ├── SStream.h
+ │ ├── TODO
+ │ ├── arch
+ │ │ ├── AArch64
+ │ │ │ ├── AArch64AddressingModes.h
+ │ │ │ ├── AArch64BaseInfo.c
+ │ │ │ ├── AArch64BaseInfo.h
+ │ │ │ ├── AArch64Disassembler.c
+ │ │ │ ├── AArch64Disassembler.h
+ │ │ │ ├── AArch64GenAsmWriter.inc
+ │ │ │ ├── AArch64GenDisassemblerTables.inc
+ │ │ │ ├── AArch64GenInstrInfo.inc
+ │ │ │ ├── AArch64GenRegisterInfo.inc
+ │ │ │ ├── AArch64GenSubtargetInfo.inc
+ │ │ │ ├── AArch64InstPrinter.c
+ │ │ │ ├── AArch64InstPrinter.h
+ │ │ │ ├── AArch64Mapping.c
+ │ │ │ ├── AArch64Mapping.h
+ │ │ │ ├── AArch64MappingInsn.inc
+ │ │ │ ├── AArch64MappingInsnOp.inc
+ │ │ │ ├── AArch64Module.c
+ │ │ │ └── AArch64Module.h
+ │ │ ├── ARM
+ │ │ │ ├── ARMAddressingModes.h
+ │ │ │ ├── ARMBaseInfo.h
+ │ │ │ ├── ARMDisassembler.c
+ │ │ │ ├── ARMDisassembler.h
+ │ │ │ ├── ARMGenAsmWriter.inc
+ │ │ │ ├── ARMGenDisassemblerTables.inc
+ │ │ │ ├── ARMGenInstrInfo.inc
+ │ │ │ ├── ARMGenRegisterInfo.inc
+ │ │ │ ├── ARMGenSubtargetInfo.inc
+ │ │ │ ├── ARMInstPrinter.c
+ │ │ │ ├── ARMInstPrinter.h
+ │ │ │ ├── ARMMapping.c
+ │ │ │ ├── ARMMapping.h
+ │ │ │ ├── ARMMappingInsn.inc
+ │ │ │ ├── ARMMappingInsnOp.inc
+ │ │ │ ├── ARMModule.c
+ │ │ │ └── ARMModule.h
+ │ │ ├── EVM
+ │ │ │ ├── EVMDisassembler.c
+ │ │ │ ├── EVMDisassembler.h
+ │ │ │ ├── EVMInstPrinter.c
+ │ │ │ ├── EVMInstPrinter.h
+ │ │ │ ├── EVMMapping.c
+ │ │ │ ├── EVMMapping.h
+ │ │ │ ├── EVMMappingInsn.inc
+ │ │ │ ├── EVMModule.c
+ │ │ │ └── EVMModule.h
+ │ │ ├── M680X
+ │ │ │ ├── M680XDisassembler.c
+ │ │ │ ├── M680XDisassembler.h
+ │ │ │ ├── M680XDisassemblerInternals.h
+ │ │ │ ├── M680XInstPrinter.c
+ │ │ │ ├── M680XInstPrinter.h
+ │ │ │ ├── M680XModule.c
+ │ │ │ ├── M680XModule.h
+ │ │ │ ├── cpu12.inc
+ │ │ │ ├── hcs08.inc
+ │ │ │ ├── hd6301.inc
+ │ │ │ ├── hd6309.inc
+ │ │ │ ├── insn_props.inc
+ │ │ │ ├── m6800.inc
+ │ │ │ ├── m6801.inc
+ │ │ │ ├── m6805.inc
+ │ │ │ ├── m6808.inc
+ │ │ │ ├── m6809.inc
+ │ │ │ └── m6811.inc
+ │ │ ├── M68K
+ │ │ │ ├── M68KDisassembler.c
+ │ │ │ ├── M68KDisassembler.h
+ │ │ │ ├── M68KInstPrinter.c
+ │ │ │ ├── M68KInstPrinter.h
+ │ │ │ ├── M68KInstructionTable.inc
+ │ │ │ ├── M68KModule.c
+ │ │ │ └── M68KModule.h
+ │ │ ├── Mips
+ │ │ │ ├── MipsDisassembler.c
+ │ │ │ ├── MipsDisassembler.h
+ │ │ │ ├── MipsGenAsmWriter.inc
+ │ │ │ ├── MipsGenDisassemblerTables.inc
+ │ │ │ ├── MipsGenInstrInfo.inc
+ │ │ │ ├── MipsGenRegisterInfo.inc
+ │ │ │ ├── MipsGenSubtargetInfo.inc
+ │ │ │ ├── MipsInstPrinter.c
+ │ │ │ ├── MipsInstPrinter.h
+ │ │ │ ├── MipsMapping.c
+ │ │ │ ├── MipsMapping.h
+ │ │ │ ├── MipsMappingInsn.inc
+ │ │ │ ├── MipsModule.c
+ │ │ │ └── MipsModule.h
+ │ │ ├── PowerPC
+ │ │ │ ├── PPCDisassembler.c
+ │ │ │ ├── PPCDisassembler.h
+ │ │ │ ├── PPCGenAsmWriter.inc
+ │ │ │ ├── PPCGenDisassemblerTables.inc
+ │ │ │ ├── PPCGenInstrInfo.inc
+ │ │ │ ├── PPCGenRegisterInfo.inc
+ │ │ │ ├── PPCGenSubtargetInfo.inc
+ │ │ │ ├── PPCInstPrinter.c
+ │ │ │ ├── PPCInstPrinter.h
+ │ │ │ ├── PPCMapping.c
+ │ │ │ ├── PPCMapping.h
+ │ │ │ ├── PPCMappingInsn.inc
+ │ │ │ ├── PPCModule.c
+ │ │ │ ├── PPCModule.h
+ │ │ │ └── PPCPredicates.h
+ │ │ ├── Sparc
+ │ │ │ ├── Sparc.h
+ │ │ │ ├── SparcDisassembler.c
+ │ │ │ ├── SparcDisassembler.h
+ │ │ │ ├── SparcGenAsmWriter.inc
+ │ │ │ ├── SparcGenDisassemblerTables.inc
+ │ │ │ ├── SparcGenInstrInfo.inc
+ │ │ │ ├── SparcGenRegisterInfo.inc
+ │ │ │ ├── SparcGenSubtargetInfo.inc
+ │ │ │ ├── SparcInstPrinter.c
+ │ │ │ ├── SparcInstPrinter.h
+ │ │ │ ├── SparcMapping.c
+ │ │ │ ├── SparcMapping.h
+ │ │ │ ├── SparcMappingInsn.inc
+ │ │ │ ├── SparcModule.c
+ │ │ │ └── SparcModule.h
+ │ │ ├── SystemZ
+ │ │ │ ├── SystemZDisassembler.c
+ │ │ │ ├── SystemZDisassembler.h
+ │ │ │ ├── SystemZGenAsmWriter.inc
+ │ │ │ ├── SystemZGenDisassemblerTables.inc
+ │ │ │ ├── SystemZGenInstrInfo.inc
+ │ │ │ ├── SystemZGenRegisterInfo.inc
+ │ │ │ ├── SystemZGenSubtargetInfo.inc
+ │ │ │ ├── SystemZInstPrinter.c
+ │ │ │ ├── SystemZInstPrinter.h
+ │ │ │ ├── SystemZMCTargetDesc.c
+ │ │ │ ├── SystemZMCTargetDesc.h
+ │ │ │ ├── SystemZMapping.c
+ │ │ │ ├── SystemZMapping.h
+ │ │ │ ├── SystemZMappingInsn.inc
+ │ │ │ ├── SystemZModule.c
+ │ │ │ └── SystemZModule.h
+ │ │ ├── TMS320C64x
+ │ │ │ ├── TMS320C64xDisassembler.c
+ │ │ │ ├── TMS320C64xDisassembler.h
+ │ │ │ ├── TMS320C64xGenAsmWriter.inc
+ │ │ │ ├── TMS320C64xGenDisassemblerTables.inc
+ │ │ │ ├── TMS320C64xGenInstrInfo.inc
+ │ │ │ ├── TMS320C64xGenRegisterInfo.inc
+ │ │ │ ├── TMS320C64xInstPrinter.c
+ │ │ │ ├── TMS320C64xInstPrinter.h
+ │ │ │ ├── TMS320C64xMapping.c
+ │ │ │ ├── TMS320C64xMapping.h
+ │ │ │ ├── TMS320C64xModule.c
+ │ │ │ └── TMS320C64xModule.h
+ │ │ ├── X86
+ │ │ │ ├── X86ATTInstPrinter.c
+ │ │ │ ├── X86BaseInfo.h
+ │ │ │ ├── X86Disassembler.c
+ │ │ │ ├── X86Disassembler.h
+ │ │ │ ├── X86DisassemblerDecoder.c
+ │ │ │ ├── X86DisassemblerDecoder.h
+ │ │ │ ├── X86DisassemblerDecoderCommon.h
+ │ │ │ ├── X86GenAsmWriter.inc
+ │ │ │ ├── X86GenAsmWriter1.inc
+ │ │ │ ├── X86GenAsmWriter1_reduce.inc
+ │ │ │ ├── X86GenAsmWriter_reduce.inc
+ │ │ │ ├── X86GenDisassemblerTables.inc
+ │ │ │ ├── X86GenDisassemblerTables_reduce.inc
+ │ │ │ ├── X86GenInstrInfo.inc
+ │ │ │ ├── X86GenInstrInfo_reduce.inc
+ │ │ │ ├── X86GenRegisterInfo.inc
+ │ │ │ ├── X86ImmSize.inc
+ │ │ │ ├── X86InstPrinter.h
+ │ │ │ ├── X86IntelInstPrinter.c
+ │ │ │ ├── X86Mapping.c
+ │ │ │ ├── X86Mapping.h
+ │ │ │ ├── X86MappingInsn.inc
+ │ │ │ ├── X86MappingInsnOp.inc
+ │ │ │ ├── X86MappingInsnOp_reduce.inc
+ │ │ │ ├── X86MappingInsn_reduce.inc
+ │ │ │ ├── X86Module.c
+ │ │ │ ├── X86Module.h
+ │ │ │ └── qsort.h
+ │ │ └── XCore
+ │ │ ├── XCoreDisassembler.c
+ │ │ ├── XCoreDisassembler.h
+ │ │ ├── XCoreGenAsmWriter.inc
+ │ │ ├── XCoreGenDisassemblerTables.inc
+ │ │ ├── XCoreGenInstrInfo.inc
+ │ │ ├── XCoreGenRegisterInfo.inc
+ │ │ ├── XCoreInstPrinter.c
+ │ │ ├── XCoreInstPrinter.h
+ │ │ ├── XCoreMapping.c
+ │ │ ├── XCoreMapping.h
+ │ │ ├── XCoreMappingInsn.inc
+ │ │ ├── XCoreModule.c
+ │ │ └── XCoreModule.h
+ │ ├── bindings
+ │ │ ├── Makefile
+ │ │ ├── README
+ │ │ ├── const_generator.py
+ │ │ ├── java
+ │ │ │ ├── Makefile
+ │ │ │ ├── README
+ │ │ │ ├── TestArm.java
+ │ │ │ ├── TestArm64.java
+ │ │ │ ├── TestBasic.java
+ │ │ │ ├── TestM680x.java
+ │ │ │ ├── TestMips.java
+ │ │ │ ├── TestPpc.java
+ │ │ │ ├── TestSparc.java
+ │ │ │ ├── TestSystemz.java
+ │ │ │ ├── TestX86.java
+ │ │ │ ├── TestXcore.java
+ │ │ │ ├── capstone
+ │ │ │ │ ├── Arm.java
+ │ │ │ │ ├── Arm64.java
+ │ │ │ │ ├── Arm64_const.java
+ │ │ │ │ ├── Arm_const.java
+ │ │ │ │ ├── Capstone.java
+ │ │ │ │ ├── Evm_const.java
+ │ │ │ │ ├── M680x.java
+ │ │ │ │ ├── M680x_const.java
+ │ │ │ │ ├── M68k_const.java
+ │ │ │ │ ├── Mips.java
+ │ │ │ │ ├── Mips_const.java
+ │ │ │ │ ├── Ppc.java
+ │ │ │ │ ├── Ppc_const.java
+ │ │ │ │ ├── Sparc.java
+ │ │ │ │ ├── Sparc_const.java
+ │ │ │ │ ├── Systemz.java
+ │ │ │ │ ├── Sysz_const.java
+ │ │ │ │ ├── TMS320C64x_const.java
+ │ │ │ │ ├── X86.java
+ │ │ │ │ ├── X86_const.java
+ │ │ │ │ ├── Xcore.java
+ │ │ │ │ └── Xcore_const.java
+ │ │ │ └── run.sh
+ │ │ ├── ocaml
+ │ │ │ ├── Makefile
+ │ │ │ ├── README
+ │ │ │ ├── arm.ml
+ │ │ │ ├── arm64.ml
+ │ │ │ ├── arm64_const.ml
+ │ │ │ ├── arm_const.ml
+ │ │ │ ├── capstone.ml
+ │ │ │ ├── evm_const.ml
+ │ │ │ ├── m680x.ml
+ │ │ │ ├── m680x_const.ml
+ │ │ │ ├── m68k_const.ml
+ │ │ │ ├── mips.ml
+ │ │ │ ├── mips_const.ml
+ │ │ │ ├── ocaml.c
+ │ │ │ ├── ppc.ml
+ │ │ │ ├── ppc_const.ml
+ │ │ │ ├── sparc.ml
+ │ │ │ ├── sparc_const.ml
+ │ │ │ ├── systemz.ml
+ │ │ │ ├── sysz_const.ml
+ │ │ │ ├── test_arm.ml
+ │ │ │ ├── test_arm64.ml
+ │ │ │ ├── test_basic.ml
+ │ │ │ ├── test_detail.ml
+ │ │ │ ├── test_m680x.ml
+ │ │ │ ├── test_mips.ml
+ │ │ │ ├── test_ppc.ml
+ │ │ │ ├── test_sparc.ml
+ │ │ │ ├── test_systemz.ml
+ │ │ │ ├── test_x86.ml
+ │ │ │ ├── test_xcore.ml
+ │ │ │ ├── tms320c64x_const.ml
+ │ │ │ ├── x86.ml
+ │ │ │ ├── x86_const.ml
+ │ │ │ ├── xcore.ml
+ │ │ │ └── xcore_const.ml
+ │ │ ├── powershell
+ │ │ │ ├── Capstone
+ │ │ │ │ ├── Capstone.Format.ps1xml
+ │ │ │ │ ├── Capstone.psd1
+ │ │ │ │ ├── Capstone.psm1
+ │ │ │ │ └── Lib
+ │ │ │ │ └── Capstone
+ │ │ │ └── README.md
+ │ │ ├── python
+ │ │ │ ├── BUILDING.txt
+ │ │ │ ├── LICENSE.TXT
+ │ │ │ ├── MANIFEST.in
+ │ │ │ ├── Makefile
+ │ │ │ ├── README.txt
+ │ │ │ ├── capstone
+ │ │ │ │ ├── arm.py
+ │ │ │ │ ├── arm64.py
+ │ │ │ │ ├── arm64_const.py
+ │ │ │ │ ├── arm_const.py
+ │ │ │ │ ├── evm.py
+ │ │ │ │ ├── evm_const.py
+ │ │ │ │ ├── m680x.py
+ │ │ │ │ ├── m680x_const.py
+ │ │ │ │ ├── m68k.py
+ │ │ │ │ ├── m68k_const.py
+ │ │ │ │ ├── mips.py
+ │ │ │ │ ├── mips_const.py
+ │ │ │ │ ├── ppc.py
+ │ │ │ │ ├── ppc_const.py
+ │ │ │ │ ├── sparc.py
+ │ │ │ │ ├── sparc_const.py
+ │ │ │ │ ├── systemz.py
+ │ │ │ │ ├── sysz_const.py
+ │ │ │ │ ├── tms320c64x.py
+ │ │ │ │ ├── tms320c64x_const.py
+ │ │ │ │ ├── x86.py
+ │ │ │ │ ├── x86_const.py
+ │ │ │ │ ├── xcore.py
+ │ │ │ │ └── xcore_const.py
+ │ │ │ ├── prebuilt
+ │ │ │ ├── pyx
+ │ │ │ │ ├── README
+ │ │ │ │ └── ccapstone.pxd
+ │ │ │ ├── setup.py
+ │ │ │ ├── setup_cython.py
+ │ │ │ ├── test_all.py
+ │ │ │ ├── test_arm.py
+ │ │ │ ├── test_arm64.py
+ │ │ │ ├── test_basic.py
+ │ │ │ ├── test_customized_mnem.py
+ │ │ │ ├── test_detail.py
+ │ │ │ ├── test_evm.py
+ │ │ │ ├── test_lite.py
+ │ │ │ ├── test_m680x.py
+ │ │ │ ├── test_m68k.py
+ │ │ │ ├── test_mips.py
+ │ │ │ ├── test_ppc.py
+ │ │ │ ├── test_skipdata.py
+ │ │ │ ├── test_sparc.py
+ │ │ │ ├── test_systemz.py
+ │ │ │ ├── test_tms320c64x.py
+ │ │ │ ├── test_x86.py
+ │ │ │ ├── test_xcore.py
+ │ │ │ └── xprint.py
+ │ │ └── vb6
+ │ │ ├── CDisassembler.cls
+ │ │ ├── CInstDetails.cls
+ │ │ ├── CInstruction.cls
+ │ │ ├── CX86Inst.cls
+ │ │ ├── CX86OpMem.cls
+ │ │ ├── CX86Operand.cls
+ │ │ ├── Form1.frm
+ │ │ ├── Form1.frx
+ │ │ ├── Module1.bas
+ │ │ ├── Project1.vbp
+ │ │ ├── Project1.vbw
+ │ │ ├── README.txt
+ │ │ ├── mMisc.bas
+ │ │ ├── mx86.bas
+ │ │ ├── screenshot.png
+ │ │ ├── vbCapstone.cpp
+ │ │ ├── vbCapstone.sln
+ │ │ └── vbCapstone.vcproj
+ │ ├── capstone.pc.in
+ │ ├── cmake.sh
+ │ ├── config.mk
+ │ ├── contrib
+ │ │ ├── README
+ │ │ ├── cs_driver
+ │ │ │ ├── README
+ │ │ │ ├── cs_driver
+ │ │ │ │ ├── cs_driver.c
+ │ │ │ │ ├── cs_driver.vcxproj
+ │ │ │ │ └── cs_driver.vcxproj.filters
+ │ │ │ └── cs_driver.sln
+ │ │ ├── m68k_instruction_tbl_gen
+ │ │ │ ├── M68KInstructionTblGen.c
+ │ │ │ └── Makefile
+ │ │ ├── objdump
+ │ │ │ └── objdump-m68k.py
+ │ │ └── windows_kernel
+ │ │ ├── README
+ │ │ ├── libc.cpp
+ │ │ └── libc.h
+ │ ├── cs.c
+ │ ├── cs_priv.h
+ │ ├── cstool
+ │ │ ├── Makefile
+ │ │ ├── README
+ │ │ ├── cstool.c
+ │ │ ├── cstool_arm.c
+ │ │ ├── cstool_arm64.c
+ │ │ ├── cstool_evm.c
+ │ │ ├── cstool_m680x.c
+ │ │ ├── cstool_m68k.c
+ │ │ ├── cstool_mips.c
+ │ │ ├── cstool_ppc.c
+ │ │ ├── cstool_sparc.c
+ │ │ ├── cstool_systemz.c
+ │ │ ├── cstool_tms320c64x.c
+ │ │ ├── cstool_x86.c
+ │ │ ├── cstool_xcore.c
+ │ │ └── getopt.h
+ │ ├── docs
+ │ │ ├── BHUSA2014-capstone.pdf
+ │ │ ├── README
+ │ │ └── capstone-logo.png
+ │ ├── functions.mk
+ │ ├── include
+ │ │ ├── capstone
+ │ │ │ ├── arm.h
+ │ │ │ ├── arm64.h
+ │ │ │ ├── capstone.h
+ │ │ │ ├── evm.h
+ │ │ │ ├── m680x.h
+ │ │ │ ├── m68k.h
+ │ │ │ ├── mips.h
+ │ │ │ ├── platform.h
+ │ │ │ ├── ppc.h
+ │ │ │ ├── sparc.h
+ │ │ │ ├── systemz.h
+ │ │ │ ├── tms320c64x.h
+ │ │ │ ├── x86.h
+ │ │ │ └── xcore.h
+ │ │ ├── platform.h
+ │ │ └── windowsce
+ │ │ ├── intrin.h
+ │ │ └── stdint.h
+ │ ├── make.sh
+ │ ├── msvc
+ │ │ ├── README
+ │ │ ├── capstone.sln
+ │ │ ├── capstone_dll
+ │ │ │ └── capstone_dll.vcxproj
+ │ │ ├── capstone_static
+ │ │ │ └── capstone_static.vcxproj
+ │ │ ├── capstone_static_winkernel
+ │ │ │ └── capstone_static_winkernel.vcxproj
+ │ │ ├── cstool
+ │ │ │ └── cstool.vcxproj
+ │ │ ├── test_arm
+ │ │ │ └── test_arm.vcxproj
+ │ │ ├── test_arm64
+ │ │ │ └── test_arm64.vcxproj
+ │ │ ├── test_basic
+ │ │ │ └── test_basic.vcxproj
+ │ │ ├── test_customized_mnem
+ │ │ │ └── test_customized_mnem.vcxproj
+ │ │ ├── test_detail
+ │ │ │ └── test_detail.vcxproj
+ │ │ ├── test_evm
+ │ │ │ └── test_evm.vcxproj
+ │ │ ├── test_iter
+ │ │ │ └── test_iter.vcxproj
+ │ │ ├── test_m680x
+ │ │ │ └── test_m680x.vcxproj
+ │ │ ├── test_m68k
+ │ │ │ └── test_m68k.vcxproj
+ │ │ ├── test_mips
+ │ │ │ └── test_mips.vcxproj
+ │ │ ├── test_ppc
+ │ │ │ └── test_ppc.vcxproj
+ │ │ ├── test_skipdata
+ │ │ │ └── test_skipdata.vcxproj
+ │ │ ├── test_sparc
+ │ │ │ └── test_sparc.vcxproj
+ │ │ ├── test_systemz
+ │ │ │ └── test_systemz.vcxproj
+ │ │ ├── test_tms320c64x
+ │ │ │ └── test_tms320c64x.vcxproj
+ │ │ ├── test_winkernel
+ │ │ │ └── test_winkernel.vcxproj
+ │ │ ├── test_x86
+ │ │ │ └── test_x86.vcxproj
+ │ │ └── test_xcore
+ │ │ └── test_xcore.vcxproj
+ │ ├── nmake.bat
+ │ ├── packages
+ │ │ ├── freebsd
+ │ │ │ └── ports
+ │ │ │ └── devel
+ │ │ │ └── capstone
+ │ │ │ ├── Makefile
+ │ │ │ ├── pkg-descr
+ │ │ │ └── pkg-plist
+ │ │ ├── macports
+ │ │ │ └── devel
+ │ │ │ └── capstone
+ │ │ │ ├── Portfile
+ │ │ │ └── files
+ │ │ │ └── patch-Makefile.diff
+ │ │ └── rpm
+ │ │ └── capstone.spec
+ │ ├── pkgconfig.mk
+ │ ├── suite
+ │ │ ├── MC
+ │ │ │ ├── AArch64
+ │ │ │ │ ├── basic-a64-instructions.s.cs
+ │ │ │ │ ├── gicv3-regs.s.cs
+ │ │ │ │ ├── neon-2velem.s.cs
+ │ │ │ │ ├── neon-3vdiff.s.cs
+ │ │ │ │ ├── neon-aba-abd.s.cs
+ │ │ │ │ ├── neon-across.s.cs
+ │ │ │ │ ├── neon-add-pairwise.s.cs
+ │ │ │ │ ├── neon-add-sub-instructions.s.cs
+ │ │ │ │ ├── neon-bitwise-instructions.s.cs
+ │ │ │ │ ├── neon-compare-instructions.s.cs
+ │ │ │ │ ├── neon-crypto.s.cs
+ │ │ │ │ ├── neon-extract.s.cs
+ │ │ │ │ ├── neon-facge-facgt.s.cs
+ │ │ │ │ ├── neon-frsqrt-frecp.s.cs
+ │ │ │ │ ├── neon-halving-add-sub.s.cs
+ │ │ │ │ ├── neon-max-min-pairwise.s.cs
+ │ │ │ │ ├── neon-max-min.s.cs
+ │ │ │ │ ├── neon-mla-mls-instructions.s.cs
+ │ │ │ │ ├── neon-mov.s.cs
+ │ │ │ │ ├── neon-mul-div-instructions.s.cs
+ │ │ │ │ ├── neon-perm.s.cs
+ │ │ │ │ ├── neon-rounding-halving-add.s.cs
+ │ │ │ │ ├── neon-rounding-shift.s.cs
+ │ │ │ │ ├── neon-saturating-add-sub.s.cs
+ │ │ │ │ ├── neon-saturating-rounding-shift.s.cs
+ │ │ │ │ ├── neon-saturating-shift.s.cs
+ │ │ │ │ ├── neon-scalar-abs.s.cs
+ │ │ │ │ ├── neon-scalar-add-sub.s.cs
+ │ │ │ │ ├── neon-scalar-by-elem-mla.s.cs
+ │ │ │ │ ├── neon-scalar-by-elem-mul.s.cs
+ │ │ │ │ ├── neon-scalar-by-elem-saturating-mla.s.cs
+ │ │ │ │ ├── neon-scalar-by-elem-saturating-mul.s.cs
+ │ │ │ │ ├── neon-scalar-compare.s.cs
+ │ │ │ │ ├── neon-scalar-cvt.s.cs
+ │ │ │ │ ├── neon-scalar-dup.s.cs
+ │ │ │ │ ├── neon-scalar-extract-narrow.s.cs
+ │ │ │ │ ├── neon-scalar-fp-compare.s.cs
+ │ │ │ │ ├── neon-scalar-mul.s.cs
+ │ │ │ │ ├── neon-scalar-neg.s.cs
+ │ │ │ │ ├── neon-scalar-recip.s.cs
+ │ │ │ │ ├── neon-scalar-reduce-pairwise.s.cs
+ │ │ │ │ ├── neon-scalar-rounding-shift.s.cs
+ │ │ │ │ ├── neon-scalar-saturating-add-sub.s.cs
+ │ │ │ │ ├── neon-scalar-saturating-rounding-shift.s.cs
+ │ │ │ │ ├── neon-scalar-saturating-shift.s.cs
+ │ │ │ │ ├── neon-scalar-shift-imm.s.cs
+ │ │ │ │ ├── neon-scalar-shift.s.cs
+ │ │ │ │ ├── neon-shift-left-long.s.cs
+ │ │ │ │ ├── neon-shift.s.cs
+ │ │ │ │ ├── neon-simd-copy.s.cs
+ │ │ │ │ ├── neon-simd-ldst-multi-elem.s.cs
+ │ │ │ │ ├── neon-simd-ldst-one-elem.s.cs
+ │ │ │ │ ├── neon-simd-misc.s.cs
+ │ │ │ │ ├── neon-simd-post-ldst-multi-elem.s.cs
+ │ │ │ │ ├── neon-simd-shift.s.cs
+ │ │ │ │ ├── neon-tbl.s.cs
+ │ │ │ │ └── trace-regs.s.cs
+ │ │ │ ├── ARM
+ │ │ │ │ ├── arm-aliases.s.cs
+ │ │ │ │ ├── arm-arithmetic-aliases.s.cs
+ │ │ │ │ ├── arm-it-block.s.cs
+ │ │ │ │ ├── arm-memory-instructions.s.cs
+ │ │ │ │ ├── arm-shift-encoding.s.cs
+ │ │ │ │ ├── arm-thumb-trustzone.s.cs
+ │ │ │ │ ├── arm-trustzone.s.cs
+ │ │ │ │ ├── arm_addrmode2.s.cs
+ │ │ │ │ ├── arm_addrmode3.s.cs
+ │ │ │ │ ├── arm_instructions.s.cs
+ │ │ │ │ ├── basic-arm-instructions-v8.s.cs
+ │ │ │ │ ├── basic-arm-instructions.s.cs
+ │ │ │ │ ├── basic-thumb-instructions.s.cs
+ │ │ │ │ ├── basic-thumb2-instructions-v8.s.cs
+ │ │ │ │ ├── basic-thumb2-instructions.s.cs
+ │ │ │ │ ├── crc32-thumb.s.cs
+ │ │ │ │ ├── crc32.s.cs
+ │ │ │ │ ├── dot-req.s.cs
+ │ │ │ │ ├── fp-armv8.s.cs
+ │ │ │ │ ├── idiv-thumb.s.cs
+ │ │ │ │ ├── idiv.s.cs
+ │ │ │ │ ├── load-store-acquire-release-v8-thumb.s.cs
+ │ │ │ │ ├── load-store-acquire-release-v8.s.cs
+ │ │ │ │ ├── mode-switch.s.cs
+ │ │ │ │ ├── neon-abs-encoding.s.cs
+ │ │ │ │ ├── neon-absdiff-encoding.s.cs
+ │ │ │ │ ├── neon-add-encoding.s.cs
+ │ │ │ │ ├── neon-bitcount-encoding.s.cs
+ │ │ │ │ ├── neon-bitwise-encoding.s.cs
+ │ │ │ │ ├── neon-cmp-encoding.s.cs
+ │ │ │ │ ├── neon-convert-encoding.s.cs
+ │ │ │ │ ├── neon-crypto.s.cs
+ │ │ │ │ ├── neon-dup-encoding.s.cs
+ │ │ │ │ ├── neon-minmax-encoding.s.cs
+ │ │ │ │ ├── neon-mov-encoding.s.cs
+ │ │ │ │ ├── neon-mul-accum-encoding.s.cs
+ │ │ │ │ ├── neon-mul-encoding.s.cs
+ │ │ │ │ ├── neon-neg-encoding.s.cs
+ │ │ │ │ ├── neon-pairwise-encoding.s.cs
+ │ │ │ │ ├── neon-reciprocal-encoding.s.cs
+ │ │ │ │ ├── neon-reverse-encoding.s.cs
+ │ │ │ │ ├── neon-satshift-encoding.s.cs
+ │ │ │ │ ├── neon-shift-encoding.s.cs
+ │ │ │ │ ├── neon-shiftaccum-encoding.s.cs
+ │ │ │ │ ├── neon-shuffle-encoding.s.cs
+ │ │ │ │ ├── neon-sub-encoding.s.cs
+ │ │ │ │ ├── neon-table-encoding.s.cs
+ │ │ │ │ ├── neon-v8.s.cs
+ │ │ │ │ ├── neon-vld-encoding.s.cs
+ │ │ │ │ ├── neon-vst-encoding.s.cs
+ │ │ │ │ ├── neon-vswp.s.cs
+ │ │ │ │ ├── neont2-abs-encoding.s.cs
+ │ │ │ │ ├── neont2-absdiff-encoding.s.cs
+ │ │ │ │ ├── neont2-add-encoding.s.cs
+ │ │ │ │ ├── neont2-bitcount-encoding.s.cs
+ │ │ │ │ ├── neont2-bitwise-encoding.s.cs
+ │ │ │ │ ├── neont2-cmp-encoding.s.cs
+ │ │ │ │ ├── neont2-convert-encoding.s.cs
+ │ │ │ │ ├── neont2-dup-encoding.s.cs
+ │ │ │ │ ├── neont2-minmax-encoding.s.cs
+ │ │ │ │ ├── neont2-mov-encoding.s.cs
+ │ │ │ │ ├── neont2-mul-accum-encoding.s.cs
+ │ │ │ │ ├── neont2-mul-encoding.s.cs
+ │ │ │ │ ├── neont2-neg-encoding.s.cs
+ │ │ │ │ ├── neont2-pairwise-encoding.s.cs
+ │ │ │ │ ├── neont2-reciprocal-encoding.s.cs
+ │ │ │ │ ├── neont2-reverse-encoding.s.cs
+ │ │ │ │ ├── neont2-satshift-encoding.s.cs
+ │ │ │ │ ├── neont2-shift-encoding.s.cs
+ │ │ │ │ ├── neont2-shiftaccum-encoding.s.cs
+ │ │ │ │ ├── neont2-shuffle-encoding.s.cs
+ │ │ │ │ ├── neont2-sub-encoding.s.cs
+ │ │ │ │ ├── neont2-table-encoding.s.cs
+ │ │ │ │ ├── neont2-vld-encoding.s.cs
+ │ │ │ │ ├── neont2-vst-encoding.s.cs
+ │ │ │ │ ├── simple-fp-encoding.s.cs
+ │ │ │ │ ├── thumb-fp-armv8.s.cs
+ │ │ │ │ ├── thumb-hints.s.cs
+ │ │ │ │ ├── thumb-neon-crypto.s.cs
+ │ │ │ │ ├── thumb-neon-v8.s.cs
+ │ │ │ │ ├── thumb-shift-encoding.s.cs
+ │ │ │ │ ├── thumb.s.cs
+ │ │ │ │ ├── thumb2-b.w-encodingT4.s.cs
+ │ │ │ │ ├── thumb2-branches.s.cs
+ │ │ │ │ ├── thumb2-mclass.s.cs
+ │ │ │ │ ├── thumb2-narrow-dp.ll.cs
+ │ │ │ │ ├── thumb2-pldw.s.cs
+ │ │ │ │ ├── vfp4-thumb.s.cs
+ │ │ │ │ ├── vfp4.s.cs
+ │ │ │ │ ├── vpush-vpop-thumb.s.cs
+ │ │ │ │ └── vpush-vpop.s.cs
+ │ │ │ ├── Mips
+ │ │ │ │ ├── hilo-addressing.s.cs
+ │ │ │ │ ├── micromips-alu-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-alu-instructions.s.cs
+ │ │ │ │ ├── micromips-branch-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-branch-instructions.s.cs
+ │ │ │ │ ├── micromips-expansions.s.cs
+ │ │ │ │ ├── micromips-jump-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-jump-instructions.s.cs
+ │ │ │ │ ├── micromips-loadstore-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-loadstore-instructions.s.cs
+ │ │ │ │ ├── micromips-loadstore-unaligned-EB.s.cs
+ │ │ │ │ ├── micromips-loadstore-unaligned.s.cs
+ │ │ │ │ ├── micromips-movcond-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-movcond-instructions.s.cs
+ │ │ │ │ ├── micromips-multiply-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-multiply-instructions.s.cs
+ │ │ │ │ ├── micromips-shift-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-shift-instructions.s.cs
+ │ │ │ │ ├── micromips-trap-instructions-EB.s.cs
+ │ │ │ │ ├── micromips-trap-instructions.s.cs
+ │ │ │ │ ├── mips-alu-instructions.s.cs
+ │ │ │ │ ├── mips-control-instructions-64.s.cs
+ │ │ │ │ ├── mips-control-instructions.s.cs
+ │ │ │ │ ├── mips-coprocessor-encodings.s.cs
+ │ │ │ │ ├── mips-dsp-instructions.s.cs
+ │ │ │ │ ├── mips-expansions.s.cs
+ │ │ │ │ ├── mips-fpu-instructions.s.cs
+ │ │ │ │ ├── mips-jump-instructions.s.cs
+ │ │ │ │ ├── mips-memory-instructions.s.cs
+ │ │ │ │ ├── mips-register-names.s.cs
+ │ │ │ │ ├── mips64-alu-instructions.s.cs
+ │ │ │ │ ├── mips64-instructions.s.cs
+ │ │ │ │ ├── mips64-register-names.s.cs
+ │ │ │ │ ├── mips_directives.s.cs
+ │ │ │ │ ├── nabi-regs.s.cs
+ │ │ │ │ ├── set-at-directive.s.cs
+ │ │ │ │ ├── test_2r.s.cs
+ │ │ │ │ ├── test_2rf.s.cs
+ │ │ │ │ ├── test_3r.s.cs
+ │ │ │ │ ├── test_3rf.s.cs
+ │ │ │ │ ├── test_bit.s.cs
+ │ │ │ │ ├── test_cbranch.s.cs
+ │ │ │ │ ├── test_ctrlregs.s.cs
+ │ │ │ │ ├── test_elm.s.cs
+ │ │ │ │ ├── test_elm_insert.s.cs
+ │ │ │ │ ├── test_elm_insve.s.cs
+ │ │ │ │ ├── test_i10.s.cs
+ │ │ │ │ ├── test_i5.s.cs
+ │ │ │ │ ├── test_i8.s.cs
+ │ │ │ │ ├── test_lsa.s.cs
+ │ │ │ │ ├── test_mi10.s.cs
+ │ │ │ │ └── test_vec.s.cs
+ │ │ │ ├── PowerPC
+ │ │ │ │ ├── ppc64-encoding-bookII.s.cs
+ │ │ │ │ ├── ppc64-encoding-bookIII.s.cs
+ │ │ │ │ ├── ppc64-encoding-ext.s.cs
+ │ │ │ │ ├── ppc64-encoding-fp.s.cs
+ │ │ │ │ ├── ppc64-encoding-vmx.s.cs
+ │ │ │ │ ├── ppc64-encoding.s.cs
+ │ │ │ │ └── ppc64-operands.s.cs
+ │ │ │ ├── README
+ │ │ │ ├── Sparc
+ │ │ │ │ ├── sparc-alu-instructions.s.cs
+ │ │ │ │ ├── sparc-atomic-instructions.s.cs
+ │ │ │ │ ├── sparc-ctrl-instructions.s.cs
+ │ │ │ │ ├── sparc-fp-instructions.s.cs
+ │ │ │ │ ├── sparc-mem-instructions.s.cs
+ │ │ │ │ ├── sparc-vis.s.cs
+ │ │ │ │ ├── sparc64-alu-instructions.s.cs
+ │ │ │ │ ├── sparc64-ctrl-instructions.s.cs
+ │ │ │ │ ├── sparcv8-instructions.s.cs
+ │ │ │ │ └── sparcv9-instructions.s.cs
+ │ │ │ ├── SystemZ
+ │ │ │ │ ├── insn-good-z196.s.cs
+ │ │ │ │ ├── insn-good.s.cs
+ │ │ │ │ └── regs-good.s.cs
+ │ │ │ └── X86
+ │ │ │ ├── 3DNow.s.cs
+ │ │ │ ├── address-size.s.cs
+ │ │ │ ├── avx512-encodings.s.cs
+ │ │ │ ├── intel-syntax-encoding.s.cs
+ │ │ │ ├── x86-32-avx.s.cs
+ │ │ │ ├── x86-32-fma3.s.cs
+ │ │ │ ├── x86-32-ms-inline-asm.s.cs
+ │ │ │ ├── x86_64-avx-clmul-encoding.s.cs
+ │ │ │ ├── x86_64-avx-encoding.s.cs
+ │ │ │ ├── x86_64-bmi-encoding.s.cs
+ │ │ │ ├── x86_64-encoding.s.cs
+ │ │ │ ├── x86_64-fma3-encoding.s.cs
+ │ │ │ ├── x86_64-fma4-encoding.s.cs
+ │ │ │ ├── x86_64-hle-encoding.s.cs
+ │ │ │ ├── x86_64-imm-widths.s.cs
+ │ │ │ ├── x86_64-rand-encoding.s.cs
+ │ │ │ ├── x86_64-rtm-encoding.s.cs
+ │ │ │ ├── x86_64-sse4a.s.cs
+ │ │ │ ├── x86_64-tbm-encoding.s.cs
+ │ │ │ └── x86_64-xop-encoding.s.cs
+ │ │ ├── README
+ │ │ ├── arm
+ │ │ │ ├── Makefile
+ │ │ │ └── test_arm_regression.c
+ │ │ ├── autogen_x86imm.py
+ │ │ ├── benchmark
+ │ │ │ ├── Makefile
+ │ │ │ └── test_iter_benchmark.c
+ │ │ ├── benchmark.py
+ │ │ ├── capstone_get_setup.c
+ │ │ ├── compile_all.sh
+ │ │ ├── disasm_mc.py
+ │ │ ├── disasm_mc.sh
+ │ │ ├── fuzz
+ │ │ │ ├── Makefile
+ │ │ │ ├── README
+ │ │ │ ├── driverbin.c
+ │ │ │ ├── drivermc.c
+ │ │ │ ├── fuzz_diff.c
+ │ │ │ ├── fuzz_disasm.c
+ │ │ │ ├── fuzz_disasm.options
+ │ │ │ ├── fuzz_harness.c
+ │ │ │ ├── fuzz_llvm.cpp
+ │ │ │ └── onefile.c
+ │ │ ├── fuzz.py
+ │ │ ├── patch_major_os_version.py
+ │ │ ├── ppcbranch.py
+ │ │ ├── python_capstone_setup.py
+ │ │ ├── regress
+ │ │ │ ├── LICENSE
+ │ │ │ ├── Makefile
+ │ │ │ ├── invalid_read_in_print_operand.c
+ │ │ │ └── regress.py
+ │ │ ├── regress.py
+ │ │ ├── test_all.sh
+ │ │ ├── test_c.sh
+ │ │ ├── test_corpus.py
+ │ │ ├── test_group_name.py
+ │ │ ├── test_mc.py
+ │ │ ├── test_mc.sh
+ │ │ ├── test_python.sh
+ │ │ ├── x86
+ │ │ │ ├── README
+ │ │ │ └── verify
+ │ │ │ └── README
+ │ │ └── x86odd.py
+ │ ├── tests
+ │ │ ├── Makefile
+ │ │ ├── README
+ │ │ ├── test_arm.c
+ │ │ ├── test_arm64.c
+ │ │ ├── test_basic.c
+ │ │ ├── test_customized_mnem.c
+ │ │ ├── test_detail.c
+ │ │ ├── test_evm.c
+ │ │ ├── test_iter.c
+ │ │ ├── test_m680x.c
+ │ │ ├── test_m68k.c
+ │ │ ├── test_mips.c
+ │ │ ├── test_ppc.c
+ │ │ ├── test_skipdata.c
+ │ │ ├── test_sparc.c
+ │ │ ├── test_systemz.c
+ │ │ ├── test_tms320c64x.c
+ │ │ ├── test_winkernel.cpp
+ │ │ ├── test_x86.c
+ │ │ └── test_xcore.c
+ │ ├── utils.c
+ │ ├── utils.h
+ │ ├── windows
+ │ │ ├── README
+ │ │ ├── winkernel_mm.c
+ │ │ └── winkernel_mm.h
+ │ ├── windowsce
+ │ │ ├── COMPILE.md
+ │ │ ├── make_windowsce7-armv7.bat
+ │ │ └── make_windowsce8-armv7.bat
+ │ └── xcode
+ │ ├── Capstone.xcodeproj
+ │ │ ├── project.pbxproj
+ │ │ ├── project.xcworkspace
+ │ │ │ └── contents.xcworkspacedata
+ │ │ └── xcshareddata
+ │ │ └── xcschemes
+ │ │ ├── Dynamic Library.xcscheme
+ │ │ ├── Framework.xcscheme
+ │ │ ├── Static Library.xcscheme
+ │ │ └── Tests.xcscheme
+ │ ├── CapstoneFramework
+ │ │ ├── Info.plist
+ │ │ └── module.modulemap
+ │ └── README.md
+ └── fmt
+ ├── CMakeLists.txt
+ ├── CONTRIBUTING.md
+ ├── ChangeLog.md
+ ├── LICENSE
+ ├── README.md
+ ├── include
+ │ └── fmt
+ │ ├── args.h
+ │ ├── base.h
+ │ ├── chrono.h
+ │ ├── color.h
+ │ ├── compile.h
+ │ ├── core.h
+ │ ├── format-inl.h
+ │ ├── format.h
+ │ ├── os.h
+ │ ├── ostream.h
+ │ ├── printf.h
+ │ ├── ranges.h
+ │ ├── std.h
+ │ └── xchar.h
+ └── src
+ ├── fmt.cc
+ ├── format.cc
+ └── os.cc
+
+```
+
+`LICENSE`:
+
+```
+MIT License
+
+Copyright (c) 2021 Axel Souchet
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+```
+
+`README.md`:
+
+```md
+# rp++: a fast ROP gadget finder for PE/ELF/Mach-O x86/x64/ARM/ARM64 binaries
+
+
+
+## Overview
+
+**rp++** or **rp** is a C++ [ROP](https://en.wikipedia.org/wiki/Return-oriented_programming) gadget finder for [PE](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format)/[ELF](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)/[Mach-O](https://en.wikipedia.org/wiki/Mach-O) executables and x86/x64/ARM/ARM64 architectures.
+
+
+
+
+
+## Finding ROP gadgets
+
+To find ROP gadget you need to specify a file with the `--file` / `-f` option and use the `--rop` / `-r` option specifying the maximum the number of instructions in the gadget:
+
+
+
+
+
+You can customize the base address of the module with the `--va` option (if you pass a base of `0`, then you get relative offsets) and you can also use the `--raw` option to analyze raw code dumps.
+
+## Finding pointers
+
+Oftentimes when building ROP chains, you might need to find pointers to integers with specific values. To look for those, you can use the `--search-int` option like in the below:
+
+
+
+
+
+Other times, you might need to find pointers to specific strings. To look for those, you can use the `--search-hexa` option like in the below:
+
+
+
+
+
+You can also use the `--va` option to specify your own base address.
+
+## Build
+
+You can find shell scripts in [src/build](src/build) for every supported platforms; below is the Linux example:
+
+```
+src/build$ chmod u+x ./build-release.sh && ./build-release.sh
+-- The C compiler identification is GNU 9.3.0
+-- The CXX compiler identification is GNU 9.3.0
+[...]
+[16/16] Linking CXX executable rp-lin-x64
+```
+
+## Authors
+
+* Axel '[0vercl0k](https://twitter.com/0vercl0k)' Souchet
+
+```
+
+`src/CMakeLists.txt`:
+
+```txt
+# Axel '0vercl0k' Souchet - January 13 2022
+cmake_minimum_required(VERSION 3.16.0)
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
+set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+
+project(rp++)
+include_directories(${CMAKE_CURRENT_LIST_DIR}/third_party/fmt/include)
+include_directories(${CMAKE_CURRENT_LIST_DIR}/third_party/beaengine/include)
+include_directories(${CMAKE_CURRENT_LIST_DIR}/third_party/capstone/include)
+include_directories(${CMAKE_CURRENT_LIST_DIR}/third_party/CLI11)
+
+add_compile_definitions(FMT_HEADER_ONLY FMT_UNICODE=0 BEA_ENGINE_STATIC CAPSTONE_HAS_ARM CAPSTONE_HAS_ARM64 CAPSTONE_USE_SYS_DYN_MEM)
+
+if(WIN32)
+ set(RP_PLAT "win")
+ add_compile_definitions(NOMINMAX)
+ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>")
+elseif(UNIX)
+ if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
+ set(RP_PLAT "fbsd")
+ elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
+ set(RP_PLAT "osx")
+ else()
+ set(RP_PLAT "lin")
+ endif()
+ endif()
+
+set(RP_PLAT "rp-${RP_PLAT}")
+
+file(
+ GLOB
+ rp_files
+ rp/*.cpp
+ third_party/capstone/arch/AArch64/*.c
+ third_party/capstone/arch/ARM/*.c
+ third_party/capstone/*.c
+)
+
+add_executable(
+ ${RP_PLAT}
+ ${rp_files}
+ "third_party/beaengine/src/BeaEngine.c"
+)
+
+if(UNIX)
+ find_package(Threads)
+ target_link_libraries(${RP_PLAT} ${CMAKE_THREAD_LIBS_INIT})
+ if(${RP_PLAT} STREQUAL "rp-osx")
+ else()
+ target_link_libraries(${RP_PLAT} -static)
+ endif()
+endif()
+
+```
+
+`src/rp/arm.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include "cpu.hpp"
+
+#include "disassenginewrapper.hpp"
+#include "ropsearch_algorithm.hpp"
+#include "rpexception.hpp"
+#include
+#include
+
+class ArmCapstone : public DisassEngineWrapper {
+public:
+ explicit ArmCapstone(const uint32_t thumb_mode) : is_thumb(true) {
+ cs_mode mode = CS_MODE_THUMB;
+ if (thumb_mode == 0) {
+ mode = CS_MODE_ARM;
+ is_thumb = false;
+ }
+
+ if (cs_open(CS_ARCH_ARM, mode, &m_handle) != CS_ERR_OK) {
+ RAISE_EXCEPTION("Apparently no support for ARM in capstone.lib");
+ }
+
+ cs_option(m_handle, CS_OPT_DETAIL, CS_OPT_ON);
+ }
+
+ ~ArmCapstone() override { cs_close(&m_handle); }
+ InstructionInformation disass(const uint8_t *data, uint64_t len,
+ const uint64_t vaddr,
+ DisassEngineReturn &ret) override {
+ cs_insn *insn = nullptr;
+ const size_t count =
+ cs_disasm(m_handle, data, size_t(len), vaddr, 1, &insn);
+ if (count != 1) {
+ ret = UnknownInstruction;
+ return {};
+ }
+
+ std::string mnemonic(insn[0].mnemonic);
+ InstructionInformation instr;
+ instr.address = uintptr_t(data);
+ instr.virtual_address_in_memory = uintptr_t(vaddr);
+ instr.disassembly = mnemonic + ' ' + std::string(insn[0].op_str);
+ instr.size = insn[0].size;
+ ret = AllRight;
+
+ if (insn[0].detail == nullptr) {
+ cs_free(insn, count);
+ return instr;
+ }
+
+ if (cs_insn_group(m_handle, insn, ARM_GRP_JUMP)) {
+ instr.is_branch = true;
+ instr.is_valid_ending_instr =
+ insn[0].detail->arm.op_count == 1 &&
+ insn[0].detail->arm.operands[0].type != ARM_OP_IMM;
+ } else if (mnemonic == "b" || mnemonic == "bl" || mnemonic == "blx" ||
+ mnemonic == "cb" || mnemonic == "cbz") {
+ instr.is_branch = true;
+ } else if (mnemonic == "swi" || mnemonic == "svc") {
+ instr.is_branch = true;
+ instr.is_valid_ending_instr = true;
+ } else if (mnemonic == "mov" && insn[0].detail->arm.op_count >= 1 &&
+ insn[0].detail->arm.operands[0].type == ARM_OP_REG &&
+ insn[0].detail->arm.operands[0].reg == ARM_REG_PC) {
+ instr.is_branch = true;
+ instr.is_valid_ending_instr = true;
+ } else if (mnemonic == "bx") {
+ instr.is_branch = true;
+ instr.is_valid_ending_instr =
+ insn[0].detail->arm.operands[0].type == ARM_OP_REG;
+ } else if (mnemonic == "blx") {
+ instr.is_branch = true;
+ instr.is_valid_ending_instr = true;
+ } else if (mnemonic == "pop") {
+ bool has_pc = false;
+ for (size_t i = 0; i < insn[0].detail->arm.op_count; ++i) {
+ if (insn[0].detail->arm.operands[i].type == ARM_OP_REG &&
+ insn[0].detail->arm.operands[i].reg == ARM_REG_PC) {
+ has_pc = true;
+ break;
+ }
+ }
+
+ if (has_pc) {
+ instr.is_branch = true;
+ instr.is_valid_ending_instr = true;
+ }
+ }
+
+ cs_free(insn, count);
+ return instr;
+ }
+
+ uint32_t get_size_biggest_instruction() const override { return 4; }
+
+ uint32_t get_alignement() const override {
+ if (is_thumb) {
+ return 2;
+ }
+
+ return 4;
+ }
+
+private:
+ csh m_handle = {};
+ bool is_thumb = false;
+};
+
+class ARM : public CPU {
+public:
+ std::string get_class_name() const override { return "ARM"; }
+
+ void find_gadget_in_memory(const std::vector &p_memory,
+ const uint64_t vaddr, const uint32_t depth,
+ GadgetMultiset &gadgets,
+ uint32_t disass_engine_options,
+ std::mutex &m) override {
+ ArmCapstone capstone_engine(disass_engine_options);
+ find_rop_gadgets(p_memory, vaddr, depth, gadgets, capstone_engine, m);
+ }
+};
+
+```
+
+`src/rp/arm64.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - February 7 2022
+#pragma once
+
+#include "cpu.hpp"
+
+#include "disassenginewrapper.hpp"
+#include "ropsearch_algorithm.hpp"
+#include "rpexception.hpp"
+#include
+#include
+
+class Arm64Capstone : public DisassEngineWrapper {
+public:
+ Arm64Capstone() {
+ if (cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &m_handle) != CS_ERR_OK) {
+ RAISE_EXCEPTION("Apparently no support for ARM64 in capstone.lib");
+ }
+
+ cs_option(m_handle, CS_OPT_DETAIL, CS_OPT_ON);
+ }
+
+ ~Arm64Capstone() override { cs_close(&m_handle); }
+ InstructionInformation disass(const uint8_t *data, uint64_t len,
+ const uint64_t vaddr,
+ DisassEngineReturn &ret) override {
+ cs_insn *insn = nullptr;
+ const size_t count =
+ cs_disasm(m_handle, data, size_t(len), vaddr, 1, &insn);
+ if (count != 1) {
+ ret = UnknownInstruction;
+ return {};
+ }
+
+ std::string mnemonic(insn[0].mnemonic);
+ InstructionInformation instr;
+ instr.address = uintptr_t(data);
+ instr.virtual_address_in_memory = uintptr_t(vaddr);
+ instr.disassembly = mnemonic + ' ' + std::string(insn[0].op_str);
+ instr.size = insn[0].size;
+ ret = AllRight;
+
+ if (insn[0].detail == nullptr) {
+ cs_free(insn, count);
+ std::abort();
+ }
+
+ const bool Jump = cs_insn_group(m_handle, insn, ARM64_GRP_JUMP);
+ const bool Call = cs_insn_group(m_handle, insn, ARM64_GRP_CALL);
+ const bool Ret = cs_insn_group(m_handle, insn, ARM64_GRP_RET);
+ const bool Int = cs_insn_group(m_handle, insn, ARM64_GRP_INT);
+ instr.is_branch = Jump || Call || Ret || Int;
+ instr.is_valid_ending_instr =
+ Ret || Int ||
+ ((Jump || Call) && insn[0].detail->arm64.op_count == 1 &&
+ insn[0].detail->arm64.operands[0].type != ARM64_OP_IMM);
+
+ cs_free(insn, count);
+ return instr;
+ }
+
+ uint32_t get_size_biggest_instruction() const override { return 4; }
+
+ uint32_t get_alignement() const override { return 4; }
+
+private:
+ csh m_handle = {};
+};
+
+class ARM64 : public CPU {
+public:
+ std::string get_class_name() const override { return "ARM64"; }
+
+ void find_gadget_in_memory(const std::vector &p_memory,
+ const uint64_t vaddr, const uint32_t depth,
+ GadgetMultiset &gadgets,
+ uint32_t disass_engine_options,
+ std::mutex &m) override {
+ Arm64Capstone capstone_engine;
+ find_rop_gadgets(p_memory, vaddr, depth, gadgets, capstone_engine, m);
+ }
+};
+
+```
+
+`src/rp/coloshell.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include "platform.h"
+#include "rpexception.hpp"
+#include
+#include
+
+#ifdef WINDOWS
+#include
+#endif
+
+static bool g_colors_desired = false;
+
+// Here you will find all you need to display the data in a cute way on a
+// windows/unix terminal
+
+#ifdef WINDOWS
+enum Colors {
+ COLO_RED = FOREGROUND_RED | FOREGROUND_INTENSITY,
+ COLO_GREEN = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+ COLO_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
+ COLO_DEFAULT = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
+};
+
+#else
+enum Colors { COLO_RED = 0, COLO_GREEN = 1, COLO_YELLOW = 2, COLO_DEFAULT = 3 };
+
+#endif
+
+inline bool g_are_colors_enabled() { return g_colors_desired; }
+
+/**
+ * \fn static void enable_color_(const Colors colo)
+ * \brief Enable a color in your shell
+ *
+ * \param colo: the color you want to activate
+ */
+static inline void enable_color_(const Colors colo) {
+#ifdef WINDOWS
+ HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hStdOutput == INVALID_HANDLE_VALUE) {
+ RAISE_EXCEPTION("Cannot find a STD_OUTPUT_HANDLE valid value");
+ }
+
+ SetConsoleTextAttribute(hStdOutput, uint16_t(colo));
+#else
+ const char *colors[] = {"\x1b[91m", "\x1b[92m", "\x1b[93m", "\x1b[0m"};
+ fmt::print("{}", colors[colo]);
+#endif
+}
+
+/**
+ * \fn static void enable_color(const Colors colo)
+ * \brief Enable a color in your shell
+ *
+ * \param colo: the color you want to activate
+ */
+static inline void enable_color(const Colors colo) {
+ if (!g_are_colors_enabled()) {
+ return;
+ }
+
+ enable_color_(colo);
+}
+
+/**
+ * \fn static void disable_color_(const Colors colo)
+ * \brief Unset the color you have previously set
+ */
+static void disable_color_() {
+#ifdef WINDOWS
+ HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hStdOutput == INVALID_HANDLE_VALUE) {
+ RAISE_EXCEPTION("Cannot find a STD_OUTPUT_HANDLE valid value");
+ }
+
+ SetConsoleTextAttribute(hStdOutput, COLO_DEFAULT);
+#else
+ const char *colors[]{"\x1b[91m", "\x1b[92m", "\x1b[93m", "\x1b[0m"};
+ fmt::print("{}", colors[COLO_DEFAULT]);
+#endif
+}
+
+/**
+ * \fn static void disable_color_(const Colors colo)
+ * \brief Unset the color you have previously set
+ */
+static inline void disable_color() {
+ if (!g_are_colors_enabled()) {
+ return;
+ }
+
+ disable_color_();
+}
+
+/**
+ * \fn static void coloshell(const T t, const Colors colo)
+ * \brief Display "t" on the stdout with the color "colo"
+ *
+ * \param t: the thing you want to output
+ * \param colo: the color you want to enable
+ */
+template static void coloshell(const T t, const Colors colo) {
+ enable_color(colo);
+ fmt::print("{}", t);
+ disable_color();
+}
+
+/**
+ * \def w_red(text)
+ * Display text in red on stdout
+ *
+ * \param text: the text you want to display
+ */
+#define w_red(text) \
+ { \
+ coloshell(text, COLO_RED); \
+ }
+
+/**
+ * \def w_yel(text)
+ * Display text in yellow on stdout
+ *
+ * \param text: the text you want to display
+ */
+#define w_yel(text) \
+ { \
+ coloshell(text, COLO_YELLOW); \
+ }
+
+/**
+ * \def w_gre(text)
+ * Display text in green on stdout
+ *
+ * \param text: the text you want to display
+ */
+#define w_gre(text) \
+ { \
+ coloshell(text, COLO_GREEN); \
+ }
+
+/**
+ * \def w_red_lf(text)
+ * Display text in red on stdout with a line feed
+ *
+ * \param text: the text you want to display
+ */
+#define w_red_lf(text) \
+ { \
+ w_red(text); \
+ fmt::print("\n"); \
+ }
+
+/**
+ * \def w_yel_lf(text)
+ * Display text in yellow on stdout with a line feed
+ *
+ * \param text: the text you want to display
+ */
+#define w_yel_lf(text) \
+ { \
+ w_yel(text); \
+ fmt::print("\n"); \
+ }
+
+/**
+ * \def w_gre_lf(text)
+ * Display text in green on stdout with a line feed
+ *
+ * \param text: the text you want to display
+ */
+#define w_gre_lf(text) \
+ { \
+ w_gre_lf(text); \
+ fmt::print("\n"); \
+ }
+
+/**
+ * \def display_hex_field(field, n)
+ * Display an hex value in red with 0 filling etc.
+ *
+ * \param field: It is the hex value you want to output
+ * \param n: It is the size of the column
+ */
+#define display_hex_field(field, n) \
+ { \
+ fmt::print("{:{}}: ", #field, n); \
+ enable_color(COLO_RED); \
+ fmt::print("0x{:0{}x} ", field, sizeof(field) * 2); \
+ disable_color(); \
+ }
+
+/**
+ * \def display_hex_field_lf(field, n)
+ * Display an hex value in red with 0 filling, a line feed and 25b column.
+ *
+ * \param field: It is the hex value you want to output
+ */
+#define display_hex_field_lf(field) \
+ { \
+ display_hex_field(field, 25); \
+ fmt::print("\n"); \
+ }
+
+/**
+ * \def display_hex_2fields_lf(field1, field2)
+ * Display two hex values in red on a same line.
+ *
+ * \param field1: It is the first hex value you want to output
+ * \param field2: It is the second hex value you want to output
+ */
+#define display_hex_2fields_lf(field1, field2) \
+ { \
+ display_hex_field(field1, 25); \
+ display_hex_field(field2, 25); \
+ fmt::print("\n"); \
+ }
+
+/**
+ * \def display_short_hex_field(field)
+ * Display a short hex value in red.
+ *
+ * \param field: It is the short hex value you want to output
+ */
+#define display_short_hex_field(field) \
+ { \
+ display_hex_field(field, 14); \
+ }
+
+/**
+ * \def display_short_hex_field_lf(field)
+ * Display a short hex value in red with a line feed.
+ *
+ * \param field: It is the short hex value you want to output
+ */
+#define display_short_hex_field_lf(field) \
+ { \
+ display_short_hex_field(field); \
+ fmt::print("\n"); \
+ }
+
+/**
+ * \def display_short_hex_2fields_lf(field1, field2)
+ * Display two short hex values in red with a line feed.
+ *
+ * \param field1: It is the first short hex value you want to output
+ * \param field2: It is the second short hex value you want to output
+ */
+#define display_short_hex_2fields_lf(field1, field2) \
+ { \
+ display_short_hex_field(field1); \
+ display_short_hex_field(field2); \
+ fmt::print("\n"); \
+ }
+
+/**
+ * \def display_gadget_lf(va, gadget)
+ * Display a gadget with a line feed and its VA.
+ *
+ * \param va: It is the gadget VA
+ * \param gadget: It is the gadget you want to output
+ */
+#define display_gadget_lf(va, gadget) \
+ { \
+ enable_color(COLO_RED); \
+ fmt::print("0x{:x}", va); \
+ disable_color(); \
+ fmt::print(": "); \
+ enable_color(COLO_GREEN); \
+ (gadget).print_disassembly(); \
+ if (g_opts.print_bytes) { \
+ fmt::print(" "); \
+ (gadget).print_bytes(); \
+ } \
+ fmt::print(" ({} found)\n", (gadget).get_nb()); \
+ disable_color(); \
+ }
+
+/**
+ * \def display_gadget_lf_badbytes(va, gadget)
+ * Display a gadget with a line feed and its VA.
+ *
+ * \param va: It is the gadget VA
+ * \param gadget: It is the gadget you want to output
+ */
+#define display_gadget_lf_badbytes(va, gadget) \
+ { \
+ if (!does_badbytes_filter_apply(va, badbyte_list)) { \
+ display_gadget_lf(va, gadget); \
+ } else { \
+ nb_gadgets_filtered++; \
+ } \
+ }
+
+/**
+ * \def display_offset_lf(va, hex_val, size)
+ * Display an offset with a line feed and the hex values.
+ *
+ * \param va: It is the gadget VA
+ * \param hex_val: It is the hex values
+ * \param size: It is the size of the hex values
+ */
+#define display_offset_lf(va, hex_val, size) \
+ { \
+ enable_color(COLO_RED); \
+ fmt::print("0x{:x}", va); \
+ disable_color(); \
+ fmt::print(": "); \
+ enable_color(COLO_GREEN); \
+ for (uint32_t i = 0; i < size; ++i) { \
+ if (isprint(hex_val[i])) { \
+ fmt::print("{:c}", hex_val[i]); \
+ } else { \
+ fmt::print("\\x{:02x}", hex_val[i]); \
+ } \
+ } \
+ fmt::print("\n"); \
+ disable_color(); \
+ }
+
+```
+
+`src/rp/cpu.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include "gadget.hpp"
+#include
+#include
+#include
+
+/*! \class CPU
+ *
+ * A CPU is an important class that compose a part of the Program class.
+ */
+class CPU {
+public:
+ virtual ~CPU() = default;
+
+ /*!
+ * \brief Obtain the name of the class (useful when you use the polymorphism)
+ *
+ * \return the name of the class
+ */
+ virtual std::string get_class_name() const = 0;
+
+ /*!
+ * \brief Each CPU class is able to find all gadgets in [p_memory,
+ * p_memory+size] NB: The vaddr field is actually used by the BeaEngine when
+ * it disassembles something like jmp instruction, it needs the original
+ * virtual address to give you disassemble correctly (indeed jmp instruction
+ * are relative)
+ *
+ * \param p_memory: It is a pointer on the memory where you want to find rop
+ * gadget \param size: It is the size of the p_memory \param vaddr: It is the
+ * real virtual address of the memory which will be disassembled (see the
+ * previous remark) \param depth: It is the number of maximum instructions
+ * contained by a gadget \param gadgets: A list of the Gadget instance \param
+ * disass_engine_options: Options you want to pass to the disassembly engine
+ *
+ */
+ virtual void find_gadget_in_memory(const std::vector &p_memory,
+ const uint64_t vaddr, const uint32_t depth,
+ GadgetMultiset &gadgets,
+ uint32_t disass_engine_options,
+ std::mutex &m) = 0;
+
+ /*! The different architectures RP++ handles */
+ enum E_CPU {
+ CPU_x86, /*!< x86 */
+ CPU_x64, /*!< x64 */
+ CPU_ARM, /*!< ARM */
+ CPU_ARM64, /*!< ARM64 */
+ CPU_UNKNOWN /*!< unknown cpu */
+ };
+};
+
+```
+
+`src/rp/disassenginewrapper.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include
+#include
+#include
+
+struct InstructionInformation {
+ std::string disassembly;
+ std::string mnemonic;
+ uint32_t size = 0;
+ uintptr_t address = 0;
+ uintptr_t virtual_address_in_memory = 0;
+ std::vector bytes;
+ bool is_branch = false;
+ bool is_valid_ending_instr = false;
+};
+
+enum DisassEngineReturn { UnknownInstruction, OutOfBlock, AllRight };
+
+class DisassEngineWrapper {
+public:
+ DisassEngineWrapper() = default;
+ virtual ~DisassEngineWrapper() = default;
+
+ DisassEngineWrapper(const DisassEngineWrapper &) = delete;
+ DisassEngineWrapper &operator=(const DisassEngineWrapper &) = delete;
+ DisassEngineWrapper(DisassEngineWrapper &&) = delete;
+ DisassEngineWrapper &operator=(DisassEngineWrapper &&) = delete;
+
+ virtual InstructionInformation disass(const uint8_t *data, uint64_t len,
+ const uint64_t vaddr,
+ DisassEngineReturn &ret) = 0;
+ virtual uint32_t get_size_biggest_instruction() const = 0;
+ virtual uint32_t get_alignement() const = 0;
+};
+
+```
+
+`src/rp/elf.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include "executable_format.hpp"
+
+#include "arm.hpp"
+#include "arm64.hpp"
+#include "elf_struct.hpp"
+#include "rpexception.hpp"
+#include "x64.hpp"
+#include "x86.hpp"
+
+class Elf : public ExecutableFormat {
+public:
+ std::unique_ptr get_cpu(std::ifstream &file) override {
+ CPU::E_CPU cpu_type = extract_information_from_binary(file);
+ switch (cpu_type) {
+ case CPU::CPU_x86: {
+ return std::make_unique();
+ }
+
+ case CPU::CPU_x64: {
+ return std::make_unique();
+ }
+
+ case CPU::CPU_ARM: {
+ return std::make_unique();
+ }
+
+ case CPU::CPU_ARM64: {
+ return std::make_unique();
+ }
+
+ default: {
+ RAISE_EXCEPTION("Cannot determine the CPU type");
+ }
+ }
+ }
+
+ void display_information(const VerbosityLevel lvl) const override {
+ ExecutableFormat::display_information(lvl);
+ fmt::print("Elf Information:\n");
+ m_ELFLayout->display(lvl);
+ }
+
+ std::string get_class_name() const override { return "Elf"; }
+
+ std::vector
+ get_executables_section(std::ifstream &file,
+ const uint64_t base) const override {
+ return m_ELFLayout->get_executable_section(file, base);
+ }
+
+ uint64_t get_image_base_address() const override {
+ return m_ELFLayout->get_image_base_address();
+ }
+
+private:
+ CPU::E_CPU extract_information_from_binary(std::ifstream &file) override {
+ uint32_t size_init = 0;
+ std::array buf;
+ CPU::E_CPU cpu = CPU::CPU_UNKNOWN;
+ fmt::print("Loading ELF information..\n");
+
+ std::streampos off = file.tellg();
+ file.seekg(0, std::ios::beg);
+ file.read((char *)buf.data(), EI_NIDENT);
+
+ switch (buf.at(EI_CLASS)) {
+ case ELFCLASS32: {
+ size_init = 4;
+ break;
+ }
+
+ case ELFCLASS64: {
+ size_init = 8;
+ break;
+ }
+
+ default: {
+ RAISE_EXCEPTION("Cannot determine the architecture size");
+ }
+ }
+
+ if (size_init == 8) {
+ init_properly_ELFLayout();
+ } else {
+ init_properly_ELFLayout();
+ }
+
+ // Filling the structure now
+ m_ELFLayout->fill_structures(file);
+
+ // Set correctly the pointer
+ file.seekg(off);
+
+ switch (m_ELFLayout->get_cpu()) {
+ case RP_ELFEM_386: {
+ cpu = CPU::CPU_x86;
+ break;
+ }
+
+ case RP_ELFEM_X86_64: {
+ cpu = CPU::CPU_x64;
+ break;
+ }
+
+ case RP_ELFEM_ARM: {
+ cpu = CPU::CPU_ARM;
+ break;
+ }
+
+ case RP_ELFEM_ARM64: {
+ cpu = CPU::CPU_ARM64;
+ break;
+ }
+
+ default: {
+ RAISE_EXCEPTION("Cannot determine the CPU type");
+ }
+ }
+
+ return cpu;
+ }
+
+ template void init_properly_ELFLayout() {
+ m_ELFLayout = std::make_unique>();
+ if (m_ELFLayout == nullptr) {
+ RAISE_EXCEPTION("m_ELFLayout allocation failed");
+ }
+ }
+
+ std::unique_ptr m_ELFLayout;
+};
+
+```
+
+`src/rp/elf_struct.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include "coloshell.hpp"
+#include "platform.h"
+#include "rpexception.hpp"
+#include "section.hpp"
+#include "toolbox.hpp"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+const uint32_t EI_NIDENT = 16;
+
+#ifdef WINDOWS
+#pragma pack(push)
+#pragma pack(1)
+#endif
+
+template struct Elf_Ehdr {
+ std::array e_ident;
+ uint16_t e_type;
+ uint16_t e_machine;
+ uint32_t e_version;
+ T e_entry;
+ T e_phoff;
+ T e_shoff;
+ uint32_t e_flags;
+ uint16_t e_ehsize;
+ uint16_t e_phentsize;
+ uint16_t e_phnum;
+ uint16_t e_shentsize;
+ uint16_t e_shnum;
+ uint16_t e_shstrndx;
+
+ void display(VerbosityLevel lvl = VERBOSE_LEVEL_1) const {
+ w_yel_lf("-> ELF_Ehdr:");
+
+ display_short_hex_field_lf(e_phoff);
+ display_short_hex_field_lf(e_shoff);
+
+ display_short_hex_field_lf(e_flags);
+
+ display_short_hex_2fields_lf(e_phentsize, e_phnum);
+ display_short_hex_2fields_lf(e_shentsize, e_shnum);
+ display_short_hex_2fields_lf(e_shstrndx, e_ehsize);
+ }
+}
+#ifdef LINUX
+__attribute__((packed))
+#endif
+;
+
+using Elf32_Ehdr = Elf_Ehdr;
+using Elf64_Ehdr = Elf_Ehdr;
+
+const uint32_t EI_OSABI = 7;
+const uint32_t EI_CLASS = 4;
+const uint32_t ELFCLASS32 = 1;
+const uint32_t ELFCLASS64 = 2;
+
+template struct Elf_Phdr {
+}
+#ifdef LINUX
+__attribute__((packed))
+#endif
+;
+
+static std::string type_to_str(const uint32_t p_type) {
+ switch (p_type) {
+ case 0: {
+ return "NULL";
+ }
+
+ case 1: {
+ return "LOAD";
+ }
+
+ case 2: {
+ return "DYNAMIC";
+ }
+
+ case 3: {
+ return "INTERP";
+ }
+
+ case 4: {
+ return "NOTE";
+ }
+
+ case 5: {
+ return "SHLIB";
+ }
+
+ case 6: {
+ return "PHDR";
+ }
+
+ case 7: {
+ return "TLS";
+ }
+
+ case 8: {
+ return "NUM";
+ }
+
+ case 0x60000000: {
+ return "LOOS";
+ }
+
+ case 0x6fffffff: {
+ return "HIOS";
+ }
+
+ case 0x70000000: {
+ return "LOPROC";
+ }
+
+ case 0x7fffffff: {
+ return "HIPROC";
+ }
+
+ case 0x6474e550: {
+ return "EH_FRAME";
+ }
+
+ case 0x6474e551: {
+ return "STACK";
+ }
+
+ case 0x6474e552: {
+ return "RELRO";
+ }
+
+ case 0x6474e553: {
+ return "PROPERTY";
+ }
+
+ case 0x65041580: {
+ return "PAX_FLAGS";
+ }
+
+ case 0x65a3dbe5: {
+ return "OPENBSD_MUTABLE";
+ }
+
+ case 0x65a3dbe6: {
+ return "OPENBSD_RANDOMIZE";
+ }
+
+ case 0x65a3dbe7: {
+ return "OPENBSD_WXNEEDED";
+ }
+
+ case 0x65a3dbe8: {
+ return "OPENBSD_NOBTCFI";
+ }
+
+ case 0x65a3dbe9: {
+ return "OPENBSD_SYSCALLS";
+ }
+
+ case 0x65a41be6: {
+ return "OPENBSD_BOOTDATA";
+ }
+
+ case 0x70000001: {
+ return "SHT_AMD64_UNWIND";
+ }
+
+ case 0x6474e554: {
+ return "PT_GNU_SFRAME";
+ }
+ }
+
+ fmt::print("Unknown ELF type 0x{:x}\n", p_type);
+ std::abort();
+ return "unknown type";
+}
+
+static std::string flags_to_str(const uint32_t p_flags) {
+ std::string ret(3, '-');
+
+ if (p_flags & 4) {
+ ret[0] = 'r';
+ }
+
+ if (p_flags & 2) {
+ ret[1] = 'w';
+ }
+
+ if (p_flags & 1) {
+ ret[2] = 'x';
+ }
+
+ return ret;
+}
+
+template <> struct Elf_Phdr {
+ uint32_t p_type;
+ uint32_t p_offset;
+ uint32_t p_vaddr;
+ uint32_t p_paddr;
+ uint32_t p_filesz;
+ uint32_t p_memsz;
+ uint32_t p_flags;
+ uint32_t p_align;
+
+ void display(VerbosityLevel lvl = VERBOSE_LEVEL_1) const {
+ w_yel_lf("-> Elf_Phdr32: ");
+ fmt::print(" {} {}\n", type_to_str(p_type), flags_to_str(p_flags));
+
+ if (lvl > VERBOSE_LEVEL_1) {
+ display_hex_2fields_lf(p_vaddr, p_filesz);
+ }
+
+ if (lvl > VERBOSE_LEVEL_2) {
+ display_hex_2fields_lf(p_align, p_flags);
+ }
+
+ display_hex_2fields_lf(p_offset, p_paddr);
+ }
+}
+#ifdef LINUX
+__attribute__((packed))
+#endif
+;
+
+template <> struct Elf_Phdr {
+ uint32_t p_type;
+ uint32_t p_flags;
+ uint64_t p_offset;
+ uint64_t p_vaddr;
+ uint64_t p_paddr;
+ uint64_t p_filesz;
+ uint64_t p_memsz;
+ uint64_t p_align;
+
+ void display(VerbosityLevel lvl = VERBOSE_LEVEL_1) const {
+ w_yel_lf("-> Elf_Phdr64:");
+ fmt::print(" {} {}\n", type_to_str(p_type), flags_to_str(p_flags));
+
+ if (lvl > VERBOSE_LEVEL_1) {
+ display_short_hex_2fields_lf(p_vaddr, p_filesz);
+ }
+
+ if (lvl > VERBOSE_LEVEL_2) {
+ display_short_hex_2fields_lf(p_align, p_flags);
+ }
+
+ display_short_hex_2fields_lf(p_offset, p_paddr);
+ }
+}
+#ifdef LINUX
+__attribute__((packed))
+#endif
+;
+
+using Elf32_Phdr = Elf_Phdr;
+using Elf64_Phdr = Elf_Phdr;
+
+template struct Elf_Shdr {
+ uint32_t sh_name;
+ uint32_t sh_type;
+ T sh_flags;
+ T sh_addr;
+ T sh_offset;
+ T sh_size;
+ uint32_t sh_link;
+ uint32_t sh_info;
+ T sh_addralign;
+ T sh_entsize;
+}
+#ifdef LINUX
+__attribute__((packed))
+#endif
+;
+
+using Elf32_Shdr = Elf_Shdr;
+using Elf64_Shdr = Elf_Shdr;
+
+#ifdef WINDOWS
+#pragma pack(pop)
+#endif
+
+template struct Elf_Shdr_Abstraction {
+ Elf_Shdr header;
+ std::string name;
+
+ void display(VerbosityLevel lvl = VERBOSE_LEVEL_1) const {
+ fmt::print("0x{:<15x}0x{:<15x}{:32}\n", header.sh_addr, header.sh_size,
+ name);
+ }
+};
+
+using Elf_Shdr32_Abstraction = Elf_Shdr_Abstraction;
+using Elf_Shdr64_Abstraction = Elf_Shdr_Abstraction;
+
+struct ExecutableLinkingFormatLayout {
+ virtual ~ExecutableLinkingFormatLayout() = default;
+ virtual void fill_structures(std::ifstream &file) = 0;
+ virtual void display(VerbosityLevel lvl = VERBOSE_LEVEL_1) const = 0;
+ virtual uint64_t get_image_base_address(void) const = 0;
+ virtual std::vector
+ get_executable_section(std::ifstream &file, const uint64_t base) const = 0;
+ virtual uint16_t get_cpu(void) const = 0;
+};
+
+const uint32_t SHT_SYMTAB = 2;
+const uint32_t SHT_STRTAB = 3;
+
+const uint32_t RP_ELFEM_386 = 0x03;
+const uint32_t RP_ELFEM_X86_64 = 0x3e;
+const uint32_t RP_ELFEM_ARM = 0x28;
+const uint32_t RP_ELFEM_ARM64 = 0xb7;
+
+template struct ELFLayout : public ExecutableLinkingFormatLayout {
+ Elf_Ehdr elfHeader;
+ std::vector>> elfProgramHeaders;
+ std::vector>> elfSectionHeaders;
+ T offset_string_table, size_string_table;
+ uint64_t image_base = 0;
+
+ void display(VerbosityLevel lvl = VERBOSE_LEVEL_1) const override {
+ uint32_t i = 0;
+ elfHeader.display(lvl);
+
+ for (const auto &programheader : elfProgramHeaders) {
+ programheader->display(lvl);
+ }
+
+ w_yel_lf("-> Elf Headers:");
+ w_gre("id");
+ fmt::print("{:10}", "");
+ w_gre("addr");
+ fmt::print("{:13}", "");
+ w_gre("size");
+ fmt::print("{:13}", "");
+ w_gre("name");
+ fmt::print("{:32}\n", "");
+ fmt::print("{:-<70}-\n", "");
+
+ for (const auto §ionheader : elfSectionHeaders) {
+ fmt::print("0x{:<10x}", i++);
+ sectionheader->display(lvl);
+ }
+ }
+
+ T find_string_table(std::ifstream &file) {
+ Elf_Shdr elf_shdr;
+ std::streampos off = file.tellg();
+
+ file.seekg(std::streamoff(elfHeader.e_shoff), std::ios::beg);
+
+ for (uint32_t i = 0; i < elfHeader.e_shnum; ++i) {
+ file.read((char *)&elf_shdr, sizeof(Elf_Shdr));
+ if (elf_shdr.sh_addr == 0 && elf_shdr.sh_type == SHT_STRTAB) {
+ offset_string_table = elf_shdr.sh_offset;
+ size_string_table = elf_shdr.sh_size;
+ break;
+ }
+ }
+
+ file.seekg(off);
+ return offset_string_table;
+ }
+
+ void fill_structures(std::ifstream &file) override {
+ // Remember where the caller was in the file
+ std::streampos off = file.tellg();
+
+ // Dump the Elf Header
+ file.seekg(0, std::ios::beg);
+ file.read((char *)&elfHeader, sizeof(Elf_Ehdr));
+
+ // Goto the first Program Header, and dump them
+ file.seekg(std::streamoff(elfHeader.e_phoff), std::ios::beg);
+ for (uint32_t i = 0; i < elfHeader.e_phnum; ++i) {
+ auto pElfProgramHeader = std::make_unique>();
+
+ file.read((char *)pElfProgramHeader.get(), sizeof(Elf_Phdr));
+
+ // Here we assume that the first LOAD program header encountered will
+ // hold the image base address and I guess this assumption is quite wrong
+ // https://stackoverflow.com/questions/18296276/base-address-of-elf
+ if (type_to_str(pElfProgramHeader->p_type) == "LOAD" && image_base == 0) {
+ image_base = pElfProgramHeader->p_vaddr;
+ }
+ elfProgramHeaders.push_back(std::move(pElfProgramHeader));
+ }
+
+ // If we want to know the name of the different section, we need to find the
+ // string table section
+ find_string_table(file);
+
+ // Keep the string table in memory
+ file.seekg(std::streamoff(offset_string_table), std::ios::beg);
+
+ std::vector string_table_section;
+ string_table_section.resize(uint32_t(size_string_table));
+ file.read(string_table_section.data(), std::streamsize(size_string_table));
+
+ // Goto the first Section Header, and dump them !
+ file.seekg(std::streamoff(elfHeader.e_shoff), std::ios::beg);
+ for (uint32_t i = 0; i < elfHeader.e_shnum; ++i) {
+ auto pElfSectionHeader = std::make_unique>();
+
+ file.read((char *)&pElfSectionHeader->header, sizeof(Elf_Shdr));
+
+ // Resolve the name of the section
+ if (pElfSectionHeader->header.sh_name < size_string_table) {
+ // Yeah we know where is the string
+ char *name_section =
+ string_table_section.data() + pElfSectionHeader->header.sh_name;
+ pElfSectionHeader->name =
+ (std::strlen(name_section) == 0) ? "unknown section" : name_section;
+ }
+
+ elfSectionHeaders.push_back(std::move(pElfSectionHeader));
+ }
+
+ // Set correctly the pointer
+ file.seekg(off);
+ }
+
+ std::vector
+ get_executable_section(std::ifstream &file,
+ const uint64_t base) const override {
+ std::vector exec_sections;
+
+ for (const auto &programheader : elfProgramHeaders) {
+ if (!(programheader->p_flags & 1)) {
+ continue;
+ }
+
+ const auto vaddr = programheader->p_vaddr - image_base;
+ const auto p_offset = programheader->p_offset;
+ const auto p_filesz = programheader->p_filesz;
+ Section sec(type_to_str(programheader->p_type).c_str(), p_offset,
+ base + vaddr, p_filesz);
+
+ sec.dump(file);
+ sec.set_props(Section::Executable);
+ exec_sections.push_back(std::move(sec));
+ }
+
+ return exec_sections;
+ }
+
+ uint64_t get_image_base_address() const override { return image_base; }
+
+ uint16_t get_cpu() const override { return elfHeader.e_machine; }
+};
+
+```
+
+`src/rp/executable_format.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include "cpu.hpp"
+#include "rpexception.hpp"
+#include "section.hpp"
+#include
+#include
+#include
+#include
+#include
+
+/*! \class ExecutableFormat
+ *
+ * An ExecutableFormat is the second part composing a Program instance ; it is
+ * required to parse correctly the binary file, to know where you can find its
+ * executable sections, etc.
+ */
+class ExecutableFormat {
+public:
+ /* The format RP++ handles */
+ enum E_ExecutableFormat { FORMAT_PE, FORMAT_ELF, FORMAT_UNKNOWN };
+
+ virtual ~ExecutableFormat() = default;
+
+ /*!
+ * \brief Obtain the CPU ; for that it parses the executable format of your
+ * binary
+ *
+ * \return a pointer on the correct CPU
+ */
+ virtual std::unique_ptr get_cpu(std::ifstream &file) = 0;
+
+ /*!
+ * \brief Display information concerning the executable format: where
+ * sections begin, entry point, etc.
+ *
+ * \param lvl: Set a verbosity level
+ */
+ virtual void display_information(const VerbosityLevel lvl) const {
+ fmt::print("Verbose level: {}\n", verbosity_to_string(lvl));
+ }
+
+ /*!
+ * \brief Retrieve the name of the class, useful when using polymorphism
+ *
+ * \return the class name
+ */
+ virtual std::string get_class_name() const = 0;
+
+ /*!
+ * \brief Get the executable sections of you binary ; it is where we will
+ * look for gadgets
+ *
+ * \param file: it is a file handle on your binary file
+ * \param base: it is the base address to use
+ *
+ * \return A vector of Section instances
+ */
+ virtual std::vector
+ get_executables_section(std::ifstream &file, const uint64_t base) const = 0;
+
+ /*!
+ * \brief Give you the base address of the executable
+ *
+ * \return The prefered base address of the executable
+ */
+ virtual uint64_t get_image_base_address() const = 0;
+
+private:
+ /*!
+ * \brief Fill the structures you need, parse your executable format to
+ * extract the useful information
+ *
+ * \param file: It is your binary file
+ *
+ * \return The CPU type used in your binary file
+ */
+ virtual CPU::E_CPU extract_information_from_binary(std::ifstream &) {
+ RAISE_EXCEPTION(
+ "This method should not be called ; you're doing it wrong!");
+ return CPU::CPU_UNKNOWN;
+ }
+};
+
+```
+
+`src/rp/gadget.hpp`:
+
+```hpp
+// Axel '0vercl0k' Souchet - January 12 2022
+#pragma once
+
+#include "instruction.hpp"
+#include
+#include
+#include