OD插件编写

article/2025/10/2 1:27:51

前言

本教程主旨用于编写一个OD插件修复部分问题或者解析反调试问题.

官方文档

异常过滤器的反调试插件

当触发异常时首先会将异常交付给SEH然后再交付到 SetUnhandledExceptionFilter,不管是哪个阶段当存在调试器时,首先会交付给调试器,但是在SEH阶段调试器可以把错误交付给被调试程序,但是位于 SetUnhandledExceptionFilter却不可以。因为我们需要修改一些系统判断逻辑从而实现调试。

首先给出一个Demo,这个Demo使用了SetUnhandledExceptionFilter机制进行了反调试,由于不是本文的重点所以不过多介绍。

.586
.model flat,stdcall
option casemap:noneinclude windows.incinclude user32.incinclude kernel32.incincludelib user32.libincludelib kernel32.libWinMain proto :DWORD,:DWORD,:DWORD,:DWORD.dataClassName db "MainWinClass",0AppName  db "Main Window",0g_szCC  db "这里有CC断点",0g_szover  db "程序结束",0g_sz1  db "非法程序后的一个窗口",0g_sz2  db "非法程序后的二个窗口",0g_sz3  db "检测到单步",0g_sz4  db "检测到返回",0g_sz5  db "异常返回",0g_sz6  db "测试",0g_sz7  db "非法程序后的三个窗口",0g_sz8  db 1
.data?hInstance HINSTANCE ?CommandLine LPSTR ?.codeMyUnhandledExceptionFilter proc pExceptionInfo:ptr EXCEPTION_POINTERSLOCAL @pContext:ptr PCONTEXTLOCAL @pExpRecord:ptr PEXCEPTION_RECORDmov ebx,pExceptionInfoassume ebx:ptr EXCEPTION_POINTERSpush [ebx].ContextRecordpop @pContextpush [ebx].pExceptionRecordpop @pExpRecordassume ebx:nothingmov ebx,@pExpRecordassume ebx:ptr EXCEPTION_RECORD;跳过内存访问异常的指令mov edx,@pContextassume edx:ptr CONTEXTmov ecx,0.if [ebx].ExceptionCode == EXCEPTION_ACCESS_VIOLATIONadd [edx].regEip,2;设置单步or [edx].regFlag,100hinvoke MessageBox,NULL,offset g_sz6,NULL,MB_OK.elseif [ebx].ExceptionCode == EXCEPTION_SINGLE_STEP;判断是否有ccmov eax,[edx].regEip.if byte ptr [eax] == 0cch;	;说明有ccinvoke MessageBox,NULL,offset g_szCC,NULL,MB_OK;检测到int3指令,证明被注入程序退出mov eax,EXCEPTION_EXECUTE_HANDLERret;	.elseif  byte ptr [eax] == 0C3h;		;如果是ret,则不设置单步;		invoke MessageBox,NULL,offset g_sz4,NULL,MB_OK.else.if g_sz8==1mov g_sz8,0mov  [edx].regEip,offset _SafePlace2;设置单步tf标志位or [edx].regFlag,100h.endif.endif.endifassume ebx:nothingassume edx:nothingmov eax,EXCEPTION_CONTINUE_EXECUTIONretMyUnhandledExceptionFilter endp; ---------------------------------------------------------------------------MyProtoctFun procmov eax,0ffffffffhmov eax,[eax]invoke MessageBox,NULL,offset g_sz1,NULL,MB_OKmov eax,0mov eax,0mov eax,0_SafePlace3:	invoke MessageBox,NULL,offset g_sz7,NULL,MB_OKretMyProtoctFun endpstart:invoke SetUnhandledExceptionFilter,offset MyUnhandledExceptionFilterinvoke MyProtoctFun_SafePlace2:	invoke MessageBox,NULL,offset g_sz2,NULL,MB_OKmov g_sz8,1invoke MyProtoctFunmov eax,0mov eax,0mov eax,0invoke MessageBox,NULL,offset g_szover,NULL,MB_OKend start

我们需要提前理解一个知识点,(异常过滤器阶段)当触发异常时系统会调用UnhandledExceptionFilter函数在这个函数内部中又会调用ZwQueryInformationProcess函数判断是否被调试。

ZwQueryInformationProcess 函数文档链接
在这里插入图片描述

