pfalcon / ScratchABit

Easily retargetable and hackable interactive disassembler with IDAPython-compatible plugin API
GNU General Public License v3.0
393 stars 47 forks source link

Capstone may return negative addresses for arguments of jump instructions #34

Closed thesourcerer8 closed 6 years ago

thesourcerer8 commented 6 years ago

It seems that addresses beyond 0x80000000 are interpreted as negative numbers, even on a 64-bit python3. The address -2147360092 or -0x7ffe1d5c is actually 0x8001E2A4 which is a valid address:

./ScratchABit.py EXT0CB6Q.dec.P2.def --script import Loading CPU plugin arm_32_capstone Adding area: Area(0x0-0x1ffff, {'name': '.bin', 'access': 'RWX'}) Adding area: Area(0x808000-0x80ffff, {'name': '.bin', 'access': 'RWX'}) Adding area: Area(0x80000200-0x800301ff, {'name': '.bin', 'access': 'RWX'}) Loading EXT0CB6Q.dec.P21.frmw @0x0 Loading EXT0CB6Q.dec.P22.frmw @0x808000 Loading EXT0CB6Q.dec.P23.frmw @0x80000200 Processing section: entrypoints Performing initial analysis... 3000 Traceback (most recent call last): File "./ScratchABit.py", line 1030, in call_script(script) File "./ScratchABit.py", line 949, in call_script mod = import(script) File "/home/user/scratch/ScratchABit/import.py", line 2464, in SetRegEx(0x8000855A,"T",1,2) File "/home/user/scratch/ScratchABit/idc.py", line 65, in SetRegEx engine.analyze() File "/home/user/scratch/ScratchABit/scratchabit/engine.py", line 947, in analyze if not _processor.emu(): File "/home/user/scratch/ScratchABit/plugins/cpu/_any_capstone.py", line 176, in emu assert GetReg(op.addr, "T") == 0 File "/home/user/scratch/ScratchABit/idc.py", line 28, in GetReg if engine.ADDRESS_SPACE.get_flags(ea, engine.AddressSpace.ALT_CODE): File "/home/user/scratch/ScratchABit/scratchabit/engine.py", line 245, in get_flags raise InvalidAddrException(addr) scratchabit.defs.InvalidAddrException: (-2147360092, '-0x7ffe1d5c')

pfalcon commented 6 years ago

Weird. So far, I don't see how to reproduce this or what may be wrong, need to ponder about it.

One thing I can say is that SetRegEx() should not call engine.analyze(), it should call SetReg().

thesourcerer8 commented 6 years ago

I guess that the problem is in ScratchABit parsing the output from Capstone, I guess that there the addresses are transferred as "int", which is signed, but should be unsigned instead. Capstone finds JUMPs (BX or something) to addresses above 0x80000000 , and somehow those addresses are interpreted as signed integers I think.

pfalcon commented 6 years ago

I guess that the problem is in ScratchABit parsing the output from Capstone

Right at spot, thanks for that hint. Indeed:

  File "/mnt/hdd/projects/ScratchABit/plugins/cpu/_any_capstone.py", line 148, in ana
    assert op.value.imm >= 0, "%x %s %s" % (op.value.imm, inst.mnemonic, inst.op_str)
AssertionError: -13e11c | b #0xffec1ee4
pfalcon commented 6 years ago

Submitted upstream as https://github.com/aquynh/capstone/issues/1081

pfalcon commented 6 years ago

Worked around on the side of ScratchABit plugin in bc75f3c13f4b6bd92b1f80e1f004e726c428c556

pfalcon commented 6 years ago

With issue reported upstream and fixed on SABit side, closing this.

thesourcerer8 commented 6 years ago

Hooray, it works! I was able to import a larger project successfully into ScratchABit now.