文章目录

  • 声明
    • 静态反调试目的
    • 注意
  • PEB
  • https://blog.csdn.net/CSNN2019/article/details/113113347
    • BeingDebugged(+0x2)
    • 破解之法:
    • Ldr(0xc)
    • 破解之法:
    • ProcessHeap(+0x18)
    • Flags(0xC)&Force Flags(+0x10)
    • 破解之法:
    • NtGlobalFlag(+0x68)
    • 破解之法
    • 调试程序代码
  • 反调试技术系列:

声明

静态反调试目的

被调试的进程用静态反调试技术来侦测自身是否处于被调试状态,若侦测到处于被调试的状态,则执行非常规代码(主要是终止代码)来阻止。具体的实现方法包括调试器检测方法调试环境检测方法强制隔离调试器的方法等等。反调试破解方法主要用来从探测代码获取信息然后修改信息本身使反调试技术失效

注意

许多静态反调试技术对OS具有很强的依懒性。这意味着静态反调试技术在Windows XP 系统下可以正常使用,而在Windows Vista/7操作系统中可能失效

接下来的东西需要用到以下知识,请自行查看:

PEB

https://blog.csdn.net/CSNN2019/article/details/113113347

 +0x002 BeingDebugged    : UChar+0x00c Ldr              : Ptr32 _PEB_LDR_DATA+0x018 ProcessHeap      : Ptr32 Void+0x068 NtGlobalFlag     : Uint4B

BeingDebugged(+0x2)

kernel32.dll中有个名Kernel32!IsDebuggerPresent()的API,但普通的应用程序开发中并不常用:

BOOL WINAPI IsDebuggerPresent()

该API就是用来判断当前进程是否处于调试状态,并返回判断结果。而该API就是通过检测PEB.BeingDebugged成员来确定是否正在调试程序(是,则返回1;否,则返回0)。

老办法,查看一下OD:


代码如下:

75074E80 >  64:A1 30000000  mov eax,dword ptr fs:[0x30]
75074E86    0FB640 02       movzx eax,byte ptr ds:[eax+0x2]
75074E8A    C3              retn

提示:
Windows 7中,IsDebuggerPresent()API是在Kernelbase.dll中实现的。而在Windows XP 及以前版本的操作系统中,它是在kernel32.dll中。

先获取FS:[30]地址,即PEB地址,然后通过[PEB+2]访问BeingDebugged

这里取出来的是0的原因呢,是因为吾爱破解OD太强悍了,加了很多插件。。。

慢慢关闭就行,用原版OD或者IDA就能返回1。

破解之法:

用吾爱破解的OD(滑稽。。哈哈),用OD 的编辑功能把BeingDebugged改为0即可。

Ldr(0xc)

调试进程时,其堆内存区域中就会出现一些特殊标识,表示它正处于被调试状态。其中未使用的堆内存区域全部填充着0xEEFEEEFE,这证明正在调试进程。利用这点可判断进程正在被调试。

PEB.Ldr成员是一个指向_ PEB_ LDR DATA结构体的指针,而 PEB_ LDR _DATA结构体恰好是在堆里面创建的,所以扫描该区域即了轻松查找是否存在0xEEFEEEFE区域

PEB起始地址为0x3D2000,然后指针指向的区域是0x7710DCA0



我看了一下,我的没有。。。有的堆内存中,如果往下拖动滑动条,会看到填充着0xEEFEEEFE的区域。。

破解之法:

只要将填充着0xEEFEEEFE值的区域全部覆写为NULL即可

提示:
该方法仅仅适用于Windows XP系统,而在Windows Vista 以后的系统中则无法使用。另外,利用附加功能的将运行中的进程附加调试器时,堆内存中并不出现上述标识

ProcessHeap(+0x18)

PEB.ProcessHeap(+0x18)成员是指向HEAP结构体的指针

+0x000 Entry                        :_HEAP_ENTRY
+0x008 Signature                   :Unit4B
+0x00c Flags                       :Unit4B
+0x010 ForceFlags                  :Unit4B
+0x014 VirtualMemoryThreshold      :Unit4B
+0x018 SegmentReserve              :Unit4B
+0x01c     SegmentCommit               :Unit4B
+0x020 DeCommitFreeBlockThreshold  :Unit4B
……………………………………………………………………

以上列出了HEAP结构体的部分成员,进程处于调试状态时,Flags(+0xC)与ForceFlags成员(+0x10)被设置为特定值

GetprocessHeap():

PEB.ProcessHeap成员(+0x18)既可以从PEB结构体直接获取,也可以通过GetprocessHeap()API获取。下面看看GetprocessHeap()API的代码


直接PEB—>PEB.ProcessHeap顺序访问


PEB.ProcessHeap=0x6B0000

Flags(0xC)&Force Flags(+0x10)

进程正常运行(非调试运行)时,Heap.Flags成员(+0xC)的值02,Heap.ForceFlags成员(+0x10)值为0。进程处于被调试状态时,这些值也会随之改变。

注意:
1.这里我用的是吾爱破解版的OD,插件比较多,内存单元里的值不能作参考。。。
2.该方法仅在Windows XP系统中有效,Windows 7系统则保留ForceFlags属性和Flags属性。此外,将运行中的进程附加到调试器时,也不会出现上述特征。

所以,比较这些值,就可以判断进程是否处于被调试状态。

破解之法:

只要将Heap.Flags成员(+0xC)的值设置成02,Heap.ForceFlags成员(+0x10)值设置成0。

NtGlobalFlag(+0x68)

调试进程时,PEB.NtGlobalFlag成员(+0x68)的值会被设置0x70。所以,检测该成员的值即可判断进程是否处于被调试状态。

NtGlobalFlag 0x70是下列Flags进行bit OR(位或)运算的结果

FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
FLG_HEAP_ENABLE_FREE_CHECK (0x20)
FLG_HEAP_VALIDATE_PARAMETERS (0x40)



被调试进程的堆内存中存在(不同于非调试运行进程的)特别标识,因此在PEB.NtGlobalFlag成员中添加了上述标志。(注意:这个OD的插件太多了。。。)

注意:
将运行的进程附加到调试器时,PEB.NtGlobalFlag的值不变

破解之法

重设PEB.NtGlobalFlag值为0即可(PEB.NtGlobalFlag=0).

strongOD->Options中的HidePEB可以绕过。

调试程序代码

#include "stdio.h"
#include "windows.h"
#include "tchar.h"void PEB()
{HMODULE hMod = NULL;FARPROC pProc = NULL;LPBYTE pTEB = NULL;LPBYTE pPEB = NULL;BOOL bIsDebugging = FALSE;//<span style="color:#ff0000;">[pPEB+0x2]==0x1</span>// IsDebuggerPresent()bIsDebugging = IsDebuggerPresent();printf("IsDebuggerPresent() = %d\n", bIsDebugging);if( bIsDebugging )  printf("  => Debugging!!!\n\n");else                printf("  => Not debugging...\n\n");// Ldr xp特有pProc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCurrentTeb");pTEB = (LPBYTE)(*pProc)();               // address of TEBpPEB = (LPBYTE)*(LPDWORD)(pTEB+0x30);     // address of PEBprintf("PEB.Ldr\n");DWORD pLdrSig[4] = { 0xEEFEEEFE, 0xEEFEEEFE, 0xEEFEEEFE, 0xEEFEEEFE };LPBYTE pLdr = (LPBYTE)*(LPDWORD)(<span style="color:#ff0000;">pPEB+0xC</span>);__try {while( TRUE ){if( !memcmp(pLdr, pLdrSig, sizeof(pLdrSig)) ){printf("  => Debugging!!!\n\n");break;}pLdr++;}}__except (EXCEPTION_EXECUTE_HANDLER){printf("  => Not debugging...\n\n");}// Process Heap - Flags     xp特有bIsDebugging = FALSE;LPBYTE pHeap = (LPBYTE)*(LPDWORD)(<span style="color:#ff0000;">pPEB+0x18</span>);DWORD dwFlags = *(LPDWORD)(<span style="color:#ff0000;">pHeap+0xC</span>);printf("PEB.ProcessHeap.Flags = 0x%X\n", dwFlags);if( dwFlags != 0x2 )  printf("  => Debugging!!!\n\n");else                  printf("  => Not debugging...\n\n");// Process Heap - ForceFlags xp特有bIsDebugging = FALSE;DWORD dwForceFlags = *(LPDWORD)(<span style="color:#ff0000;">pHeap+0x10</span>);printf("PEB.ProcessHeap.ForceFlags = 0x%X\n", dwForceFlags);if( dwForceFlags != 0x0 )  printf("  => Debugging!!!\n\n");else                       printf("  => Not debugging...\n\n");// NtGlobalFlagbIsDebugging = FALSE;DWORD dwNtGlobalFlag = *(LPDWORD)(<span style="color:#ff0000;">pPEB+0x68</span>);printf("PEB.NtGlobalFlag = 0x%X\n", dwNtGlobalFlag);if( (dwNtGlobalFlag & 0x70) == 0x70 )  printf("  => Debugging!!!\n\n");else                                   printf("  => Not debugging...\n\n");
}int _tmain(int argc, TCHAR* argv[])
{PEB();printf("\npress any key to quit...\n");_gettch();return 0;
}

反调试技术系列:

静态反调试技术(1)https://blog.csdn.net/CSNN2019/article/details/113105292
静态反调试技术(2)https://blog.csdn.net/CSNN2019/article/details/113147820
静态反调试技术(3)https://blog.csdn.net/CSNN2019/article/details/113178232
动态反调试技术 https://blog.csdn.net/CSNN2019/article/details/113181558
高级反调试技术 https://blog.csdn.net/CSNN2019/article/details/113263215

静态反调试技术(1)相关推荐

  1. 静态反调试技术(2)

    文章目录 NtQueryInformationProcess() `ProcessDebugPort`(0x7) CheckRemoteDebuggerPresent() ProcessDebugOb ...

  2. 静态反调试技术(3)

    文章目录 ZwSetInformationThread 破解方法 **调试程序代码**: 利用TLS回调函数(详情通过以下链接查看) ETC 破解之法 **调试程序代码**: 篇章大总结: 反调试技术 ...

  3. 详解反调试技术(转)

    反调试技术,恶意代码用它识别是否被调试,或者让调试器失效.恶意代码编写者意识到分析人员经常使用调试器来观察恶意代码的操作,因此他们使用反调试技术尽可能地延长恶意代码的分析时间.为了阻止调试器的分析,当 ...

  4. 反调试技术揭秘(转)

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编之类的方法破解自己.为了了解如何破解反调试技术, ...

  5. windows平台下的反调试技术

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...

  6. Windows反调试技术全攻略

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...

  7. 如何绕过反调试技术——PhantOM插件总结

    PhantOM是OllyDbg的一款插件,可以用来绕过大多数的反调试技术,功能十分强大,所以单独对这个插件进行使用总结.(Ps:现在似乎不怎么常用,在64位下的兼容性比较差,现在比较常用的是sharp ...

  8. 恶意软件反检测技术简介:反调试技术解析

    本文中,我们将向读者介绍恶意软件用以阻碍对其进行逆向工程的各种反调试技术,以帮助读者很好的理解这些技术,从而能够更有效地对恶意软件进行动态检测和分析. 一.反调试技术 反调试技术是一种常见的反检测技术 ...

  9. 180306 逆向-反调试技术(1)BeingDebugged

    1625-5 王子昂 总结<2018年3月6日> [连续第521天总结] A. 反调试技术(1) B. BeingDebugged Win32API为程序提供了IsDebuggerPres ...

最新文章

  1. localStorage值的最大大小是多少?
  2. Ubuntu常用命令与技巧
  3. 醒来觉得甚是爱你。--朱生豪
  4. 浅学JavaScript
  5. 2019.8.15几道练习题
  6. C# 关于yield return的研究(转载)
  7. python2添加pip,无法在python2.6中使用PIP更新/添加任何包
  8. c++类与对象(1)——构造,复制构造函数
  9. PHP获取每个订单下订单商品的数量
  10. matlab实验求不定积分函数,如何用matlab求取函数的不定积分与定积分 涨知识了...
  11. 34岁程序员年薪50w,java工程师转正答辩
  12. C++自定义列表实现贪吃蛇
  13. Android 单个指定蓝牙设备通讯流程
  14. FITS文件标准 1:介绍
  15. HDU 5755 Gambler Bo(数论)
  16. zxing 生成二维码,可设置logo、二维码颜色、白边大小
  17. 使用vi编辑器编辑一个C语言源程序hello.c,并使用编译工具GCC编译该源程序。
  18. srand rand RAND_MAX
  19. django3.0+ 使用 xadmin
  20. SiteRAS一款外贸网站SEO分析工具,给您的网站做个深度体检

热门文章

  1. 使鼠标保持按住状态_MouseInc 鼠标手势工具
  2. 成功解决 修改pip的默认安装packages包的路径
  3. 微信小程序——添加按钮格式
  4. os_mem.c(全)
  5. log4j无法显示mybatis sql
  6. 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包 - - 博客频道 - CSDN.NET...
  7. Ubuntu Linux系统下的SVN客户端工具PySVN
  8. Merge Sorted Array
  9. unity3d-知识汇总
  10. Ubuntu 下连接Github