使用VS2010以上版本的MFC编写OllyDbg插件
前面已经说过,MFC早期版本的CString实现没有使用ATL,而plugin.h要求编译时加入/J命令,或定义_CHAR_UNSIGNED宏,而ATL要求则相反。因此这个问题在VC6中不存在,而在VS2010及以上版本存在,目前我就测试了这几个版本。如何解决这个矛盾呢?今天我研究出一种方法。#if宏在这里起了决定性作用,如果命令行定义/J则所有工程文件都默认定义_CHAR_UNSIGNED,那么我们退而求其次,只在必要处添加该定义,使用结束后取消定义,这样就不和ATL冲突了!!!下面是该宏用法:
#if !defined _CHAR_UNSIGNED
#define _CHAR_UNSIGNED
#define _ISCHARTYPEUNSIGNED1
#else
#define_ISCHARTYPEUNSIGNED 0
#endif
#if _ISCHARTYPEUNSIGNED == 1
#undef _CHAR_UNSIGNED
#endif
我使用_ISCHARTYPEUNSIGNED 判断是否修改了_CHAR_UNSIGNED,如果原来未定义_CHAR_UNSIGNED,那么就在当前代码块定义该标志,块结束再改回去。如果原来定义过,则不用做任何操作。该代码要和MFC相关宏分开,因此
下面来测试,新建一个MFC的常规DLL,主文件中修改为如下形式:
// MFCLibrary1.cpp : 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include "MFCLibrary1.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
// 则从此 DLL 导出的任何调入
// MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
// 该函数的最前面。
//
// 例如:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // 此处为普通函数体
// }
//
// 此宏先于任何 MFC 调用
// 出现在每个函数中十分重要。这意味着
// 它必须作为函数中的第一个语句
// 出现,甚至先于所有对象变量声明,
// 这是因为它们的构造函数可能生成 MFC
// DLL 调用。
//
// 有关其他详细信息,
// 请参阅 MFC 技术说明 33 和 58。
//
// CMFCLibrary1App
BEGIN_MESSAGE_MAP(CMFCLibrary1App, CWinApp)
END_MESSAGE_MAP()
// CMFCLibrary1App 构造
CMFCLibrary1App::CMFCLibrary1App()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CMFCLibrary1App 对象
CMFCLibrary1App theApp;
// CMFCLibrary1App 初始化
BOOL CMFCLibrary1App::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
#if !defined _CHAR_UNSIGNED
#define _CHAR_UNSIGNED
#define _ISCHARTYPEUNSIGNED1
#else
#define_ISCHARTYPEUNSIGNED 0
#endif
#include <Windows.h>
#include "Plugin.h"
#include <stdio.h>
#pragma comment(lib,"ollydbg.lib")
HINSTANCE hInst;
HWND hOllyWnd;
t_module* MainModule;
extc int_export cdecl ODBG_Pluginmenu(int origin,char data,void *item)
{
return 1;
}
extc int_export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw, ulong *features)
{
return 0;
}
extc int_export cdecl ODBG_Plugindata(char shortname)
{
strcat(shortname,"testMFC");
return 108;
}
#if _ISCHARTYPEUNSIGNED == 1
#undef _CHAR_UNSIGNED
#endif
MFC扩展DLL例子:
// dllmain.cpp : 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include <afxwin.h>
#include <afxdllx.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
static AFX_EXTENSION_MODULE MFCLibrary2DLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// 如果使用 lpReserved,请将此移除
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("MFCLibrary2.DLL 正在初始化!\n");
// 扩展 DLL 一次性初始化
if (!AfxInitExtensionModule(MFCLibrary2DLL, hInstance))
return 0;
// 将此 DLL 插入到资源链中
// 注意: 如果此扩展 DLL 由
//MFC 规则 DLL (如 ActiveX 控件)隐式链接到,
//而不是由 MFC 应用程序链接到,则需要
//将此行从 DllMain 中移除并将其放置在一个
//从此扩展 DLL 导出的单独的函数中。使用此扩展 DLL 的
//规则 DLL 然后应显式
//调用该函数以初始化此扩展 DLL。否则,
//CDynLinkLibrary 对象不会附加到
//规则 DLL 的资源链,并将导致严重的
//问题。
new CDynLinkLibrary(MFCLibrary2DLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("MFCLibrary2.DLL 正在终止!\n");
// 在调用析构函数之前终止该库
AfxTermExtensionModule(MFCLibrary2DLL);
}
return 1; // 确定
}
#if !defined _CHAR_UNSIGNED
#define _CHAR_UNSIGNED
#define _ISCHARTYPEUNSIGNED1
#else
#define_ISCHARTYPEUNSIGNED 0
#endif
#include <Windows.h>
#include "Plugin.h"
#include <stdio.h>
#pragma comment(lib,"ollydbg.lib")
HINSTANCE hInst;
HWND hOllyWnd;
t_module* MainModule;
extc int_export cdecl ODBG_Pluginmenu(int origin,char data,void *item)
{
return 1;
}
extc int_export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw, ulong *features)
{
return 0;
}
extc int_export cdecl ODBG_Plugindata(char shortname)
{
strcat(shortname,"testMFC");
return 108;
}
#if _ISCHARTYPEUNSIGNED == 1
#undef _CHAR_UNSIGNED
#endif
页:
[1]