Posted September 2, 20168 yr I tried to create an olly2 plugin with msvc 2010. But I was unable to display a DialogBox,, even after trying. Can some one please look at the code and figure out the problem and help me display the DialogBox correctly.... Here's the code. main.c /* In OllyDbg 2.x the plugin exports are a mixture of _cdecl and _stdcall Cdecl functions can be declared in the DEF file as FunctionName@Ordinal Stdcall functions must be declared in the DEF file in the decorated format FunctionName@<number_of_parameter_bytes>@Ordinal DllEntryPoint ODBG2_Pluginquery() ->->->-> real entry point ODBG2_Plugininit() mainmenu[] -> function calls ODBG2_Pluginmenu -> main menu & popup menu create processing functions */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif // VERY IMPORTANT NOTICE: PLUGINS ARE UNICODE LIBRARIES! COMPILE THEM WITH BYTE // ALIGNMENT OF STRUCTURES AND DEFAULT UNSIGNED CHAR! // #define UNICODE #define _CHAR_UNSIGNED // Microsoft compilers hate (and maybe justifiably) old-school functions like // wcscpy() that may cause buffer overflow and all related dangers; Still, I // don't want to see all these bloody warnings #define _CRT_SECURE_NO_DEPRECATE #include <windows.h> #include "plugin.h" #include "resource.h" #define PLUGINNAME L"Olly2isDnPE" // Unique plugin name #define VERSION L"2.00.01" // Plugin version static HINSTANCE hdllinst = NULL; // DLL instance static int menuHandler(t_table *pTable, wchar_t *pName, ulong index, int mode); void displayDialogBox(); BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); void disLastError(); void aboutIsDebug(); // 1. // Entry point of the plugin DLL. Many system calls require DLL instance // which is passed to DllEntryPoint() as one of parameters. Remember it. Do // not make any initializations here, preferrable way is to place them into // ODBG_Plugininit() and cleanup in ODBG_Plugindestroy(). BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) { if(reason == DLL_PROCESS_ATTACH) hdllinst = hinstDLL; // Mark plugin instance return 1; // Report success // return TRUE; }; // 2. // ODBG2_Pluginquery() is a "must" for valid OllyDbg plugin. It must check // whether given OllyDbg version is correctly supported, and return 0 if not. // Then it should fill plugin name and plugin version (as UNICODE strings) and // return version of expected plugin interface. If OllyDbg decides that this // plugin is not compatible, it will be unloaded. Plugin name identifies it // in the Plugins menu. This name is max. 31 alphanumerical UNICODE characters // or spaces + terminating L'\0' long. To keep life easy for users, name must // be descriptive and correlate with the name of DLL. Parameter features is // reserved for the future. I plan that features[0] will contain the number // of additional entries in features[]. Attention, this function should not // call any API functions: they may be incompatible with the version of plugin! extc int __cdecl ODBG2_Pluginquery(int ollydbgversion, ulong *features, 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 < 201) return 0; // Report name and version to OllyDbg wcscpy(pluginname, PLUGINNAME); // Name of plugin wcscpy(pluginversion, VERSION); // Version of plugin return PLUGIN_VERSION; // Expected API version }; // 3. // 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) { // Report success Addtolist(0, DRAW_HILITE, L"IsDebugPresent & PE Viewer for Olly2"); // Addtolist(0, DRAW_HILITE, L"IsDebugPresent status - "); return 0; }; // 4. // Function is called when user opens new or restarts current application. // Plugin should reset internal variables and data structures to the initial // state. extc void __cdecl ODBG2_Pluginreset(void) { // restore isDebug }; // 5. // OllyDbg calls this optional function when user wants to terminate OllyDbg. // All MDI windows created by plugins still exist. Function must return 0 if // it is safe to terminate. Any non-zero return will stop closing sequence. Do // not misuse this possibility! Always inform user about the reasons why // termination is not good and ask for his decision! Attention, don't make any // unrecoverable actions for the case that some other plugin will decide that // OllyDbg should continue running. extc int __cdecl ODBG2_Pluginclose(void) { return 0; }; // 6. // OllyDbg calls this optional function once on exit. At this moment, all MDI // windows created by plugin are already destroyed (and received WM_DESTROY // messages). Function must free all internally allocated resources, like // window classes, files, memory etc. extc void __cdecl ODBG2_Plugindestroy(void) { }; // 7. // // Menu processing functions // // Plugin menu that will appear in the main OllyDbg menu. Note that this menu // must be static and must be kept for the whole duration of the debugging // session. // // We create an array with the description of all menu items and their processing functions // // // static int ToggleFunc(t_table *pt, wchar_t *name, ulong index, int mode) // static int aboutIsDebug(t_table *pt, wchar_t *name, ulong index, int mode) // // pt -> pointer to table // name // index // mode -> // static t_menu mainmenu[] = { { L"PE Viewer", L"simple PE Viewer", K_NONE, menuHandler, NULL, MENU_PEVIEWER }, { L"|About", L"About IsDebug plugin", K_NONE, menuHandler, NULL, MENU_ABOUT }, { NULL, NULL, K_NONE, NULL, NULL, 0 } }; // 8. // Adds items either to main OllyDbg menu (type=PWM_MAIN) or to popup menu in // one of the standard OllyDbg windows, like PWM_DISASM or PWM_MEMORY. When // type matches, plugin should return address of menu. When there is no menu of // given type, it must return NULL. If menu includes single item, it will // appear directly in menu, otherwise OllyDbg will create a submenu with the // name of plugin. Therefore, if there is only one item, make its name as // descriptive as possible. // // function for returning menu for OllyDbg // extc t_menu * __cdecl ODBG2_Pluginmenu(wchar_t *type) { // if(wcscmp(type,PWM_MAIN)==0 || wcscmp(type,PWM_DISASM)==0){ if(wcscmp(type, PWM_MAIN)==0 || wcscmp(type, PWM_DISASM)==0) { // Main menu return mainmenu; } return NULL; // No menu }; // create processing functions // 9. //////////////////////////////////////////////////////////////////////////////// ////////////////// PLUGIN MENUS EMBEDDED INTO OLLYDBG WINDOWS ////////////////// // Menu processing functions are called twice. First time (mode=MENU_VERIFY) // OllyDbg asks to verify whether corresponding menu item applies or not. If // necessary, menu function may change menu text (parameter name, up to TEXTLEN // UNICODE characters). It must return one of the following codes: // // MENU_ABSENT: menu item does not apply and should not be present in // the menu; // MENU_NORMAL: menu item appears in the menu; // MENU_CHECKED: menu item appears in the menu and has attached checkmark; // MENU_CHKPARENT: menu item appears in the menu and has attached checkmark. // Additionally, attaches checkmark to the parent item in // menu on the previous level. This feature does not work in // the main menu; // MENU_SHORTCUT: menu item does not appear in the menu but is active and // participates in the search for keyboard shortcut; // MENU_GRAYED: item is present in the menu but disabled. This style is // not compatible with OllyDbg's look-and-feel, use it only // if absolutely necessary due to the menu logic. // // When menu item is selected (mouseclick or keyboard shortcut), menu function // is called for the second time (mode=MENU_EXECUTE, name is undefined). At // this moment, all threads of the debugged application are suspended. Function // must make all necessary actions and return one of the following codes: // // MENU_REDRAW: this action has global impact, all OllyDbg windows must // be updated. OllyDbg broadcasts WM_USER_CHGALL; // MENU_NOREDRAW: no redrawing is necessary. // // If processing is lengthy and application should continue execution, use // Resumeallthreads() at entry to the MENU_EXECUTE block and Suspendallthreads() // on exit. Note that MENU_ABSENT and MENU_NOREDRAW are interchangeable. // // Parameter index allows to use single menu function with several similar menu // items. // // Note that OllyDbg uses menu structures to process keyboard shortcuts. It is // done automatically, without the need to pay additional attention. // Menu function of main menu, opens or brings to top list of bookmarks. static int menuHandler(t_table *pTable, wchar_t *pName, ulong index, int mode) { UNREFERENCED_PARAMETER(pTable); UNREFERENCED_PARAMETER(pName); switch(mode) { case MENU_VERIFY: return MENU_NORMAL; case MENU_EXECUTE: switch (index) { case MENU_PEVIEWER: displayDialogBox(); break; case MENU_ABOUT: aboutIsDebug(); break; } return MENU_NOREDRAW; } return MENU_ABSENT; } void displayDialogBox() { // if(DialogBox(hdllinst, MAKEINTRESOURCE(IDD_ABOUT), NULL, AboutDlgProc) == -1) if(DialogBox(hdllinst, MAKEINTRESOURCE(IDD_ABOUT), hwollymain, AboutDlgProc) == -1) disLastError(); } BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { // HWND - handle to the dialog box switch(Message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: // user has chosen BUTTON item from the dialog box switch(LOWORD(wParam)) { case IDOK: EndDialog(hwnd, IDOK); break; case IDCANCEL: EndDialog(hwnd, IDCANCEL); break; } break; default: return FALSE; } return TRUE; } void disLastError() { TCHAR *messageBuffer = NULL; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&messageBuffer, 0, NULL); MessageBox(NULL, (LPCTSTR)messageBuffer, TEXT("LastError"), MB_OK); LocalFree(messageBuffer); } // 10. void aboutIsDebug() { int n; wchar_t s[TEXTLEN]; // Debuggee should continue execution while message box is displayed. Resumeallthreads(); // In this case, Swprintf() would be as good as a sequence of StrcopyW(), // but secure copy makes buffer overflow impossible. n=StrcopyW(s, TEXTLEN, L"Olly2isDnPE plugin v"); n+=StrcopyW(s+n, TEXTLEN-n, VERSION); // COPYRIGHT POLICY: This bookmark plugin is an open-source freeware. It's // just a sample. The copyright below is also just a sample and applies to // the unmodified sample code only. Replace or remove copyright message if // you make ANY changes to this code! n+=StrcopyW(s+n, TEXTLEN-n, L"\nCopyright (C) 2001-2012 Oleh Yuschuk"); // The conditionals below are here to verify that this plugin can be // compiled with all supported compilers. They are not necessary in the // final code. #if defined(__BORLANDC__) n+=StrcopyW(s+n,TEXTLEN-n,L"\n\nCompiled with Borland (R) "); #elif defined(_MSC_VER) n+=StrcopyW(s+n, TEXTLEN-n, L"\n\nCompiled with Microsoft (R) "); #elif defined(__MINGW32__) n+=StrcopyW(s+n,TEXTLEN-n,L"\n\nCompiled with MinGW32 "); #else n+=StrcopyW(s+n,TEXTLEN-n,L"\n\nCompiled with "); #endif #ifdef __cplusplus StrcopyW(s+n, TEXTLEN-n, L"C++ compiler"); #else StrcopyW(s+n,TEXTLEN-n,L"C compiler"); #endif MessageBox(hwollymain, s, L"Olly2isDnPE plugin", MB_OK|MB_ICONINFORMATION); // Suspendallthreads() and Resumeallthreads() must be paired, even if they // are called in inverse order! Suspendallthreads(); }; resource.h #define IDD_ABOUT 101 #define IDC_STATIC -1 #define MENU_PEVIEWER 11 #define MENU_ABOUT 12 resource.rc // Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (United States) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_ABOUT DIALOGEX 0, 0, 239, 66 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "My About Box" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN DEFPUSHBUTTON "OK",IDOK,174,18,50,14 PUSHBUTTON "Cancel",IDCANCEL,174,35,50,14 GROUPBOX "About this program...",IDC_STATIC,7,7,225,52 CTEXT "An example program showing how to use Dialog Boxes\r\n\r\nby theForger",IDC_STATIC,16,18,144,33 END ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN IDD_DIALOG1, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 309 TOPMARGIN, 7 BOTTOMMARGIN, 176 END END #endif // APSTUDIO_INVOKED #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED The code simply display the Forger's DialogBox.... I still learning. The dll is created OK and About MessageBox is working OK Edited September 2, 20168 yr by HellRaider added more info
September 4, 20168 yr Hello I have debug your plugin DialogBox(hdllinst, MAKEINTRESOURCE(IDD_ABOUT), hwollymain, AboutDlgProc Your Hinstance is 0 you must define the DllEntryPoint in your project settings. Choose Properties -> Configuration Properties -> Linker -> Advanced -> Entry Point add DllEntryPoint Clean your project and Recompile it. Greets, Edited September 4, 20168 yr by ragdog
September 4, 20168 yr Author @ragdog Thanks a lot, it worked like a charm.... Though, I have some queries. 1. I coded "Hide Debugger" for Olly2 {studied original of Asterix} and it worked. But there I did not define the DllEntryPoint in the project settings (Properties -> Configuration Properties -> Linker -> Advanced -> Entry Point add DllEntryPoint) and it still worked. Why? (Shall I PM you the code??) 2. How did you find out the error. A little peek into, as to how did you debug the dll. (how to get that hInstance is 0) (New to msvc, so I am trying to understand things) Thanks anyways. Edited September 4, 20168 yr by HellRaider
September 11, 20168 yr Hello I have debug this dll The best way fo debug your plugin is with Debug Macros and send this result to a Console . Or the a other way is Copy your plugin to your Ollydbg2 and load Ollydbg2 in a other debugger and run it. Now can you go in your plugin or set a Beakpoint on DialogBoxParamA or DialogBoxParamW. Quote (Shall I PM you the code??) Yes you can it.
Create an account or sign in to comment