Jump to content
Nytro

Malware related compile-time hacks with C++11

Recommended Posts

Posted

[h=1]Malware related compile-time hacks with C++11[/h]by LeFF

Hello, community! This code shows how some features of the new C++11 standard can be used to randomly and automaticaly obfuscate code for every build you make (so for every build you will have different hash-values, different encrypted strings and so on)... I decided to show examples on random code generation, string hashing and string encryption only, as more complex ones gets much harder to read... Code is filled with comments and pretty self-explanatory, but if you have some questions, feel free to ask... Hope this stuff will be useful for you, guys!

#include <stdio.h>
#include <stdint.h>

//-------------------------------------------------------------//
// "Malware related compile-time hacks with C++11" by LeFF //
// You can use this code however you like, I just don't really //
// give a shit, but if you feel some respect for me, please //
// don't cut off this comment when copy-pasting... ;-) //
//-------------------------------------------------------------//

// Usage examples:
void exampleRandom1() __attribute__((noinline));
void exampleRandom2() __attribute__((noinline));
void exampleHashing() __attribute__((noinline));
void exampleEncryption() __attribute__((noinline));

#ifndef vxCPLSEED
// If you don't specify the seed for algorithms, the time when compilation
// started will be used, seed actually changes the results of algorithms...
#define vxCPLSEED ((__TIME__[7] - '0') * 1 + (__TIME__[6] - '0') * 10 + \
(__TIME__[4] - '0') * 60 + (__TIME__[3] - '0') * 600 + \
(__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000)
#endif

// The constantify template is used to make sure that the result of constexpr
// function will be computed at compile-time instead of run-time
template <uint32_t Const> struct vxCplConstantify { enum { Value = Const }; };

// Compile-time mod of a linear congruential pseudorandom number generator,
// the actual algorithm was taken from "Numerical Recipes" book
constexpr uint32_t vxCplRandom(uint32_t Id)
{ return (1013904223 + 1664525 * ((Id > 0) ? (vxCplRandom(Id - 1)) : (vxCPLSEED))) & 0xFFFFFFFF; }

// Compile-time random macros, can be used to randomize execution
// path for separate builds, or compile-time trash code generation
#define vxRANDOM(Min, Max) (Min + (vxRAND() % (Max - Min + 1)))
#define vxRAND() (vxCplConstantify<vxCplRandom(__COUNTER__ + 1)>::Value)

// Compile-time recursive mod of string hashing algorithm,
// the actual algorithm was taken from Qt library (this
// function isn't case sensitive due to vxCplTolower)
constexpr char vxCplTolower(char Ch) { return (Ch >= 'A' && Ch <= 'Z') ? (Ch - 'A' + 'a') : (Ch); }
constexpr uint32_t vxCplHashPart3(char Ch, uint32_t Hash) { return ((Hash << 4) + vxCplTolower(Ch)); }
constexpr uint32_t vxCplHashPart2(char Ch, uint32_t Hash) { return (vxCplHashPart3(Ch, Hash) ^ ((vxCplHashPart3(Ch, Hash) & 0xF0000000) >> 23)); }
constexpr uint32_t vxCplHashPart1(char Ch, uint32_t Hash) { return (vxCplHashPart2(Ch, Hash) & 0x0FFFFFFF); }
constexpr uint32_t vxCplHash(const char* Str) { return (*Str) ? (vxCplHashPart1(*Str, vxCplHash(Str + 1))) : (0); }

// Compile-time hashing macro, hash values changes using the first pseudorandom number in sequence
#define vxHASH(Str) (uint32_t)(vxCplConstantify<vxCplHash(Str)>::Value ^ vxCplConstantify<vxCplRandom(1)>::Value)

// Compile-time generator for list of indexes (0, 1, 2, ...)
template <uint32_t...> struct vxCplIndexList {};
template <typename IndexList, uint32_t Right> struct vxCplAppend;
template <uint32_t... Left, uint32_t Right> struct vxCplAppend<vxCplIndexList<Left...>, Right> { typedef vxCplIndexList<Left..., Right> Result; };
template <uint32_t N> struct vxCplIndexes { typedef typename vxCplAppend<typename vxCplIndexes<N - 1>::Result, N - 1>::Result Result; };
template <> struct vxCplIndexes<0> { typedef vxCplIndexList<> Result; };

// Compile-time string encryption of a single character
const char vxCplEncryptCharKey = vxRANDOM(0, 0xFF);
constexpr char vxCplEncryptChar(const char Ch, uint32_t Idx) { return Ch ^ (vxCplEncryptCharKey + Idx); }

// Compile-time string encryption class
template <typename IndexList> struct vxCplEncryptedString;
template <uint32_t... Idx> struct vxCplEncryptedString<vxCplIndexList<Idx...> >
{
char Value[sizeof...(Idx) + 1]; // Buffer for a string

// Compile-time constructor
constexpr inline vxCplEncryptedString(const char* const Str)
: Value({ vxCplEncryptChar(Str[Idx], Idx)... }) {}

// Run-time decryption
char* decrypt()
{
for(uint32_t t = 0; t < sizeof...(Idx); t++)
{ this->Value[t] = this->Value[t] ^ (vxCplEncryptCharKey + t); }
this->Value[sizeof...(Idx)] = '\0'; return this->Value;
}
};

