无关函数开头的单步异常

逆向工程 例外 CRC
2021-06-18 04:03:48

我正在反转一个应用程序,我知道它使用 CRC 检查的事实,所以如果我修改代码,例如挂钩某些东西,它会被检测到。该应用程序使用了一个 DLL,我用我的自定义 DLL 替换了它,我正在尝试绕过 CRC 检查。然而,这些症状让我感到困惑。如果我修改代码并检测到它,就会发生这种情况:

在此处输入图片说明

然而,这个地址的代码似乎只是一些无关函数的开始: 在此处输入图片说明


我觉得这有点令人费解;我期待类似的东西 if (detected) RaiseException(EXCEPTION_SINGLE_STEP),但它只是在此功能开始时“崩溃”。

  • 这意味着什么?
  • 我认为我们在第一个屏幕截图中看到的内容暗示必须在代码中的某处故意调用 RaiseException 是否正确?
2个回答

它只是意味着应用程序已经设置了陷阱标志(大概是作为对您修改的响应)。但是,这不一定必须通过 RaiseException 发生。相反,它可以像这样完成:

pushf
pop eax
or eax, 100h
push eax
popf

或者通过该代码的简单变体。

更新

请注意,单步异常实际上是陷阱异常(与错误异常相对)。陷阱被升高执行该指令引起该陷阱,而故障被升高之前该指令的执行,将产生故障。例如,在引用分页内存的指令实际执行之前引发页面错误。出于同样的原因,您有除以零错误,您最好在除以零之前获得异常 ;) 因此,您的应用程序中的代码在概念上可能如下所示:

pushf
pop eax
or eax, 100h
push eax
popf
call MySub

并且您在 MySub 的入口处得到异常,这是有道理的,因为在调用执行后会引发异常。另一种可能的解释是,当从内核返回时,引发了 SEH 异常并且在 cpu 上下文中启用了 TF。

好吧,再过几天我就有了一个解决方案。

首先,我仍然完全不知道代码正在做什么导致异常 - 这是对该函数的唯一调用的样子(我已经确定这是代码到达那里的方式 - 返回地址是相同的):

在此处输入图片说明

没有 RaiseException,没有设置陷阱标志 - 我不知道这意味着什么。无论如何,我能够以这种方式丢弃异常:

LONG WINAPI VEH_Handler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
    printf("Got an exception %X at address %X\n", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);

    if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
    {
        printf("patching trap flag\n");

        __asm PUSHF
        __asm POP EAX
        __asm AND EAX, 0xFEFF
        __asm PUSH EAX
        __asm POPF

        return EXCEPTION_CONTINUE_EXECUTION;
    }

    return EXCEPTION_CONTINUE_SEARCH;
}

它有效,我觉得这有点有趣。