反调试 - 用于int 3断点检测的calc函数内存占用

Dav*_*Woo 5 c++ windows visual-studio

我正在研究本文中列出的一些简单的反调试措施 http://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide#BpMem

我已经在给定函数中实现了对int 3断点的简单检查,以便如果在thisIsADummyFunction中的任何位置设置断点,则函数testForInt3Breakpoints返回true .

int thisIsADummyFunction()
{
    int i = rand();
    ++i;  
    return i;
}

bool testForInt3Breakpoints()
{  
    bool breakPointPresent = false;
    unsigned char* memPtr = reinterpret_cast<unsigned char*>( thisIsADummyFunction );

    auto size = 0x16; //this value determined by manual inspection of compiled code

    for ( size_t i = 0; i < size; i++ ) {
        if ( memPtr[ i ] == 0xCC ) {           //see if byte equals int 3 instruction
            breakPointPresent = true;
            break;            
        }
    }
    return breakPointPresent;
}
Run Code Online (Sandbox Code Playgroud)

上面的函数对我来说对于那个特定的函数很好,但我希望能够监视多个函数,而不必每次都检查编译的代码.

我的问题是有没有任何方法来获取函数的内存占用,以便知道要监视的内存?

我知道在运行时没有通用的跨平台方法: 如何以字节为单位获取函数的长度?

但是我在Windows x64和visual studio 2015上运行,并且对于特定于平台的答案或任何可以某种方式自动化该过程的任何事情都非常满意.

Che*_*yDT 0

正如上面的评论中已经指出的,对于这个特定的问题描述没有好的解决方案,特别是不能与扫描 0xCC 结合使用,因为它是一个有效的字节,即使没有设置断点,迟早也会出现在代码中。

如前所述,更好的方法是对整个代码部分进行哈希处理。然而,这样做有以下缺点:

  • 先有鸡还是先有蛋的问题:您需要在编译后获取哈希值,但实际上在代码中使用它来将实际哈希值与预期哈希值进行比较。
  • 根据您执行检查的频率以及代码部分(包括库代码)的大小,这可能会对性能产生更大的影响。另外,如果您在应用程序空闲时进行检查,Windows 将必须调入代码的所有部分,即使它们当前没有执行,从而有效地将整个程序锁定在内存中,即使这不是必需的。
  • 您可能会遇到对其他进程进行低级修改的安全软件和其他工具的问题。像这样的一些工具直接在内存中覆盖/挂钩部分代码以执行附加的安全功能。

如果您仍然想走这条路,您可以使用代码VirtualQuery中任意位置的指针(例如&main)来获取代码部分的边界,然后读取所有内容并使用哈希算法,例如Murmurhash(速度相当快)创建一个哈希并将其与存储的值进行比较。

为了解决那里的母鸡和鸡蛋问题,例如,您可以从程序的运行副本中获取哈希值(使用某种“秘密”命令行开关,或者使用另一个程序读取内存)您使用的OpenProcessVirtualQueryExReadProcessMemory完成工作)并将其存储在不属于哈希的位置,例如您的数据部分或资源。如果您使用后者,您甚至可以在文件中设置正确的哈希值,而无需重新编译它。