Beispiel #1
0
def get_memory_map():
    api.Listmemory()
    t = api.pluginvalue_to_t_table(api.Plugingetvalue(api.VAL_MEMORY))
    rv = rpc.GetMemoryMapResult()

    for i in xrange(t.data.n):
        mi = rv.memories.add()
        m = api.void_to_t_memory(api.Getsortedbyselection(t.data, i))
        module = api.Findmodule(m.base)
        module_name = ("'%s'" % module.name) if module else ''
        mi.access = m.access
        mi.base = m.base
        mi.name = str(module_name)
        mi.size = m.size
        
    return rv
Beispiel #2
0
def RemoteAllocRWE(addr, size, alloc_type='commit'):
    """ Allocate memory in debuggee as RWE
    :param addr: Address or None or 0
    :param size: Size, must be greater than 0
    :param alloc_type: 'commit' or 'reserve'
    :return: Address of new allocated memory or None if failed
    """
    at = {'commit': D.MEM_COMMIT, 'reserve': D.MEM_RESERVE}.get(alloc_type)
    if at is None:
        raise Exception('Invalid argument: `alloc_type`')
    rv = C.windll.kernel32.VirtualAllocEx(api.Plugingetvalue(api.VAL_HPROCESS),
                                          addr, size, at,
                                          D.PAGE_EXECUTE_READWRITE)
    if not rv:
        last_error = C.windll.kernel32.GetLastError()
        if last_error:
            print >> sys.stderr, '[-] VirtualAllocEx failed with error: %x' % last_error

    return rv
Beispiel #3
0
def jump_to_from(is_to, base, remote_base, to=None):
    rv = rpc.JumpToFromResult()
    ptrdiff = 0
    if base != remote_base:
        ptrdiff = remote_base - base
    if is_to:
        api.Setcpu(
            0, int(to + ptrdiff), 0, 0, api.CPU_ASMHIST | api.CPU_ASMCENTER
            | api.CPU_ASMFOCUS | api.CPU_REDRAW)
        rv.result = rpc.JumpToFromResult.JR_OK
        return rv

    dmp = api.pluginvalue_to_t_dump(api.Plugingetvalue(api.VAL_CPUDASM))
    va = int(dmp.sel0)
    if va:
        rv.va = va - ptrdiff
        rv.result = rpc.JumpToFromResult.JR_OK
    else:
        rv.result = rpc.JumpToFromResult.JR_FAILED

    return rv
Beispiel #4
0
def safe_read_chunked_memory_region_as_one(base, size):
    mbi = D.MEMORY_BASIC_INFORMATION()
    VirtualQueryEx = C.windll.kernel32.VirtualQueryEx
    VirtualProtectEx = C.windll.kernel32.VirtualProtectEx
    GRANULARITY = 0x1000

    h_process = wintypes.HANDLE(api.Plugingetvalue(api.VAL_HPROCESS))
    try:
        rv = bytearray(size)
    except MemoryError:
        return

    guarded = list()
    gpoints = dict()
    protect = 0

    queried = VirtualQueryEx(h_process, C.c_void_p(base), C.byref(mbi), C.sizeof(mbi))
    if queried:
        protect = mbi.Protect
    else:
        print >> sys.stderr, 'safe_read_chunked_memory_region_as_one: VirtualQueryEx() failed'
    if queried and mbi.Protect & D.PAGE_GUARD:
        g = {'ea': base, 'size': GRANULARITY, 'p': mbi.Protect}
        gpoints[base] = 0
        ea = base
        while True:
            ea -= GRANULARITY
            if VirtualQueryEx(h_process, C.c_void_p(ea), C.byref(mbi), C.sizeof(mbi)) and\
                    (mbi.Protect & D.PAGE_GUARD) != 0 and g['p'] == mbi.Protect:
                g['ea'] -= GRANULARITY
                g['size'] += GRANULARITY
            else:
                break

        guarded.append(g)

    for i in range(base + GRANULARITY, base + size, GRANULARITY):
        p_addr = C.c_void_p(i)
        if VirtualQueryEx(h_process, p_addr, C.byref(mbi), C.sizeof(mbi)) and\
                        mbi.Protect & D.PAGE_GUARD:
            prevaddr = i - GRANULARITY
            if prevaddr in gpoints and guarded[gpoints[prevaddr]]['p'] == mbi.Protect:
                idx = gpoints[prevaddr]
            else:
                guarded.append({'ea': i, 'size': 0, 'p': mbi.Protect})
                idx = len(guarded) - 1
            guarded[idx]['size'] += GRANULARITY
            gpoints[i] = idx

    ea = base + size - GRANULARITY
    if ea in gpoints:
        while True:
            ea += GRANULARITY
            if VirtualQueryEx(h_process, C.c_void_p(ea), C.byref(mbi), C.sizeof(mbi)) and\
                        mbi.Protect & D.PAGE_GUARD:
                guarded[-1]['size'] += GRANULARITY
            else:
                break

    # turn off page guard before read
    dummy = C.c_long()
    for g in guarded:
        for off in range(0, g['size'], GRANULARITY):
            g['ok'] = VirtualProtectEx(h_process, C.c_void_p(g['ea'] + off), GRANULARITY,
                                       C.c_long(g['p'] & ~D.PAGE_GUARD), C.byref(dummy))

    for i in range(base, base + size, GRANULARITY):
        p_addr = C.c_void_p(i)
        if VirtualQueryEx(h_process, p_addr, C.byref(mbi), C.sizeof(mbi)):
            if mbi.Protect & D.PAGE_GUARD:
                # TODO
                pass
            mem = unsafe_read_process_memory(i, GRANULARITY)
            if mem is None:
                continue
            mem = mem[1]
            if mem:
                off = i - base
                rv[off:off + GRANULARITY] = mem

    for g in guarded:
        for off in range(0, g['size'], GRANULARITY):
            if not g['ok']:
                continue
            if not VirtualProtectEx(h_process, C.c_void_p(g['ea'] + off), GRANULARITY, C.c_long(g['p']), C.byref(dummy)):
                print >> sys.stderr, 'VirtualProtectEx(ptr 0x%08X, size 0x%08X, protect 0x%08X) failed' %\
                                     (g['ea'] + off, GRANULARITY, g['p'])
    if rv and len(rv) > size:
        rv = rv[:size]
    return size, rv, protect
