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

Browse other questions tagged or ask your own question.