2

Hi I was learning reverse engineering by doing some crackme(s) found online using IDA and x64dbg.

I'm quite confused on the below decompiled code.

bool Logic()
{
    char CODE[] = "RAND_STRING", *lpString1, *v13, v14;
    char CONST_STRING1[] = "XZULKBBXOK";
    char CONST_STRING3[] = "ZXHYGKLQ9867WEPRCDSANMJBVFTU5342";
    int* v10 = CONST_STRING1;
    int* a2 = CONST_STRING1;
    int* v2 = a2;
    int* a1 = CODE;
    int v3;
    char v4, v6;
    char v7;
    int v8;
    char v9;
    char v10;
    char v11;
    v3 = lstrlenA(CONST_STRING3);
    if ( *a2 )
    {
        v4 = CONST_STRING3[0];
        do
        {
            v6 = *a1;
            if ( !*a1 )
                break;
            if ( v6 < 48 || v6 > 122 )
            {
                ++a1;
            }
            else
            {
                v7 = TO_UPPER(*a1);
                v8 = 0;
                if ( v4 )
                {
                    v9 = v4;
                    do
                    {
                        if ( v9 == v7 )
                        break;
                        v9 = CONST_STRING3[++v8];
                    }
                    while ( v9 );
                }
                v10 = TO_UPPER(*v2);
                if ( v10 % v3 != v8 )
                return 0;
                ++a1;
                ++v2;
            }
        }
        while ( *v2 );
    }
    return *v2 == 0;
}

Basically it checks whether the initial character of CODE falls inside CONST_STRING3, what puzzles me is the next condition following it

if ( v10 % v3 != v8 )
return 0;

What does this code snippet mean? Why is modulus operation done between the ASCII value of first string in CONST_STRING1 and strlen(CONST_STRING3) and then compared with the index upon the loop break?

Some help to understand this is much appreciated.

EDIT ---- Added TO_UPPER decompiled - code

int __cdecl TO_UPPER(unsigned __int8 a1)
{
  int result; // eax

  result = a1;
  if ( (char)a1 >= 97 && (char)a1 <= 122 )
    result = a1 - 32;
  return result;
}
1
  • is rand_string the pass_phrase it appears to be checking if rand_string == result of this >>> for i in "XZULKBBXOK": ... print("ZXHYGKLQ9867WEPRCDSANMJBVFTU5342"[(ord(i)%0x20)-1])
    – blabb
    Apr 13 at 20:38

1 Answer 1

2

Are you sure TO_UPPER's purpose is uppercasing? The strings are all in uppercase anyway and it seems like it returns an index from an iterator rather than a modified character.

If you take a look at v3, it's CONST_STRING3's length:

v3 = lstrlenA(CONST_STRING3);

Conditions of type index % length are a common pattern in decompiled code, they prevent index overflow in arrays - for instance if CONST_STRING1 was longer than CONST_STRING3.

v8 is some index in CONST_STRING3 while v10 looks like the currently processed index of CONST_STRING1. The condition below could be interpreted as:

if ( v10 % v3 != v8 )
return 0;

If we're at different indexes of CONST_STRING1 and CONST_STRING3, return false (likely to indicate processing failure).

Note that the processing is not linear and the value of v8 depends on CODE.

2
  • Thanks @mimak for the answer, I've added in the decompiled code I found for TO_UPPER, can you verify whether it returns the index or the modified character?
    – Nimrod
    Apr 13 at 12:25
  • Well it definitely does just that. I'm unsure about this function's purpose, however if you want to make it return true the easiest way to do that is to set CONST_STRING1 to an empty string.
    – mimak
    Apr 15 at 13:15

Your Answer

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

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