THIS WRITEUP IS VERY VERY LONG AND MOST OF THE PART IS NOT ACTUALLY RELATED TO THE VM. YOU CAN SKIP TO THE “THE MOMENT OF TRUTH” TO ACTUALLY READ THE SOLUTION.

After completing the previous CrackMe based on a very good Anti-Debug technique (which can be further improved as I pointed out in that post by reading a research paper), Elvis, the author of previous challenge gave me another challenge. He already gave me a major hint about the challenge which you usually don’t get in real world scenarios. This challenge is another VM challenge and is an OISC (One Instruction Set Computer)

Untitled

Running the executable shows a password prompt :

Untitled

I type anything into it and it keeps watining until unless I exceed certain number of characters, after which it just exits. I don’t know this “certain number” yet but we can find this out by analyzing this in IDA.

Running this in IDA debugger successfully shows this prompt again but pausing the process is something else. We either run this process or stop it, no pausing and resuming execution. This might mean there is anti-debug or something more interesting to discover 🤩

Let’s analyze the start function of this program

Untitled

aha… ok.. ok.. analysis of start complete 😆

This is spooky. I’ll rename these to mainfn1 and mainfn2 to be able to identify them when I encounter these again, but then again I can also check their XREFs and see when they are called or referenced, but this won’t be able to detect indirect references.

uintptr_t mainfn1() {
    uintptr_t result; // eax
    unsigned int v1; // ecx
    LARGE_INTEGER PerformanceCount; // [esp+0h] [ebp-14h] BYREF
    struct _FILETIME SystemTimeAsFileTime; // [esp+8h] [ebp-Ch] BYREF
    DWORD v4; // [esp+10h] [ebp-4h] BYREF

    if (__security_cookie == -1153374642 || (__security_cookie & 0xFFFF0000) == 0) {
        SystemTimeAsFileTime.dwLowDateTime = 0;
        SystemTimeAsFileTime.dwHighDateTime = 0;
        GetSystemTimeAsFileTime( & SystemTimeAsFileTime);
        v4 = SystemTimeAsFileTime.dwLowDateTime ^ SystemTimeAsFileTime.dwHighDateTime;
        v4 ^= GetCurrentThreadId();
        v4 ^= GetCurrentProcessId();
        v4 ^= GetTickCount64();
        QueryPerformanceCounter( & PerformanceCount);
        result = (uintptr_t) & v4;
        v1 = (unsigned int) & v4 ^ v4 ^ PerformanceCount.LowPart ^ PerformanceCount.HighPart;
        if (v1 == 0xBB40E64E) {
            __security_cookie = 0xBB40E64F;
            dword_B44008 = 0x44BF19B0;
        } else {
            if ((v1 & 0xFFFF0000) == 0) {
                result = (v1 | 0x4711) << 16;
                v1 |= result;
            }
            __security_cookie = v1;
            dword_B44008 = ~v1;
        }
    } else {
        result = ~__security_cookie;
        dword_B44008 = ~__security_cookie;
    }
    return result;
}

Untitled

Untitled

Untitled

Untitled

Untitled

Untitled