Igor’s tip of the week #60: Type libraries

Type libraries are collections of high-level type information for selected platforms and compilers which can be used by IDA and the decompiler.

A type library may contain:

    1. function prototypes, e.g.:
      void *__cdecl memcpy(void *, const void *Src, size_t Size);
      BOOL __stdcall EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    2. typedefs, e.g.:
      typedef unsigned long DWORD;
      BOOL (__stdcall *WNDENUMPROC)(HWND, LPARAM);
      
    3. standard structure and enum definitions, e.g.:
      struct tagPOINT
      {
       LONG x;
       LONG y;
      };
      enum tagSCRIPTGCTYPE
      {
        SCRIPTGCTYPE_NORMAL = 0x0,
        SCRIPTGCTYPE_EXHAUSTIVE = 0x1,
      };
      
    4. Synthetic enums created from groups of preprocessor definitions (macros):
      enum MACRO_WM
      {
        WM_NULL = 0x0,
        WM_CREATE = 0x1,
        WM_DESTROY = 0x2,
        WM_MOVE = 0x3,
        WM_SIZEWAIT = 0x4,
        WM_SIZE = 0x5,
        WM_ACTIVATE = 0x6,
        WM_SETFOCUS = 0x7,
        WM_KILLFOCUS = 0x8,
        WM_SETVISIBLE = 0x9,
        [...]
       };

Manipulating type libraries

The list of currently loaded type libraries is available in the Type Libraries view (View >  Open subiews > Type Libraries, or ShiftF11).

Additional libraries can be loaded using “Load type library…” context menu item or the Ins hotkey.

Once loaded, definitions from the type library can be used in IDA and the decompiler: you can use them in function prototypes and global variable types (Y hotkey), as well as when adding new definitions in Local Types.

Importing types into IDB

While the decompiler can use types from loaded type libraries without extra work, to use them in the disassembly some additional action may be necessary. For example, to use a standard structure or enum, it has to be added to the list in the corresponding view first:

  1. Open the Structures (ShiftF9) or Enums (ShiftF10) window;
  2. Select “Add struct type..” or “Add enum” from the context menu, or use the hotkey (Ins);
  3. If you know the struct/enum name, enter it in the name field and click OK;
  4. If you don’t know or remember the exact name, click “Add standard structure” (“Add standard enum”) and select the struct or enum from the list of all corresponding types in the loaded type libraries. As with all choosers, you can use incremental search or filtering (CtrlF).

After importing, the structure or enum can be used in the disassembly view.

Function prototypes

When a type library is loaded, functions with name matching the prototypes present in the library will have their prototypes applied in the database. Alternatively, you can rename functions after loading the library, like we described last week.