Jump to content
Tuts 4 You
Sign in to follow this  
HellRaider

Ollydbg 2 plugin - How to display DialogBox

Recommended Posts

HellRaider

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 by HellRaider
added more info (see edit history)

Share this post


Link to post
ragdog

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 by ragdog (see edit history)
  • Like 2

Share this post


Link to post
HellRaider

@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 by HellRaider (see edit history)

Share this post


Link to post
ragdog

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.

Share this post


Link to post
HellRaider

Thank you, will try both the methods...

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
×
×
  • Create New...