分析OD插件原理及反反调试插件的制作

1.OllyDbg,文中均简称为OD。
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[SHORTNAME], wchar_t pluginversion[SHORTNAME])
{
    // 1. 检查OllyDBG的兼容版本
    if (ollydbgversion < 201)
        return 0;
    // 2. 设置OllyDBG插件的名称与版本
    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 }
};

③实现反反调试

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.调试检测
①未开启反调试
在这里插入图片描述
②加载插件
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值