Search code examples
pointersassemblyx86dwordollydbg

Help deciphering a few lines of assembly


I have found these few lines of assembly in ollydbg:

MOV ECX,DWORD PTR DS:[xxxxxxxx] ; xxxxxxxx is an address
MOV EDX,DWORD PTR DS:[ECX]
MOV EAX,DWORD PTR DS:[EDX+116]
CALL EAX

Could someone step through and tell me what's happening here?


Solution

  • This is an invocation of a function pointer stored in a struct.

    This first line obtains a pointer stored at address DS:xxxxxxxx. The square brackets indicate dereferencing of the address, much like * in C. The value from memory is about to be used as a pointer; it is placed into ecx register.

    MOV ECX,DWORD PTR DS:[xxxxxxxx] ; xxxxxxxx is an address
    

    The second line dereferences the pointer obtained above. That value from ecx is now used as the address, which is dereferenced. The value found in memory is another pointer. This second pointer is placed into the edx register.

    MOV EDX,DWORD PTR DS:[ECX]
    

    The third line again dereferences memory; this time, the access occurs to an address offset from the pointer obtained above by 0x116 bytes. This is not evenly divisible by four, so this function pointer does not appear to come from a C++ vtable. The value obtained from the memory is this time stored in register eax.

    MOV EAX,DWORD PTR DS:[EDX+116]
    

    Finally, the function pointed to by eax is executed. This simply invokes the function via a function pointer. The function appears to take zero arguments, but I have a question on revision of my answer: are there PUSH instruction which precede this snippet? Those would be the function arguments. The question marks indicate this function might return a value, we can't tell from our vantage.

    CALL EAX
    

    Overall, the code snippet looks like an invocation of an extension function from a plug-in library to OllyDbg. The OllyDbg ABI specifies various structs which contain some function pointers. There are also arrays of function pointers, but the double-indirection to get to the edx-held pointer (also the not-aligned-by-even-multiple offset) makes me think this is a struct and not an array of function pointers or a C++ class's vtable.

    In other words, xxxxxxxx is a pointer to a pointer to a struct containing a function pointer.

    In the OllyDbg source file PlugIn.h are some candidate struct definitions. Here's an example:

    typedef struct t_sorted {              // Descriptor of sorted table
      char           name[MAX_PATH];       // Name of table, as appears in error
      int            n;                    // Actual number of entries
      int            nmax;                 // Maximal number of entries
      int            selected;             // Index of selected entry or -1
      ulong          seladdr;              // Base address of selected entry
      int            itemsize;             // Size of single entry
      ulong          version;              // Unique version of table
      void           *data;                // Entries, sorted by address
      SORTFUNC       *sortfunc;            // Function which sorts data or NULL
      DESTFUNC       *destfunc;            // Destructor function or NULL
      int            sort;                 // Sorting criterium (column)
      int            sorted;               // Whether indexes are sorted
      int            *index;               // Indexes, sorted by criterium
      int            suppresserr;          // Suppress multiple overflow errors
    } t_sorted;
    

    Those examples are allowed to be NULL, and your asm snippet does not check for NULL pointer in the function pointer. Therefore, it would have to be DRAWFUNC from t_table or SPECFUNC of t_dump.

    You could create a small project which includes the header file and uses printf() and offsetof() to determine whether either of those is at an offset of 0x116.

    Otherwise, I imagine that the insides of OllyDbg are written in this same style. So there are likely to be private struct definitions (not published in the Plugin.h file) used for various purposes within OllyDbg.


    I would like to add, I think it's a shame that OllyDbg sources are not available. I was under the impression that the statically-linked disassembler it contains was under some kind of ?GPL license, but I haven't had any luck getting the sources to OllyDbg.