65.9K
CodeProject 正在变化。 阅读更多。
Home

反 BPX

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.69/5 (8投票s)

2004年9月8日

CPOL

2分钟阅读

viewsIcon

82605

简单检查系统调试器的执行断点!

Sample Image - Anti_BPX.jpg

引言

任何软件都可以通过调试器逐步分析!调试器是发现错误的有效工具,但大多数时候,黑客/破解者使用它来更改我们程序的保护程序,或者更糟糕的是,为了逆向工程整个算法!

背景

在 Windows 系统中,存在一个名为 IsDebuggerPresent 的 API 函数(包含在 kernel32.dll 中)。它用于验证是否存在调试器。此函数在 Windows 95 中不存在。使用 VB.NET 中的指针来查看也很有趣!

示例代码 (VB.NET)

Declare Function IsDebuggerPresent Lib "kernel32" () As Integer

Dim chkDebug as Integer = IsDebuggerPresent
chkDebug = 0 --> not debugged
chkDebug = 1 --> debugged

使用代码

在本演示中,假设使用 SoftIce 调试器。

似乎很简单,我可以阻止黑客!不幸的是,事实并非如此,因为我们的对手可以自己采取行动

  1. 启动调试器;
  2. 它按下 ctrl+d;
  3. 它写入 BPX IsDebuggerPresent
  4. 按下 F5 以便发送到程序的执行中,神奇地出现一个类似于此的窗口(代码汇编器 x86)

    001B:77E52740    64A118000000    MOV    EAX, FS:[00000018] 
    001B:77E52746    8B4030          MOV    EAX, [EAX+30] 
    001B:77E52749    0FB64002        MOVZX  EAX, BYTE PTR [EAX+02] 
    001B:77E5274D    C3              RET

因此,它不必进行其他更改,只需修改函数的返回值和/或直接为库 kernel32.dll 打补丁

001B:77E52749    0FB64002        MOVZX  EAX, BYTE PTR [EAX+02]

它变成

001B:77E52749    33C0            XOR    EAX, EAX    ;return always 0 !
001B:77E5274B    90              NOP                ;nothing
001B:77E5274C    90              NOP

我们的对手是一个很好的逆向工程师!但是从那件事我们可以做什么?我们可以检查 BPX 的存在。BPX 意味着实际上将十六进制值 0CCh 放入一个确定的内存区域中。为了解决这个问题,我们获得我们感兴趣的内存地址(在这种情况下,在我的 WinXP home 上),即 77E52740h,并验证在 14 个字节中的一个是否存在等于 0CCh 的值!似乎很简单。

我们使用 API

Declare Function LoadLibrary Lib "kernel32" Alias _
      "LoadLibraryA" (ByVal lpLibFileName As String) As Integer
Declare Function FreeLibrary Lib "kernel32" Alias _
      "FreeLibrary" (ByVal hLibModule As Integer) As Integer
Declare Function GetProcAddress Lib "kernel32" Alias _
      "GetProcAddress" (ByVal hModule As Integer, _
      ByVal lpProcName As String) As Integer

我们按如下方式进行

  1. 我们将库 kernel32.dll 加载到内存中;
  2. 我们使用 GetProcAddress 找到 API IsDebuggerPresent 的地址;
  3. 我们分析内存区域。

示例代码 (VB.NET)

Dim hLib As Integer = LoadLibrary("kernel32") 'address base
Dim apiaddress as integer = GetProcAddress(hLib, _
                "IsDebuggerPresent") 'return value: 77E52740h
Dim memdebug(13) As Byte 'lenght 14-1
'<<<
Marshal.Copy(IntPtr.op_Explicit(apiaddress), _
        memdebug, _
        0, _
        memdebug.Length) 'read to memory pointer
'+++
Dim bFlag as Boolean = False
Dim ij As Integer
For ij = 0 To memdebug.Length - 1
    If memdebug(ij) = &HCC Then
            '[i] no bpx please
        bFlag = True
        Exit For
    End If
Next ij
FreeLibrary(hLib) 'release library
'+++
If bFlag Then
    '[i] some actions: reset, hd format ;-p, ...your creativity!
End If

显然,这只是一个例子!您可以分析和检查从其地址开始的任何内存部分。

关注点

阻止我们程序的逆向工程会使黑客/破解者陷入困境……至少是那些不太擅长的人!

作者的其他文章

有关更多信息,请访问我的网站(持续现代化中)。

历史

2004 年 9 月:首次公开发布。(对不起,我的英语不好……我是意大利人。)

© . All rights reserved.