// Compile-time string encryption macro
#define vxENCRYPT(Str) (vxCplEncryptedString<vxCplIndexes<sizeof(Str) - 1>::Result>(Str).decrypt())

// A small random code path example
void exampleRandom1()
{
switch(vxRANDOM(1, 4))
{
case 1: { printf("exampleRandom1: Code path 1!\n"); break; }
case 2: { printf("exampleRandom1: Code path 2!\n"); break; }
case 3: { printf("exampleRandom1: Code path 3!\n"); break; }
case 4: { printf("exampleRandom1: Code path 4!\n"); break; }
default: { printf("Fucking poltergeist!\n"); }
}
}

// A small random code generator example
void exampleRandom2()
{
volatile uint32_t RndVal = vxRANDOM(0, 100);
if(vxRAND() % 2) { RndVal += vxRANDOM(0, 100); }
else { RndVal -= vxRANDOM(0, 200); }
printf("exampleRandom2: %d\n", RndVal);
}

// A small string hasing example
void exampleHashing()
{
printf("exampleHashing: 0x%08X\n", vxHASH("hello world!"));
printf("exampleHashing: 0x%08X\n", vxHASH("HELLO WORLD!"));
}

void exampleEncryption()
{
printf("exampleEncryption: %s\n", vxENCRYPT("Hello world!"));
}

extern "C" void Main()
{
exampleRandom1();
exampleRandom2();
exampleHashing();
exampleEncryption();
}

To build code with GCC/MinGW I used this command:

g++  -o main.exe -m32 -std=c++0x -Wall -O3 -Os -fno-exceptions -fno-rtti  -flto -masm=intel -e_Main -nostdlib -O3 -Os -flto -s main.cpp -lmsvcrt


Compiled binary returs this, as expected:

exampleRandom1: Code path 2!
exampleRandom2: 145
exampleHashing: 0x2D13947A
exampleHashing: 0x2D13947A
exampleEncryption: Hello world!


Decompiled code, that was generated by compiler:

exampleRandom1 proc near
var_18= dword ptr -18h
push ebp
mov ebp, esp
sub esp, 18h
mov [esp+18h+var_18], offset aExamplerandom1 ; "exampleRandom1: Code path 2!"
call puts
leave
retn
exampleRandom1 endp

exampleRandom2 proc near
var_28= dword ptr -28h
var_24= dword ptr -24h
var_C= dword ptr -0Ch
push ebp
mov ebp, esp
sub esp, 28h
mov [ebp+var_C], 78
mov eax, [ebp+var_C]
mov [esp+28h+var_28], offset aExamplerandom2 ; "exampleRandom2: %d\n"
add eax, 67
mov [ebp+var_C], eax
mov eax, [ebp+var_C]
mov [esp+28h+var_24], eax
call printf
leave
retn
exampleRandom2 endp

exampleHashing proc near
var_18= dword ptr -18h
var_14= dword ptr -14h
push ebp
mov ebp, esp
sub esp, 18h
mov [esp+18h+var_14], 2D13947Ah
mov [esp+18h+var_18], offset aExamplehashing ; "exampleHashing: 0x%08X\n"
call printf
mov [esp+18h+var_14], 2D13947Ah
mov [esp+18h+var_18], offset aExamplehashing ; "exampleHashing: 0x%08X\n"
call printf
leave
retn
exampleHashing endp

exampleEncryption proc near
var_28= dword ptr -28h
var_24= dword ptr -24h
var_15= byte ptr -15h
var_14= byte ptr -14h
var_13= byte ptr -13h
var_12= byte ptr -12h
var_11= byte ptr -11h
var_10= byte ptr -10h
var_F= byte ptr -0Fh
var_E= byte ptr -0Eh
var_D= byte ptr -0Dh
var_C= byte ptr -0Ch
var_B= byte ptr -0Bh
var_A= byte ptr -0Ah
var_9= byte ptr -9
push ebp
xor eax, eax
mov ebp, esp
mov ecx, 0Dh
push edi
lea edi, [ebp+var_15]
sub esp, 24h
rep stosb
xor eax, eax
mov [ebp+var_15], 4Ah
mov [ebp+var_14], 66h
mov [ebp+var_13], 68h
mov [ebp+var_12], 69h
mov [ebp+var_11], 69h
mov [ebp+var_10], 27h
mov [ebp+var_F], 7Fh
mov [ebp+var_E], 66h
mov [ebp+var_D], 78h
mov [ebp+var_C], 67h
mov [ebp+var_B], 68h
mov [ebp+var_A], 2Ch
loc_401045:
lea ecx, [eax+2]
xor [ebp+eax+var_15], cl
inc eax
cmp eax, 0Ch
lea edx, [ebp+var_15]
jnz short loc_401045
mov [esp+28h+var_24], edx
mov [esp+28h+var_28], offset aExampleencrypt ; "exampleEncryption: %s\n"
mov [ebp+var_9], 0
call printf
add esp, 24h
pop edi
pop ebp
retn
exampleEncryption endp

[h=4]Attached Files[/h]

Sursa: Malware related compile-time hacks with C++11 - rohitab.com - Forums

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...