Decodeknownbyaddr
int Decodeknownbyaddr(ulong addr,t_procdata *pd,t_argdec adec[NARG],wchar_t *rettype,wchar_t *name,int nexp,int follow);
If function with entry point addr
is known to OllyDbg, determines characteristics of this function
like type of return, preserved registers, number of stack
arguments and number of bytes discarded from stack on return, and
decodes arguments passed to this function in the stack.
If you want to decode function's arguments to text, you must read these arguments from the stack and supply them to Decodeknownbyaddr(). On entry, you only need to set adec[].mode and adec[].value and zero adec[].pushaddr. adec[0]
corresponds to the first argument (pushed last, with the lowest stack
address). Note that ESP at the entry points to the address of
return and first argument is at ESP+4.
Why may Decodeknownbyaddr() need pushaddr
at all? There is one special case. Push address is the address of the
command that writes data to the stack. Frequently, but not always, this
is the command PUSH. Instead of pushing long arguments in parts,
compiler may use sequences like SUB ESP,8; FSTP [QWORD ESP] to save
large items at once. In this case two consecutive pushaddrs in adec
will point to the same FSTP. When OllyDbg decodes call brackets,
it takes this into account and corrects the name of such argument.
Without correction, you might get the names Arg1, Arg3, Arg4 with no
explanation why Arg2 is missing. But if the name is decoded as Arg1_2,
this question will not arise. (Except that you may ask what
Arg1_2 means). In other words, in practically all cases plugins may set
adec[].pushaddr to 0.
If function has variable number of arguments and uses printf()-like format, parameter nexp
can be set to the expected number of doublewords following format, or
to -1 if this number is unknown. If nexp is positive and format string
specified in the function is not obtainable, format specifiers will be
decoded in the "blind" mode.
Parameters:
addr
(in) Address of the entry point of known function or, if follow is set and function at addr is not known, address of the sequence of jumps that end on the known function
pd
(out) Optional pointer to the descriptor of the procedure, structure of type t_procdata, or NULL if description is not necessary. Decodeknownbyaddr() fills only the following members of this artificial descriptor:
t_procdata.addr is set to 0
t_procdata.size is set to 1
t_procdata.type (only flags PD_RETSIZE, PD_FIXARG, PD_FORMATA / PD_FORMATW / PD_SCANA / PD_SCANW) if apply
t_procdata.retsize (only if PD_RETSIZE is set)
t_procdata.narg (only if PD_FIXARG, PD_FORMATA, PD_FORMATW, PD_SCANA or PD_SCANW is set)
t_procdata.preserved (if known)
adec
(in/out) Optional pointer to the list of arguments, array of at least NARG structures of type t_argdec, or NULL if decoding of arguments is not necessary. Calling routine must fill members adec[].mode and adec[].value and zero adec[].pushaddr in all elements of this array. (See explanation above to learn when you may need pushaddr). If function is known, Decodeknownbyaddr() fills adec[].prtype (prefixed type of the argument), adec[].name (name of the argument) and adec[].text (adec[].value decoded to text according to its type)
rettype
(out) Optional pointer to the UNICODE buffer, at least SHORTNAME wide characters long, that receives prefixed type of the answer that procedure returns in EAX. May be NULL
name
(out) Optional pointer to the UNICODE buffer, at least TEXTLEN wide characters long, that receives the name of the function . May be NULL
nexp
(in) If function includes printf()-like
format followed by a variable number of arguments, number of the
doublewords that follow format on the stack (-1 if this number is
unknown or format is defined). Ignored in all other cases. The safest
"don't care" way is to set this parameter to -1
follow
(in) If this flag is set and addr points to JMP, follows the sequence of jumps till it reaches entry point of known function or any non-jump command
Return
values:
On success, returns number of function arguments (may be 0). Otherwise, returns -1
See
also: