Ox00 前言

本文首发于 语雀笔记


Ox10 异常处理机制

  • SEH
    • __try 和 __except
      • EXCEPTION_EXCUTE_HANDLER : 执行except块
      • EXCEPTION_CONTINUE_EXECUTE : 继续执行(重新执行触发异常的指令)
      • EXCEPTION_CONTINUE_SEACH : 继续搜索
    • __try 和 __finally
    • SEH异常链头节点地址: FS:[0]
  • UEH
  • VEH
  • VCH
  • 异常处理机制优先级: VEH > SEH > UEH > VCH

Ox20 异常分发机制

  • R0->内核调试器->内核SEH处理->第二次->内核调试器->蓝屏
  • R3->内核调试器->用户调试器->回到用户层->VEH->SEH->UEH->VCH->RaiseException->第二次->KiDispathchException->用户调试器->程序结束

Ox30 反调试与反反调试

  • PEB
    • PEB.BeginDebug
      • 字段值为0,否则为1
    • PEB.HeapFlags
      • 结构体中Flags和ForceFlages字段值为2和0
    • PEB.NtGlobalFlag
      • 值为0x70
  • 查询内核信息
    • NtQueryInfomationProcess
      • 参数2设置为0x7,返回int型值,若为-1则表示被调试
      • 参数2设置为0x1E,返回句柄,若为真则表示被调试
      • 参数2设置为0x1F,返回int型值,若为假表示被调试
  • 动态反调试
    • SEH检测
    • 时间戳检测
    • HASH检测
    • 0xCC检测
  •  脱离调试器,ZwSetInformationThread

Ox40 调试器

  • 创建调试会话
    • CreateProcess 并指定DEBUG_PROCESS标志
    • 附加进程 : DebugActiveProcess
  • 接收调试事件
    • WaitForDebugEvent
  • 回复调试子系统
    • DBG_CONTINUE : 继续执行
    • DBG_EXCEPTION_NOT_HANDLE : 未处理
  • 断电原理
    • 单步断点
        1. 使用GetThreadContext获取线程上下文
        1. 将线程上下文的elfags寄存器的TF位设置为1
        1. 使用SetThreadContext设置线程上下文
    • 软件断点
        1. 使用ReadProcessMemory将下断地址处第一个字节读取出备份.
        1. 使用WriteProcessMemory将0xCC写入到下断的第一个字节
    • 硬件断点
      • 将下断的地址写入到 DR0~DR3中
      • 将L0~L3设置为1 , 以启用断点
      • 设置 RW0~RW3
        • 设置为0 : 执行断点
        • 设置为1 : 写入断点
        • 设置为3 : 读写断点
      • 设置LEN0~LEN3,控制断点长度
        • 设置为0 : 表示1字节(断点类型是执行断点时,长度必须是这个)
        • 设置为1 : 表示2字节
        • 设置为3 : 表示4字节
    • 内存断点
      • 将内存分页属性设置为没有访问权限.
      • 当断点断下后, 检测是否命中断点, 如果没有命中还需恢复原始的内存分页属性, 以便代码能够继续执行. 恢复运行前, 还需设置一个单步断点. 在单步断点断下后,需要重新设置内存断点.