CENSUS / shadow

jemalloc heap exploitation framework
Other
447 stars 69 forks source link

I get a Python Exception when execute jeparse #5

Closed jltxgcy closed 6 years ago

jltxgcy commented 6 years ago

(gdb) set architecture arm The target architecture is assumed to be arm (gdb) target remote:5039 Remote debugging using :5039 0xb6ec4864 in ?? () (gdb) source gdb_driver.py (gdb) jeparse [shadow] parsing structures from memory... [shadow] 2017-10-03 17:29:56 Python Exception <class 'TypeError'> unsupported operand type(s) for : 'NoneType' and 'int': Error occurred in Python command: unsupported operand type(s) for : 'NoneType' and 'int'

My python version is 2.7.6 and I use gdb-multiarch on Ubuntu and set architecture arm.

vats- commented 6 years ago

Hey jltxgcy,

Which Android version are you using?

jltxgcy commented 6 years ago

I tested it on Nexus 5 for Android 5.0(LRX21O).

vats- commented 6 years ago

Currently, shadow supports Android versions >= 6. We've never tested it on any of the older Android versions until now.

I reproduced the issue using an Android 5 device and it seems that the error occurs because gdb can't read the loaded shared libraries.

You can fix this by copying your device's shared libraries to your host and then setting gdb's solib-search-path accordingly.

You can read more about it here: http://visualgdb.com/gdbreference/commands/set_solib-search-path

I'll update the debug environment notes and spend some time to see whether Android 5 support can be easily added. For now if you want to use shadow you should update your device.

Thanks for the report.

jltxgcy commented 6 years ago

I tested it on Nexus 5 for Android 6.0.1, The phone has already rooted. I download http://android.googlesource.com/toolchain/gdb and compile instead of gdb-mutilarch. In this way, gdb can read the loaded shared libraries, as below: Reading symbols from target:/system/lib/libdivxdrmdecrypt.so...(no debugging symbols found)...done. Reading symbols from target:/system/lib/libqdMetaData.so...(no debugging symbols found)...done. 0xb6ac39bc in __ioctl () from target:/system/lib/libc.so

But when I source gdb_driver.py, I get error: (gdb) source /home/jltxgcy/shadow-master/gdb_driver.py /home/jltxgcy/shadow-master/gdb_driver.py:3: Error in sourced command file: Undefined command: "import". Try "help".

I compile use command as what you tell: ./configure --program-prefix=arm-eabi-linux- --target=arm-eabi-linux --disable-werror

How can I get gdb with Python support enabled?

vats- commented 6 years ago

Try passing --with-python to ./configure.

jltxgcy commented 6 years ago

I have already got this tip: (gdb) source /home/jltxgcy/shadow-master/gdb_driver.py (gdb) jeparse [shadow] Detecting Android version... [shadow] Using Android 6 32 bit configuration. (/home/jltxgcy/shadow-master/cfg/android6_32.cfg) [shadow] parsing structures from memory... [shadow] 2017-10-05 09:22:23

The terminal stop here and can't return (gdb). I can't get structures parsed.

jltxgcy commented 6 years ago

I must type Ctrl + C , finally I get: [shadow] 2017-10-05 10:02:30 ^C[shadow] structures parsed [shadow] 2017-10-05 10:02:42

If I don't type Ctrl + C , It will stop and can't return (gdb). I wonder if there is a bug here.

jltxgcy commented 6 years ago

I add some logs and find it stop in function parse_general. It seems to stop here: jeheap.nbins = int(dbg.execute('p __mallinfo_nbins()').split()[2])

jltxgcy commented 6 years ago

I still have another problem about jemalloc. I use command jechunk 0xb6080000: addr info size usage

0xb6080000 headers 0x2000 -
0xb6082000 small run (0x1000) 0x1000 1/1
0xb6083000 small run (0x400) 0x1000 4/4
0xb6084000 small run (0x1000) 0x1000 1/1

As above, regions are full of run, I want to know that where is struct arena_run_s. struct arena_run_s {

/ Index of bin this run is associated with. / index_t binind; / Number of free regions in run. / unsigned nfree; / Per region allocated/deallocated bitmap. / bitmap_t bitmap[BITMAP_GROUPS_MAX]; };

As far as I know, arena_run_s should be at the head of run. Thanks for your reply.

vats- commented 6 years ago
  1. The __mallinfo_nbins() call was causing more problems that it solved so i removed it. You should be able to use jeparse without problems now.

  2. arena_run_s is no longer stored at the head of each run.

    As you can see here it is now stored within an arena_chunk_map_misc_s struct.

    An array of arena_chunk_map_misc_s structs is stored at the start of each chunk. Each element of this array(let's call it map_misc[]) corresponds to one page within the chunk.

    So for example, if you want to read the metadata for the run that starts at the first usable page of the chunk you'll have to read map_misc[0]. If the next run starts at the 5th page you'll have to read map_misc[4], etc.

    You can see a visual representation of this here (slide 32).

    There is no command that prints the address of a run's arena_run_s, but since this information
    is stored within the parsed heap object you can write a script that does.

    Save the following into my_script.py:

    def print_run_hdr_addr(run_addr):
        for _, run in shadow.jeheap.runs.items():
            if run.addr == run_addr:
                print(hex(run.hdr_addr))
                break

    Load and use the script (remember to use jeparse first):

    (gdb) source /path/to/my_script.py
    (gdb) py print_run_hdr_addr(0x7a420ee000)
    0x7a42006488