This tool lets you search your gadgets on your binaries to facilitate your ROP exploitation. ROPgadget supports ELF, PE and Mach-O format on x86, x64, ARM, ARM64, PowerPC, SPARC, MIPS, RISC-V 64, and RISC-V Compressed architectures.
The loader for PE and Mach-O files relies on the native endianness of the host machine. This will fail when reading files for machines with a different endianness. This PR fixes all locations where the native endianness is applied.
This behavior was discovered during execution of the test suite on a PowerPC machine (big endian). See: https://bugs.gentoo.org/865149:
RUN core
RUN elf-ARM64-bash
RUN elf-ARMv7-ls
RUN elf-FreeBSD-x86
RUN elf-Linux-x64
RUN elf-Linux-x86
RUN elf-Linux-x86-NDH-chall
RUN elf-Mips-Defcon-20-pwn100
RUN elf-PowerPC-bash
RUN elf-PPC64-bash
RUN elf-SparcV8-bash
RUN elf-x64-bash-v4.1.5.1
RUN elf-x86-bash-v4.1.5.1
RUN Linux_lib32.so
RUN Linux_lib64.so
RUN macho-x64-ls
Traceback (most recent call last):
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/test-suite-binaries/../ROPgadget.py", line 12, in <module>
ropgadget.main()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/__init__.py", line 30, in main
sys.exit(0 if Core(args.getArgs()).analyze() else 1)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/core.py", line 244, in analyze
self.__binary = Binary(self.__options)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/binary.py", line 46, in __init__
self.__binary = MACHO(self.__rawBinary)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/macho.py", line 123, in __init__
self.__setLoadCmd()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/macho.py", line 137, in __setLoadCmd
command = LOAD_COMMAND.from_buffer_copy(base)
TypeError: a bytes-like object is required, not 'NoneType'
RUN macho-x86-ls
Traceback (most recent call last):
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/test-suite-binaries/../ROPgadget.py", line 12, in <module>
ropgadget.main()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/__init__.py", line 30, in main
sys.exit(0 if Core(args.getArgs()).analyze() else 1)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/core.py", line 244, in analyze
self.__binary = Binary(self.__options)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/binary.py", line 46, in __init__
self.__binary = MACHO(self.__rawBinary)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/macho.py", line 123, in __init__
self.__setLoadCmd()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/macho.py", line 137, in __setLoadCmd
command = LOAD_COMMAND.from_buffer_copy(base)
TypeError: a bytes-like object is required, not 'NoneType'
RUN pe-Windows-ARMv7-Thumb2LE-HelloWorld
Traceback (most recent call last):
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/test-suite-binaries/../ROPgadget.py", line 12, in <module>
ropgadget.main()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/__init__.py", line 30, in main
sys.exit(0 if Core(args.getArgs()).analyze() else 1)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/core.py", line 244, in analyze
self.__binary = Binary(self.__options)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/binary.py", line 42, in __init__
self.__binary = PE(self.__rawBinary)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/pe.py", line 154, in __init__
self.__parseSections()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/pe.py", line 185, in __parseSections
sec = IMAGE_SECTION_HEADER.from_buffer_copy(base)
ValueError: Buffer size too small (0 instead of at least 40 bytes)
RUN pe-x64-cmd-v6.1.7601
RUN pe-x86-cmd-v6.1.7600
RUN raw-x86.raw
RUN UNIVERSAL-x86-x64-libSystem.B.dylib
Traceback (most recent call last):
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/test-suite-binaries/../ROPgadget.py", line 12, in <module>
ropgadget.main()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/__init__.py", line 30, in main
sys.exit(0 if Core(args.getArgs()).analyze() else 1)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/core.py", line 244, in analyze
self.__binary = Binary(self.__options)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/binary.py", line 44, in __init__
self.__binary = UNIVERSAL(self.__rawBinary)
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/universal.py", line 61, in __init__
self.__setBinaries()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/universal.py", line 72, in __setBinaries
self.__machoBinaries.append(MACHO(rawBinary))
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/macho.py", line 123, in __init__
self.__setLoadCmd()
File "/var/tmp/portage/dev-util/ROPgadget-6.9/work/ROPgadget-6.9/ropgadget/loaders/macho.py", line 137, in __setLoadCmd
command = LOAD_COMMAND.from_buffer_copy(base)
TypeError: a bytes-like object is required, not 'NoneType'
RUN elf-Linux-x86 --ropchain
RUN elf-Linux-x86 --depth 3
RUN elf-Linux-x86 --string "main"
RUN elf-Linux-x86 --string "m..n"
RUN elf-Linux-x86 --opcode c9c3
RUN elf-Linux-x86 --only "mov|ret"
RUN elf-Linux-x86 --only "mov|pop|xor|ret"
RUN elf-Linux-x86 --filter "xchg|add|sub|cmov.*"
RUN elf-Linux-x86 --norop --nosys
RUN elf-Linux-x86 --range 0x08041000-0x08042000
RUN elf-Linux-x86 --string main --range 0x080c9aaa-0x080c9aba
RUN elf-Linux-x86 --memstr "/bin/sh"
RUN elf-Linux-x86 --badbytes "00|01-1f|7f|42"
RUN elf-Linux-x86 --offset 5555e000 --badbytes "00-20|80-ff"
RUN Linux_lib64.so --offset 0xdeadbeef00000000
RUN elf-ARMv7-ls --depth 5
RUN elf-ARM64-bash --depth 5
RUN elf-PPC64-bash --depth 5
With this patch, the test suite runs successfully on little endian and big endian machines.
The loader for PE and Mach-O files relies on the native endianness of the host machine. This will fail when reading files for machines with a different endianness. This PR fixes all locations where the native endianness is applied.
This behavior was discovered during execution of the test suite on a PowerPC machine (big endian). See: https://bugs.gentoo.org/865149:
With this patch, the test suite runs successfully on little endian and big endian machines.