逆向——反调试

逆向——反调试

  • 反调试
    • IsDebuggerPresent
    • 检测进程名
    • 检测类名与标题名
    • ZwQueryInformationProcess
    • 两个标志一个崩溃
            • 参考文献

反调试

阻止你调试这个程序。

IsDebuggerPresent

  • 检测用户是否正在调试程序
  • 语法
    BOOL WINAPI IsDebuggerPresent(void);
  • 返回值:检测到在进行调试返回非0值,没检测到返回0.
    返回值90%都放在EAX。
  • 检测到非0值后,会调用PostQuitMessage(投递退出消息)、ExitProcess(结束进程)函数。
  • 汇编下的代码(3行)
    • MOV EAX, DWORD PTR FS:[18]
      FS:[18]存储的就是FS寄存器的起始地址,也就是将FS寄存器的起始地址放入EAX
    • MOV EAX, DWORD PTR DS:[EAX+30]
    • MOVZX EAX, BYTE PTR DS:[EAX+2]
  • OD中绕过插件
    • Hide Debugger

检测进程名

  • 依照进程名判断是否开启OD
  • 实现原理
    • 相关函数
      • GetProcAddress:获取函数地址(可查看间接调用的函数)
        如果想在函数列表中设置找不到的函数(被隐藏),可通过该函数找到目标函数的地址。
      • EnumProcesses:获取当前进程列表的PID。
      • OpenProcess:利用PID获取句柄。
        一个程序获取了另一个程序的句柄,那么这个程序就可以操纵另一个程序。
      • EnumProcessModules:通过句柄获取对应进程的基址。
      • GetModuleBaseNameA:获取当前句柄的进程名。
      • CloseHandle:释放句柄。
      • TerminateProcess:关闭当前进程并结束所有线程。
    • 整个分析流程
      逆向——反调试_第1张图片
  • 绕过方法
    • 给程序改名字

检测类名与标题名

  • 相关API
    • CreataToolhelp32Snapshot:将当前进程中的信息做一个快照,将快照的句柄返回给EAX。
    • Process32First:获取快照中第一个进程的内容。
    • OpenProcess:根据PID获取句柄。
    • Process32Next:获取快照中下一个进程的内容。
    • TerminateProcess:结束进程。
    • lstrcmpA:字符串比较。
    • FindWindowA:通过参数(类名或标题)获得程序的句柄。
  • 分析流程
    逆向——反调试_第2张图片

ZwQueryInformationProcess

利用程序异常达到反调试的目的。

  • OD未设置任何断点运行程序会自动断下。
  • 相关API
    • SetUnhandleExceptionFilter调用UnhandleExceptionFilter
      • 功能
        判断是否调试,以及异常是否有地方处理,当没有调试并发生异常就将异常给其参数中的代码去处理。
    • 在UnhandleExceptionFilter下断,然后跟进到ZwQueryInformationProcess
    • ZwQueryInformationProcess:判断是否在调试
      • 参数
        • InfoClass:函数功能
        • Buffer:判断结果,在OD中不是00 00 00 00就是在调试

三者之间不是必须相互依赖。

  • 绕过
    • 插件:HideOD

两个标志一个崩溃

  • 两个标志
    • ProcessHeap标志:FS:[68]改为00 00 00 00
    • NTGlobalFlag标志:FS:[18]作为地址查看数据,此时加10的偏移量处的数据改为00 00 00 00
  • 一个崩溃(OD的一个Bug)
    • OutputDebugStringA
      • 原理
        输出一个长字符串,OD无法处理会导致错误,进而程序崩溃。
      • 修复
        插件
参考文献

《逆向视频》

你可能感兴趣的:(逆向)