ulong CCmdLog::set(ulong id, int code, int type, ulong flag) { LPLOGGER logger = nullptr; if (id <= 0) return 0; EnterCriticalSection(&m_csShare); // Initialize the sorted data if it hasn't initialize yet .. if (Issortedinit(&m_Table.sorted) == 0) { if (Createsorteddata ( // Make sure it's already initialized. &m_Table.sorted, // Descriptor of sorted data sizeof(LOGGER), // Size of single data item 10, // Initial number of allocated items (SORTFUNC *)CCmdLog::SortProc, // Sorting function (DESTFUNC *)CCmdLog::DestProc, // Data destructor 0 ) != 0) { LeaveCriticalSection(&m_csShare); return 0; } } // Get the logger .. void *temp = Findsorteddata(&m_Table.sorted, id, 0); logger = reinterpret_cast<LPLOGGER>(temp); if (logger != nullptr) { logger->code = code; id = logger->addr; if (type) logger->type = type; if (flag) logger->flag = flag; } else id = 0; LeaveCriticalSection(&m_csShare); // Now redraw the window and return ... Updatetable(&m_Table, false); return id; }
/** * Called when Ollydbg loads this plugin and requests information. * * @param ollydbgversion * The version of this instance of Ollydbg. * @param pluginname * String buffer that should hold the plugin name on return. * @param pluginversion * String buffer that should hold the plugin version on return. * * @return * The supported plugin version, should always be PLUGIN_VERSION. * 0 to report an error and abort loading the plugin. */ int ODBG2_Pluginquery(int ollydbgversion, wchar_t pluginname[SHORTNAME], wchar_t pluginversion[SHORTNAME]) { // Check whether OllyDbg has compatible version. This plugin uses only the // most basic functions, so this check is done pro forma, just to remind of // this option. if(ollydbgversion < MINOLLYDBGVERSION) { MessageBox(hwollymain, L"Incompatible Ollydbg Version !", PLUGIN_NAME, MB_OK | MB_ICONERROR | MB_TOPMOST); return 0; } // Report plugin in the log window. Addtolist(0, 0, PLUGIN_NAME L" v%i.%i.%i " VERSIONCOMPILED, VERSIONHI, VERSIONLO, VERSIONST); Addtolist(0, 0, L" http://odbgscript.sf.net"); mru.load(); mru.add(L"C:\\Program Files (x86)\\RE\\Olly 2\\Plugins\\Test1.txt"); mru.add(L"C:\\Program Files (x86)\\RE\\Olly 2\\Plugins\\Test2.txt"); mru.add(L"C:\\Program Files (x86)\\RE\\Olly 2\\Plugins\\Test3.txt"); ollylang = new OllyLang(); if(0 != Createsorteddata(&ollylang->wndLog.sorted, // Descriptor of sorted data sizeof(t_wndlog_data), // Size of single data item 20, // Initial number of allocated items wndlog_sort_function, // Sorting function wndlog_dest_function, // Data destructor 0)) // Simple data, no special options { return -1; } //2 if (Createsorteddata(&(ollylang->wndProg.sorted), sizeof(t_wndprog_data),50, //2 wndprog_sort_function,wndprog_dest_function, 0) != 0) return -1; //2 HINSTANCE hinst = (HINSTANCE)GetModuleHandleW(PLUGIN_NAME L".dll"); //2 if (Registerpluginclass(wndprogclass,NULL,hinst,wndprog_winproc)<0) { //2 return -1; //2 } //2 if (Registerpluginclass(wndlogclass,NULL,hinst,wndlog_winproc)<0) { //2 return -1; //2 } //2 if (Plugingetvalue(VAL_RESTOREWINDOWPOS)!=0 && Pluginreadintfromini(hinst, L"Restore Script Log",0)!=0) // initLogWindow(); //2 if (Plugingetvalue(VAL_RESTOREWINDOWPOS)!=0 && Pluginreadintfromini(hinst, L"Restore Script window",0)!=0) // initProgTable(); // Report name and version to OllyDbg. wcscpy(pluginname, PLUGIN_NAME); swprintf(pluginversion, SHORTNAME, L"%d.%d.%d", VERSIONHI, VERSIONLO, VERSIONST); return PLUGIN_VERSION; }
// Optional entry, called immediately after ODBG2_Pluginquery(). Plugin should // make one-time initializations and allocate resources. On error, it must // clean up and return -1. On success, it must return 0. extc int __cdecl ODBG2_Plugininit(void) { // Data contains no resources, so destructor is // not necessary. (Destructor is called each time data item is removed from // the sorted data). // create list of hit addresses if (Createsorteddata( &baselist, // Descriptor of sorted data sizeof(t_hitlist), // Size of single data item 10, // Initial number of allocated items NULL,//(SORTFUNC *)Bookmarksortfunc, // Sorting function NULL,//(DESTFUNC *)Bookmarkdestfunc, // Data destructor 0)!=0) // Simple data, no special options return -1; // create list of differential hit addresses if (Createsorteddata( &(hitlisttable.sorted), // Descriptor of sorted data sizeof(t_hitlist), // Size of single data item 10, // Initial number of allocated items NULL,//(SORTFUNC *)Bookmarksortfunc, // Sorting function NULL,//(DESTFUNC *)Bookmarkdestfunc, // Data destructor 0)!=0) // Simple data, no special options return -1; wcscpy(hitlisttable.name,L"Hit Trace Difference"); hitlisttable.mode=TABLE_SAVEALL; hitlisttable.bar.visible=1; hitlisttable.bar.name[0]=L"Address"; hitlisttable.bar.expl[0]=L"Address of instruction"; hitlisttable.bar.mode[0]=BAR_FLAT; hitlisttable.bar.defdx[0]=9; hitlisttable.bar.name[1]=L"Instruction"; hitlisttable.bar.expl[1]=L"Decoded Instruction"; hitlisttable.bar.mode[1]=BAR_FLAT; hitlisttable.bar.defdx[1]=80; hitlisttable.bar.nbar=2; hitlisttable.tabfunc=HitlistSelfunc; hitlisttable.custommode=0; hitlisttable.customdata=NULL; hitlisttable.updatefunc=NULL; hitlisttable.drawfunc=(DRAWFUNC *)Hitlistdraw; hitlisttable.tableselfunc=NULL; hitlisttable.menu=NULL; // Report success. return 0; };
ulong CCmdLog::msg(ulong id, const std::wstring& msg, bool append) { std::wstring *pmsg; LPLOGGER plog; if (id <= 0) return 0; EnterCriticalSection(&m_csShare); // Initialize the sorted data if it hasn't initialize yet .. if (Issortedinit(&m_Table.sorted) == 0) { if (Createsorteddata ( // Make sure it's already initialized. &m_Table.sorted, // Descriptor of sorted data sizeof(LOGGER), // Size of single data item 10, // Initial number of allocated items (SORTFUNC *)CCmdLog::SortProc, // Sorting function (DESTFUNC *)CCmdLog::DestProc, // Data destructor 0 ) != 0) { LeaveCriticalSection(&m_csShare); return 0; } } // Get the logger .. void *temp = Findsorteddata(&m_Table.sorted, id, 0); if ((plog = reinterpret_cast<LPLOGGER>(temp)) != nullptr) { m_Table.custommode -= plog->rows; pmsg = reinterpret_cast<std::wstring*>(plog->msge); if (pmsg == nullptr) pmsg = new std::wstring(); if (append == false) { pmsg->clear(); plog->rows = 0; } else if (pmsg->back() != text('\n')) --plog->rows; // Extract the message ... std::wstring::const_iterator itr, eitr = msg.cend(); for (itr = msg.cbegin(); itr != eitr; ++itr) { // We don't support old mac format ... if (*itr == text('\t')) { pmsg->append(8, text(' ')); continue; } if (*itr == text('\r')) continue; if (*itr == text('\n')) ++ plog->rows; pmsg->push_back(*itr); } if (pmsg->back() != text('\n')) ++ plog->rows; plog->msge = pmsg; // Set the string ... m_Table.custommode += plog->rows; } else id = 0; // return 0 if the logger doesn't exist. LeaveCriticalSection(&m_csShare); // Redrawing the logger window and return .. if (m_Table.offset <= 0) Updatetable(&m_Table, false); else PostMessage(m_Table.hw,WM_VSCROLL,SB_PAGEDOWN,0); return id; }
// OllyDbg calls this obligatory function once during startup. I place all // one-time initializations here. Parameter features is reserved for future // extentions, do not use it. extc int _export cdecl ODBG_Plugininit(int ollydbgversion, HWND hw, ulong *features) { HINSTANCE hinst; if(ollydbgversion < PLUGIN_VERSION) { MessageBox(hwndOllyDbg(), "Incompatible Ollydbg Version !", "ODbgScript", MB_OK | MB_ICONERROR | MB_TOPMOST); return -1; } // Report plugin in the log window. Addtolist(0, 0, "ODbgScript v%i.%i.%i",VERSIONHI,VERSIONLO,VERSIONST); Addtolist(0, -1," http://odbgscript.sf.net"); ollylang = new OllyLang(); if (Createsorteddata(&ollylang->wndProg.data,"ODbgScript Data", sizeof(t_wndprog_data),50, (SORTFUNC *)wndprog_sort_function,NULL)!=0) return -1; if (Createsorteddata(&ollylang->wndLog.data,"ODbgScript Log", sizeof(t_wndlog_data),20, (SORTFUNC *)wndlog_sort_function,NULL)!=0) return -1; hinst = hinstModule(); if (Registerpluginclass(wndprogclass,NULL,hinst,wndprog_winproc)<0) { return -1; } if (Registerpluginclass(wndlogclass,NULL,hinst,wndlog_winproc)<0) { return -1; } if (Plugingetvalue(VAL_RESTOREWINDOWPOS)!=0 && Pluginreadintfromini(hinst,"Restore Script Log",0)!=0) initLogWindow(); if (Plugingetvalue(VAL_RESTOREWINDOWPOS)!=0 && Pluginreadintfromini(hinst,"Restore Script window",0)!=0) initProgTable(); return 0; }
// OllyDbg calls this obligatory function once during startup. Place all // one-time initializations here. If all resources are successfully allocated, // function must return 0. On error, it must free partially allocated resources // and return -1, in this case plugin will be removed. Parameter ollydbgversion // is the version of OllyDbg, use it to assure that it is compatible with your // plugin; hw is the handle of main OllyDbg window, keep it if necessary. // Parameter features is reserved for future extentions, do not use it. extc int _export cdecl ODBG_Plugininit(int ollydbgversion, HWND hw, ulong *features) { // This plugin uses all the newest features, check that version of OllyDbg is // correct. I will try to keep backward compatibility at least to v1.99. if (ollydbgversion < PLUGIN_VERSION) return -1; // Keep handle of main OllyDbg window. This handle is necessary, for example, // to display message box. hwmain = hw; // Initialize bookmark data. Data consists of elements of type t_bookmark, // we reserve space for 10 elements. If necessary, table will allocate more // space, but in our case maximal number of bookmarks is 10. Elements do not // allocate memory or other resources, so destructor is not necessary. if (Createsorteddata(&(bookmark.data), "Bookmarks", sizeof(t_bookmark), 10, (SORTFUNC *)Bookmarksortfunc, NULL) != 0) return -1; // Unable to allocate bookmark data // Register window class for MDI window that will display plugins. Please // note that formally this class belongs to instance of main OllyDbg program, // not a plugin DLL. String bookmarkwinclass gets unique name of new class. // Keep it to create window and unregister on shutdown. if (Registerpluginclass(bookmarkwinclass, NULL, hinst, Bookmarkwinproc) < 0) { // Failure! Destroy sorted data and exit. Destroysorteddata(&(bookmark.data)); return -1; }; // Plugin successfully initialized. Now is the best time to report this fact // to the log window. To conform OllyDbg look and feel, please use two lines. // The first, in black, should describe plugin, the second, gray and indented // by two characters, bears copyright notice. Addtolist(0, 0, "Bookmarks sample plugin v1.10 (plugin demo)"); Addtolist(0, -1, " Copyright (C) 2001-2004 Oleh Yuschuk & Piérrot !"); // OllyDbg saves positions of plugin windows with attribute TABLE_SAVEPOS to // the .ini file but does not automatically restore them. Let us add this // functionality here. I keep information whether window was open when // OllyDbg terminated also in ollydbg.ini. This information is saved in // ODBG_Pluginclose. To conform to OllyDbg norms, window is restored only // if corresponding option is enabled. if (Plugingetvalue(VAL_RESTOREWINDOWPOS) != 0 && Pluginreadintfromini(hinst, "Restore bookmarks window", 0) != 0) Createbookmarkwindow(); return 0; };
int ODBG2_Plugininit(void) { if(Createsorteddata(&handletable.sorted, sizeof(HANDLE_DATA), 1, NULL , NULL, SDM_NOSIZE) != 0) { Addtolist(0, DRAW_HILITE, L"[%s]: Unable to created sorted table data.", PLUGIN_NAME); return -1; } StrcopyW(handletable.name,SHORTNAME,PLUGIN_NAME); handletable.mode = TABLE_SAVEPOS | TABLE_AUTOUPD; handletable.bar.visible = 1; handletable.bar.name[0] = L"Handle"; handletable.bar.expl[0] = L""; handletable.bar.mode[0] = BAR_FLAT; handletable.bar.defdx[0] = 24; handletable.bar.name[1] = L"Type"; handletable.bar.expl[1] = L""; handletable.bar.mode[1] = BAR_FLAT; handletable.bar.defdx[1] = 30; handletable.bar.name[2] = L"Name"; handletable.bar.expl[2] = L""; handletable.bar.mode[2] = BAR_FLAT; handletable.bar.defdx[2] = 256; handletable.bar.nbar = 3; handletable.tabfunc = (TABFUNC*)handletable_proc; handletable.custommode = 0; handletable.customdata = NULL; handletable.updatefunc = NULL; handletable.drawfunc = (DRAWFUNC *)handletable_draw; handletable.tableselfunc = NULL; handletable.menu = (t_menu*)handlesmenu; return 0; }
bool CCmdLog::InitLog() { // Create sorted data .. if (Issortedinit(&(m_Table.sorted)) == 0) { if ( Createsorteddata ( &(m_Table.sorted), // Descriptor of sorted data sizeof(LOGGER), // Size of single data item 10, // Initial number of allocated items (SORTFUNC *)CCmdLog::SortProc, // Sorting function (DESTFUNC *)CCmdLog::DestProc, // Data destructor SDM_NOSIZE|SDM_INDEXED ) != 0 ) { Addtolist( // ................. reinterpret_cast<ulong>(GetRetAddr()), DRAW_HILITE, text("Fail to create logger sorted data .") ); return false; } else InitializeCriticalSection(&m_csShare); } // Initialize pipe logging system .. if (initcon() == 0) { Addtolist( // We don't care if it success ... reinterpret_cast<ulong>(GetRetAddr()), DRAW_NORMAL, text("Fail to initialize pipe connect") ); return false; } // Create the logger window .. if ( Create() == false ) { Addtolist( // We don't care if it success ... reinterpret_cast<ulong>(GetRetAddr()), DRAW_NORMAL, text("Fail to create the logger window") ); } // All done .... return true; }
ulong CCmdLog::log(ulong id, int code, int type, const wchar *msg) { std::wstring *pmsg = nullptr; void *temp = nullptr; LPLOGGER plog = nullptr; ulong ulNewId = 0; EnterCriticalSection(&m_csShare); if (Issortedinit(&m_Table.sorted) == 0) { if (Createsorteddata ( // Initialize the sorted data &m_Table.sorted, // Descriptor of sorted data sizeof(LOGGER), // Size of single data item 10, // Initial number of allocated items (SORTFUNC *)CCmdLog::SortProc, // Sorting function (DESTFUNC *)CCmdLog::DestProc, // Data destructor 0 ) != 0) { LeaveCriticalSection(&m_csShare); return 0; } } if (id <= 0) { // Add new record .. // Can't add logger any more ... if (m_Table.custommode < MAXINT) { // Find a new id .. while (Findsorteddata(&m_Table.sorted,m_nNextId,0)) ++ m_nNextId; // Initialize a new item ... time_t timer; time(&timer); LOGGER logger = { m_nNextId, 1, type, 0, LOGGER_FLAG_IDLE, timer, code, nullptr }; // Initialize a new string.. (it's suck without c++11) std::wstring *pmsg = new std::wstring(); for (size_t npos = 0; msg[npos]; ++npos) { // We don't support old mac format ... if (msg[npos] == text('\r')) continue; if (msg[npos] == text('\n')) ++logger.rows; pmsg->push_back(msg[npos]); } if (pmsg->back() != text('\n')) { pmsg->push_back(text('\n')); ++logger.rows; } logger.msge = pmsg; // Set the string .... // Add a new item and return it's id .. temp = Addsorteddata(&m_Table.sorted, &logger); plog = reinterpret_cast<LPLOGGER>(temp); if (plog != nullptr) ulNewId = plog->addr; else { ulNewId = 0; delete logger.msge; } // Update the line count .. if (plog) m_Table.custommode += plog->rows; } } else { // Modify existed record . temp = Findsorteddata(&m_Table.sorted, id, 0); if ((plog = reinterpret_cast<LPLOGGER>(temp)) != nullptr) { m_Table.custommode -= plog->rows; // Update the logger .. plog->code = code; plog->type = type; plog->rows = 0; pmsg = reinterpret_cast<std::wstring*>(plog->msge); if (pmsg == nullptr) pmsg = new std::wstring(); else pmsg->clear(); // Clear the message first.. for (size_t npos = 0; msg[npos]; ++npos) { // We don't support old mac format ... if (msg[npos] == text('\r')) continue; if (msg[npos] == text('\n')) ++plog->rows; pmsg->push_back(msg[npos]); } if (pmsg->back() != text('\n')) { pmsg->push_back(text('\n')); ++plog->rows; } plog->msge = pmsg; // Set the string ........ m_Table.custommode += plog->rows; // Return this id . ulNewId = plog->addr; } } LeaveCriticalSection(&m_csShare); // Redrawing the logger window and return .. if (m_Table.offset <= 0) Updatetable(&m_Table, false); else PostMessage(m_Table.hw,WM_VSCROLL,SB_PAGEDOWN,0); return ulNewId; }