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.


(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
(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)
(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)
(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
(out) Optional pointer to the UNICODE buffer, at least TEXTLEN wide characters long, that receives the name of the function . May be NULL
(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
(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:
Analysis, Decodeargument(), Decodeknownbyname(), Decodetype()