在这里插入图片描述
我们的思路如下:
修改jnz 7732E179这个指令为NOP即可完成任务,在默认情况如果被调试这个指令会被执行跳转。

在捋清楚思路之后我们就开始编写对应的OD插件把.这个插件您可以用c语言编写也可以用汇编编写可以根据您的个人习惯。

若为的OD插件只不过是一个dll库罢了,不过你需要按照官方的说明导出对应的函数

  1. 下载所需文件在这里插入图片描述
  2. 编写对应的导出函数

OD提供了多个导出函数这里我们举例本例子用到的几个

_ODBG_Plugininit导出函数用于被od加载时回调,你可以在这个函数里面做初始化操作,如果初始化成功返回0

ODBG_Plugindata用于告诉OD这个插件支持的版本

ODBG_Paused OD被执行暂停的时候回调,会传入被暂停的原因

我们这里给出一个汇编版本

;odDllPlugin.Def
EXPORTS_ODBG_Plugindata=ODBG_Plugindata_ODBG_Plugininit=ODBG_Plugininit_ODBG_Paused=ODBG_Paused;Plugin.Inc
PLUGIN_VERSION equ 110
PP_MAIN     equ           0003h  
PP_EVENT equ            0000h  
PP_PAUSE equ            0001h  
PP_TERMINATED   equ     0002h  MM_RESTORE   equ  01h          
MM_SILENT    equ  02h           
MM_DELANAL   equ  04h          MM_RESILENT   equ (MM_RESTORE or MM_SILENT)_Readmemory proto C :ptr, :dword,:dword, :dword
_Writememory proto C :ptr, :dword,:dword, :dword

最重要的实现文件

.586
.model flat,stdcall
option casemap:noneinclude Plugin.Incinclude windows.incinclude user32.incinclude kernel32.incinclude msvcrt.incincludelib user32.libincludelib kernel32.libincludelib msvcrt.lib.datag_szPluginName db "myplugin",0g_szformatmsg db "地址为%x",0g_szKernelBase db "KernelBase",0 g_szUnhandledExceptionFilter db "UnhandledExceptionFilter",0g_aryCodeNop db 6 dup(90h)g_szprint db 100 dup(0h)g_dwFixAddr dd 0
.code;int  _export cdecl ODBG_Plugindata(char shortname[32]);ODBG_Plugindata proc C shortname:LPSTRinvoke crt_strcpy,shortname,offset g_szPluginNamemov eax,PLUGIN_VERSIONretODBG_Plugindata endp;extc int  _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw,
;                        ulong *features);ODBG_Plugininit proc C ollydbgversion:dword,hw:dword,features:dwordLOCAL @hKernalbase:dwordinvoke  GetModuleHandle,offset g_szKernelBasemov @hKernalbase,eaxinvoke GetProcAddress,@hKernalbase,offset g_szUnhandledExceptionFilteradd eax,0bdhmov g_dwFixAddr,eaxxor eax,eaxretODBG_Plugininit endpODBG_Paused proc C reason:dword,reg:dwordLOCAL @btCode:byte.if reason==PP_EVENTinvoke _Readmemory,addr @btCode,g_dwFixAddr,1,MM_RESILENT.if @btCode != 90hinvoke crt_sprintf,offset g_szprint,offset g_szformatmsg,g_dwFixAddrinvoke MessageBox,NULL,offset g_szprint,NULL,MB_OKinvoke	_Writememory,offset g_aryCodeNop,g_dwFixAddr,size g_aryCodeNop, MM_RESILENT or MM_DELANAL.endif.endifmov eax,1ret
ODBG_Paused endpDllMain proc hinstDLL:HINSTANCE, fdwReason:DWORD,lpReserved:LPVOIDmov eax,TRUEret
DllMain endpend DllMain

记得在编译的时候加上OLLYDBG.LIB库即可,这个库位于第一步中的压缩包中。

OD 窗口过程函数bug

我们知道OD有一个可以检查出程序的窗口过程函数,我们当然也可以用Spy++去查看

OD截图:
在这里插入图片描述

SPY++截图
在这里插入图片描述
一切看起来都非常正常。

我们现在使用一个unicode程序呢?

在这里插入图片描述

OD:
在这里插入图片描述
对于unicode程序发现OD并没有正确获取到窗口过程函数.

