分析OD插件原理并制作反反调试插件
1.OllyDbg,文中均简称为OD。OD版本为论坛专用虚拟机工具包中的OD2.0版本。OD的插件本质上就是一个到处有指定函数的DLL文件,这些按照指定名称、指定格式导出的函数会在OD执行到某一阶段或触发某个事件时主动调用。
OD启动时会遍历指定目录下的所有DLL文件并加载,然后根据插件返回的API版本信息决定是否继续加载,如果API版本不符合则会卸载此插件。
// OD 2.0 版本的插件接口
#define PLUGIN_VERSION 0x02010001 // Version 2.01.0001 of plugin interface
// 1. 检查OD的兼容版本
if (ollydbgversion < 201)
return 0;
// 2. 设置OD插件的名称与版本
StringCchCopy(pluginname, SHORTNAME, PLUGINNAME);
StringCchCopy(pluginversion, SHORTNAME, MY_VERSION);
// 3. 返回需要的API版本
return PLUGIN_VERSION;
2.编写插件需要包含“plugin.h”,“ollydbg.lib”两个文件
#include "Plugin/od_plugin.h"
#pragma comment(lib,".\\Plugin\\ollydbg.lib")
3.此外,还需要在C/C++命令行选项中添加“/J”,以说明工程中的char均为unsigned类型
4.定义全局变量与宏定义
#include <Windows.h>
#include <winternl.h>
#include "Plugin/od_plugin.h"
#pragma comment(lib,"ntdll.lib")
#pragma comment(lib,".\\Plugin\\ollydbg.lib")
#define PLUGINNAME L"ODPlugin"// 插件名称
#define MY_VERSION L"0.00.01" // 插件版本
t_table g_stcPlugin = { 0 };
/**********************************************************/
/* 函数名:插件信息查询函数【回调函数】
/* 说明: 此函数是必须存在的函数,也是OllyDBG第1个调用的函数。此函数负责检查当前的OllyDBG版本是否可以运行此插件,如果不能运行则需要返回0 。
/**********************************************************/
extc int __cdecl ODBG2_Pluginquery(int ollydbgversion, ulong* features, wchar_t pluginname, wchar_t pluginversion)
{
// 1. 检查OD的兼容版本
if (ollydbgversion < 201)
return 0;
// 2. 设置OD插件的名称与版本
StringCchCopy(pluginname, SHORTNAME, PLUGINNAME);
StringCchCopy(pluginversion, SHORTNAME, MY_VERSION);
// 3. 返回需要的API版本
return PLUGIN_VERSION;
}
// 函数名:插件初始化函数【回调函数】
// 说 明:此函数是可选函数,也是OllyDBG第2个调用的函数。负责初始化插件的初始资源。
// 返回值:
// int : 成功返回0,失败返回-1
extc int __cdecl ODBG2_Plugininit(void) {
MessageBox(0, L"插件加载成功,此时正在初始化",L"提示", 0);
return 0;
};
// 函数名:插件重置函数【回调函数】
// 说 明: 此函数是可选函数,当O重新加载程序或打开新的程序时,这个函数将会被调用。
extc void __cdecl ODBG2_Pluginreset(void) {
Deletesorteddatarange(&(g_stcPlugin.sorted), 0, 0xFFFFFFFF);
};
// 函数名:插件关闭函数【回调函数】
extc int __cdecl ODBG2_Pluginclose(void) {
Writetoini(NULL, (WCHAR*)PLUGINNAME, (WCHAR*)L"Restore", (WCHAR*)L"%i", g_stcPlugin.hw != NULL);
return 0;
};
// 函数名:插件销毁函数【回调函数】。
extc void __cdecl ODBG2_Plugindestroy(void) {
Destroysorteddata(&(g_stcPlugin.sorted));
};
5.插件菜单部分
①菜单响应函数是OD已经预定义好的函数类型,响应函数根据被调用的时机做出处理
static int MenuFun(t_table* pt, wchar_t* name, ulong index, int mode)
{
if (mode == MENU_VERIFY) // 第一次调用(一般执行初始化操作)
return MENU_NORMAL;
if (mode == MENU_EXECUTE) // 第二次调用(一般执行菜单逻辑操作)
{
MessageBox(0, L"我被点击了", L"提示",0);
return MENU_NOREDRAW;
}
return MENU_ABSENT;
};
②菜单结构体数组
// 设置主菜单数组
static t_menu g_stcMainMenu[] = {
{ (WCHAR*)L"反反调试",
(WCHAR*)L"提示:主菜单。",
K_NONE, MenuAntiAntiDebug, NULL, 0 },
{ NULL, NULL, K_NONE, NULL, NULL, 0 }
};
// 设置右键单数组
static t_menu g_stcDISASMMenu[] = {
{(WCHAR*)L"右键菜单",
(WCHAR*)L"提示:右键菜单。",
KK_DIRECT | KK_CTRL | 'A', MenuFun, NULL, 0 },
{ NULL, NULL, K_NONE, NULL, NULL, 0 }
};
③实现反反调试
检查PEB中的BeingDebugged标志以确定进程是否正在被用户模式的调试器调试。
static int MenuAntiAntiDebug(t_table* pt, wchar_t* name, ulong index, int mode)
{
if (mode == MENU_VERIFY) // 第一次调用(一般执行初始化操作)
return MENU_NORMAL;
if (mode == MENU_EXECUTE) // 第二次调用(一般执行菜单逻辑操作)
{
MessageBox(0, L"开始反反调试", L"提示", 0);
//1. 打开目标进程
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, g_nId);
//2. 获取对方PEB的地址
_PROCESS_BASIC_INFORMATION pbi = {0};
DWORD dwSize = 0;
NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi),&dwSize);
//3. 修改BeingDebugged
char cCh = 0;
WriteProcessMemory(hProcess, (LPVOID)((DWORD)pbi.PebBaseAddress + 0x02), &cCh, 1, &dwSize);
return MENU_NOREDRAW;
}
return MENU_ABSENT;
};
int g_nId = 0;
// 函数名:事件通知函数【回调函数】
// 说 明:当进程创建,线程创建,进程退出,线程退出会调用这个函数
// code 原因
// 当原因是进程创建的时候,parm1是进程PID
// 返回值:
void ODBG2_Pluginnotify(int code, void* data, ulong parm1, ulong parm2)
{
//处理进程创建时消息
if (code == PN_NEWPROC)
g_nId = parm1;
return;
}
④菜单回调函数
extc t_menu* __cdecl ODBG2_Pluginmenu(wchar_t* type)
{
// 1. 判断是否为主菜单弹出请求,是则弹出主菜单
if (!wcscmp(type, PWM_MAIN))
return g_stcMainMenu;
// 2. 判断是否为CPU窗口右键菜单弹出请求,是则弹出右键菜单
if (!wcscmp(type, PWM_DISASM))
return g_stcDISASMMenu;
// 3. 返回空
return NULL;
};
6.设置操作
①新建plugin 和 udd两个文件夹,将DLL放在plugin中
②修改路径,这里圈错了,UDD是第一个路径
7.调试检测
①未开启反调试
②加载插件
matao5168 发表于 2021-12-10 11:05
这两个反反调试插件在哪儿可以下载呀,楼主???
论坛的OD1.0版本的自带有反反调试插件,这是自己随便写的一个OD2.0版本的插件,很简单就一两行代码的事儿 冥界3大法王 发表于 2021-12-8 22:41
这两文件相当于x64dbg的那个调试桥文件吧? 负责消息的传送?
你的签名很有个性,写的都是关于破解的。 谢谢大佬分享,很有用 “plugin.h”,“ollydbg.lib”两个文件
这两文件相当于x64dbg的那个调试桥文件吧? 负责消息的传送? {:301_993:}{:301_993:}{:301_993:}向楼主学习 冥界3大法王 发表于 2021-12-8 22:41
这两文件相当于x64dbg的那个调试桥文件吧? 负责消息的传送?
调用od API 一下子感觉自己又学到了不少{:1_893:} 我感觉我又行了 感谢分享 支持一波
一下子感觉自己又学到了不少 学习一下