
反调试之内存非法访问易语言源码实现原理:创建一个特定的“陷阱”内存页,然后将其从进程的**工作集(Working Set)**中清除。
创建陷阱内存:
程序使用 VirtualAlloc 分配一块 4096 字节的内存区域作为“陷阱”。
清除工作集:
调用 EmptyWorkingSet,将所有内存页从物理内存中移除。此时,陷阱内存页的 Valid 标志位变为 0。
循环检测:
程序使用 QueryWorkingSetEx 持续监控陷阱内存页的状态。通过位运算(位与 (PWINFO.PSAPI_WORKING_SET_EX_BLOCK, 1))来检查 Valid 标志。
检测非法访问:
一旦有调试器或 Hook 程序尝试访问这块内存,Windows 会触发缺页中断,并将该页面重新加载到物理内存。这时,Valid 标志就会从 0 变为 1。
触发警报:
程序检测到 Valid 标志变为 1 后,会立即弹窗并结束程序,从而实现反调试。
如何实现
选择目标函数:选择一个在程序运行时不经常被调用,但又不能被删除的函数。例如,一个用于初始化配置、只在程序启动时运行一次的函数,或者是一个用于日志记录、但目前处于关闭状态的函数。
设置陷阱:在程序正常运行期间,当你不需要调用这个函数时,你可以将这个函数的代码页从进程的工作集中移除(使用 EmptyWorkingSet)。
循环监控:你的监控线程会像之前一样,持续检查这个函数代码页的 Valid 标志。
按需使用:当你的程序需要真正执行这个函数时,你只需调用它。此时,操作系统会再次触发缺页中断,将代码页重新加载到物理内存中,Valid 标志会变为 1。在函数执行完毕后,你再将它从工作集中移除,继续监控。
反调试效果:如果一个调试器或Hook程序试图在你的程序不调用这个函数时,去查看或修改这个函数所在的内存区域,就会提前触发缺页中断。你的监控线程会立即捕捉到 Valid 标志的异常变化,并采取相应的反调试措施。


评论(0)