I have been reversing Dyre in my spare time. I'm hoping to have a full analysis out in the next week or two. Something kind of annoying about Dyre is it uses what looks like a massive structure to store it's data and function pointers. For example in the image below we can see it it passing a handle stored at [eax+0x130] to WaitForSingleObject.
Manually tracing the code or searching for all cross references is kind of painful to find what populated the value. Since the displacement is kind of unique due to it's value of 0x130 or 304 it can be targeted very easily in IDAPython.

import idautils 
import idaapi
displace = {}

# for each known function 
for func in idautils.Functions():
    flags = idc.GetFunctionFlags(func)
    # skip library & thunk functions 
    if flags & FUNC_LIB or flags & FUNC_THUNK:
    dism_addr = list(idautils.FuncItems(func))
    for curr_addr in dism_addr:
        op = None
        index = None 
        # same as idc.GetOptype, just a different way of accessing the types
        if idaapi.cmd.Op1.type == idaapi.o_displ:
            op = 1
        if idaapi.cmd.Op2.type == idaapi.o_displ:
            op = 2
        if op == None:
        if "bp" in idaapi.tag_remove(idaapi.ua_outop2(curr_addr, 0)) or \
               "bp" in idaapi.tag_remove(idaapi.ua_outop2(curr_addr, 1)):
            # ebp will return a negative number
            if op == 1:
                index = (~(int(idaapi.cmd.Op1.addr) - 1) & 0xFFFFFFFF)
                index = (~(int(idaapi.cmd.Op2.addr) - 1) & 0xFFFFFFFF)
            if op == 1:
                index = int(idaapi.cmd.Op1.addr)
                index = int(idaapi.cmd.Op2.addr)
        # create key for each unique displacement value 
        if index:
            if displace.has_key(index) == False:
                displace[index] = []
The above code will create a dictionary of all the displacement values in known functions. A simple for loop can be used to find the address and disassembly of all uses for the defined displacement value.
Python>for x in displace[0x130]: print hex(x), GetDisasm(x)
0x10004f12 mov     [esi+130h], eax
0x10004f68 mov     [esi+130h], eax
0x10004fda push    dword ptr [esi+130h]  ; hObject
0x10005260 push    dword ptr [esi+130h]  ; hObject
0x10005293 push    dword ptr [eax+130h]  ; hHandle
0x100056be push    dword ptr [esi+130h]  ; hEvent
0x10005ac7 push    dword ptr [esi+130h]  ; hEvent
With the addresses it makes it easy to find where the value is populated.

The dictionary created by the script is named displace. It will contain all displaced values.  Not super 1337 but still useful. Cheers.

No comments:

Post a Comment