diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7c20cf0..b074629 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,8 +11,8 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Python code style linter - uses: wemake-services/wemake-python-styleguide@0.14.1 + # - name: Python code style linter + # - uses: wemake-services/wemake-python-styleguide@0.16.0 - name: Build run: | python2 -m pip install --upgrade setuptools wheel diff --git a/README.md b/README.md index 712aa51..e09dc72 100644 --- a/README.md +++ b/README.md @@ -46,41 +46,83 @@ Usage [--rawEndian ] [--re ] [--offset ] [--ropchain] [--thumb] [--console] [--norop] [--nojop] [--callPreceded] [--nosys] [--multibr] [--all] [--noinstr] - [--dump] [--silent] [--align ALIGN] + [--dump] [--silent] [--align ALIGN] [--mipsrop ] + + description: + ROPgadget lets you search your gadgets on a binary. It supports several + file formats and architectures and uses the Capstone disassembler for + the search engine. + + formats supported: + - ELF + - PE + - Mach-O + - Raw + + architectures supported: + - x86 + - x86-64 + - ARM + - ARM64 + - MIPS + - PowerPC + - Sparc optional arguments: - -h, --help show this help message and exit - -v, --version Display the ROPgadget's version - -c, --checkUpdate Checks if a new version is available - --binary Specify a binary filename to analyze - --opcode Search opcode in executable segment - --string Search string in readable segment - --memstr Search each byte in all readable segment - --depth Depth for search engine (default 10) - --only Only show specific instructions - --filter Suppress specific mnemonics - --range Search between two addresses (0x...-0x...) - --badbytes Rejects specific bytes in the gadget's address - --rawArch Specify an arch for a raw file - --rawMode Specify a mode for a raw file - --rawEndian Specify an endianness for a raw file - --re Regular expression - --offset Specify an offset for gadget addresses - --ropchain Enable the ROP chain generation - --thumb Use the thumb mode for the search engine (ARM only) - --console Use an interactive console for search engine - --norop Disable ROP search engine - --nojop Disable JOP search engine - --callPreceded Only show gadgets which are call-preceded - --nosys Disable SYS search engine - --multibr Enable multiple branch gadgets - --all Disables the removal of duplicate gadgets - --noinstr Disable the gadget instructions console printing - --dump Outputs the gadget bytes - --silent Disables printing of gadgets during analysis - --align ALIGN Align gadgets addresses (in bytes) - --mipsrop MIPS useful gadgets finder - stackfinder|system|tails|lia0|registers + -h, --help show this help message and exit + -v, --version Display the ROPgadget's version + -c, --checkUpdate Checks if a new version is available + --binary Specify a binary filename to analyze + --opcode Search opcode in executable segment + --string Search string in readable segment + --memstr Search each byte in all readable segment + --depth Depth for search engine (default 10) + --only Only show specific instructions + --filter Suppress specific mnemonics + --range Search between two addresses (0x...-0x...) + --badbytes Rejects specific bytes in the gadget's address + --rawArch Specify an arch for a raw file + x86|arm|arm64|sparc|mips|ppc + --rawMode Specify a mode for a raw file 32|64|arm|thumb + --rawEndian Specify an endianness for a raw file little|big + --re Regular expression + --offset Specify an offset for gadget addresses + --ropchain Enable the ROP chain generation + --thumb Use the thumb mode for the search engine (ARM only) + --console Use an interactive console for search engine + --norop Disable ROP search engine + --nojop Disable JOP search engine + --callPreceded Only show gadgets which are call-preceded + --nosys Disable SYS search engine + --multibr Enable multiple branch gadgets + --all Disables the removal of duplicate gadgets + --noinstr Disable the gadget instructions console printing + --dump Outputs the gadget bytes + --silent Disables printing of gadgets during analysis + --align ALIGN Align gadgets addresses (in bytes) + --mipsrop MIPS useful gadgets finder + stackfinder|system|tails|lia0|registers + + examples: + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --ropchain + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --depth 3 + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --string "main" + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --string "m..n" + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --opcode c9c3 + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --only "mov|ret" + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --only "mov|pop|xor|ret" + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --filter "xchg|add|sub|cmov.*" + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --norop --nosys + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --range 0x08041000-0x08042000 + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --string main --range 0x080c9aaa-0x080c9aba + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --memstr "/bin/sh" + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --console + ROPgadget.py --binary ./test-suite-binaries/elf-Linux-x86 --badbytes "00|01-1f|7f|42" + ROPgadget.py --binary ./test-suite-binaries/Linux_lib64.so --offset 0xdeadbeef00000000 + ROPgadget.py --binary ./test-suite-binaries/elf-ARMv7-ls --depth 5 + ROPgadget.py --binary ./test-suite-binaries/elf-ARM64-bash --depth 5 + ROPgadget.py --binary ./test-suite-binaries/raw-x86.raw --rawArch=x86 --rawMode=32 How can I contribute ? ---------------------- diff --git a/ropgadget/args.py b/ropgadget/args.py index 6e40cdb..983ee6b 100644 --- a/ropgadget/args.py +++ b/ropgadget/args.py @@ -79,9 +79,9 @@ def __parse(self, arguments, custom_arguments_provided=False): parser.add_argument("--filter", type=str, metavar="", help="Suppress specific mnemonics") parser.add_argument("--range", type=str, metavar="", default="0x0-0x0", help="Search between two addresses (0x...-0x...)") parser.add_argument("--badbytes", type=str, metavar="", help="Rejects specific bytes in the gadget's address") - parser.add_argument("--rawArch", type=str, metavar="", help="Specify an arch for a raw file") - parser.add_argument("--rawMode", type=str, metavar="", help="Specify a mode for a raw file") - parser.add_argument("--rawEndian", type=str, metavar="", help="Specify an endianness for a raw file") + parser.add_argument("--rawArch", type=str, metavar="", help="Specify an arch for a raw file x86|arm|arm64|sparc|mips|ppc") + parser.add_argument("--rawMode", type=str, metavar="", help="Specify a mode for a raw file 32|64|arm|thumb") + parser.add_argument("--rawEndian", type=str, metavar="", help="Specify an endianness for a raw file little|big") parser.add_argument("--re", type=str, metavar="", help="Regular expression") parser.add_argument("--offset", type=str, metavar="", help="Specify an offset for gadget addresses") parser.add_argument("--ropchain", action="store_true", help="Enable the ROP chain generation") @@ -107,6 +107,23 @@ def __parse(self, arguments, custom_arguments_provided=False): if self.__args.noinstr and self.__args.re: raise ValueError("[Error] --noinstr and --re= can't be used together") + if self.__args.thumb and self.__args.rawMode and self.__args.rawMode != "thumb": + raise ValueError("[Error] --rawMode is conflicting with --thumb") + + if not self.__args.rawArch and self.__args.rawMode: + raise ValueError("[Error] Specify --rawArch") + + if not self.__args.rawArch and self.__args.rawEndian: + raise ValueError("[Error] Specify --rawArch") + + rawMode = "thumb" if self.__args.thumb else self.__args.rawMode + + if self.__args.rawArch and not rawMode: + raise ValueError("[Error] Specify --rawMode") + + if self.__args.rawArch and not self.__args.rawEndian and self.__args.rawArch != "x86": + raise ValueError("[Error] Specify --rawEndian") + if self.__args.version: self.__printVersion() sys.exit(0) diff --git a/ropgadget/binary.py b/ropgadget/binary.py index e5c5556..02b8ce6 100644 --- a/ropgadget/binary.py +++ b/ropgadget/binary.py @@ -29,11 +29,11 @@ def __init__(self, options): print("[Error] Can't open the binary or binary not found") return None - if options.rawArch and options.rawMode: + if options.rawArch: self.__binary = Raw( self.__rawBinary, options.rawArch, - options.rawMode, + "thumb" if options.thumb else options.rawMode, options.rawEndian, ) elif self.__rawBinary[:4] == unhexlify(b"7f454c46"): diff --git a/test-suite-binaries/ref_output.bz2 b/test-suite-binaries/ref_output.bz2 index faba211..3ff4721 100644 Binary files a/test-suite-binaries/ref_output.bz2 and b/test-suite-binaries/ref_output.bz2 differ