Beispiel #5
0
def update_modules_meta():
    global modules_meta
    global modules_exports

    modules_meta = dict()
    modules_exports = dict()

    me32 = D.MODULEENTRY32()
    me32.dwSize = C.sizeof(D.MODULEENTRY32)
    pid = api.Plugingetvalue(api.VAL_PROCESSID)
    h_snap = C.windll.kernel32.CreateToolhelp32Snapshot(D.TH32CS_SNAPMODULE, pid)
    if h_snap == 0xFFFFFFFF:
        print >> sys.stderr, 'get_modules_meta(): Unable to open Toolhelp32 snapshot'
        return modules_meta

    # available_modules = set()

    ret = C.windll.kernel32.Module32First(h_snap, C.pointer(me32))
    if ret == 0:
        C.windll.kernel32.CloseHandle(h_snap)
        print >> sys.stderr, 'get_modules_meta(): Module32First() failed'
        return modules_meta

    while ret:
        modname = path.splitext(path.basename(me32.szExePath))[0].lower()
        if modname not in modules_meta or modules_meta[modname]['base'] != me32.modBaseAddr:
            mem = safe_read_chunked_memory_region_as_one(me32.modBaseAddr, me32.modBaseSize)
            print 'get_modules_meta(): %s at 0x%08X' % (modname, me32.modBaseAddr)
            if mem:
                pe = PEHelper(me32.modBaseAddr, modname, mem[1])
                exps = pe.get_exports()
                if modname in modules_meta:
                    modules_meta[modname]['base'].append(me32.modBaseAddr)
                    modules_meta[modname]['size'].append(me32.modBaseSize)
                    modules_meta[modname]['end'].append(me32.modBaseAddr + me32.modBaseSize)
                    modules_meta[modname]['apis'].append(exps)
                    # re_match_mod_ordinals = re.compile(r'%s\.#\d+' % modname, re.I)
                    modules_exports.update(pe.get_ea_to_longname_map())
                    # modules_exports = dict(filter(lambda (k, v): not re_match_mod_ordinals.match(v), modules_exports.items()))
                else:
                    mi = {
                        'path': [me32.szExePath],
                        'base': [me32.modBaseAddr],
                        'size': [me32.modBaseSize],
                        'apis': [exps],
                        'end':  [me32.modBaseAddr + me32.modBaseSize]
                    }
                    modules_meta[modname] = mi
                    modules_exports.update(pe.get_ea_to_longname_map())
        ret = C.windll.kernel32.Module32Next(h_snap, C.pointer(me32))
    C.windll.kernel32.CloseHandle(h_snap)

    # t = oa.pluginvalue_to_t_table(oa.Plugingetvalue(oa.VAL_MODULES))
    #
    # for i in xrange(t.data.n):
    #     m = oa.void_to_t_module(oa.Getsortedbyselection(t.data, i))
    #     modname = path.splitext(path.basename(m.path))[0].lower()
    #     if modname in modules_meta and modules_meta[modname]['base'] == m.base:
    #         continue
    #     available_modules.add(modname)
    #     externals = list()
    #     for off in xrange(m.codesize):
    #         name = bytearray(oa.TEXTLEN)
    #         if oa.Findname(m.codebase + off, oa.NM_EXPORT, name):
    #             name = str(name.replace('\x00', ''))
    #             externals.append({'ea': m.codebase + off, 'name': name})
    #             modules_exports[m.codebase + off] = '%s.%s' % (modname, name)
    #     mi = {
    #         'path': m.path,
    #         'base': m.base,
    #         'size': m.size,
    #         'apis': externals,
    #         'end': m.base + m.size
    #     }
    #
    #     modules_meta[modname] = mi
    # for name in filter(lambda x: x not in available_modules, modules_meta.keys()):
    #     del modules_meta[name]
    return modules_meta  # sorted(rv, key=lambda x: x['base'])
Beispiel #6
0
def RemoteFree(addr, size):
    if not addr:
        raise Exception('Invalid argument: `addr`')

    return C.windll.kernel32.VirtualFreeEx(
        api.Plugingetvalue(api.VAL_HPROCESS), addr, size, D.MEM_RELEASE)