Plugins are dynamic link libraries (DLLs) that attach to the OllyDbg and extend its functionality.

How plugins work

During startup, OllyDbg walks plugin directory (specified under Options | Directories | Plugin directory) and attempts to load all files with extension .dll. In each file it looks for the procedure named ODBG2_Pluginquery() (or _ODBG2_Pluginquery(), see Compilation below) and calls it, passing actual OllyDbg version. If this version is too low and does not support all required features, plugin must return 0. Otherwise, it must return PLUGIN_VERSION defined in the API header file plugin.h. If version of the plugin interface for which plugin was compiled is not compatible with the actual, OllyDbg will unload plugin and won't use it anymore.

All other plugin entries are optional. Let's assume that plugin implements them all. In this case, the sequence of calls is following:
Plugins should not unnecessarily define the following functions:
They are called very frequently and may slow down the debugging.

Private data types

OllyDbg keeps small pieces of the data of variable size in the central depository called data table. Each kind of data has its own tag, or data type. For example, labels added by the Analyser are saved as NM_ANALYSE and switch cases - as records of type DT_CASE. Data table may keep tens of millions of records. Access to these records is very quick, so it looks like an ideal depository for the plugin-related data. However, data types are scarce resource (only 126 types available to plugins) and can't be distributed statically.

To get private tags, plugin may call
Plugingetuniquedatatype(), once for each private data type it needs. These types are valid till OllyDbg closes. Types are distributed according to the "first asked - first served" rule. The best time to get private types is inside the ODBG2_Plugininit().

 As data types is a really scarce resource, please always check whether there is an alternative way to keep your data.


When creating and compiling plugins, please note the following:
Note that old plugins (for OllyDbg v1.xx) are not compatible with the version 2.xx.

Plugin callback functions:

int ODBG2_Pluginquery(int ollydbgversion,ulong *features,wchar_t pluginname[SHORTNAME],wchar_t pluginversion[SHORTNAME]);
int ODBG2_Plugininit(void);
void ODBG2_Pluginanalyse(t_module *pmod);
void ODBG2_Pluginmainloop(DEBUG_EVENT *debugevent);
int ODBG2_Pluginexception(t_run *prun,const t_disasm *da,t_thread *pthr,t_reg *preg,wchar_t *message);
void ODBG2_Plugintempbreakpoint(ulong addr,const t_disasm *da,t_thread *pthr,t_reg *preg);
void ODBG2_Pluginnotify(int code,void *data,ulong parm1,ulong parm2);
int ODBG2_Plugindump(t_dump *pd,wchar_t *s,uchar *mask,int n,int *select,ulong addr,int column);
t_menu * ODBG2_Pluginmenu(wchar_t *type);
t_control * ODBG2_Pluginoptions(UINT msg,WPARAM wp,LPARAM lp);
void ODBG2_Pluginsaveudd(t_uddsave *psave,t_module *pmod,int ismainmodule);
void ODBG2_Pluginuddrecord(t_module *pmod,int ismainmodule,ulong tag,ulong size,void *data);
void ODBG2_Pluginreset(void);
int ODBG2_Pluginclose(void);
void ODBG2_Plugindestroy(void);

Functions used only by plugins:

int Pluginsaverecord(t_uddsave *psave,ulong tag,ulong size,void *data);
int Pluginpackedrecord(t_uddsave *psave,ulong tag,ulong size,void *data);
void Pluginmodulechanged(ulong addr);
int Plugingetuniquedatatype(void);
int Plugintempbreakpoint(ulong addr,ulong type,int forceint3);
void Pluginshowoptions(t_control *options);


See annotated copies of bookmark.c and traceapi.c