JonathanSalwan / ROPgadget

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.
Other
3.97k stars 557 forks source link

Add hexdump to print non-ascii characters #173

Closed Ekultek closed 2 years ago

Ekultek commented 2 years ago
(venv) me@DESKTOP-123456:~$ ROPgadget --binary '/bin/ls' --string '.+\w+(.)?\\.+'
Strings information
============================================================
0x000000000001c7bf : GBI\
0x000000000001c7f7 : GBI\
0x000000000001ca32 : ABN\
Traceback (most recent call last):
  File "/home/me/erop/venv/bin/ROPgadget", line 12, in <module>
    ropgadget.main()
  File "/home/me/erop/venv/lib/python3.8/site-packages/ropgadget/__init__.py", line 30, in main
    sys.exit(0 if Core(args.getArgs()).analyze() else 1)
  File "/home/me/erop/venv/lib/python3.8/site-packages/ropgadget/core.py", line 246, in analyze
    return self.__lookingForAString(self.__options.string)
  File "/home/me/erop/venv/lib/python3.8/site-packages/ropgadget/core.py", line 176, in __lookingForAString
    print("0x{{0:0{}x}} : {{1}}".format(8 if arch == CS_MODE_32 else 16).format(vaddr, match.decode()))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 12: invalid start byte
(venv) me@DESKTOP-123456:~$

Create a hexdump for it so that it can decode the string properly, for example (in core.py):

class Core(cmd.Cmd):
    ....

    def __hexdump(self, s):
        acceptable = string.printable[0:-6] # everything except \x00 and shit like that
        results = []
        for c in list(s):
            if c in acceptable:
                results.append(c)
            else:
                results.append(".")
        return "".join(results)

    ...

        def __lookingForAString(self, string):
        ....
                try:
                    match = section["opcodes"][ref:ref + len(string)]
                    print("0x{{0:0{}x}} : {{1}}".format(8 if arch == CS_MODE_32 else 16).format(vaddr, match.decode()))
                except UnicodeDecodeError:
                    match = self.__hexdump(section["opcodes"][ref:ref + len(string)].decode())
                    print("0x{{0:0{}x}} : {{1}}".format(8 if arch == CS_MODE_32 else 16).format(vaddr, match))
        return True

This way if anything comes up thats not printable you can still see it without crashing the program

SweetVishnya commented 2 years ago

Can you make a PR with this fix?

Ekultek commented 2 years ago

@SweetVishnya yes I can, I don't have time right now though that's why I put it in an issue.

Ekultek commented 2 years ago

Hey, I'm most likely not going to have time in the near future, so the code above should work, if you want to test it.

SweetVishnya commented 2 years ago

Ok, I'll try to find time this week to apply this patch.

SweetVishnya commented 2 years ago

I merged a fix to master