欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]反调试之检测类名与标题名

[原创]反调试之检测类名与标题名

本次主要介绍的是基于检测类名与标题名的反调试基本原理

分为两部分:1.介绍涉及到的API 2.实践

涉及到的API函数的学习:

1、GetProcAddress

定义:GetProcAddress是一个计算机函数,功能是检索指定的动态链接库(DLL)中的输出库函数地址。lpProcName参数能够识别DLL中的函数。**

功能描述:

GetProcAddress函数被用来检索在DLL中的输出函数地址.

函数原型:

FARPROC GetProcAddress(

      HMODULE hModule, // DLL模块句柄

      LPCSTR lpProcName // 函数名

    );

参数:

hModule

[in] 包含此函数的DLL模块的句柄。LoadLibrary、AfxLoadLibrary或者GetModuleHandle函数可以返回此句柄。

lpProcName

[in] 包含函数名的以NULL结尾的字符串,或者指定函数的序数值。如果此参数是一个序数值,它必须在一个字的低字节,高字节必须为0。

返回值:

如果函数调用成功,返回值是DLL中的输出函数地址。

如果函数调用失败,返回值是NULL。得到进一步的错误信息,调用函数GetLastError。

句柄(handle):

    一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节) 长的数值,来标识应用程序中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不在I/O文件中,它是毫无用处的。句柄是Windows用来标志应用程序中建立的或是使用的唯一整数Windows大量使用了句柄来标识对象。

2、CreateToolhelp32Snapshot

功能:CreateToolhelp32Snapshot可以通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照。

函数原型:

     HANDLE WINAPI CreateToolhelp32Snapshot(

           DWORD dwFlags, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等

           DWORD th32ProcessID //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取当前进程快照时可以设为0

);

返回值:

     调用成功,返回快照的句柄,调用失败,返回INVALID_HANDLE_VALUE

3、OpenProcess

位置:Kernel32.dll
功能:OpenProcess函数用来打开一个已存在的进程对象,并返回进程的句柄。

函数原型:

HANDLE OpenProcess(

          DWORD dwDesiredAccess, //渴望得到的访问权限(标志)

          BOOL bInheritHandle, // 是否继承句柄

          DWORD dwProcessId// 进程标示符

);

4、Process32First

功能:process32First 是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,我们可以利用process32First函数来获得第一个进程的句柄.

5、Process32Next

功能:Process32Next是一个进程获取函数,当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,我们可以利用Process32Next函数来获得下一个进程的句柄

6、TerminateProcess

功能:结束一个程序

7、FindWindowA(关键函数)

功能:findwindow是函数检索处理顶级窗口的类名和窗口名称匹配指定的字符串,这个函数不搜索子窗口。

函数原型:

HWNDFindWindow

(

    LPCSTRlpClassName,//指向类名

    LPCSTRlpWindowName//指向窗口名

);

如果有指定的类名和窗口的名字则表示成功返回一个窗口的句柄。否则返回零。

参数:

lpClassName:

    指向一个以null结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。

如果该参数为null时,将会寻找任何与lpWindowName参数匹配的窗口。

lpWindowName:

指向一个以null结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。

返回值:

如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。

如果函数执行失败,则返回值为NULL。可以通过调用GetLastError函数获得更加详细的错误信息。

实践部分:

测试文件:bugger.exe(已上传至附件)
使用工具:OllyDbg v1.10
运行环境:windows xp(虚拟机)

1.学会使用软件

①当我们打开bugger.exe,会弹出如下提示:

②当我们先打开ollydbg,再打开此软件时,无任何弹窗。

猜想:此软件内部设有反调试机制,当我们运行此软件时,它会检测此时是否有调试软件(这里是ollydbg)正在运行,若有,则不运行,若无,则正常运行此软件。(当我们每次分析一个软件的时候,都应该学会首先使用这个软件,并做一定的测试,再做出一定的猜想)

2.分析原因

①首先将此软件载入od(如下图所示):

检查函数列表(ctrl+N):

我们发现函数列表中只有一个退出进程函数,并没有什么可疑函数供我们下断。我在前文介绍的第一个函数就是GetProAddress(需要了解的话可以看下)。此函数我们可以理解为一个间接调用函数,它里面存储了大量函数的地址。我们这里也可以猜想一下程序是否调用了此函数,此函数非常重要需要我们重点掌握,我们可以给此函数下F2断点(如图),这个函数由于没有在函数列表中显示,我们可以采取用bp的方式。这里也需要强调一点,不能对在函数列表中没有的函数使用bp的方式下断点,此函数不知道为什么是可以的,如果读者想要弄清楚可以自行研究,哈哈。

查看断点窗口,检查是否下好,已存在(如下图)

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功