I am trying to reverse engineer a malware, and came across a piece of code that I suspect is an encryption/decryption procedure, however I do not know for sure. I can recognize that it extracts its payload from it's own .rsrc
section.
I scanned this algorithm with FindCrypt and IDAScope, Both plugins failed identifying it as a cryptographic algorithm.
I am not familiar with cryptographic algorithms. What are some good indications of code being an encryption or decryption algorithm, and what indications rule it out?
The extraction algorithm is(generated by IDA):
int __stdcall sub_9001320(int a1, unsigned int a2, int a3)
{
// a1 = a3 = 0x09003000
// a2 = 0x7600
int result; // eax@2
char v4; // al@23
unsigned int l; // [sp+4h] [bp-4Ch]@33
unsigned int k; // [sp+10h] [bp-40h]@19
unsigned int v7; // [sp+14h] [bp-3Ch]@19
int v8; // [sp+18h] [bp-38h]@40
signed int j; // [sp+1Ch] [bp-34h]@13
unsigned int v10; // [sp+20h] [bp-30h]@5
unsigned int i; // [sp+24h] [bp-2Ch]@5
unsigned int v12; // [sp+28h] [bp-28h]@5
unsigned int v13; // [sp+2Ch] [bp-24h]@5
signed int v14; // [sp+30h] [bp-20h]@13
unsigned int v15; // [sp+34h] [bp-1Ch]@5
unsigned int v16; // [sp+38h] [bp-18h]@5
unsigned __int8 v17; // [sp+3Fh] [bp-11h]@5
signed int v18; // [sp+40h] [bp-10h]@5
_DWORD *lpAddress; // [sp+44h] [bp-Ch]@11
unsigned int v20; // [sp+48h] [bp-8h]@13
unsigned int v21; // [sp+4Ch] [bp-4h]@16
if ( a2 > 0xC )
{
if ( *(_DWORD *)a1 == 1083581807 )
{
v16 = sub_9001300(a1);
v18 = 12;
v17 = 0;
v15 = 9;
v12 = 256;
v13 = 256;
v10 = 8 * a2 - 96;
for ( i = 9; v10 >= i; v10 -= i )
{
if ( i != 12 && v13 == 1 << i )
++i;
++v13;
}
lpAddress = VirtualAlloc(0, 0xC000u, 0x1000u, 4u);
if ( lpAddress )
{
v20 = 0;
v14 = 256;
for ( j = 0; j <= 255; ++j )
{
lpAddress[3 * j] = 0;
lpAddress[3 * j + 2] = 0;
lpAddress[3 * j + 1] = 1;
}
v21 = 0;
while ( v21 < v16 && v12 < v13 )
{
v7 = 0;
for ( k = 0; k < v15; ++k )
{
if ( (1 << (7 - (v17 + 8 * v18) % 8)) & *(_BYTE *)(a1 + (v17 + 8 * v18) / 8) )
v7 |= 1 << k;
v4 = (v17 + 1) % 8;
v17 = (v17 + 1) % 8;
if ( !v4 )
++v18;
}
if ( v7 > 0xFF )
{
if ( v20 < 0xF00 && v7 > v20 + 255 )
return 0;
if ( v21 + lpAddress[3 * v7 + 1] > v16 )
return 0;
for ( l = 0; l < lpAddress[3 * v7 + 1]; ++l )
*(_BYTE *)(a3 + l + v21) = *(_BYTE *)(a3 + l + lpAddress[3 * v7]);
}
else
{
*(_BYTE *)(v21 + a3) = v7;
}
if ( v20 == 3840 )
{
if ( (unsigned int)++v14 >> 12 )
v14 = 256;
}
if ( v20 >= 0xF00 )
{
v8 = v14 - 1;
if ( v14 == 256 )
v8 = 4095;
}
else
{
v8 = v20 + v14;
}
lpAddress[3 * v8] = v21;
lpAddress[3 * v8 + 1] = lpAddress[3 * v7 + 1] + 1;
lpAddress[3 * v8 + 2] = 0;
if ( v20 < 0xF00 )
++v20;
v21 = v21 + lpAddress[3 * v8 + 1] - 1;
++v12;
if ( v15 < 0xC && 1 << v15 == v12 )
++v15;
}
if ( v21 >= v16 )
{
// sub_9001000 is only called onece and always return 0
if ( *(_DWORD *)(a1 + 8) == sub_9001000(a3, v16) )
{
VirtualFree(lpAddress, 0, 0x8000u);
result = 0;
}
else
{
result = 0;
}
}
else
{
result = 0;
}
}
else
{
result = 0;
}
}
else
{
result = 0;
}
}
else
{
result = 0;
}
return result;
}
int __stdcall sub_9001300(int a1)
{
int result; // eax@2
if ( *(_DWORD *)a1 == 1083581807 )
result = *(_DWORD *)(a1 + 4);
else
result = 0;
return result;
}
File info: file format pei-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00001000 09001000 09001000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rdata 00001000 09002000 09002000 00002000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .rsrc 00005000 09003000 09003000 00003000 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .reloc 00001000 09008000 09008000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA