OllyDbg supports very complex expressions. Formal grammar of expressions is described at the end of this topic, but honestly - you are not interested in it, are you? So I'll begin with examples:
10 - constant 0x10 (unsigned). All integer constants are assumed hexadecimal unless followed by a decimal point;
10. - decimal constant 10 (signed);
'A' - character constant 0x41;
EAX - contents of register EAX, interpreted as unsigned number;
EAX. - contents of register EAX, interpreted as signed number;
[123456] - contents of unsigned doubleword at address 123456. By default, OllyDbg assumes doubleword operands;
DWORD PTR [123456] - same as above. Keyword PTR is optional;
[SIGNED BYTE 123456] - contents of signed byte at address 123456. OllyDbg allows both MASM- and IDEAL-like memory expressions;
STRING [123456] - ASCII zero-terminated string that begins at address 123456. Square brackets are necessary because you display the contents of memory;
[[123456]] - doubleword at address that is stored in doubleword at address 123456;
2+3*4 - evaluates to 14. OllyDbg assigns standard C priorities to arithmetical operations;
(2+3)*4 - evaluates to 20. Use parentheses to change the order of operations;
EAX.<0. - 0 if EAX is in range 0..0x7FFFFFFF and 1 otherwise. Notice that constant 0 is also signed. When comparing signed with unsigned, OllyDbg always converts signed operand to unsigned.
EAX<0 - always 0 (false), because unsigned numbers are always positive.
MSG==111 - true if message is WM_COMMAND. 0x0111 is the code for WM_COMMAND. Use of MSG makes sense only within conditional or conditional logging breakpoint set on call to or entry of known function that processes messages.
[STRING 123456]=="Brown fox" - true if memory starting from address 0x00123456 contains ASCII string "Brown fox", "BROWN FOX JUMPS", "brown fox???" or similar. The comparison is case-insensitive and limited in length to the length of text constant.
EAX=="Brown fox" - same as above, EAX is treated as a pointer.
UNICODE [EAX]=="Brown fox" - OllyDbg treats EAX as a pointer to UNICODE string, converts it to ASCII and compares with text constant.
[ESP+8]==WM_PAINT - in expressions, you can use hundreds of symbolic constants from Windows API.
([BYTE ESI+DWORD DS:[450000+15*(EAX-1)]] & 0F0)!=0 - absolutly valid expression.
And now the formal grammar. Eeach element in braces ( {} ) may occur only once, order of embraced elements is not important:
expression = memterm | memterm <binary operation> memterm
memterm = term | { sigmod sizemod prefix [ } expression ]
term = (expression) | unaryoperation memterm | signedregister | register | fpuregister | segmentregister | integerconst | floatingconst | stringconst | parameter | pseudovariable
unaryoperation = ! | ~ | + | -
signedregister = register .
register = AL | BL | CL ... | AX | BX | CX ... | EAX | EBX | ECX ...
fpuregister = ST | ST0 | ST1 ...
segmentregister = CS | DS | ES | SS | FS | GS
integerconst = <decimal constant>. | <hexadecimal constant> | <character constant> | <symbolic API constant>
floatingconst = <floating constant>
stringconst = "<string constant>"
sigmod = SIGNED | UNSIGNED
sizemod = BYTE | CHAR | WORD | SHORT | DWORD | LONG | QWORD | FLOAT | DOUBLE | FLOAT10 | STRING | UNICODE
prefix = term:
parameter = %A | %B // Allowed in inspectors only
pseudovariable = MSG // Code of window message
This grammar is not too strict, there is an intrinsic ambiguity in the interpretation of [WORD [EAX]] or similar expressions. Is this a DWORD on address which is stored in two bytes on address EAX, or is this a WORD on address to be taken from 4-byte memory addressed by EAX? OllyDbg tries to add modifiers to the outermost address as long as it's possible. In our case, [WORD [EAX]] is equivalent to WORD [[EAX]].
By default, BYTE, WORD and DWORD are unsigned whereas CHAR, SHORT and LONG are signed. All general-purpose registers are unsigned. One may use explicit modifiers SIGNED and UNSIGNED (even with registers). In binary operations, if one of operands is float, another will be converted to float, else if one is unsigned, another will be also converted to unsigned. Floating-point types do not accept UNSIGNED. MASM-compatible keyword PTR after size modifier (like in BYTE PTR) is also allowed but not required. Register names and size modifiers are not case-sensitive.
You can use following C-like arithmetical operations (priority 0 is highest):
Priority Type Operations
0 Unary ! ~ + -
1 Multiplication * / %
2 Addition + -
3 Shifts << >>
4 Comparisons < <= > >=
5 Comparisons == !=
6 Boolean AND &
7 Boolean XOR ^
8 Boolean OR |
9 Logical AND &&
10 Logical OR ||
In calculations, intermediate results are kept as either DWORD or FLOAT10. Some combinations of term types and operations are not allowed. For example, QWORDs can be only displayed; STRING and UNICODE allow only + and - (as if they were C pointers) and comparison for equal/not equal with STRING, UNICODE or string constant; you cannot shift FLOAT etc.
10 - constant 0x10 (unsigned). All integer constants are assumed hexadecimal unless followed by a decimal point;
10. - decimal constant 10 (signed);
'A' - character constant 0x41;
EAX - contents of register EAX, interpreted as unsigned number;
EAX. - contents of register EAX, interpreted as signed number;
[123456] - contents of unsigned doubleword at address 123456. By default, OllyDbg assumes doubleword operands;
DWORD PTR [123456] - same as above. Keyword PTR is optional;
[SIGNED BYTE 123456] - contents of signed byte at address 123456. OllyDbg allows both MASM- and IDEAL-like memory expressions;
STRING [123456] - ASCII zero-terminated string that begins at address 123456. Square brackets are necessary because you display the contents of memory;
[[123456]] - doubleword at address that is stored in doubleword at address 123456;
2+3*4 - evaluates to 14. OllyDbg assigns standard C priorities to arithmetical operations;
(2+3)*4 - evaluates to 20. Use parentheses to change the order of operations;
EAX.<0. - 0 if EAX is in range 0..0x7FFFFFFF and 1 otherwise. Notice that constant 0 is also signed. When comparing signed with unsigned, OllyDbg always converts signed operand to unsigned.
EAX<0 - always 0 (false), because unsigned numbers are always positive.
MSG==111 - true if message is WM_COMMAND. 0x0111 is the code for WM_COMMAND. Use of MSG makes sense only within conditional or conditional logging breakpoint set on call to or entry of known function that processes messages.
[STRING 123456]=="Brown fox" - true if memory starting from address 0x00123456 contains ASCII string "Brown fox", "BROWN FOX JUMPS", "brown fox???" or similar. The comparison is case-insensitive and limited in length to the length of text constant.
EAX=="Brown fox" - same as above, EAX is treated as a pointer.
UNICODE [EAX]=="Brown fox" - OllyDbg treats EAX as a pointer to UNICODE string, converts it to ASCII and compares with text constant.
[ESP+8]==WM_PAINT - in expressions, you can use hundreds of symbolic constants from Windows API.
([BYTE ESI+DWORD DS:[450000+15*(EAX-1)]] & 0F0)!=0 - absolutly valid expression.
And now the formal grammar. Eeach element in braces ( {} ) may occur only once, order of embraced elements is not important:
expression = memterm | memterm <binary operation> memterm
memterm = term | { sigmod sizemod prefix [ } expression ]
term = (expression) | unaryoperation memterm | signedregister | register | fpuregister | segmentregister | integerconst | floatingconst | stringconst | parameter | pseudovariable
unaryoperation = ! | ~ | + | -
signedregister = register .
register = AL | BL | CL ... | AX | BX | CX ... | EAX | EBX | ECX ...
fpuregister = ST | ST0 | ST1 ...
segmentregister = CS | DS | ES | SS | FS | GS
integerconst = <decimal constant>. | <hexadecimal constant> | <character constant> | <symbolic API constant>
floatingconst = <floating constant>
stringconst = "<string constant>"
sigmod = SIGNED | UNSIGNED
sizemod = BYTE | CHAR | WORD | SHORT | DWORD | LONG | QWORD | FLOAT | DOUBLE | FLOAT10 | STRING | UNICODE
prefix = term:
parameter = %A | %B // Allowed in inspectors only
pseudovariable = MSG // Code of window message
This grammar is not too strict, there is an intrinsic ambiguity in the interpretation of [WORD [EAX]] or similar expressions. Is this a DWORD on address which is stored in two bytes on address EAX, or is this a WORD on address to be taken from 4-byte memory addressed by EAX? OllyDbg tries to add modifiers to the outermost address as long as it's possible. In our case, [WORD [EAX]] is equivalent to WORD [[EAX]].
By default, BYTE, WORD and DWORD are unsigned whereas CHAR, SHORT and LONG are signed. All general-purpose registers are unsigned. One may use explicit modifiers SIGNED and UNSIGNED (even with registers). In binary operations, if one of operands is float, another will be converted to float, else if one is unsigned, another will be also converted to unsigned. Floating-point types do not accept UNSIGNED. MASM-compatible keyword PTR after size modifier (like in BYTE PTR) is also allowed but not required. Register names and size modifiers are not case-sensitive.
You can use following C-like arithmetical operations (priority 0 is highest):
Priority Type Operations
0 Unary ! ~ + -
1 Multiplication * / %
2 Addition + -
3 Shifts << >>
4 Comparisons < <= > >=
5 Comparisons == !=
6 Boolean AND &
7 Boolean XOR ^
8 Boolean OR |
9 Logical AND &&
10 Logical OR ||
In calculations, intermediate results are kept as either DWORD or FLOAT10. Some combinations of term types and operations are not allowed. For example, QWORDs can be only displayed; STRING and UNICODE allow only + and - (as if they were C pointers) and comparison for equal/not equal with STRING, UNICODE or string constant; you cannot shift FLOAT etc.