A type in the sense of OllyDbg is the way to decode doubleword to text. Internal OllyDbg database contains descriptions of hundreds of known functions, types and structures. For example, a function may have several arguments. Each argument can be a number, a constant, a combination of flags or binary fields, or a pointer to type or structure. Value returned by the function in register EAX also has some type.
Here is a typical Windows API function:
HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);
It has three arguments: pen style, which is one of the constants PS_xxx defined somewhere in the API headers, integer pen width, and color, which is the combination of three components (red, green and blue) together with some additional information. CreatePen() returns GDI handle. And here is the description in the database:
STDFUNC GDI32.CreatePen
PS_X Style
INT Width
COLORREF Color
RETURNS HGDI
END
This is a standard API function that preserves EBX, EBP, ESI and EDI and removes its argument from the stack (STDFUNC). It is defined in GDI32.dll, so there is no change of confusion if function with the same name is defined elsewhere.
Type PS_X is just an enumeration. If value is unknown, it will be displayed as an integer:
TYPE PS_X
IF 0. "PS_SOLID"
ELSEIF 1. "PS_DASH"
ELSEIF 2. "PS_DOT"
ELSEIF 3. "PS_DASHDOT"
ELSEIF 4. "PS_DASHDOTDOT"
ELSEIF 5. "PS_NULL"
ELSEIF 6. "PS_INSIDEFRAME"
ELSEIF 7. "PS_USERSTYLE"
ELSEIF 8. "PS_ALTERNATE"
ELSE INT
ENDIF
END
Width of the pen is just an integer. Type COLORREF is more complicated. First, there are several subfields that must be decoded separately. Second, it would be nice to decode frequently used colours as a plain text instead of cryptical RGB(128,128,0):
TYPE COLORREF
IF 0x00000000 "<BLACK>"
ELSEIF 0x00FFFFFF "<WHITE>"
ELSEIF 0x00800000 "<BLUE>"
ELSEIF 0x00008000 "<GREEN>"
ELSEIF 0x00808000 "<CYAN>"
ELSEIF 0x00000080 "<RED>"
ELSEIF 0x00800080 "<MAGENTA>"
ELSEIF 0x00008080 "<BROWN>"
ELSEIF 0x00C0C0C0 "<GRAY>"
ELSEIF 0x00808080 "<DARKGRAY>"
ELSEIF 0x00FF0000 "<LIGHTBLUE>"
ELSEIF 0x0000FF00 "<LIGHTGREEN>"
ELSEIF 0x00FFFF00 "<LIGHTCYAN>"
ELSEIF 0x000000FF "<LIGHTRED>"
ELSEIF 0x00FF00FF "<LIGHTMAGENTA>"
ELSEIF 0x0000FFFF "<YELLOW>"
ELSE
SELECT FIELD 0xFF000000
IF EQ 2 "PALETTERGB"
ELSE "RGB"
ENDIF
ENDSEL
SELECT FIELD 0x000000FF
TEXT "(" UINT
ENDSEL
SELECT FIELD 0x0000FF00
TEXT "," UINT
ENDSEL
SELECT FIELD 0x00FF0000
TEXT "," UINT
ENDSEL
TEXT ")"
SELECT FIELD 0xFF000000
IF NE 0
IF NE 2
TEXT ", flags = "
HEX
ENDIF
ENDIF
ENDSEL
ENDIF
END
Finally, function returns HGDI. This is the GDI handle that will be decoded by OllyDbg in a special way. And here is the result:
0042437C 6A 00 PUSH 0 ; Color = <BLACK>
0042437D 6A 00 PUSH 0 ; Width = 0
0042437F 6A 00 PUSH 0 ; Style = PS_SOLID
00424381 E8 5EC40300 CALL <JMP.&GDI32.CreatePen> ; GDI32.CreatePen
Prefixed names
To describe the type internally, OllyDbg uses prefixed names. A prefixed name is a UNICODE string, at most SHORTNAME wide characters long, where first character (prefix) is a combination of flags ARG_xxx and remaining characters are the name of this type in the database. By the way, the database is extendable and users may add their own descriptions.
Prefix consists of the following bits:
|
Prefix bits always form valid ASCII/UNICODE character. In the above example, prefixed names have encodings @COLORREF, @INT, @PS_X and @HGDI.