0

Does anyone know of any helpful tools or a way to automate decryption of XOR in IDA? I know that they have a built in function to do some bare XOR encryption but this one seems a bit more sophisticated. I was having issues trying to create a signature to auto find the examples but I could pick them out by hand all day.

I found this in some malware I was reversing to see if I could find their config / server to report it.

IDA's decompile:

if ( !(v19 << 31) && j___cxa_guard_acquire((__guard *)&byte_41C448) )
  {
    dword_41C69B = -1227590233;
    dword_41C697 = -1856542672;
    dword_41C693 = -1661843002;
    word_41C69F = 325;
    _cxa_atexit((void (__fastcall *)(void *))sub_1014B0, &dword_41C693, &off_40EC10);
    j___cxa_guard_release((__guard *)&byte_41C448);
  }
  if ( HIBYTE(word_41C69F) )
  {
    LOBYTE(dword_41C693) = dword_41C693 ^ 0x87;
    BYTE1(dword_41C693) ^= 0x3Bu;
    BYTE2(dword_41C693) ^= 0x91u;
    HIBYTE(dword_41C693) ^= 0xF9u;
    LOBYTE(dword_41C697) = dword_41C697 ^ 0x45;
    BYTE1(dword_41C697) ^= 0x1Bu;
    BYTE2(dword_41C697) ^= 0x77u;
    HIBYTE(dword_41C697) ^= 0xC9u;
    LOBYTE(dword_41C69B) = dword_41C69B ^ 0x87;
    BYTE1(dword_41C69B) ^= 0x3Bu;
    BYTE2(dword_41C69B) ^= 0x91u;
    HIBYTE(dword_41C69B) ^= 0xF9u;
    word_41C69F = (unsigned __int8)word_41C69F ^ 0x45;
  }

Example of the dissembled view of the XOR, the keys change for each hash which is what makes it hard to decrypt, I could do it all by hand but I want to automate it somehow in IDA.

Example of XOR in dissembled code

Example of decompiled code

This was my manual decompile of the XOR in C: (pretty much an exact copy of it)

include <stdio.h>
#include <stdint.h>
#include <string.h> // Necessary for memset

#define LOBYTE(addr) *(uint8_t*)(bytes + addr - offset)
#define BYTE1(addr) *(uint8_t*)(bytes + addr - offset + 1)
#define BYTE2(addr) *(uint8_t*)(bytes + addr - offset + 2)
#define HIBYTE(addr) *(uint8_t*)(bytes + addr - offset + 3)

int main() {
    uintptr_t offset = 0x41DB11;
    uint8_t bytes[0x1000];
    memset(bytes, 0, 0x1000);

    // Set the new values according to the example
    *(uint32_t*)(bytes + 0x41DB11 - offset) = -426373180;
    *(uint32_t*)(bytes + 0x41DB15 - offset) = 1696185954;
    *(uint32_t*)(bytes + 0x41DB19 - offset) = -860867675;
    *(uint16_t*)(bytes + 0x41DB1D - offset) = 279;

    // Apply XOR operations based on the new keys
    LOBYTE(0x41DB11) ^= 0x85;
    BYTE1(0x41DB11) ^= 0x7Du;
    BYTE2(0x41DB11) ^= 0xF5u;
    HIBYTE(0x41DB11) ^= 0x83u;
    LOBYTE(0x41DB15) ^= 0x17;
    BYTE1(0x41DB15) ^= 0xCDu;
    BYTE2(0x41DB15) ^= 0x39u;
    HIBYTE(0x41DB15) ^= 0x3Du;
    LOBYTE(0x41DB19) ^= 0x85;
    BYTE1(0x41DB19) ^= 0x7Du;
    BYTE2(0x41DB19) ^= 0xF5u;
    HIBYTE(0x41DB19) ^= 0x83u;
    *(uint8_t*)(bytes + 0x41DB1D - offset) ^= 0x17; // Apply XOR to the lower byte of word_41DB1D

    printf("Decrypted string: %s\n", bytes);

    return 0;
}

0

Your Answer

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

Browse other questions tagged or ask your own question.