2

I'm reversing an application and I know for a fact it employs CRC checks, so if I modify the code, for instance hooking something, it'll be detected. The application uses a DLL which I replaced with my custom one and I'm trying to get around the CRC checks. The symptoms are, however, puzzling me. This is what happens if I modify the code and it gets detected:

enter image description here

However, it seems that the code at this address is just the start of some unrelated function: enter image description here


I find that a bit puzzling; I expected something like if (detected) RaiseException(EXCEPTION_SINGLE_STEP), and instead it simply "crashes" at the start of this function.

  • What does that mean?
  • Am I right in thinking that what we see in the first screenshot implies RaiseException must be deliberately called somewhere in the code?

2 Answers 2

1

It simply means the application has set the trap flag (presumably as a response to your modifications). However, this doesn't necessarily have to happen via RaiseException. Instead, it could have been done like this:

pushf
pop eax
or eax, 100h
push eax
popf

Or by a simple variaion of that code.

Update:

Note that a single step exception is in fact a trap exception (as opposed to a fault exception). A trap is raised after the instruction executed that caused the trap, whereas a fault is raised before the instruction executes that would generate that fault. For example, a page fault is raised before the instruction that references paged memory actually executes. For the same reason you have division by zero faults, you better get the exception before dividing by zero ;) So the code in your application might conceptually look like this:

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

And you get the exception at the entry of MySub, which makese sense because the exception is raised after the call executed. Another possible explanation could be, that an SEH exception is raised and the TF is enabled in the cpu context upon return from the kernel.

5
  • Okay, and why does MSVC claim it happens at that address? Is that correct? If yes, what does the function have to do with anything?
    – user4520
    Commented Feb 22, 2015 at 17:18
  • Instead of popf, the code might be pushing the address of your function, then use iret to return to that function and pop the changed flags at the same time. If i remember correctly, if the NT (nested task) flag isn't set, the protected mode iret works very much like the real mode iret (pop ip, pop cs, pop flags, execute next instruction at ip). Did you check the xref at 0x41de94 ? Commented Feb 22, 2015 at 19:29
  • @Guntram yes this would work, but then he'd get the exception after the first instruction in the function above, not before the first instruction.
    – newgre
    Commented Feb 22, 2015 at 19:43
  • Hmmm, last time i played with the trap flag was in DOS times - must be 20 years ago. So this means that after setting the trap flag, one more instruction gets executed before the trap happens. So a jmp after the popf should do the trick, shouldn't it? Commented Feb 22, 2015 at 21:31
  • Oops, didn't see the update. Commented Feb 22, 2015 at 21:31
0

Okay, after a few more days I sort of have a solution.

First off, I still have absolutely no idea what the code is doing to cause the exception - this is what the only call to the function looks like (and I've made sure this is how the code gets there - the return address is the same):

enter image description here

No RaiseException, the trap flag is not set - I have no ideas what this means. Regardless, I was able to discard the exception in this way:

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;
}

It works, which I find somewhat amusing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.