首页
社区
课程
招聘
[推荐]OD插件编写技术
发表于: 2009-8-6 15:08 15955

[推荐]OD插件编写技术

2009-8-6 15:08
15955
第一课 Windows 动态链接库基础

Windows 动态链接库

自从Microsoft 公司推出第一个版本的Windows 操作系统以来,动态链接库(DLL)一直是这个操作系统的基础。Windows API中的所有函数都包含在DLL 中。三个最重要的DLL:

Kernel32.dll: 包含用于管理内存、进程和线程的各个函数;

User32.dll: 包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数;

GDI32.dll: 包含用于画图和显示文本的各个函数。

当然Windows  还配有若干别的DLL,它们提供了用于执行一些特殊任务的函数。如:

AdvAPI32.dll: 包含用于实现对象安全性、注册表操作和事件记录的函数。

ComDlg32.dll: 包含常用对话框(如File Open 和File Save)。

ComCtl32.dll: 则支持常用窗口控件。

什么是DLL

一个Windows 应用程序是一个可执行文件,它创建一个或多个窗口并用一个消息循环接收用户输入。而动态链接库通常不能直接运行,也一般不接收消息。DLL 是包含函数的独立 文件(某些DLL 也可包含类或数据)。通过其他应用程序或DLL 调用来完成特定的功能。

动态链接和静态链接

动态链接是相对于静态链接来说的。在程序开发过程中,产生一个Windows 可执行文件,需要链接不同的目标模块(.obj)、运行时库(.lib)文件以及编译过的资源(.res)文件,此时的链接称为静态链接。与静态连接相对应,动态链接发生在程序运行时。

DLL 与进程的地址空间

在应用程序(或另一个DLL)能够调用DLL中的函数之前,必须能够找到DLL 文件中 的函数,即DLL 文件必须被映射到调用进程的地址空间中。有两种方式可以实现这一点,即加载时的隐含链接或运行时的显式链接(后面介绍)。一旦DLL 被映射到调用进程的地址空间中,DLL的代码和数据看上去就像是在进程的地址空间中的额外代码和数据一样。DLL 中函数代码创建的任何对象均由调用线程所拥有,而DLL 本身并不拥有任何东西。

显式链接与隐式链接

链接DLL到可执行程序有两种方式:隐式链接和显式链接。隐式链接时,使用DLL的可执行程序需要链接DLL  的导入库(.lib 文件)。可执行程序需要获取以下内容:包含导出函数(或导出类)声明的头文件、导入库(.lib 文件)、实际的DLL(.dll 文件)。从编程的角度看,调用导出函数与调用其他函数完全一样。

显式链接时,使用DLL 的可执行程序在运行时通过函数调用来显示加载或卸载DLL,并通过函数指针来调用DLL 的导出函数。

DLL 的搜索路径及extern “C”修饰符

如果显式链接DLL,那么可以指定DLL的路径。如果不指定路径或用隐式链接,那么Windows 将使用下列搜索顺序来寻找DLL,即包含EXE 文件的目录、进程的当前目录、Windows 系统目录、环境变量列出的目录。需要注意的是,因为有这么多搜索路径,所以

要注意DLL 版本的一致性,否则容易发生运行老版本DLL 的错误。

通常来说,C++编译器会改变函数和变量的名字,而加上extern  “C”修饰符,就可以告诉编译器不要改变变量名或函数名,这样,我们编写的DLL 中输出的变量和函数就可以供使用C、C + +或任何其他编程语言编写的可执行模块来访问。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
第二课 基于C 语言的动态链接库

建立动态链接库

从File 菜单中选择New,单击Projects 标签,选 择Win32 Dynamic-Link Library。

---------------------------------------

header file               

---------------------------------------

#ifdef __cplusplus

#define    EXPORT extern "C" __declspec (dllexport)

#else

#define    EXPORT __declspec (dllexport)

#endif

EXPORT     int  Add(int x, int y);

定义了EXPORT宏。DLL中应用程序使用的函 数必须是输出(exported)的。

EXPORT宏包括储存方式限定词__declspec(dllexport)和在头文件按C++模式编译时附加的extern “C”。

----------------------------------

c

----------------------------------

#include <windows.h>

#include "cektop.h"

int WINAPI DllMain ( HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)

{

  return TRUE ;

}

EXPORT int  Add(int x, int y)

{

   return (x+y);

}

包含函数DllMain,取代了Windows 应用程序中的WinMain 。如果需要的话,此函数可以用于执行初始化和清除(deinitialization)操作。现在需要的只是从 DllMain 返回TRUE。

使用动态链接库

方式1

1.       把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;

打开你的目标工程选中工程,选择Visual C++的Project主菜单的Settings菜单;

VC将会弹出一个对话框,在对话框的多页显示控件中选择Link页。然后在Object/library modules输入框中输入:youApp.lib

2. Exe 工程头文件中添加:

#ifdef __cplusplus