原因

由于OD获取窗口过程都使用多字节编码函数而不是根据目标语言选择因此存在问题。

我们首先看看GetClassLongA在这个OD中的调用处
在这里插入图片描述
前面两处调用 00497a0300479b23最后都是调用到004af420,这里的原因是got和ptl重定向的原因,我们不需深究。
我们直接看004af420处汇编

在这里插入图片描述
我们只需要替换50d858此处内容的地址即可完成。

MyGetClassLong proc hwnd:HWND,index:DWORDinvoke IsWindowUnicode,hwnd.if eax ==TRUEinvoke GetClassLongW,hwnd,indexret.endifinvoke GetClassLongA,hwnd,indexretMyGetClassLong endpODBG_Plugininit proc C ollydbgversion:dword,hw:dword,features:dwordLOCAL @pGetAddr:dwordLOCAL @dwOlddprotect:dwordmov @pGetAddr,0050D858hinvoke VirtualProtect,@pGetAddr,1,PAGE_EXECUTE_READWRITE,addr @dwOlddprotectmov eax,@pGetAddrmov dword ptr [eax],offset MyGetClassLonginvoke VirtualProtect,@pGetAddr,1,@dwOlddprotect,addr @dwOlddprotectxor eax,eaxretODBG_Plugininit endp

http://chatgpt.dhexx.cn/article/hiuxqJGx.shtml

相关文章

OD实战(1)

软件暴力破解 软件破解 软件 TraceMe下载地址:https://pan.baidu.com/s/1bWWm3L6cZ0gOqFIsKXQqkw 提取码:uqcd 破解 软件运行以后需要输入用户名和序列号,通过文本比较,只有正确的账号信息才能够进入,我们所要作的就…

Od软件破解

【文章标题】:算法分析与注册机编写 【文章作者】:hahaya 【软件名称】:Free Internet Window Washer 【软件大小】:1177KB 【保护方式】:注册码 【软件介绍】:无 【下载地址】:http://download…

简单详细的OD破解教程

2007-08-04 15:46作者:CCDebuger注:昨天在网上见到了这篇文章,但缺少插图,从另外一篇文章中也看到了类似的的教程文章,里面的插图质量实在不敢恭维。在一个论坛中正好下载了文章中所介绍的破解软件CRACKME3&#xff0c…

通过一个例子来介绍OD的简单使用

OllyDbg是一个32位的动态调试器,在平常做逆向的题中用的比较多,下面用bugku一个简单的例子Eazy-Re来介绍一下OllyDbg的使用。 首先打开程序,看一下是干什么的,他提示你输入flag,这里我随便输入几个字母,提…

OD基本介绍及快捷键讲解

OD简介 Ollydbg(简称OD)是Windows平台下Ring3级的程序调试利器。程序调试有静态调试和动态调试两种。静态调试是指将程序源代码编译成可执行程序之前,用手工或编译程序等方法对程序源代码进行测试,来查找和修正程序中的语法错误和…

OD修改软件

一、打开软件,查看正常运行的程序 二、打开OD,拖入要调试的程序 三、分析汇编代码 title是"Hello world",内存地址是0x00403000 四、数据窗口跳转到该地址,快捷键ctrlG 五、修改数据 点击要修改的地方,按…

简单详细的OD破解教程(转)

简单详细的OD破解教程 2007-08-04 15:46作者:CCDebuger注:昨天在网上见到了这篇文章,但缺少插图,从另外一篇文章中也看到了类似的的教程文章,里面的插图质量实在不敢恭维。在一个论坛中正好下载了文章中所介绍的破解软…

OD教程(汇编基础)

一、call有以下几种方式&#xff1a; call 404000h ;直接跳到函数或过程的地址 call eax ;函数或过程地址存放在eax call dword ptr [eax] call dword prt[eax ] call dword ptr [eax5] call dword prt[eax5] calldword ptr [<&API>] ;执行一个系统API 二、关于…

小甲鱼解密系列调试篇——OD使用教程笔记(持续更新中)

目录 一点铺垫&#xff1a;基础知识 1.汇编语言 2.NAG窗口 3.SEH 4.断点类型 一、MessageBox.exe修改程序标题内容——修改函数传入值 二、TraceMe.exe暴力破解程序登陆界面——搜索函数、寻找附近调用取值的地方 三、reverseMe.exe暴力破解/打补丁实现注册——分析文件…