#define    EXPORT extern "C" __declspec (dllexport)

#else

#define    EXPORT __declspec (dllexport)

#endif

EXPORT     int  Add(int x, int y);

或者

把你的youApp.h(包含输出函数的定义)拷到你目标工程(需调用youApp.DLL的工程)目录下;

选择你的目标工程Head Files加入:youApp.h文件;

最后在你目标工程(*.cpp,需要调用DLL中的函数)中包含你的:#include "youApp.h"

注:youApp是你DLL的工程名。

3. 把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下;

方式2

汇编做演示:

API

LoadLibrary 载入DLL

GetProcAddress 获取指定函数地址

FreeLibrary  释放
2009-8-6 15:08
0
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
第三课 MFCDll

MFC 提供两种类型的DLL:正规的DLL(Regular DLL)和扩展的DLL(Extension DLL)。(MFC AppWizard[dll])

共有以下3 种DLL 类型:

正规的DLL 用MFC 静态链接(Regular DLL with MFC statically linked);

正规的DLL 共享MFC DLL(Regular DLL using shared MFC DLL);

扩展的DLL 共享MFC DLL(MFC Extension DLL (using shared MFC DLL))。

.def文件的规则为:

  (1)LIBRARY语句说明.def文件相应的DLL;

  (2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);

(3).def 文件中的注释由每个注释行开始处的分号 (;) 指定,且注释不能与语句共享一行。

使用Dll:

1.  把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;

打开你的目标工程选中工程,选择Visual C++的Project主菜单的Settings菜单;

VC将会弹出一个对话框,在对话框的多页显示控件中选择Link页。然后在Object/library modules输入框中输入:youApp.lib

2.头文件中添加:

示例:

int  add(int x, int y);
2009-8-6 15:09
0
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
第四课 OD插件开发环境介绍

1.       环境配置

下载OD的API手册 仔细阅读。

2.       基本知识

C语言基础

汇编语言基础
2009-8-6 15:11
0
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
第五课 OD插件开发

插件编写:

(1). 设置编译器。打开VC++6.0新建一个Win32 Dynamic-Link Library工程,把Plugin.h头文件加到工程中来,在.cpp文件中include Plugin.h头文件。然后ALT+F7打开Project->Settings,在C/C++选项卡的最下面Project Options里加上“/J”(没有引号),就是将缺省的char类型设置为unsigned(Set default char type to unsigned)。(注意大小写/J)

把OllyDbg.lib文件加到Resource Files里面。

(2) 在编译链接过程中出现LNK2001错误可将Plugin.h头文件中的API函数名称前加下划线"_"即可。

(3) 编写OD插件的必要元素:

int ODBG_Plugindata(char *shortname);

shortname - 32个字节的字符指针,buffer内容为我们要编写的插件名称,此名称用来显示在OD的插件菜单里面。

extc int _export cdecl ODBG_Plugindata(char shortname[32])

{

    strcpy(shortname, g_szPluginName);

    return PLUGIN_VERSION;

}

 

int ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features);

 

ollydbgversion - 看名字就知道了,OD的版本号;

hw          - OD主窗口的句柄;

features       - 保留。

 

extc int _export ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features)

{

HOD=hw;

return 0;

}


在你的程序中编写完这两个回调函数,你就可以在OD的插件菜单里看到你自己的插件的名称了。

(4) 编写插件的子菜单的显示

ODBG_Pluginmenu(int origin,char data[4096],void *item);


origin - 调用该回调函数的窗口编号。具体值请参考API手册,举例来说,PM_MAIN,子菜单显示在主窗口的插件菜单中,PM_DISASM, 子菜单显示在反汇编窗口中。

data - 子菜单显示的字符串,具体格式请参考API手册;

item   - 指向窗口中显示的和被选中的数据,可以为NULL。

extc int _export cdecl ODBG_Pluginmenu(int origin, char data[4096], void *item)

{

if (origin == PM_MAIN)

{

strcpy(data, "0 OD, | 1 关于");

return 1;

}

return 0;

}

 

ODBG_Pluginaction(int origin, int action, void *item);

 

origin - 上面介绍过了;

action - 菜单的ID;

item   - 同上。


回调函数中用switch (action)来分类各个菜单ID并添加响应代码。
2009-8-6 15:12
0
雪    币: 134
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Windows 动态链接库
上传的附件:
2009-8-6 15:14
0
雪    币: 561
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
非常不错,谢谢分享
2009-8-6 15:25
0
雪    币: 124
活跃值: (205)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
非常感谢楼主的分享,收下了
2009-12-25 09:22
0
雪    币: 95
活跃值: (419)
能力值: ( LV9,RANK:310 )
在线值:
发帖
回帖
粉丝
9
谢谢lz,mark一下,准备研究研究
2009-12-26 15:24
0
雪    币: 108
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢楼主这么好的教程,学习了
2009-12-28 00:19
0
游客
登录 | 注册 方可回帖
返回
//