第52篇:OD使用教程2-设置API函数断点去除软件对话框及过期校验

Part1 前言 大家好&#xff0c;我是ABC_123。之前分享过一篇Ollydbg逆向分析入门教程《第50篇&#xff1a;使用OD逆向破解流光Fluxay扫描器各种限制》&#xff0c;这篇文章主要讲解了在使用OD逆向分析时&#xff0c;如何按照编程人员的思维去解除软件的各种限制。方法有点麻烦…

od的简单使用--(1)

od的简单使用——&#xff08;1&#xff09; 一&#xff0c;本教程需要的工具OllyDBG 下载&#xff1a; OllyDBG 中各个窗口的功能如上图。简单解释一下各个窗口的功能&#xff0c;更详细的内容可以参考 TT 小组翻译的中文帮助&#xff1a;反汇编窗口&#xff1a;显示被调试程…

PyCharm 社区版(Community)能不能商用?

其实官方博客已经给出了答案&#xff0c;截图如下&#xff1a; PyCharm社区版是专业版的阉割版&#xff0c;PYcharm专业版增加了Web开发、Python We框架、Python分析器、远程开发、支持数据库与SQL等更多高级功能。两者区分如下&#xff1a; 所以&#xff0c;大胆放心的用PyC…

Pycharm社区版下载及安装教程

下载&#xff1a; 下载地址&#xff1a;https://www.jetbrains.com/pycharm/download/#sectionwindows 安装&#xff1a; 打开你下载的路径&#xff0c;双击.exe文件&#xff0c;点击运行 默认点击next之后&#xff0c;选择路径&#xff0c;尽量不要选择在C盘&#xff0c;然后…

Pycharm社区版安装教程(永久免费,随时升级)

首先进入JetBrain的官网(国内正常访问): https://www.jetbrains.com/ 第一眼看到的界面如下图所示: 然后找到我们的Pycharm专题页: 进入Pycharm的专题页面之后,点击下载按钮(这里有两个按钮,点任何一个都行): 然后进入到真正的下载页面你会发现有两个版本的Pycharm,一个…

pycharm安装-社区版

下载地址 Download PyCharm: Python IDE for Professional Developers by JetBrains https://www.jetbrains.com/pycharm/download/#sectionwindows 下载社区版 安装过程 双击安装包 开始安装 安装过程 首次启动 双击桌面图标 选风格 深色保护视力 新建项目 新建文件

如何用Pycharm社区版连接数据库

用Pycharm社区版连接数据库 Pycharm 社区版安装过程 Pycharm 社区版 Pycharm社区版是比专业少了一些功能&#xff0c;直接并没有连接数据库的工具&#xff0c;所以需要自行下载安装。 安装过程 1.file->settings 2.在Plugins中搜索database 3.点击搜素 4.选中要下载的…

pycharm社区版安装及使用教程(win10系统)

1.下载 下载地址&#xff1a;https://www.jetbrains.com/pycharm/download/#sectionwindows 2.双击安装程序&#xff0c;直接next 3.选择安装路径&#xff08;安装路径最好不要带中文和空格&#xff09; 4.勾选配置&#xff0c;然后next 没有框起来的那一项不用勾选&#xf…

Pycharm的安装并且连接已有的Python环境实现自由编译(附中文配置)|并通过Pycharm实现增加网站访问

&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d;&#x1f51d; &#x1f947;博主昵称&#xff1a;Jovy. &#x1f35f;博客主页…

使用Pycharm连接服务器,实现代码同步

Table of Contents 一.目标 二.本地环境 三.步骤 四.同步代码 五. 配置远程Python解释器 六. 使用远程解释器运行本地Python程序 一.目标 Pycharm软件连接服务器&#xff0c;同步本地代码到服务器 二.本地环境 Pycharm专业版&#xff08;社区版没有该功能&#xff09;…

linux下pycharm专业版和社区版的安装

一.社区版的安装 1.在官网下载pycharm的源码安装包(https://www.jetbrains.com/pycharm/&#xff09; 进入官网&#xff0c;选择toolsx下的pycharm&#xff0c;再点击右上角的download&#xff0c;进去后选择想要的版本即可。 当然安装包也可以通过别人的分享获得&#xff0…