decompiled_code:
void *__fastcall vector_removeall(_QWORD *a1, __int64 a2, __int64 (__fastcall *a3)(void *, __int64))
{
void *result; // rax
void *v5; // rbp
unsigned __int64 v6; // rbx

if ( !a1 )
_assert_fail("vec", "vector.c", 0xDDu, "vector_removeall");
if ( !a2 )
_assert_fail("object", "vector.c", 0xDEu, "vector_removeall");
if ( !a3 )
_assert_fail("eq", "vector.c", 0xDFu, "vector_removeall");
result = vector_alloc_object((__int64)a1);
v5 = result;
if ( result )
{
vector_current_size = a1[2];
result = (void *)a1[3];
v6 = (unsigned __int64)result - 1;
if ( (__int64)result - 1 > 0 )
{
do
{
result = vector_objectat(a1, v5, v6);
if ( result )
{
result = (void *)a3(v5, a2);
if ( (_BYTE)result )
result = vector_removeat(a1, v6);
}
--v6;
}
while ( v6 );
}
}
return result;
}

canonical_decompiled_code:
void *__fastcall func9(_QWORD *a1, __int64 a2, __int64 (__fastcall *a3)(void *, __int64))
{
void *result; // rax
void *v5; // rbp
unsigned __int64 v6; // rbx

if ( !a1 )
_assert_fail("vec", "vector.c", 0xDDu, "vector_removeall");
if ( !a2 )
_assert_fail("object", "vector.c", 0xDEu, "vector_removeall");
if ( !a3 )
_assert_fail("eq", "vector.c", 0xDFu, "vector_removeall");
result = func5((__int64)a1);
v5 = result;
if ( result )
{
vector_current_size = a1[2];
result = (void *)a1[3];
v6 = (unsigned __int64)result - 1;
if ( (__int64)result - 1 > 0 )
{
do
{
result = func6(a1, v5, v6);
if ( result )
{
result = (void *)a3(v5, a2);
if ( (_BYTE)result )
result = func8(a1, v6);
}
--v6;
}
while ( v6 );
}
}
return result;
}

original_code:
void vector_removeall(vector_t vec, const void *object, equality_t eq)
{
    ssize_t idx = 0;
    void *buf = ((void *)0);
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 221, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 222, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((eq) ? 1 : 0), __extension__ ({ if (eq) ; else __assert_fail ("eq", "vector.c", 223, __extension__ __PRETTY_FUNCTION__); }));
    buf = vector_alloc_object(vec);
    if (!buf)
        return;
    vector_current_size = vec -> element_size;
    for (idx = vec -> count - 1; idx > 0; idx--)
    {
        if (vector_objectat(vec, buf, idx))
        {
            if (eq(buf, object))
                vector_removeat(vec, idx);
        }
    }
}

canonical_original_code:
void vector_removeall(struct __vector_s *vec, void *object, _Bool (*eq)(void *, void *))
{
    long idx = 0;
    void *buf = ((void *)0);
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 221, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 222, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((eq) ? 1 : 0), __extension__ ({ if (eq) ; else __assert_fail ("eq", "vector.c", 223, __extension__ __PRETTY_FUNCTION__); }));
    buf = vector_alloc_object(vec);
    if (!buf)
        return;
    vector_current_size = vec -> element_size;
    for (idx = vec -> count - 1; idx > 0; idx--)
    {
        if (vector_objectat(vec, buf, idx))
        {
            if (eq(buf, object))
                vector_removeat(vec, idx);
        }
    }
}

variable_types:
eq
_Bool (*)(void *, void *)

variable_types: idx long


repo: xcvista/libcore

decompiled_code:
void __fastcall vector_sort(__int64 a1, int (*a2)(const void *, const void *))
{
qsort(*(void **)a1, *(_QWORD *)(a1 + 24), *(_QWORD *)(a1 + 16), a2);
}

canonical_decompiled_code:
void __fastcall func10(__int64 a1, int (*a2)(const void *, const void *))
{
qsort(*(void **)a1, *(_QWORD *)(a1 + 24), *(_QWORD *)(a1 + 16), a2);
}

original_code:
void vector_sort(vector_t vec, comparator_t comp)
{
    qsort(vec -> data,
          vec -> count,
          vec -> element_size,
          comp);
}

canonical_original_code:
void vector_sort(struct __vector_s *vec, enum __comparison_result (*comp)(void *, void *))
{
    qsort(vec -> data,
          vec -> count,
          vec -> element_size,
          comp);
}

variable_types: struct __vector_s { void *data; unsigned long alloc_size; unsigned long element_size; unsigned long count; } *

variable_types: enum __comparison_result { compare_ascending=-1, compare_same=0, compare_descending=1 } (*)(void *, void *)

return_type: void


decompiled_code:
__int64 __fastcall vector_expand(__int64 a1, unsigned __int64 a2)
{
size_t v2; // rax
size_t v3; // rsi
void *v4; // rax
void *v5; // r12

if ( !a1 )
_assert_fail("vec", "vector.c", 0x111u, "vector_expand");
if ( *(_QWORD *)(a1 + 24) > a2 )
_assert_fail("alloc_size >= vec -> count", "vector.c", 0x112u, "vector_expand");
v2 = *(_QWORD *)(a1 + 16);
v3 = v2 * a2;
if ( v2 >= v3 )
v3 = *(_QWORD *)(a1 + 16);
v4 = malloc(v3);
v5 = v4;
if ( !v4 )
return 0LL;
memset(v4, 0, v3);
memcpy(v5, *(const void **)a1, *(_QWORD *)(a1 + 8));
*(_QWORD *)a1 = v5;
*(_QWORD *)(a1 + 8) = v3;
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1, unsigned __int64 a2)
{
size_t v2; // rax
size_t v3; // rsi
void *v4; // rax
void *v5; // r12

if ( !a1 )
_assert_fail("vec", "vector.c", 0x111u, "vector_expand");
if ( *(_QWORD *)(a1 + 24) > a2 )
_assert_fail("alloc_size >= vec -> count", "vector.c", 0x112u, "vector_expand");
v2 = *(_QWORD *)(a1 + 16);
v3 = v2 * a2;
if ( v2 >= v3 )
v3 = *(_QWORD *)(a1 + 16);
v4 = malloc(v3);
v5 = v4;
if ( !v4 )
return 0LL;
memset(v4, 0, v3);
memcpy(v5, *(const void **)a1, *(_QWORD *)(a1 + 8));
*(_QWORD *)a1 = v5;
*(_QWORD *)(a1 + 8) = v3;
return 1LL;
}

original_code:
_Bool vector_expand(vector_t vec, size_t alloc_size)
{
    void *buf = ((void *)0);
    size_t size;
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 273, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((alloc_size >= vec -> count) ? 1 : 0), __extension__ ({ if (alloc_size >= vec -> count) ; else __assert_fail ("alloc_size >= vec -> count", "vector.c", 274, __extension__ __PRETTY_FUNCTION__); }));
    size = alloc_size * vec -> element_size;
    if (size < vec -> element_size)
        size = vec -> element_size;
    buf = malloc(size);
    if (!buf)
        return 0;
    memset(buf, 0, size);
    memcpy(buf, vec -> data, vec -> alloc_size);
    vec -> data = buf;
    vec -> alloc_size = size;
    return 1;
}

canonical_original_code:
_Bool vector_expand(struct __vector_s *vec, unsigned long alloc_size)
{
    void *buf = ((void *)0);
    unsigned long size;
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 273, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((alloc_size >= vec -> count) ? 1 : 0), __extension__ ({ if (alloc_size >= vec -> count) ; else __assert_fail ("alloc_size >= vec -> count", "vector.c", 274, __extension__ __PRETTY_FUNCTION__); }));
    size = alloc_size * vec -> element_size;
    if (size < vec -> element_size)
        size = vec -> element_size;
    buf = malloc(size);
    if (!buf)
        return 0;
    memset(buf, 0, size);
    memcpy(buf, vec -> data, vec -> alloc_size);
    vec -> data = buf;
    vec -> alloc_size = size;
    return 1;
}

variable_types:
buf
void *

variable_types:
size
unsigned long

user_defined_types: struct __vector_s { void *data; unsigned long alloc_size; unsigned long element_size; unsigned long count; }


decompiled_code:
__int64 __fastcall vector_append(_QWORD *a1, const void *a2)
{
unsigned __int64 v3; // rsi
__int64 result; // rax
void *v5; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0xAEu, "vector_append");
if ( !a2 )
_assert_fail("object", "vector.c", 0xAFu, "vector_append");
v3 = a1[3];
if ( v3 > a1[1] / a1[2] || (result = vector_expand((__int64)a1, v3 + 1), (_BYTE)result) )
{
v5 = (void *)vector_max_pointer(a1);
memcpy(v5, a2, a1[2]);
++a1[3];
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func12(_QWORD *a1, const void *a2)
{
unsigned __int64 v3; // rsi
__int64 result; // rax
void *v5; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0xAEu, "vector_append");
if ( !a2 )
_assert_fail("object", "vector.c", 0xAFu, "vector_append");
v3 = a1[3];
if ( v3 > a1[1] / a1[2] || (result = func11((__int64)a1, v3 + 1), (_BYTE)result) )
{
v5 = (void *)func1(a1);
memcpy(v5, a2, a1[2]);
++a1[3];
result = 1LL;
}
return result;
}

original_code:
_Bool vector_append(vector_t vec, const void * object)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 174, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 175, __extension__ __PRETTY_FUNCTION__); }));
    if (vec -> count <= vec -> alloc_size / vec -> element_size)
        if (!vector_expand(vec, vec -> count + 1))
            return 0;
    memcpy(vector_max_pointer(vec), object, vec -> element_size);
    vec -> count++;
    return 1;
}

canonical_original_code:
_Bool vector_append(struct __vector_s *vec, void *object)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 174, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 175, __extension__ __PRETTY_FUNCTION__); }));
    if (vec -> count <= vec -> alloc_size / vec -> element_size)
        if (!vector_expand(vec, vec -> count + 1))
            return 0;
    memcpy(vector_max_pointer(vec), object, vec -> element_size);
    vec -> count++;
    return 1;
}

variable_types:
object
void *


decompiled_code:
__int64 __fastcall vector_insert(_QWORD *a1, const void *a2, unsigned __int64 a3)
{
unsigned __int64 v5; // rsi
__int64 result; // rax
__int64 v7; // rax
char *v8; // rbp
char *v9; // r13
__int64 v10; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0x96u, "vector_insert");
if ( !a2 )
_assert_fail("object", "vector.c", 0x97u, "vector_insert");
v5 = a1[3];
if ( v5 < a3 )
_assert_fail("index <= vec -> count", "vector.c", 0x98u, "vector_insert");
if ( v5 == a3 )
return vector_append(a1, a2);
if ( v5 > a1[1] / a1[2] || (result = vector_expand((__int64)a1, v5 + 1), (_BYTE)result) )
{
v7 = a1[2];
v8 = (char *)(*a1 + v7 * a3);
v9 = &v8[v7];
v10 = vector_max_pointer(a1);
memmove(v9, v8, v10 - (_QWORD)v8);
memcpy(v8, a2, a1[2]);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func13(_QWORD *a1, const void *a2, unsigned __int64 a3)
{
unsigned __int64 v5; // rsi
__int64 result; // rax
__int64 v7; // rax
char *v8; // rbp
char *v9; // r13
__int64 v10; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0x96u, "vector_insert");
if ( !a2 )
_assert_fail("object", "vector.c", 0x97u, "vector_insert");
v5 = a1[3];
if ( v5 < a3 )
_assert_fail("index <= vec -> count", "vector.c", 0x98u, "vector_insert");
if ( v5 == a3 )
return func12(a1, a2);
if ( v5 > a1[1] / a1[2] || (result = func11((__int64)a1, v5 + 1), (_BYTE)result) )
{
v7 = a1[2];
v8 = (char *)(*a1 + v7 * a3);
v9 = &v8[v7];
v10 = func1(a1);
memmove(v9, v8, v10 - (_QWORD)v8);
memcpy(v8, a2, a1[2]);
result = 1LL;
}
return result;
}

original_code:
_Bool vector_insert(vector_t vec, const void *object, size_t index)
{
    void *ptr = ((void *)0);
    void *ptrnext = ((void *)0);
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 150, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 151, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((index <= vec -> count) ? 1 : 0), __extension__ ({ if (index <= vec -> count) ; else __assert_fail ("index <= vec -> count", "vector.c", 152, __extension__ __PRETTY_FUNCTION__); }));
    if (index == vec -> count)
        return vector_append(vec, object);
    if (vec -> count <= vec -> alloc_size / vec -> element_size)
        if (!vector_expand(vec, vec -> count + 1))
            return 0;
    ptr = vec -> data + vec -> element_size * index;
    ptrnext = ptr + vec -> element_size;
    memmove(ptrnext, ptr, vector_max_pointer(vec) - ptr);
    memcpy(ptr, object, vec -> element_size);
    return 1;
}

canonical_original_code:
_Bool vector_insert(struct __vector_s *vec, void *object, unsigned long index)
{
    void *ptr = ((void *)0);
    void *ptrnext = ((void *)0);
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 150, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 151, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((index <= vec -> count) ? 1 : 0), __extension__ ({ if (index <= vec -> count) ; else __assert_fail ("index <= vec -> count", "vector.c", 152, __extension__ __PRETTY_FUNCTION__); }));
    if (index == vec -> count)
        return vector_append(vec, object);
    if (vec -> count <= vec -> alloc_size / vec -> element_size)
        if (!vector_expand(vec, vec -> count + 1))
            return 0;
    ptr = vec -> data + vec -> element_size * index;
    ptrnext = ptr + vec -> element_size;
    memmove(ptrnext, ptr, vector_max_pointer(vec) - ptr);
    memcpy(ptr, object, vec -> element_size);
    return 1;
}

variable_types:
index
unsigned long

variable_types:
ptr
void *

variable_types:
ptrnext
void *


decompiled_code:
__int64 __fastcall vector_compact(__int64 a1)
{
if ( !a1 )
_assert_fail("vec", "vector.c", 0x128u, "vector_compact");
return vector_expand(a1, *(_QWORD *)(a1 + 24));
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1)
{
if ( !a1 )
_assert_fail("vec", "vector.c", 0x128u, "vector_compact");
return func11(a1, *(_QWORD *)(a1 + 24));
}

original_code:
_Bool vector_compact(vector_t vec)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 296, __extension__ __PRETTY_FUNCTION__); }));
    return vector_expand(vec, vec -> count);
}

canonical_original_code:
_Bool vector_compact(struct __vector_s *vec)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 296, __extension__ __PRETTY_FUNCTION__); }));
    return vector_expand(vec, vec -> count);
}


decompiled_code:
void __fastcall vector_fini(void *ptr)
{
void *v2; // rdi

if ( !ptr )
_assert_fail("vec", "vector.c", 0x130u, "vector_fini");
v2 = *(void **)ptr;
if ( v2 )
free(v2);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func15(void *ptr)
{
void *v2; // rdi

if ( !ptr )
_assert_fail("vec", "vector.c", 0x130u, "vector_fini");
v2 = *(void **)ptr;
if ( v2 )
free(v2);
free(ptr);
}

original_code:
void vector_fini(vector_t vec)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 304, __extension__ __PRETTY_FUNCTION__); }));
    if (vec -> data)
        free(vec -> data);
    free(vec);
}

canonical_original_code:
void vector_fini(struct __vector_s *vec)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 304, __extension__ __PRETTY_FUNCTION__); }));
    if (vec -> data)
        free(vec -> data);
    free(vec);
}


decompiled_code:
__int64 __fastcall vector_begin_iterator(__int64 a1)
{
if ( !a1 )
_assert_fail("vec", "vector.c", 0x148u, "vector_begin_iterator");
return *(_QWORD *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1)
{
if ( !a1 )
_assert_fail("vec", "vector.c", 0x148u, "vector_begin_iterator");
return *(_QWORD *)a1;
}

original_code:
void *vector_begin_iterator(vector_t vec)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 328, __extension__ __PRETTY_FUNCTION__); }));
    return vec->data;
}

canonical_original_code:
void *vector_begin_iterator(struct __vector_s *vec)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 328, __extension__ __PRETTY_FUNCTION__); }));
    return vec->data;
}

return_type: void *


decompiled_code:
bool __fastcall vector_check_iterator(_QWORD *a1, __int64 a2)
{
bool result; // al

if ( !a1 )
_assert_fail("vec", "vector.c", 0x14Fu, "vector_check_iterator");
if ( a2 )
result = (unsigned __int64)(a2 - *a1) / a1[2] < a1[3];
else
result = 0;
return result;
}

canonical_decompiled_code:
bool __fastcall func17(_QWORD *a1, __int64 a2)
{
bool result; // al

if ( !a1 )
_assert_fail("vec", "vector.c", 0x14Fu, "vector_check_iterator");
if ( a2 )
result = (unsigned __int64)(a2 - *a1) / a1[2] < a1[3];
else
result = 0;
return result;
}

original_code:
_Bool vector_check_iterator(vector_t vec, const void *it)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 335, __extension__ __PRETTY_FUNCTION__); }));
    if (!it)
        return 0;
    return ((it - vec->data) / vec->element_size) < vec->count ? 1 : 0;
}

canonical_original_code:
_Bool vector_check_iterator(struct __vector_s *vec, void *it)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 335, __extension__ __PRETTY_FUNCTION__); }));
    if (!it)
        return 0;
    return ((it - vec->data) / vec->element_size) < vec->count ? 1 : 0;
}

variable_types:
it
void *


decompiled_code:
__int64 __fastcall vector_next_iterator(_QWORD *a1, __int64 a2)
{
unsigned __int64 v2; // rcx
unsigned __int64 v3; // rax
__int64 v4; // rsi
bool v5; // cf
__int64 result; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0x158u, "vector_next_iterator");
v2 = a1[2];
v3 = (a2 - *a1) / v2;
v4 = v2 + a2;
v5 = v3 < a1[3] - 1LL;
result = 0LL;
if ( v5 )
result = v4;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func18(_QWORD *a1, __int64 a2)
{
unsigned __int64 v2; // rcx
unsigned __int64 v3; // rax
__int64 v4; // rsi
bool v5; // cf
__int64 result; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0x158u, "vector_next_iterator");
v2 = a1[2];
v3 = (a2 - *a1) / v2;
v4 = v2 + a2;
v5 = v3 < a1[3] - 1LL;
result = 0LL;
if ( v5 )
result = v4;
return result;
}

original_code:
void *vector_next_iterator(vector_t vec, const void *it)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 344, __extension__ __PRETTY_FUNCTION__); }));
    if (((it - vec->data) / vec->element_size) < (vec->count - 1))
        return (void *)it + vec->element_size;
    else
        return ((void *)0);
}

canonical_original_code:
void *vector_next_iterator(struct __vector_s *vec, void *it)
{
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 344, __extension__ __PRETTY_FUNCTION__); }));
    if (((it - vec->data) / vec->element_size) < (vec->count - 1))
        return (void *)it + vec->element_size;
    else
        return ((void *)0);
}


decompiled_code:
__int64 __fastcall vector_indexof(unsigned __int64 *a1, __int64 a2, unsigned __int8 (__fastcall *a3)(__int64, __int64))
{
__int64 i; // rbx

if ( !a1 )
_assert_fail("vec", "vector.c", 0x5Bu, "vector_indexof");
if ( !a2 )
_assert_fail("object", "vector.c", 0x5Cu, "vector_indexof");
if ( !a3 )
_assert_fail("eq", "vector.c", 0x5Du, "vector_indexof");
if ( !vector_alloc_object((__int64)a1) )
return -1LL;
vector_current_size = a1[2];
for ( i = vector_begin_iterator((__int64)a1); vector_check_iterator(a1, i); i = vector_next_iterator(a1, i) )
{
if ( a3(i, a2) )
return (int)vector_indexof_ptr(a1, i);
}
return -1LL;
}

canonical_decompiled_code:
__int64 __fastcall func19(unsigned __int64 *a1, __int64 a2, unsigned __int8 (__fastcall *a3)(__int64, __int64))
{
__int64 i; // rbx

if ( !a1 )
_assert_fail("vec", "vector.c", 0x5Bu, "vector_indexof");
if ( !a2 )
_assert_fail("object", "vector.c", 0x5Cu, "vector_indexof");
if ( !a3 )
_assert_fail("eq", "vector.c", 0x5Du, "vector_indexof");
if ( !func5((__int64)a1) )
return -1LL;
vector_current_size = a1[2];
for ( i = func16((__int64)a1); func17(a1, i); i = func18(a1, i) )
{
if ( a3(i, a2) )
return (int)func3(a1, i);
}
return -1LL;
}

original_code:
ssize_t vector_indexof(vector_t vec, const void *object, equality_t eq)
{
    void *buf = ((void *)0);
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 91, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 92, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((eq) ? 1 : 0), __extension__ ({ if (eq) ; else __assert_fail ("eq", "vector.c", 93, __extension__ __PRETTY_FUNCTION__); }));
    buf = vector_alloc_object(vec);
    if (!buf)
        return (-1);
    vector_current_size = vec -> element_size;
    for (void * obj = vector_begin_iterator(vec); vector_check_iterator(vec, obj); obj = vector_next_iterator(vec, obj))
    {
        if (eq(obj, object))
            return vector_indexof_ptr(vec, obj);
    }
    return (-1);
}

canonical_original_code:
long vector_indexof(struct __vector_s *vec, void *object, _Bool (*eq)(void *, void *))
{
    void *buf = ((void *)0);
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 91, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 92, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((eq) ? 1 : 0), __extension__ ({ if (eq) ; else __assert_fail ("eq", "vector.c", 93, __extension__ __PRETTY_FUNCTION__); }));
    buf = vector_alloc_object(vec);
    if (!buf)
        return (-1);
    vector_current_size = vec -> element_size;
    for (void *obj = vector_begin_iterator(vec); vector_check_iterator(vec, obj); obj = vector_next_iterator(vec, obj))
    {
        if (eq(obj, object))
            return vector_indexof_ptr(vec, obj);
    }
    return (-1);
}

variable_types:
obj
void *

return_type: long


decompiled_code:
signed __int64 __fastcall vector_removefirst(unsigned __int64 *a1, __int64 a2, unsigned __int8 (__fastcall *a3)(__int64, __int64))
{
signed __int64 result; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0xF8u, "vector_removefirst");
if ( !a2 )
_assert_fail("object", "vector.c", 0xF9u, "vector_removefirst");
if ( !a3 )
_assert_fail("eq", "vector.c", 0xFAu, "vector_removefirst");
vector_current_size = a1[2];
result = vector_indexof(a1, a2, a3);
if ( result >= 0 )
result = (signed __int64)vector_removeat(a1, result);
return result;
}

canonical_decompiled_code:
signed __int64 __fastcall func20(unsigned __int64 *a1, __int64 a2, unsigned __int8 (__fastcall *a3)(__int64, __int64))
{
signed __int64 result; // rax

if ( !a1 )
_assert_fail("vec", "vector.c", 0xF8u, "vector_removefirst");
if ( !a2 )
_assert_fail("object", "vector.c", 0xF9u, "vector_removefirst");
if ( !a3 )
_assert_fail("eq", "vector.c", 0xFAu, "vector_removefirst");
vector_current_size = a1[2];
result = func19(a1, a2, a3);
if ( result >= 0 )
result = (signed __int64)func8(a1, result);
return result;
}

original_code:
void vector_removefirst(vector_t vec, const void *object, equality_t eq)
{
    ssize_t idx = 0;
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 248, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 249, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((eq) ? 1 : 0), __extension__ ({ if (eq) ; else __assert_fail ("eq", "vector.c", 250, __extension__ __PRETTY_FUNCTION__); }));
    vector_current_size = vec -> element_size;
    idx = vector_indexof(vec, object, eq);
    if (idx >= 0)
        vector_removeat(vec, idx);
}

canonical_original_code:
void vector_removefirst(struct __vector_s *vec, void *object, _Bool (*eq)(void *, void *))
{
    long idx = 0;
    ((void) sizeof ((vec) ? 1 : 0), __extension__ ({ if (vec) ; else __assert_fail ("vec", "vector.c", 248, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((object) ? 1 : 0), __extension__ ({ if (object) ; else __assert_fail ("object", "vector.c", 249, __extension__ __PRETTY_FUNCTION__); }));
    ((void) sizeof ((eq) ? 1 : 0), __extension__ ({ if (eq) ; else __assert_fail ("eq", "vector.c", 250, __extension__ __PRETTY_FUNCTION__); }));
    vector_current_size = vec -> element_size;
    idx = vector_indexof(vec, object, eq);
    if (idx >= 0)
        vector_removeat(vec, idx);
}


die

decompiled_code:
void __fastcall __noreturn die(const char *a1)
{
fprintf(stderr, "# fatal error: %s\n", a1);
exit(2);
}

canonical_decompiled_code:
void __fastcall __noreturn func1(const char *a1)
{
fprintf(stderr, "# fatal error: %s\n", a1);
exit(2);
}

original_code:
static void
die(const char * msg)
{
  fprintf(stderr, "# fatal error: %s\n", msg);
  exit(2);
}

canonical_original_code:
static void die(char *msg)
{
  fprintf(stderr, "# fatal error: %s\n", msg);
  exit(2);
}

variable_types:
msg
char *


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // r13
unsigned int v4; // er12
int v5; // eax
void *v6; // rax
void *v7; // rbx
void *v8; // rax
void *v9; // rbp
size_t v10; // rax
void *v12; // rax
size_t v13; // rax
void *v14; // rax
size_t v15; // rax
unsigned __int16 v16; // [rsp+0h] [rbp-38h] BYREF
unsigned __int16 v17; // [rsp+2h] [rbp-36h] BYREF
size_t n; // [rsp+4h] [rbp-34h] BYREF
unsigned int v19[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v3 = *argv;
v19[0] = 0;
v4 = 0;
while ( 1 )
{
v5 = getopt(argc, (char *const *)argv, "vmph");
if ( v5 == -1 )
break;
if ( v5 == 112 )
{
if ( v4 )
fprintf(stderr, "# ignoring option '%c', already got '%c'\n", 112LL, v4);
else
v4 = 112;
}
else if ( v5 > 112 )
{
if ( v5 != 118 )
goto LABEL_20;
if ( v4 )
fprintf(stderr, "# ignoring option '%c', already got '%c'\n", 118LL, v4);
else
v4 = 118;
}
else if ( v5 == 109 )
{
if ( v4 )
fprintf(stderr, "# ignoring option '%c', already got '%c'\n", 109LL, v4);
else
v4 = 109;
}
else
{
if ( v5 <= 109 && (v5 == 63 || v5 == 104) )
{
usage(v3);
exit(0);
}
LABEL_20:
fprintf(stderr, "# unknown option '%c'\n", (unsigned int)v5);
}
}
if ( argc - optind != 1 )
{
usage(v3);
exit(1);
}
v6 = readFile(argv[optind], (_DWORD *)&n + 1);
v7 = v6;
switch ( v4 )
{
case 'p':
v14 = (void *)woffGetPrivateData(v6, HIDWORD(n), &n, v19);
v9 = v14;
if ( LOBYTE(v19[0]) )
reportErr(v19[0]);
if ( v14 )
{
v15 = fwrite(v14, 1uLL, (unsigned int)n, stdout);
if ( v15 != (unsigned int)n )
die("error writing private data to output");
LABEL_46:
free(v9);
}
break;
case 'v':
woffGetFontVersion(v6, HIDWORD(n), &v16, &v17, v19);
if ( LOBYTE(v19[0]) )
reportErr(v19[0]);
printf("%u.%u\n", v16, v17);
break;
case 'm':
v12 = (void *)woffGetMetadata(v6, HIDWORD(n), &n, v19);
v9 = v12;
if ( LOBYTE(v19[0]) )
reportErr(v19[0]);
if ( v12 )
{
v13 = fwrite(v12, 1uLL, (unsigned int)n, stdout);
if ( v13 != (unsigned int)n )
die("error writing metadata to output");
goto LABEL_46;
}
puts("<!-- No WOFF metadata available. -->");
break;
default:
v8 = (void *)woffDecode(v6, HIDWORD(n), &n, v19);
v9 = v8;
if ( LOBYTE(v19[0]) )
reportErr(v19[0]);
if ( !v8 )
die("unable to decode WOFF data");
v10 = fwrite(v8, 1uLL, (unsigned int)n, stdout);
if ( v10 != (unsigned int)n )
die("error writing sfnt data to output");
goto LABEL_46;
}
if ( (v19[0] & 0xFFFFFF00) != 0 )
woffPrintStatus(stderr, v19[0], "### ");
free(v7);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // r13
unsigned int v4; // er12
int v5; // eax
void *v6; // rax
void *v7; // rbx
void *v8; // rax
void *v9; // rbp
size_t v10; // rax
void *v12; // rax
size_t v13; // rax
void *v14; // rax
size_t v15; // rax
unsigned __int16 v16; // [rsp+0h] [rbp-38h] BYREF
unsigned __int16 v17; // [rsp+2h] [rbp-36h] BYREF
size_t n; // [rsp+4h] [rbp-34h] BYREF
unsigned int v19[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v3 = *argv;
v19[0] = 0;
v4 = 0;
while ( 1 )
{
v5 = getopt(argc, (char *const *)argv, "vmph");
if ( v5 == -1 )
break;
if ( v5 == 112 )
{
if ( v4 )
fprintf(stderr, "# ignoring option '%c', already got '%c'\n", 112LL, v4);
else
v4 = 112;
}
else if ( v5 > 112 )
{
if ( v5 != 118 )
goto LABEL_20;
if ( v4 )
fprintf(stderr, "# ignoring option '%c', already got '%c'\n", 118LL, v4);
else
v4 = 118;
}
else if ( v5 == 109 )
{
if ( v4 )
fprintf(stderr, "# ignoring option '%c', already got '%c'\n", 109LL, v4);
else
v4 = 109;
}
else
{
if ( v5 <= 109 && (v5 == 63 || v5 == 104) )
{
func0(v3);
exit(0);
}
LABEL_20:
fprintf(stderr, "# unknown option '%c'\n", (unsigned int)v5);
}
}
if ( argc - optind != 1 )
{
func0(v3);
exit(1);
}
v6 = func3(argv[optind], (_DWORD *)&n + 1);
v7 = v6;
switch ( v4 )
{
case 'p':
v14 = (void *)woffGetPrivateData(v6, HIDWORD(n), &n, v19);
v9 = v14;
if ( LOBYTE(v19[0]) )
func2(v19[0]);
if ( v14 )
{
v15 = fwrite(v14, 1uLL, (unsigned int)n, stdout);
if ( v15 != (unsigned int)n )
func1("error writing private data to output");
LABEL_46:
free(v9);
}
break;
case 'v':
woffGetFontVersion(v6, HIDWORD(n), &v16, &v17, v19);
if ( LOBYTE(v19[0]) )
func2(v19[0]);
printf("%u.%u\n", v16, v17);
break;
case 'm':
v12 = (void *)woffGetMetadata(v6, HIDWORD(n), &n, v19);
v9 = v12;
if ( LOBYTE(v19[0]) )
func2(v19[0]);
if ( v12 )
{
v13 = fwrite(v12, 1uLL, (unsigned int)n, stdout);
if ( v13 != (unsigned int)n )
func1("error writing metadata to output");
goto LABEL_46;
}
puts("<!-- No WOFF metadata available. -->");
break;
default:
v8 = (void *)woffDecode(v6, HIDWORD(n), &n, v19);
v9 = v8;
if ( LOBYTE(v19[0]) )
func2(v19[0]);
if ( !v8 )
func1("unable to decode WOFF data");
v10 = fwrite(v8, 1uLL, (unsigned int)n, stdout);
if ( v10 != (unsigned int)n )
func1("error writing sfnt data to output");
goto LABEL_46;
}
if ( (v19[0] & 0xFFFFFF00) != 0 )
woffPrintStatus(stderr, v19[0], "### ");
free(v7);
return 0;
}

original_code:
int
main(int argc, char *argv[])
{
  const char * progName = argv[0];
  uint32_t status = eWOFF_ok;
  int opt;
  int option = 0;
  while ((opt = getopt(argc, argv, "vmph")) != -1) {
    switch (opt) {
    case 'v':
      if (option)
        fprintf(stderr, "# ignoring option '%c', already got '%c'\n", opt, option);
      else
        option = 'v';
      break;
    case 'm':
      if (option)
        fprintf(stderr, "# ignoring option '%c', already got '%c'\n", opt, option);
      else
        option = 'm';
      break;
    case 'p':
      if (option)
        fprintf(stderr, "# ignoring option '%c', already got '%c'\n", opt, option);
      else
        option = 'p';
      break;
    case 'h':
    case '?':
      usage(progName);
      exit(0);
    default:
      fprintf(stderr, "# unknown option '%c'\n", opt);
      break;
    }
  }
  argc -= optind;
  argv += optind;
  if (argc != 1) {
    usage(progName);
    exit(1);
  }
  uint32_t woffLen;
  const uint8_t * woffData = readFile(argv[0], &woffLen);
  uint32_t len;
  const uint8_t * data;
  switch (option) {
  case 'v':
    {
      uint16_t maj, min;
      woffGetFontVersion(woffData, woffLen, &maj, &min, &status);
      if ((!(((uint32_t)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      printf("%u.%u\n", maj, min);
    }
    break;
  case 'm':
    {
      data = woffGetMetadata(woffData, woffLen, &len, &status);
      if ((!(((uint32_t)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      if (data) {
        if (fwrite(data, 1, len, stdout) != len)
          die("error writing metadata to output");
        free((void *) data);
      } else {
        printf("<!-- No WOFF metadata available. -->\n");
      }
    }
    break;
  case 'p':
    {
      data = woffGetPrivateData(woffData, woffLen, &len, &status);
      if ((!(((uint32_t)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      if (data) {
        if (fwrite(data, 1, len, stdout) != len)
          die("error writing private data to output");
        free((void *) data);
      }
    }
    break;
  default:
    {
      data = woffDecode(woffData, woffLen, &len, &status);
      if ((!(((uint32_t)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      if (data) {
        if (fwrite(data, 1, len, stdout) != len)
          die("error writing sfnt data to output");
        free((void *) data);
      } else {
        die("unable to decode WOFF data");
      }
    }
    break;
  }
  if (((uint32_t)(status) & ~0xff)) {
    woffPrintStatus(stderr, status, "### ");
  }
  free((void *) woffData);
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
  char *progName = argv[0];
  unsigned int status = eWOFF_ok;
  int opt;
  int option = 0;
  while ((opt = getopt(argc, argv, "vmph")) != -1) {
    switch (opt) {
    case 'v':
      if (option)
        fprintf(stderr, "# ignoring option '%c', already got '%c'\n", opt, option);
      else
        option = 'v';
      break;
    case 'm':
      if (option)
        fprintf(stderr, "# ignoring option '%c', already got '%c'\n", opt, option);
      else
        option = 'm';
      break;
    case 'p':
      if (option)
        fprintf(stderr, "# ignoring option '%c', already got '%c'\n", opt, option);
      else
        option = 'p';
      break;
    case 'h':
    case '?':
      usage(progName);
      exit(0);
    default:
      fprintf(stderr, "# unknown option '%c'\n", opt);
      break;
    }
  }
  argc -= optind;
  argv += optind;
  if (argc != 1) {
    usage(progName);
    exit(1);
  }
  unsigned int woffLen;
  unsigned char *woffData = readFile(argv[0], &woffLen);
  unsigned int len;
  unsigned char *data;
  switch (option) {
  case 'v':
    {
      unsigned short maj; unsigned short min;
      woffGetFontVersion(woffData, woffLen, &maj, &min, &status);
      if ((!(((unsigned int)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      printf("%u.%u\n", maj, min);
    }
    break;
  case 'm':
    {
      data = woffGetMetadata(woffData, woffLen, &len, &status);
      if ((!(((unsigned int)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      if (data) {
        if (fwrite(data, 1, len, stdout) != len)
          die("error writing metadata to output");
        free((void *) data);
      } else {
        printf("<!-- No WOFF metadata available. -->\n");
      }
    }
    break;
  case 'p':
    {
      data = woffGetPrivateData(woffData, woffLen, &len, &status);
      if ((!(((unsigned int)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      if (data) {
        if (fwrite(data, 1, len, stdout) != len)
          die("error writing private data to output");
        free((void *) data);
      }
    }
    break;
  default:
    {
      data = woffDecode(woffData, woffLen, &len, &status);
      if ((!(((unsigned int)(status) & 0xff) == eWOFF_ok))) {
        reportErr(status);
      }
      if (data) {
        if (fwrite(data, 1, len, stdout) != len)
          die("error writing sfnt data to output");
        free((void *) data);
      } else {
        die("unable to decode WOFF data");
      }
    }
    break;
  }
  if (((unsigned int)(status) & ~0xff)) {
    woffPrintStatus(stderr, status, "### ");
  }
  free((void *) woffData);
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
progName
char *

variable_types:
status
unsigned int

variable_types: opt int

variable_types: option int

variable_types:
woffLen
unsigned int

variable_types:
woffData
unsigned char *

variable_types:
len
unsigned int

variable_types:
data
unsigned char *

variable_types:
maj
unsigned short

variable_types:
min
unsigned short

return_type: int


usage

repo: xenserver/xentpm

decompiled_code:
int usage()
{
puts("usage: xentpm");
puts(" --is_tpm_owned");
puts(" --take_ownership");
puts(" --get_ekey");
puts(" --get_ekcert");
puts(" --gen_aik <xencert_base64>");
puts(" --get_aik_pem ");
puts(" --get_aik_tcpa ");
puts(" --tpm_challenge <challenge>");
return puts(" --tpm_quote <nonce> ");
}

canonical_decompiled_code:
int func0()
{
puts("usage: xentpm");
puts(" --is_tpm_owned");
puts(" --take_ownership");
puts(" --get_ekey");
puts(" --get_ekcert");
puts(" --gen_aik <xencert_base64>");
puts(" --get_aik_pem ");
puts(" --get_aik_tcpa ");
puts(" --tpm_challenge <challenge>");
return puts(" --tpm_quote <nonce> ");
}

original_code:
void usage()
{
    printf("usage: xentpm\n");
    printf("           --is_tpm_owned\n");
    printf("           --take_ownership\n");
    printf("           --get_ekey\n");
    printf("           --get_ekcert\n");
    printf("           --gen_aik <xencert_base64>\n");
    printf("           --get_aik_pem \n");
    printf("           --get_aik_tcpa \n");
    printf("           --tpm_challenge <challenge>\n");
    printf("           --tpm_quote <nonce> \n");
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // ebx
int v5; // eax
int longind[7]; // [rsp+Ch] [rbp-1Ch] BYREF

longind[0] = 0;
openlog("xentpm", 1, 8);
v3 = 3;
if ( argc <= 1 )
{
usage();
closelog();
LABEL_7:
fprintf(stderr, "%d", v3);
return 1;
}
while ( 2 )
{
v5 = getopt_long(argc, (char *const *)argv, "otek:a:p:b:c:q:", &long_options_0, longind);
if ( v5 == -1 )
goto LABEL_6;
switch ( v5 )
{
case 'a':
if ( argc != 3 )
goto LABEL_5;
v3 = generate_aik(optarg);
continue;
case 'b':
if ( argc != 2 )
goto LABEL_5;
v3 = get_aik_tcpa();
continue;
case 'c':
if ( argc != 3 )
goto LABEL_5;
v3 = tpm_challenge(optarg);
continue;
case 'e':
if ( argc != 2 )
goto LABEL_5;
v3 = get_endorsment_key();
continue;
case 'k':
if ( argc != 2 )
goto LABEL_5;
v3 = get_endorsment_keycert();
continue;
case 'o':
if ( argc != 2 )
goto LABEL_5;
v3 = tpm_owned();
continue;
case 'p':
if ( argc != 2 )
goto LABEL_5;
v3 = get_aik_pem();
continue;
case 'q':
if ( argc != 3 )
goto LABEL_5;
v3 = tpm_quote(optarg);
continue;
case 't':
if ( argc == 2 )
{
v3 = take_ownership();
continue;
}
LABEL_5:
usage();
LABEL_6:
closelog();
if ( v3 )
goto LABEL_7;
return v3;
default:
usage();
continue;
}
}
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // ebx
int v5; // eax
int longind[7]; // [rsp+Ch] [rbp-1Ch] BYREF

longind[0] = 0;
openlog("xentpm", 1, 8);
v3 = 3;
if ( argc <= 1 )
{
func0();
closelog();
LABEL_7:
fprintf(stderr, "%d", v3);
return 1;
}
while ( 2 )
{
v5 = getopt_long(argc, (char *const *)argv, "otek:a:p:b:c:q:", &long_options_0, longind);
if ( v5 == -1 )
goto LABEL_6;
switch ( v5 )
{
case 'a':
if ( argc != 3 )
goto LABEL_5;
v3 = generate_aik(optarg);
continue;
case 'b':
if ( argc != 2 )
goto LABEL_5;
v3 = get_aik_tcpa();
continue;
case 'c':
if ( argc != 3 )
goto LABEL_5;
v3 = tpm_challenge(optarg);
continue;
case 'e':
if ( argc != 2 )
goto LABEL_5;
v3 = get_endorsment_key();
continue;
case 'k':
if ( argc != 2 )
goto LABEL_5;
v3 = get_endorsment_keycert();
continue;
case 'o':
if ( argc != 2 )
goto LABEL_5;
v3 = tpm_owned();
continue;
case 'p':
if ( argc != 2 )
goto LABEL_5;
v3 = get_aik_pem();
continue;
case 'q':
if ( argc != 3 )
goto LABEL_5;
v3 = tpm_quote(optarg);
continue;
case 't':
if ( argc == 2 )
{
v3 = take_ownership();
continue;
}
LABEL_5:
func0();
LABEL_6:
closelog();
if ( v3 )
goto LABEL_7;
return v3;
default:
func0();
continue;
}
}
}

original_code:
int main(int argc, char *argv[])
{
    int opt = 0;
    int status = (UINT32)(0x00000000L + 0x003L);
    int long_index = 0;
    openlog("xentpm", 0x01, (1<<3));
    static struct option long_options[] = {
        {"is_tpm_owned", 0, 0, 'o' },
        {"take_ownership", 0, 0, 't' },
        {"get_ekey", 0, 0, 'e' },
        {"get_ekcert", 0, 0, 'k' },
        {"gen_aik", 1, 0, 'a' },
        {"get_aik_pem", 0, 0, 'p' },
        {"get_aik_tcpa", 0, 0, 'b' },
        {"tpm_challenge", 1, 0, 'c' },
        {"tpm_quote", 1, 0, 'q' },
        {0, 0, 0, 0 }
    };
    if( argc < 2 ){
        usage();
        goto clean;
    }
    while ((opt = getopt_long(argc, argv,"otek:a:p:b:c:q:",
                    long_options, &long_index)) != -1) {
        switch (opt) {
            case 'o' :
                if (argc != 2) {
                    usage();
                    goto clean;
                }
                status = tpm_owned();
                break;
            case 't' :
                if (argc != 2) {
                    usage();
                    goto clean;
                }
                status = take_ownership();
                break;
            case 'e' :
                if (argc != 2) {
                    usage();
                    goto clean;
                }
                status = get_endorsment_key();
                break;
            case 'k' :
                if (argc != 2) {
                    usage();
                    goto clean;
                }
                status = get_endorsment_keycert();
                break;
            case 'a' :
                if (argc != 3) {
                    usage();
                    goto clean;
                }
                status = generate_aik(optarg);
                break;
            case 'p' :
                if (argc != 2) {
                    usage();
                    goto clean;
                }
                status = get_aik_pem();
                break;
            case 'b' :
                if (argc != 2) {
                    usage();
                    goto clean;
                }
                status = get_aik_tcpa();
                break;
            case 'c' :
                if (argc != 3) {
                    usage();
                    goto clean;
                }
                status = tpm_challenge(optarg);
                break;
            case 'q' :
                if (argc != 3) {
                    usage();
                    goto clean;
                }
                status = tpm_quote(optarg);
                break;
            default:
                usage();
                break;
        }
    }
clean:
    closelog();
    if (!status) {
        return 0;
    } else {
        fprintf(stderr, "%d", status);
        return 1;
    }
}

variable_types: status int

variable_types: struct option { char *name; int has_arg; int *flag; int val; } []


decompiled_code:
__int64 take_ownership()
{
int v0; // edx
__int64 result; // rax
unsigned int v2; // ebx
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
const char *v8; // rax
const char *v9; // rax
const char *v10; // rax
const char *v11; // rax
const char *v12; // rax
_BYTE v13[28]; // [rsp+0h] [rbp-38h] BYREF
unsigned int v14; // [rsp+1Ch] [rbp-1Ch] BYREF
unsigned int v15; // [rsp+20h] [rbp-18h] BYREF
unsigned int v16; // [rsp+24h] [rbp-14h] BYREF
unsigned int v17; // [rsp+28h] [rbp-10h] BYREF
unsigned int v18[3]; // [rsp+2Ch] [rbp-Ch] BYREF

v0 = tpm_owned();
result = 0LL;
if ( !v0 )
{
syslog(6, "Taking ownership of the TPM.\n");
v2 = read_tpm_key(v13, 20LL);
if ( v2 )
{
syslog(3, "TPM Key Not Found \n");
}
else
{
v3 = tpm_init_context(v18, &v17, &v16);
v2 = v3;
if ( v3 )
{
v8 = (const char *)Trspi_Error_String(v3);
syslog(3, "Error 0x%x tpm_init_context %s \n", v2, v8);
}
else
{
v4 = Tspi_Context_CreateObject(v18[0], 2LL, 67108865LL, &v15);
v2 = v4;
if ( v4 )
{
v9 = (const char *)Trspi_Error_String(v4);
syslog(3, "Error 0x%x on Tspi_Context_CreateObject %s \n", v2, v9);
}
else
{
v5 = Tspi_GetPolicyObject(v15, 1LL, &v14);
v2 = v5;
if ( v5 )
{
v10 = (const char *)Trspi_Error_String(v5);
syslog(3, "Error 0x%x on Tspi_GetPolicyObject %s \n", v2, v10);
}
else
{
v6 = Tspi_Policy_SetSecret(v14, 4096LL, 20LL, v13);
v2 = v6;
if ( v6 )
{
v11 = (const char *)Trspi_Error_String(v6);
syslog(3, "Error Setting SRK Password %s \n", v11);
}
else
{
v7 = Tspi_TPM_TakeOwnership(v17, v15, 0LL);
v2 = v7;
if ( v7 )
{
v12 = (const char *)Trspi_Error_String(v7);
syslog(3, "Error 0x%x on Tspi_TPM_TakeOwnership (%s)\n", v2, v12);
}
else
{
syslog(6, "XenServer now owns the TPM.\n");
unregister_aik_uuid(v18[0]);
}
}
}
}
}
tpm_free_context(v18[0], v16);
}
result = v2;
}
return result;
}

canonical_decompiled_code:
__int64 func1()
{
int v0; // edx
__int64 result; // rax
unsigned int v2; // ebx
unsigned int v3; // eax
unsigned int v4; // eax
unsigned int v5; // eax
unsigned int v6; // eax
unsigned int v7; // eax
const char *v8; // rax
const char *v9; // rax
const char *v10; // rax
const char *v11; // rax
const char *v12; // rax
_BYTE v13[28]; // [rsp+0h] [rbp-38h] BYREF
unsigned int v14; // [rsp+1Ch] [rbp-1Ch] BYREF
unsigned int v15; // [rsp+20h] [rbp-18h] BYREF
unsigned int v16; // [rsp+24h] [rbp-14h] BYREF
unsigned int v17; // [rsp+28h] [rbp-10h] BYREF
unsigned int v18[3]; // [rsp+2Ch] [rbp-Ch] BYREF

v0 = func0();
result = 0LL;
if ( !v0 )
{
syslog(6, "Taking ownership of the TPM.\n");
v2 = read_tpm_key(v13, 20LL);
if ( v2 )
{
syslog(3, "TPM Key Not Found \n");
}
else
{
v3 = tpm_init_context(v18, &v17, &v16);
v2 = v3;
if ( v3 )
{
v8 = (const char *)Trspi_Error_String(v3);
syslog(3, "Error 0x%x tpm_init_context %s \n", v2, v8);
}
else
{
v4 = Tspi_Context_CreateObject(v18[0], 2LL, 67108865LL, &v15);
v2 = v4;
if ( v4 )
{
v9 = (const char *)Trspi_Error_String(v4);
syslog(3, "Error 0x%x on Tspi_Context_CreateObject %s \n", v2, v9);
}
else
{
v5 = Tspi_GetPolicyObject(v15, 1LL, &v14);
v2 = v5;
if ( v5 )
{
v10 = (const char *)Trspi_Error_String(v5);
syslog(3, "Error 0x%x on Tspi_GetPolicyObject %s \n", v2, v10);
}
else
{
v6 = Tspi_Policy_SetSecret(v14, 4096LL, 20LL, v13);
v2 = v6;
if ( v6 )
{
v11 = (const char *)Trspi_Error_String(v6);
syslog(3, "Error Setting SRK Password %s \n", v11);
}
else
{
v7 = Tspi_TPM_TakeOwnership(v17, v15, 0LL);
v2 = v7;
if ( v7 )
{
v12 = (const char *)Trspi_Error_String(v7);
syslog(3, "Error 0x%x on Tspi_TPM_TakeOwnership (%s)\n", v2, v12);
}
else
{
syslog(6, "XenServer now owns the TPM.\n");
unregister_aik_uuid(v18[0]);
}
}
}
}
}
tpm_free_context(v18[0], v16);
}
result = v2;
}
return result;
}

original_code:
int take_ownership()
{
    TSS_HCONTEXT context;
    TSS_HTPM tpm_handle;
    TSS_RESULT result;
    TSS_HPOLICY tpm_policy;
    TSS_HKEY srk_handle;
    TSS_HPOLICY srk_policy;
    TSS_FLAG srk_attributes;
    BYTE tpm_key[20];
    if (tpm_owned()) {
        return (UINT32)(0x00000000L);
    }
    syslog(6, "Taking ownership of the TPM.\n");
    if ((result = read_tpm_key(tpm_key, 20)) != 0) {
        syslog(3, "TPM Key Not Found \n");
        goto out;
    }
    result = tpm_init_context(& context, &tpm_handle, &tpm_policy);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x tpm_init_context %s \n",
                result,Trspi_Error_String(result));
        goto free_context;
    }
    srk_attributes = (0x04000000) | (0x00000001);
    result = Tspi_Context_CreateObject(context, (0x02),
  srk_attributes, &srk_handle);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x on Tspi_Context_CreateObject %s \n",
                result,Trspi_Error_String(result));
        goto free_context;
    }
    result = Tspi_GetPolicyObject(srk_handle, (0x00000001), &srk_policy);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x on Tspi_GetPolicyObject %s \n",
                result, Trspi_Error_String(result));
        goto free_context;
    }
    result = Tspi_Policy_SetSecret(srk_policy, (0x00001000),
            (UINT32)(sizeof(tpm_key)), (BYTE*)tpm_key);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error Setting SRK Password %s \n",
  Trspi_Error_String(result));
        goto free_context;
    }
    result = Tspi_TPM_TakeOwnership(tpm_handle, srk_handle, 0);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x on Tspi_TPM_TakeOwnership (%s)\n",
  result, Trspi_Error_String(result));
        goto free_context;
    }
    syslog(6, "XenServer now owns the TPM.\n");
    unregister_aik_uuid(context);
free_context:
    tpm_free_context(context, tpm_policy);
out:
    return result;
}

canonical_original_code:
int take_ownership()
{
    unsigned int context;
    unsigned int tpm_handle;
    unsigned int result;
    unsigned int tpm_policy;
    unsigned int srk_handle;
    unsigned int srk_policy;
    unsigned int srk_attributes;
    unsigned char tpm_key[20];
    if (tpm_owned()) {
        return (UINT32)(0x00000000L);
    }
    syslog(6, "Taking ownership of the TPM.\n");
    if ((result = read_tpm_key(tpm_key, 20)) != 0) {
        syslog(3, "TPM Key Not Found \n");
        goto out;
    }
    result = tpm_init_context(& context, &tpm_handle, &tpm_policy);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x tpm_init_context %s \n",
                result,Trspi_Error_String(result));
        goto free_context;
    }
    srk_attributes = (0x04000000) | (0x00000001);
    result = Tspi_Context_CreateObject(context, (0x02),
  srk_attributes, &srk_handle);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x on Tspi_Context_CreateObject %s \n",
                result,Trspi_Error_String(result));
        goto free_context;
    }
    result = Tspi_GetPolicyObject(srk_handle, (0x00000001), &srk_policy);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x on Tspi_GetPolicyObject %s \n",
                result, Trspi_Error_String(result));
        goto free_context;
    }
    result = Tspi_Policy_SetSecret(srk_policy, (0x00001000),
            (UINT32)(sizeof(tpm_key)), (unsigned char *)tpm_key);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error Setting SRK Password %s \n",
  Trspi_Error_String(result));
        goto free_context;
    }
    result = Tspi_TPM_TakeOwnership(tpm_handle, srk_handle, 0);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error 0x%x on Tspi_TPM_TakeOwnership (%s)\n",
  result, Trspi_Error_String(result));
        goto free_context;
    }
    syslog(6, "XenServer now owns the TPM.\n");
    unregister_aik_uuid(context);
free_context:
    tpm_free_context(context, tpm_policy);
out:
    return result;
}

variable_types:
context
unsigned int

variable_types:
result
unsigned int


decompiled_code:
__int64 __fastcall get_nonce_sha1(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v4; // rax
void *v5; // rbx
__int64 result; // rax
unsigned int v7[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v4 = base64_decode(a1, v7);
if ( v4 )
{
v5 = (void *)v4;
sha1(a3, v4, v7[0], a2);
free(v5);
result = 0LL;
}
else
{
syslog(3, "Unable to b64 decode nonce \n");
result = 3LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v4; // rax
void *v5; // rbx
__int64 result; // rax
unsigned int v7[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v4 = base64_decode(a1, v7);
if ( v4 )
{
v5 = (void *)v4;
sha1(a3, v4, v7[0], a2);
free(v5);
result = 0LL;
}
else
{
syslog(3, "Unable to b64 decode nonce \n");
result = 3LL;
}
return result;
}

original_code:
static int
get_nonce_sha1(char* b64_nonce, BYTE * nonce_hash, TSS_HCONTEXT tpm_context)
{
    int nonce_len ;
    BYTE* nonce_buf = ((void *)0);
    nonce_buf = base64_decode(b64_nonce, &nonce_len);
    if (!nonce_buf) {
        syslog(3, "Unable to b64 decode nonce \n");
        return (UINT32)(0x00000000L + 0x003L);
    }
    sha1(tpm_context, nonce_buf, nonce_len, nonce_hash);
    free(nonce_buf);
    return (UINT32)(0x00000000L);
}

canonical_original_code:
static int get_nonce_sha1(char *b64_nonce, unsigned char *nonce_hash, unsigned int tpm_context)
{
    int nonce_len;
    unsigned char *nonce_buf = ((void *)0);
    nonce_buf = base64_decode(b64_nonce, &nonce_len);
    if (!nonce_buf) {
        syslog(3, "Unable to b64 decode nonce \n");
        return (UINT32)(0x00000000L + 0x003L);
    }
    sha1(tpm_context, nonce_buf, nonce_len, nonce_hash);
    free(nonce_buf);
    return (UINT32)(0x00000000L);
}


decompiled_code:
__int64 __fastcall tpm_quote(const char *a1)
{
unsigned int v1; // eax
unsigned int v2; // ebx
unsigned int v3; // eax
unsigned int v4; // ebp
int v5; // er13
unsigned int v6; // eax
unsigned int v7; // ebp
int v8; // ebp
_WORD *v9; // r15
const char *v11; // rax
const char *v12; // rax
unsigned int v13; // eax
unsigned int v14; // ebp
unsigned int v15; // eax
unsigned int v16; // er12
_DWORD *v17; // rbp
_DWORD *v18; // rbp
const char *v19; // rax
unsigned int v20; // eax
unsigned int v21; // er13
__int64 v22; // r13
unsigned int v23; // ebp
unsigned int v24; // ebx
unsigned int v25; // er12
_WORD *v26; // rax
const char *v27; // rax
const char *v28; // rax
unsigned int n; // [rsp+8h] [rbp-C0h]
char v30[28]; // [rsp+10h] [rbp-B8h] BYREF
unsigned int v31; // [rsp+2Ch] [rbp-9Ch] BYREF
int *v32; // [rsp+30h] [rbp-98h] BYREF
int v33; // [rsp+3Ch] [rbp-8Ch] BYREF
char v34[4]; // [rsp+40h] [rbp-88h] BYREF
int v35; // [rsp+44h] [rbp-84h]
char *v36; // [rsp+48h] [rbp-80h]
size_t v37; // [rsp+60h] [rbp-68h]
void *src; // [rsp+68h] [rbp-60h]
unsigned int v39; // [rsp+74h] [rbp-54h] BYREF
unsigned int v40; // [rsp+78h] [rbp-50h] BYREF
unsigned int v41; // [rsp+7Ch] [rbp-4Ch] BYREF
unsigned int v42; // [rsp+80h] [rbp-48h] BYREF
unsigned int v43; // [rsp+84h] [rbp-44h] BYREF
unsigned int v44; // [rsp+88h] [rbp-40h] BYREF
unsigned int v45[15]; // [rsp+8Ch] [rbp-3Ch] BYREF

syslog(3, "Request for TPM quote generation for nonce %s \n", a1);
v1 = take_ownership();
if ( v1 )
{
v2 = v1;
syslog(3, "tpm_quote Error 0x%X taking ownership of TPM.\n", v1);
}
else
{
v2 = tpm_create_context(v45, &v44, &v43, &v40, &v41);
if ( !v2 )
{
v2 = get_nonce_sha1((__int64)a1, (__int64)v30, v45[0]);
if ( v2 )
{
syslog(3, "Unable to b64 decode nonce \n");
}
else
{
v2 = load_aik_tpm(v45[0], v43, &v42);
if ( v2 )
{
syslog(3, "xenquote Unable to load citrix aik");
}
else
{
v33 = 16;
v3 = Tspi_TPM_GetCapability(v44, 19LL, 4LL, &v33, &v31, &v32);
v4 = v3;
v2 = v3;
if ( v3 )
{
v11 = (const char *)Trspi_Error_String(v3);
syslog(3, "Tspi_TPM_GetCapability failed with 0x%X %s", v4, v11);
}
else
{
v5 = *v32;
Tspi_Context_FreeMemory(v45[0]);
v6 = Tspi_Context_CreateObject(v45[0], 4LL, 1LL, &v39);
v7 = v6;
v2 = v6;
if ( v6 )
{
v12 = (const char *)Trspi_Error_String(v6);
syslog(3, "Tspi_Context_CreateObject(PCR) failed with 0x%X %s", v7, v12);
}
else
{
n = (unsigned int)(v5 + 7) >> 3;
v8 = n + 20 * v5 + 6;
v9 = malloc(v8);
if ( v9 )
{
*v9 = _bswap_16(n);
memset(v9 + 1, 0, n);
if ( v5 )
{
while ( 1 )
{
v13 = Tspi_PcrComposite_SelectPcrIndex(v39, v2);
v14 = v13;
if ( v13 )
{
v19 = (const char *)Trspi_Error_String(v13);
syslog(3, "Tspi_PcrComposite_SelectPcrIndex failed with 0x%X %s", v14, v19);
v2 = v14;
goto LABEL_25;
}
*((_BYTE *)v9 + (int)v2 / 8 + 2) |= 1 << ((int)v2 % 8);
if ( v5 == v2 + 1 )
break;
++v2;
}
v35 = 20;
v36 = v30;
v15 = Tspi_TPM_Quote(v44, v42, v39, v34);
v16 = v15;
if ( v15 )
goto LABEL_37;
v17 = (_DWORD *)((char *)v9 + n + 2);
*v17 = _bswap_32(20 * v5);
v18 = v17 + 1;
while ( 1 )
{
v20 = Tspi_PcrComposite_GetPcrValue(v39, v16, &v31, &v32);
v21 = v20;
if ( v20 )
break;
v22 = v31;
memcpy(v18, v32, v31);
v18 = (_DWORD *)((char *)v18 + v22);
if ( v2 == v16 )
goto LABEL_29;
++v16;
}
v27 = (const char *)Trspi_Error_String(v20);
syslog(3, "Tspi_PcrComposite_GetPcrValue failed with 0x%X %s", v21, v27);
v2 = v21;
}
else
{
v35 = 20;
v36 = v30;
v15 = Tspi_TPM_Quote(v44, v42, v39, v34);
v16 = v15;
if ( v15 )
{
LABEL_37:
v28 = (const char *)Trspi_Error_String(v15);
syslog(3, "Tspi_TPM_Quote failed with 0x%X %s", v16, v28);
v2 = v16;
}
else
{
v18 = (_DWORD *)((char *)v9 + n + 2);
*v18 = _bswap_32(0);
LODWORD(v18) = (_DWORD)v18 + 4;
LABEL_29:
v23 = (_DWORD)v18 - (_DWORD)v9;
v24 = v37;
v25 = v37 + v23;
v26 = realloc(v9, (int)(v37 + v23));
v9 = v26;
if ( !v26 )
{
syslog(3, "Unable to realloc memory for size %d at %s and %d \n", v25, "xenquote.c", 286LL);
v2 = -3;
goto LABEL_13;
}
memcpy((char *)v26 + v23, src, v24);
v2 = print_base64(v9, v25);
if ( v2 )
{
syslog(3, "Error in converting B64 %s and %d ", "xenquote.c", 296LL);
v2 = -3;
}
else
{
syslog(6, "Generate TPM Quote Success!\n");
}
}
}
}
else
{
syslog(3, "Unable to allocate memory %d , %s and %d \n", (unsigned int)v8, "xenquote.c", 197LL);
v2 = -3;
}
LABEL_25:
free(v9);
}
}
}
}
LABEL_13:
Tspi_Context_CloseObject(v45[0], v41);
tpm_free_context(v45[0], v40);
return v2;
}
syslog(3, "Error in aik context for generating aik_pem");
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func3(const char *a1)
{
unsigned int v1; // eax
unsigned int v2; // ebx
unsigned int v3; // eax
unsigned int v4; // ebp
int v5; // er13
unsigned int v6; // eax
unsigned int v7; // ebp
int v8; // ebp
_WORD *v9; // r15
const char *v11; // rax
const char *v12; // rax
unsigned int v13; // eax
unsigned int v14; // ebp
unsigned int v15; // eax
unsigned int v16; // er12
_DWORD *v17; // rbp
_DWORD *v18; // rbp
const char *v19; // rax
unsigned int v20; // eax
unsigned int v21; // er13
__int64 v22; // r13
unsigned int v23; // ebp
unsigned int v24; // ebx
unsigned int v25; // er12
_WORD *v26; // rax
const char *v27; // rax
const char *v28; // rax
unsigned int n; // [rsp+8h] [rbp-C0h]
char v30[28]; // [rsp+10h] [rbp-B8h] BYREF
unsigned int v31; // [rsp+2Ch] [rbp-9Ch] BYREF
int *v32; // [rsp+30h] [rbp-98h] BYREF
int v33; // [rsp+3Ch] [rbp-8Ch] BYREF
char v34[4]; // [rsp+40h] [rbp-88h] BYREF
int v35; // [rsp+44h] [rbp-84h]
char *v36; // [rsp+48h] [rbp-80h]
size_t v37; // [rsp+60h] [rbp-68h]
void *src; // [rsp+68h] [rbp-60h]
unsigned int v39; // [rsp+74h] [rbp-54h] BYREF
unsigned int v40; // [rsp+78h] [rbp-50h] BYREF
unsigned int v41; // [rsp+7Ch] [rbp-4Ch] BYREF
unsigned int v42; // [rsp+80h] [rbp-48h] BYREF
unsigned int v43; // [rsp+84h] [rbp-44h] BYREF
unsigned int v44; // [rsp+88h] [rbp-40h] BYREF
unsigned int v45[15]; // [rsp+8Ch] [rbp-3Ch] BYREF

syslog(3, "Request for TPM quote generation for nonce %s \n", a1);
v1 = take_ownership();
if ( v1 )
{
v2 = v1;
syslog(3, "tpm_quote Error 0x%X taking ownership of TPM.\n", v1);
}
else
{
v2 = tpm_create_context(v45, &v44, &v43, &v40, &v41);
if ( !v2 )
{
v2 = func0((__int64)a1, (__int64)v30, v45[0]);
if ( v2 )
{
syslog(3, "Unable to b64 decode nonce \n");
}
else
{
v2 = load_aik_tpm(v45[0], v43, &v42);
if ( v2 )
{
syslog(3, "xenquote Unable to load citrix aik");
}
else
{
v33 = 16;
v3 = Tspi_TPM_GetCapability(v44, 19LL, 4LL, &v33, &v31, &v32);
v4 = v3;
v2 = v3;
if ( v3 )
{
v11 = (const char *)Trspi_Error_String(v3);
syslog(3, "Tspi_TPM_GetCapability failed with 0x%X %s", v4, v11);
}
else
{
v5 = *v32;
Tspi_Context_FreeMemory(v45[0]);
v6 = Tspi_Context_CreateObject(v45[0], 4LL, 1LL, &v39);
v7 = v6;
v2 = v6;
if ( v6 )
{
v12 = (const char *)Trspi_Error_String(v6);
syslog(3, "Tspi_Context_CreateObject(PCR) failed with 0x%X %s", v7, v12);
}
else
{
n = (unsigned int)(v5 + 7) >> 3;
v8 = n + 20 * v5 + 6;
v9 = malloc(v8);
if ( v9 )
{
*v9 = func1(n);
memset(v9 + 1, 0, n);
if ( v5 )
{
while ( 1 )
{
v13 = Tspi_PcrComposite_SelectPcrIndex(v39, v2);
v14 = v13;
if ( v13 )
{
v19 = (const char *)Trspi_Error_String(v13);
syslog(3, "Tspi_PcrComposite_SelectPcrIndex failed with 0x%X %s", v14, v19);
v2 = v14;
goto LABEL_25;
}
*((_BYTE *)v9 + (int)v2 / 8 + 2) |= 1 << ((int)v2 % 8);
if ( v5 == v2 + 1 )
break;
++v2;
}
v35 = 20;
v36 = v30;
v15 = Tspi_TPM_Quote(v44, v42, v39, v34);
v16 = v15;
if ( v15 )
goto LABEL_37;
v17 = (_DWORD *)((char *)v9 + n + 2);
*v17 = func2(20 * v5);
v18 = v17 + 1;
while ( 1 )
{
v20 = Tspi_PcrComposite_GetPcrValue(v39, v16, &v31, &v32);
v21 = v20;
if ( v20 )
break;
v22 = v31;
memcpy(v18, v32, v31);
v18 = (_DWORD *)((char *)v18 + v22);
if ( v2 == v16 )
goto LABEL_29;
++v16;
}
v27 = (const char *)Trspi_Error_String(v20);
syslog(3, "Tspi_PcrComposite_GetPcrValue failed with 0x%X %s", v21, v27);
v2 = v21;
}
else
{
v35 = 20;
v36 = v30;
v15 = Tspi_TPM_Quote(v44, v42, v39, v34);
v16 = v15;
if ( v15 )
{
LABEL_37:
v28 = (const char *)Trspi_Error_String(v15);
syslog(3, "Tspi_TPM_Quote failed with 0x%X %s", v16, v28);
v2 = v16;
}
else
{
v18 = (_DWORD *)((char *)v9 + n + 2);
*v18 = func2(0);
LODWORD(v18) = (_DWORD)v18 + 4;
LABEL_29:
v23 = (_DWORD)v18 - (_DWORD)v9;
v24 = v37;
v25 = v37 + v23;
v26 = realloc(v9, (int)(v37 + v23));
v9 = v26;
if ( !v26 )
{
syslog(3, "Unable to realloc memory for size %d at %s and %d \n", v25, "xenquote.c", 286LL);
v2 = -3;
goto LABEL_13;
}
memcpy((char *)v26 + v23, src, v24);
v2 = print_base64(v9, v25);
if ( v2 )
{
syslog(3, "Error in converting B64 %s and %d ", "xenquote.c", 296LL);
v2 = -3;
}
else
{
syslog(6, "Generate TPM Quote Success!\n");
}
}
}
}
else
{
syslog(3, "Unable to allocate memory %d , %s and %d \n", (unsigned int)v8, "xenquote.c", 197LL);
v2 = -3;
}
LABEL_25:
free(v9);
}
}
}
}
LABEL_13:
Tspi_Context_CloseObject(v45[0], v41);
tpm_free_context(v45[0], v40);
return v2;
}
syslog(3, "Error in aik context for generating aik_pem");
}
return v2;
}

original_code:
int
tpm_quote(char * b64_nonce)
{
    TSS_HCONTEXT tpm_context;
    TSS_HTPM tpm_handle;
    TSS_HKEY srk_handle;
    TSS_HKEY aik_handle;
    TSS_HPOLICY srk_policy;
    TSS_HPOLICY tpm_policy;
    TSS_HPCRS pcr_handle;
    TSS_VALIDATION valid;
    UINT32 pcr_property;
    UINT32 max_pcr;
    BYTE* pcr_mask ;
    UINT32 mask_size;
    BYTE* quote_buf;
    UINT32 quote_buf_len;
    BYTE* marker;
    BYTE* api_buf;
    UINT32 api_buf_len;
    BYTE nonce_hash[20];
    int i;
    int result;
    int alloc_size;
    syslog(3, "Request for TPM quote generation for nonce %s \n", b64_nonce);
    result = take_ownership();
    if (result) {
        syslog(3, "tpm_quote Error 0x%X taking ownership of TPM.\n", result);
        goto out;
    }
    if ((result = tpm_create_context(&tpm_context, &tpm_handle, &srk_handle,
                &tpm_policy, &srk_policy)) != (UINT32)(0x00000000L)) {
        syslog(3, "Error in aik context for generating aik_pem");
        goto out;
    }
    if ((result = get_nonce_sha1(b64_nonce, nonce_hash,
                tpm_context)) != (UINT32)(0x00000000L)) {
        syslog(3, "Unable to b64 decode nonce \n");
        goto free_context;
    }
    if ((result = load_aik_tpm(tpm_context,
                srk_handle, &aik_handle)) != (UINT32)(0x00000000L)) {
        syslog(3, "xenquote Unable to load citrix aik");
        goto free_context;
    }
    pcr_property = (0x10);
    if ((result = Tspi_TPM_GetCapability(tpm_handle, (0x13),
          sizeof(pcr_property), (BYTE *)&pcr_property, &api_buf_len,
                &api_buf)) != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_TPM_GetCapability failed with 0x%X %s", result,
            Trspi_Error_String(result));
        goto free_context;
    }
    max_pcr = *(UINT32 *)api_buf;
    Tspi_Context_FreeMemory(tpm_context, api_buf);
    mask_size = ((max_pcr + 8 - 1 ) / 8);
    if ((result = Tspi_Context_CreateObject(tpm_context, (0x04),
          (0x00000001), &pcr_handle)) != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_Context_CreateObject(PCR) failed with 0x%X %s",
            result, Trspi_Error_String(result));
        goto free_context;
    }
    alloc_size = sizeof(UINT16) + mask_size + sizeof(UINT32) +
                    (0x14) * max_pcr;
    quote_buf = (BYTE*)malloc(alloc_size);
    if (!quote_buf) {
        syslog(3, "Unable to allocate memory %d , %s and %d \n",
        alloc_size, "xenquote.c", 197);
        result = -3;
        goto free_quote;
    }
    *(UINT16 *)quote_buf = htons(mask_size);
    pcr_mask = quote_buf + sizeof(UINT16);
    memset(pcr_mask, 0, mask_size);
    for (i = 0;i < max_pcr; i++) {
        result = Tspi_PcrComposite_SelectPcrIndex(pcr_handle, i);
        if (result != (UINT32)(0x00000000L)) {
            syslog(3, "Tspi_PcrComposite_SelectPcrIndex failed with 0x%X %s",
                 result, Trspi_Error_String(result));
            goto free_quote;
        }
        ((((BYTE*)pcr_mask)[i/8] |= 1 << (i%8)));
    }
    valid.ulExternalDataLength = sizeof(nonce_hash);
    valid.rgbExternalData = nonce_hash;
    result = Tspi_TPM_Quote(tpm_handle, aik_handle, pcr_handle, &valid);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_TPM_Quote failed with 0x%X %s",
            result, Trspi_Error_String(result));
        goto free_quote;
    }
    marker = quote_buf + sizeof(UINT16) + mask_size;
    *(UINT32 *)marker = htonl((0x14)*max_pcr);
    marker += sizeof(UINT32);
    for (i = 0;i < max_pcr; i++) {
        result = Tspi_PcrComposite_GetPcrValue(pcr_handle, i, &api_buf_len,
                &api_buf);
        if (result != (UINT32)(0x00000000L)) {
            syslog(3, "Tspi_PcrComposite_GetPcrValue failed with 0x%X %s",
                    result, Trspi_Error_String(result));
            goto free_quote;
        }
        memcpy (marker, api_buf, api_buf_len);
        marker += api_buf_len;
    }
    quote_buf_len = marker - quote_buf;
    alloc_size = quote_buf_len + valid.ulValidationDataLength;
    quote_buf = realloc(quote_buf, alloc_size);
    if (!quote_buf) {
        syslog(3, "Unable to realloc memory for size %d at %s and %d \n",
            alloc_size, "xenquote.c", 286);
        result = -3;
        goto free_context;
    }
    memcpy(&quote_buf[quote_buf_len], valid.rgbValidationData,
            valid.ulValidationDataLength);
    quote_buf_len += valid.ulValidationDataLength;
    if ((result = print_base64(quote_buf, quote_buf_len)) != 0) {
        syslog(3, "Error in converting B64 %s and %d ", "xenquote.c", 296);
        result = -3;
        goto free_quote;
    }
    syslog(6, "Generate TPM Quote Success!\n");
free_quote:
    free(quote_buf);
free_context:
    Tspi_Context_CloseObject(tpm_context, srk_policy);
    tpm_free_context(tpm_context, tpm_policy);
out:
    return result;
}

canonical_original_code:
int tpm_quote(char *b64_nonce)
{
    unsigned int tpm_context;
    unsigned int tpm_handle;
    unsigned int srk_handle;
    unsigned int aik_handle;
    unsigned int srk_policy;
    unsigned int tpm_policy;
    unsigned int pcr_handle;
    struct tdTSS_VALIDATION valid;
    unsigned int pcr_property;
    unsigned int max_pcr;
    unsigned char *pcr_mask;
    unsigned int mask_size;
    unsigned char *quote_buf;
    unsigned int quote_buf_len;
    unsigned char *marker;
    unsigned char *api_buf;
    unsigned int api_buf_len;
    unsigned char nonce_hash[20];
    int i;
    int result;
    int alloc_size;
    syslog(3, "Request for TPM quote generation for nonce %s \n", b64_nonce);
    result = take_ownership();
    if (result) {
        syslog(3, "tpm_quote Error 0x%X taking ownership of TPM.\n", result);
        goto out;
    }
    if ((result = tpm_create_context(&tpm_context, &tpm_handle, &srk_handle,
                &tpm_policy, &srk_policy)) != (UINT32)(0x00000000L)) {
        syslog(3, "Error in aik context for generating aik_pem");
        goto out;
    }
    if ((result = get_nonce_sha1(b64_nonce, nonce_hash,
                tpm_context)) != (UINT32)(0x00000000L)) {
        syslog(3, "Unable to b64 decode nonce \n");
        goto free_context;
    }
    if ((result = load_aik_tpm(tpm_context,
                srk_handle, &aik_handle)) != (UINT32)(0x00000000L)) {
        syslog(3, "xenquote Unable to load citrix aik");
        goto free_context;
    }
    pcr_property = (0x10);
    if ((result = Tspi_TPM_GetCapability(tpm_handle, (0x13),
          sizeof(pcr_property), (unsigned char *)&pcr_property, &api_buf_len,
                &api_buf)) != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_TPM_GetCapability failed with 0x%X %s", result,
            Trspi_Error_String(result));
        goto free_context;
    }
    max_pcr = *(unsigned int *)api_buf;
    Tspi_Context_FreeMemory(tpm_context, api_buf);
    mask_size = ((max_pcr + 8 - 1 ) / 8);
    if ((result = Tspi_Context_CreateObject(tpm_context, (0x04),
          (0x00000001), &pcr_handle)) != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_Context_CreateObject(PCR) failed with 0x%X %s",
            result, Trspi_Error_String(result));
        goto free_context;
    }
    alloc_size = sizeof(UINT16) + mask_size + sizeof(UINT32) +
                    (0x14) * max_pcr;
    quote_buf = (unsigned char *)malloc(alloc_size);
    if (!quote_buf) {
        syslog(3, "Unable to allocate memory %d , %s and %d \n",
        alloc_size, "xenquote.c", 197);
        result = -3;
        goto free_quote;
    }
    *(unsigned short *)quote_buf = htons(mask_size);
    pcr_mask = quote_buf + sizeof(UINT16);
    memset(pcr_mask, 0, mask_size);
    for (i = 0;i < max_pcr; i++) {
        result = Tspi_PcrComposite_SelectPcrIndex(pcr_handle, i);
        if (result != (UINT32)(0x00000000L)) {
            syslog(3, "Tspi_PcrComposite_SelectPcrIndex failed with 0x%X %s",
                 result, Trspi_Error_String(result));
            goto free_quote;
        }
        ((((unsigned char *)pcr_mask)[i/8] |= 1 << (i%8)));
    }
    valid.ulExternalDataLength = sizeof(nonce_hash);
    valid.rgbExternalData = nonce_hash;
    result = Tspi_TPM_Quote(tpm_handle, aik_handle, pcr_handle, &valid);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_TPM_Quote failed with 0x%X %s",
            result, Trspi_Error_String(result));
        goto free_quote;
    }
    marker = quote_buf + sizeof(UINT16) + mask_size;
    *(unsigned int *)marker = htonl((0x14)*max_pcr);
    marker += sizeof(UINT32);
    for (i = 0;i < max_pcr; i++) {
        result = Tspi_PcrComposite_GetPcrValue(pcr_handle, i, &api_buf_len,
                &api_buf);
        if (result != (UINT32)(0x00000000L)) {
            syslog(3, "Tspi_PcrComposite_GetPcrValue failed with 0x%X %s",
                    result, Trspi_Error_String(result));
            goto free_quote;
        }
        memcpy (marker, api_buf, api_buf_len);
        marker += api_buf_len;
    }
    quote_buf_len = marker - quote_buf;
    alloc_size = quote_buf_len + valid.ulValidationDataLength;
    quote_buf = realloc(quote_buf, alloc_size);
    if (!quote_buf) {
        syslog(3, "Unable to realloc memory for size %d at %s and %d \n",
            alloc_size, "xenquote.c", 286);
        result = -3;
        goto free_context;
    }
    memcpy(&quote_buf[quote_buf_len], valid.rgbValidationData,
            valid.ulValidationDataLength);
    quote_buf_len += valid.ulValidationDataLength;
    if ((result = print_base64(quote_buf, quote_buf_len)) != 0) {
        syslog(3, "Error in converting B64 %s and %d ", "xenquote.c", 296);
        result = -3;
        goto free_quote;
    }
    syslog(6, "Generate TPM Quote Success!\n");
free_quote:
    free(quote_buf);
free_context:
    Tspi_Context_CloseObject(tpm_context, srk_policy);
    tpm_free_context(tpm_context, tpm_policy);
out:
    return result;
}

variable_types: struct tdTSS_VALIDATION { struct tdTSS_VERSION { unsigned char bMajor; unsigned char bMinor; unsigned char bRevMajor; unsigned char bRevMinor; } versionInfo; unsigned int ulExternalDataLength; unsigned char *rgbExternalData; unsigned int ulDataLength; unsigned char *rgbData; unsigned int ulValidationDataLength; unsigned char *rgbValidationData; }

variable_types:
marker
unsigned char *

variable_types: i int

variable_types: result int

user_defined_types: struct tdTSS_VALIDATION { struct tdTSS_VERSION versionInfo; unsigned int ulExternalDataLength; unsigned char *rgbExternalData; unsigned int ulDataLength; unsigned char *rgbData; unsigned int ulValidationDataLength; unsigned char *rgbValidationData; }


decompiled_code:
__int64 __fastcall tpm_challenge(__int64 a1)
{
__int64 v1; // rax
unsigned int *v2; // rbp
unsigned int v3; // ebx
int v4; // ebx
__int64 v5; // r12
unsigned int v6; // eax
__int64 v7; // rdx
__int64 v8; // rcx
unsigned int v10; // eax
unsigned int v11; // ebp
const char *v12; // rax
unsigned int v13; // [rsp+8h] [rbp-50h] BYREF
unsigned int v14; // [rsp+Ch] [rbp-4Ch] BYREF
__int64 v15; // [rsp+10h] [rbp-48h] BYREF
unsigned int v16; // [rsp+18h] [rbp-40h] BYREF
unsigned int v17; // [rsp+1Ch] [rbp-3Ch] BYREF
unsigned int v18; // [rsp+20h] [rbp-38h] BYREF
unsigned int v19; // [rsp+24h] [rbp-34h] BYREF
unsigned int v20; // [rsp+28h] [rbp-30h] BYREF
unsigned int v21[11]; // [rsp+2Ch] [rbp-2Ch] BYREF

syslog(6, "Recieved a Challange");
v1 = base64_decode(a1, &v13);
if ( v1 )
{
v2 = (unsigned int *)v1;
v3 = tpm_create_context(v21, &v20, &v19, &v17, &v16);
if ( v3 )
{
syslog(3, "Error in aik context for generating aik");
return v3;
}
v3 = load_aik_tpm(v21[0], v19, &v18);
if ( v3 )
{
syslog(3, "challange Unable to load citrix aik");
}
else
{
v4 = v13;
if ( v13 <= 7 )
{
syslog(3, "Challenge Length too small\n");
v3 = 3;
}
else
{
v5 = (unsigned int)_bswap_32(*v2);
if ( v4 < (unsigned __int64)(v5 + 8) )
{
syslog(3, "Challenge incomplete\n");
v3 = 3;
}
else
{
v6 = _bswap_32(*(unsigned int *)((char *)v2 + v5 + 4));
if ( v4 == (unsigned int)v5 + v6 + 8LL )
{
v10 = Tspi_TPM_ActivateIdentity(v20, v18, (unsigned int)v5, v2 + 1, v6, (char *)v2 + v5 + 8, &v14, &v15);
v11 = v10;
v3 = v10;
if ( v10 )
{
v12 = (const char *)Trspi_Error_String(v10);
syslog(3, "Tspi_TPM_ActivateIdentity failed with 0x%X %s", v11, v12);
}
else
{
v3 = print_base64(v15, v14);
if ( v3 )
syslog(3, "Error in converting B64 %s and %d ", "challenge.c", 160LL);
else
syslog(6, "XenTPM challange success!\n");
}
}
else
{
syslog(3, "Challenge does not have SYM and ASYM keys\n", v7, v8, v6);
v3 = 3;
}
}
}
}
}
else
{
syslog(3, "Unable to b64 decode challange \n");
v3 = 3;
}
Tspi_Context_CloseObject(v21[0], v16);
tpm_free_context(v21[0], v17);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 v1; // rax
unsigned int *v2; // rbp
unsigned int v3; // ebx
int v4; // ebx
__int64 v5; // r12
unsigned int v6; // eax
__int64 v7; // rdx
__int64 v8; // rcx
unsigned int v10; // eax
unsigned int v11; // ebp
const char *v12; // rax
unsigned int v13; // [rsp+8h] [rbp-50h] BYREF
unsigned int v14; // [rsp+Ch] [rbp-4Ch] BYREF
__int64 v15; // [rsp+10h] [rbp-48h] BYREF
unsigned int v16; // [rsp+18h] [rbp-40h] BYREF
unsigned int v17; // [rsp+1Ch] [rbp-3Ch] BYREF
unsigned int v18; // [rsp+20h] [rbp-38h] BYREF
unsigned int v19; // [rsp+24h] [rbp-34h] BYREF
unsigned int v20; // [rsp+28h] [rbp-30h] BYREF
unsigned int v21[11]; // [rsp+2Ch] [rbp-2Ch] BYREF

syslog(6, "Recieved a Challange");
v1 = base64_decode(a1, &v13);
if ( v1 )
{
v2 = (unsigned int *)v1;
v3 = tpm_create_context(v21, &v20, &v19, &v17, &v16);
if ( v3 )
{
syslog(3, "Error in aik context for generating aik");
return v3;
}
v3 = load_aik_tpm(v21[0], v19, &v18);
if ( v3 )
{
syslog(3, "challange Unable to load citrix aik");
}
else
{
v4 = v13;
if ( v13 <= 7 )
{
syslog(3, "Challenge Length too small\n");
v3 = 3;
}
else
{
v5 = (unsigned int)func0(*v2);
if ( v4 < (unsigned __int64)(v5 + 8) )
{
syslog(3, "Challenge incomplete\n");
v3 = 3;
}
else
{
v6 = func0(*(unsigned int *)((char *)v2 + v5 + 4));
if ( v4 == (unsigned int)v5 + v6 + 8LL )
{
v10 = Tspi_TPM_ActivateIdentity(v20, v18, (unsigned int)v5, v2 + 1, v6, (char *)v2 + v5 + 8, &v14, &v15);
v11 = v10;
v3 = v10;
if ( v10 )
{
v12 = (const char *)Trspi_Error_String(v10);
syslog(3, "Tspi_TPM_ActivateIdentity failed with 0x%X %s", v11, v12);
}
else
{
v3 = print_base64(v15, v14);
if ( v3 )
syslog(3, "Error in converting B64 %s and %d ", "challenge.c", 160LL);
else
syslog(6, "XenTPM challange success!\n");
}
}
else
{
syslog(3, "Challenge does not have SYM and ASYM keys\n", v7, v8, v6);
v3 = 3;
}
}
}
}
}
else
{
syslog(3, "Unable to b64 decode challange \n");
v3 = 3;
}
Tspi_Context_CloseObject(v21[0], v16);
tpm_free_context(v21[0], v17);
return v3;
}

original_code:
int tpm_challenge(char *b64_challenge)
{
    TSS_HCONTEXT context;
    TSS_HTPM tpm_handle;
    TSS_HKEY srk_handle;
    TSS_HKEY aik_handle;
    TSS_HPOLICY tpm_policy;
    TSS_HPOLICY srk_policy;
    BYTE *response;
    UINT32 responseLen;
    BYTE *asymCA_data;
    UINT32 asymCA_data_len;
    BYTE *symCA_data;
    UINT32 symCA_data_len;
    BYTE* challenge = ((void *)0);
    int challenge_len;
    int result;
    syslog(6, "Recieved a Challange");
    challenge = base64_decode(b64_challenge, &challenge_len);
    if (!challenge) {
        syslog(3, "Unable to b64 decode challange \n");
        result = (UINT32)(0x00000000L + 0x003L);
        goto free_context;
    }
    result = tpm_create_context(&context, &tpm_handle, &srk_handle,
            &tpm_policy, &srk_policy);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error in aik context for generating aik");
        goto out;
    }
    if ((result = load_aik_tpm(context,
            srk_handle, &aik_handle)) != 0) {
        syslog(3, "challange Unable to load citrix aik");
        goto free_context;
    }
    if (challenge_len < 2*sizeof(UINT32)){
        result = (UINT32)(0x00000000L + 0x003L);
        syslog(3, "Challenge Length too small\n");
        goto free_context;
    }
    asymCA_data_len = ntohl(*(UINT32*)challenge);
    asymCA_data = challenge + sizeof(UINT32);
    challenge += (asymCA_data_len + sizeof(UINT32));
    if (challenge_len < asymCA_data_len + 2*sizeof(UINT32)) {
        syslog(3, "Challenge incomplete\n");
        result = (UINT32)(0x00000000L + 0x003L);
        goto free_context;
    }
    symCA_data_len = ntohl(*(UINT32*)challenge);
    if (challenge_len != asymCA_data_len + symCA_data_len + 2*sizeof(UINT32)) {
        syslog(3, "Challenge does not have SYM and ASYM keys\n");
        result = (UINT32)(0x00000000L + 0x003L);
        goto free_context;
    }
    symCA_data = challenge + sizeof(UINT32);
    result = Tspi_TPM_ActivateIdentity(tpm_handle, aik_handle, asymCA_data_len,
                asymCA_data, symCA_data_len, symCA_data, &responseLen,
                &response);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_TPM_ActivateIdentity failed with 0x%X %s",
            result, Trspi_Error_String(result));
        goto free_context;
    }
    if ((result = print_base64(response, responseLen)) != 0) {
        syslog(3, "Error in converting B64 %s and %d ",
            "challenge.c",160);
        goto free_context;
    }
    syslog(6, "XenTPM challange success!\n");
free_context:
    Tspi_Context_CloseObject(context, srk_policy);
    tpm_free_context(context, tpm_policy);
out:
    return result;
}

canonical_original_code:
int tpm_challenge(char *b64_challenge)
{
    unsigned int context;
    unsigned int tpm_handle;
    unsigned int srk_handle;
    unsigned int aik_handle;
    unsigned int tpm_policy;
    unsigned int srk_policy;
    unsigned char *response;
    unsigned int responseLen;
    unsigned char *asymCA_data;
    unsigned int asymCA_data_len;
    unsigned char *symCA_data;
    unsigned int symCA_data_len;
    unsigned char *challenge = ((void *)0);
    int challenge_len;
    int result;
    syslog(6, "Recieved a Challange");
    challenge = base64_decode(b64_challenge, &challenge_len);
    if (!challenge) {
        syslog(3, "Unable to b64 decode challange \n");
        result = (UINT32)(0x00000000L + 0x003L);
        goto free_context;
    }
    result = tpm_create_context(&context, &tpm_handle, &srk_handle,
            &tpm_policy, &srk_policy);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Error in aik context for generating aik");
        goto out;
    }
    if ((result = load_aik_tpm(context,
            srk_handle, &aik_handle)) != 0) {
        syslog(3, "challange Unable to load citrix aik");
        goto free_context;
    }
    if (challenge_len < 2*sizeof(UINT32)){
        result = (UINT32)(0x00000000L + 0x003L);
        syslog(3, "Challenge Length too small\n");
        goto free_context;
    }
    asymCA_data_len = ntohl(*(unsigned int *)challenge);
    asymCA_data = challenge + sizeof(UINT32);
    challenge += (asymCA_data_len + sizeof(UINT32));
    if (challenge_len < asymCA_data_len + 2*sizeof(UINT32)) {
        syslog(3, "Challenge incomplete\n");
        result = (UINT32)(0x00000000L + 0x003L);
        goto free_context;
    }
    symCA_data_len = ntohl(*(unsigned int *)challenge);
    if (challenge_len != asymCA_data_len + symCA_data_len + 2*sizeof(UINT32)) {
        syslog(3, "Challenge does not have SYM and ASYM keys\n");
        result = (UINT32)(0x00000000L + 0x003L);
        goto free_context;
    }
    symCA_data = challenge + sizeof(UINT32);
    result = Tspi_TPM_ActivateIdentity(tpm_handle, aik_handle, asymCA_data_len,
                asymCA_data, symCA_data_len, symCA_data, &responseLen,
                &response);
    if (result != (UINT32)(0x00000000L)) {
        syslog(3, "Tspi_TPM_ActivateIdentity failed with 0x%X %s",
            result, Trspi_Error_String(result));
        goto free_context;
    }
    if ((result = print_base64(response, responseLen)) != 0) {
        syslog(3, "Error in converting B64 %s and %d ",
            "challenge.c",160);
        goto free_context;
    }
    syslog(6, "XenTPM challange success!\n");
free_context:
    Tspi_Context_CloseObject(context, srk_policy);
    tpm_free_context(context, tpm_policy);
out:
    return result;
}

variable_types:
response
unsigned char *

variable_types:
responseLen
unsigned int

variable_types:
challenge
unsigned char *


mstots

repo: xenserver/xha

decompiled_code:
__int64 __fastcall mstots(__int64 a1)
{
return a1 / 1000;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return a1 / 1000;
}

original_code:
static __inline struct timespec
mstots(MTC_CLOCK ms)
{
    struct timespec ts;
    ts.tv_sec = ms / 1000;
    ts.tv_nsec = (ms % 1000) * 1000 * 1000;
    return ts;
}

canonical_original_code:
static __inline struct timespec mstots(long long ms)
{
    struct timespec ts;
    ts.tv_sec = ms / 1000;
    ts.tv_nsec = (ms % 1000) * 1000 * 1000;
    return ts;
}

variable_types:
ms
long long

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


mstotv

decompiled_code:
__int64 __fastcall mstotv(__int64 a1)
{
return a1 / 1000;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return a1 / 1000;
}

original_code:
static __inline struct timeval
mstotv(MTC_CLOCK ms)
{
    struct timeval tv;
    tv.tv_sec = ms / 1000;
    tv.tv_usec = (ms % 1000) * 1000;
    return tv;
}

canonical_original_code:
static __inline struct timeval mstotv(long long ms)
{
    struct timeval tv;
    tv.tv_sec = ms / 1000;
    tv.tv_usec = (ms % 1000) * 1000;
    return tv;
}

variable_types: struct timeval { long tv_sec; long tv_usec; }


decompiled_code:
int __fastcall xm_sleep(__int64 a1)
{
struct timespec v1; // rax
int result; // eax
struct timespec v3; // [rsp+0h] [rbp-28h] BYREF
struct timespec requested_time; // [rsp+10h] [rbp-18h] BYREF

v1.tv_sec = mstots(a1);
v3 = v1;
for ( requested_time = v1; ; requested_time = (struct timespec)_mm_loadu_si128((const __m128i *)&v3) )
{
result = nanosleep(&requested_time, &v3);
if ( !result )
break;
}
return result;
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1)
{
struct timespec v1; // rax
int result; // eax
struct timespec v3; // [rsp+0h] [rbp-28h] BYREF
struct timespec requested_time; // [rsp+10h] [rbp-18h] BYREF

v1.tv_sec = func0(a1);
v3 = v1;
for ( requested_time = v1; ; requested_time = (struct timespec)_mm_loadu_si128((const __m128i *)&v3) )
{
result = nanosleep(&requested_time, &v3);
if ( !result )
break;
}
return result;
}

original_code:
void
xm_sleep(
    MTC_CLOCK msec)
{
    struct timespec ts, ts_rem;
    ts = ts_rem = mstots(msec);
    while (nanosleep(&ts, &ts_rem)) ts = ts_rem;
}

canonical_original_code:
void xm_sleep(long long msec)
{
    struct timespec ts; struct timespec ts_rem;
    ts = ts_rem = mstots(msec);
    while (nanosleep(&ts, &ts_rem)) ts = ts_rem;
}

variable_types:
msec
long long

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


decompiled_code:
int xm_close_descriptors()
{
rlim_t v0; // rax
__int64 v1; // rbx
__int64 v2; // rax
struct rlimit v4; // [rsp+0h] [rbp-18h] BYREF

LODWORD(v0) = getrlimit(RLIMIT_NOFILE, &v4);
if ( v4.rlim_cur > 2 )
{
v1 = 0LL;
do
{
close(v1 + 2);
v2 = v1++;
v0 = v2 + 3;
}
while ( v4.rlim_cur > v0 );
}
return v0;
}

canonical_decompiled_code:
int func5()
{
rlim_t v0; // rax
__int64 v1; // rbx
__int64 v2; // rax
struct rlimit v4; // [rsp+0h] [rbp-18h] BYREF

LODWORD(v0) = getrlimit(RLIMIT_NOFILE, &v4);
if ( v4.rlim_cur > 2 )
{
v1 = 0LL;
do
{
close(v1 + 2);
v2 = v1++;
v0 = v2 + 3;
}
while ( v4.rlim_cur > v0 );
}
return v0;
}

original_code:
void
xm_close_descriptors()
{
    struct rlimit rlimit;
    int fd;
    getrlimit(RLIMIT_NOFILE, &rlimit);
    for (fd = 2; fd < rlimit.rlim_cur; fd++)
    {
        close(fd);
    }
}

variable_types: struct rlimit { unsigned long rlim_cur; unsigned long rlim_max; }

variable_types: fd int


decompiled_code:
__int64 __fastcall xapi_healthcheck(__pid_t *a1, _DWORD *a2)
{
__pid_t v2; // eax
__int64 result; // rax
int *v4; // rax
int *v5; // rax
int pipedes[2]; // [rsp+8h] [rbp-20h] BYREF

if ( pipe(pipedes) < 0 )
{
v4 = _errno_location();
log_message(131075LL, "Xapimon: cannot create pipe. (%d)\n", (unsigned int)*v4);
result = 2002LL;
}
else
{
v2 = fork();
*a1 = v2;
if ( !v2 )
{
dup2(pipedes[1], 1);
close(pipedes[0]);
close(pipedes[1]);
xm_close_descriptors();
main_reset_scheduler();
execl("/opt/xensource/libexec/xapi-health-check", "xapi-health-check", 0LL);
exit(-1);
}
if ( v2 < 0 )
{
v5 = _errno_location();
log_message(131075LL, "Xapimon: cannot start xapi healthchecker. (%d)\n", (unsigned int)*v5);
close(pipedes[0]);
close(pipedes[1]);
result = 2003LL;
}
else
{
close(pipedes[1]);
*a2 = pipedes[0];
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__pid_t *a1, _DWORD *a2)
{
__pid_t v2; // eax
__int64 result; // rax
int *v4; // rax
int *v5; // rax
int pipedes[2]; // [rsp+8h] [rbp-20h] BYREF

if ( pipe(pipedes) < 0 )
{
v4 = _errno_location();
log_message(131075LL, "Xapimon: cannot create pipe. (%d)\n", (unsigned int)*v4);
result = 2002LL;
}
else
{
v2 = fork();
*a1 = v2;
if ( !v2 )
{
dup2(pipedes[1], 1);
close(pipedes[0]);
close(pipedes[1]);
func5();
main_reset_scheduler();
execl("/opt/xensource/libexec/xapi-health-check", "xapi-health-check", 0LL);
exit(-1);
}
if ( v2 < 0 )
{
v5 = _errno_location();
log_message(131075LL, "Xapimon: cannot start xapi healthchecker. (%d)\n", (unsigned int)*v5);
close(pipedes[0]);
close(pipedes[1]);
result = 2003LL;
}
else
{
close(pipedes[1]);
*a2 = pipedes[0];
result = 0LL;
}
}
return result;
}

original_code:
MTC_STATUS
xapi_healthcheck(
    pid_t *ppid,
    PMTC_S32 ppip)
{
    MTC_S32 pip[2];
    if (pipe(pip) < 0)
    {
        log_message(((((3 | (1<<16) | (1<<17))) & ~(1<<16)) | (1<<17)), "Xapimon: cannot create pipe. (%d)\n", (*__errno_location ()));
        return (1000 + 1000 + 2);
    }
    if ((*ppid = fork()) == 0)
    {
        dup2(pip[1], 1);
        close(pip[0]);
        close(pip[1]);
        xm_close_descriptors();
        main_reset_scheduler();
        execl("/opt/xensource/libexec/" "xapi-health-check",
              "xapi-health-check", (char *) ((void *)0));
        _exit(-1);
    }
    if (*ppid < 0)
    {
        log_message(((((3 | (1<<16) | (1<<17))) & ~(1<<16)) | (1<<17)), "Xapimon: cannot start xapi healthchecker. (%d)\n", (*__errno_location ()));
        close(pip[0]);
        close(pip[1]);
        return (1000 + 1000 + 3);
    }
    else
    {
        close(pip[1]);
        *ppip = pip[0];
        return 0;
    }
}

canonical_original_code:
int xapi_healthcheck(int *ppid, int *ppip)
{
    int pip[2];
    if (pipe(pip) < 0)
    {
        log_message(((((3 | (1<<16) | (1<<17))) & ~(1<<16)) | (1<<17)), "Xapimon: cannot create pipe. (%d)\n", (*__errno_location ()));
        return (1000 + 1000 + 2);
    }
    if ((*ppid = fork()) == 0)
    {
        dup2(pip[1], 1);
        close(pip[0]);
        close(pip[1]);
        xm_close_descriptors();
        main_reset_scheduler();
        execl("/opt/xensource/libexec/" "xapi-health-check",
              "xapi-health-check", (char *) ((void *)0));
        _exit(-1);
    }
    if (*ppid < 0)
    {
        log_message(((((3 | (1<<16) | (1<<17))) & ~(1<<16)) | (1<<17)), "Xapimon: cannot start xapi healthchecker. (%d)\n", (*__errno_location ()));
        close(pip[0]);
        close(pip[1]);
        return (1000 + 1000 + 3);
    }
    else
    {
        close(pip[1]);
        *ppip = pip[0];
        return 0;
    }
}

variable_types:
ppid
int *

variable_types:
ppip
int *

variable_types:
pip
int [2]


decompiled_code:
__int64 restart_xapi()
{
__pid_t v0; // eax
unsigned int v1; // ebx
int *v3; // rax

v0 = fork();
if ( !v0 )
{
xm_close_descriptors();
main_reset_scheduler();
if ( execlp("service", "service", "xapi", "restart", 0LL) < 0 && *_errno_location() == 2 )
execl("/sbin/service", "service", "xapi", "restart", 0LL);
exit(-1);
}
v1 = v0;
if ( v0 < 0 )
{
v3 = _errno_location();
log_message(131076LL, "Xapimon: cannot fork xapi restart process. (%d)\n", (unsigned int)*v3);
}
return v1;
}

canonical_decompiled_code:
__int64 func7()
{
__pid_t v0; // eax
unsigned int v1; // ebx
int *v3; // rax

v0 = fork();
if ( !v0 )
{
func5();
main_reset_scheduler();
if ( execlp("service", "service", "xapi", "restart", 0LL) < 0 && *_errno_location() == 2 )
execl("/sbin/service", "service", "xapi", "restart", 0LL);
exit(-1);
}
v1 = v0;
if ( v0 < 0 )
{
v3 = _errno_location();
log_message(131076LL, "Xapimon: cannot fork xapi restart process. (%d)\n", (unsigned int)*v3);
}
return v1;
}

original_code:
pid_t
restart_xapi()
{
    pid_t pid;
    if ((pid = fork()) == 0)
    {
        xm_close_descriptors();
        main_reset_scheduler();
        if (execlp("service",
                   "service", "xapi", "restart",
                   (char *) ((void *)0)) < 0)
        {
            switch ((*__errno_location ()))
            {
            case 2:
                execl("/sbin/" "service",
                      "service", "xapi", "restart",
                      (char *) ((void *)0));
                break;
            default:
                break;
            }
        }
        _exit(-1);
    }
    if (pid < 0)
    {
        log_message((4 | (1<<17)),
            "Xapimon: cannot fork xapi restart process. (%d)\n", (*__errno_location ()));
    }
    return pid;
}

canonical_original_code:
int restart_xapi()
{
    int pid;
    if ((pid = fork()) == 0)
    {
        xm_close_descriptors();
        main_reset_scheduler();
        if (execlp("service",
                   "service", "xapi", "restart",
                   (char *) ((void *)0)) < 0)
        {
            switch ((*__errno_location ()))
            {
            case 2:
                execl("/sbin/" "service",
                      "service", "xapi", "restart",
                      (char *) ((void *)0));
                break;
            default:
                break;
            }
        }
        _exit(-1);
    }
    if (pid < 0)
    {
        log_message((4 | (1<<17)),
            "Xapimon: cannot fork xapi restart process. (%d)\n", (*__errno_location ()));
    }
    return pid;
}

variable_types: pid int


decompiled_code:
__int64 Xapi_license_check()
{
__pid_t v0; // eax
unsigned int v1; // ebx
__int64 result; // rax
int *v3; // rax
struct timespec v4; // [rsp+0h] [rbp-28h] BYREF
int stat_loc[3]; // [rsp+1Ch] [rbp-Ch] BYREF

v0 = fork();
if ( !v0 )
{
xm_close_descriptors();
main_reset_scheduler();
execl("/opt/xensource/libexec/xha-lc", "xha-lc", 0LL);
exit(-1);
}
v1 = v0;
if ( v0 < 0 )
{
v3 = _errno_location();
log_message(131076LL, "Xapimon: cannot fork xapi license checker. (%d)\n", (unsigned int)*v3);
result = 0xFFFFFFFFLL;
}
else
{
clock_gettime(1, &v4);
if ( v1 == wait_pid_timeout(
v1,
stat_loc,
1000 * v4.tv_sec + v4.tv_nsec / 1000000,
(unsigned int)(1000 * ha_config[984])) )
{
result = (unsigned int)stat_loc[0];
if ( stat_loc[0] )
{
log_message(131076LL, "Xapimon: Xapi license checker failed. (%d)\n", (unsigned int)stat_loc[0]);
result = 0xFFFFFFFFLL;
}
}
else
{
log_message(131076LL, "Xapimon: Xapi license checker (pid=%d) is fung.\n", v1);
kill(v1, 9);
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 func10()
{
__pid_t v0; // eax
unsigned int v1; // ebx
__int64 result; // rax
int *v3; // rax
struct timespec v4; // [rsp+0h] [rbp-28h] BYREF
int stat_loc[3]; // [rsp+1Ch] [rbp-Ch] BYREF

v0 = fork();
if ( !v0 )
{
func5();
main_reset_scheduler();
execl("/opt/xensource/libexec/xha-lc", "xha-lc", 0LL);
exit(-1);
}
v1 = v0;
if ( v0 < 0 )
{
v3 = _errno_location();
log_message(131076LL, "Xapimon: cannot fork xapi license checker. (%d)\n", (unsigned int)*v3);
result = 0xFFFFFFFFLL;
}
else
{
clock_gettime(1, &v4);
if ( v1 == func3(
v1,
stat_loc,
1000 * v4.tv_sec + v4.tv_nsec / 1000000,
(unsigned int)(1000 * ha_config[984])) )
{
result = (unsigned int)stat_loc[0];
if ( stat_loc[0] )
{
log_message(131076LL, "Xapimon: Xapi license checker failed. (%d)\n", (unsigned int)stat_loc[0]);
result = 0xFFFFFFFFLL;
}
}
else
{
log_message(131076LL, "Xapimon: Xapi license checker (pid=%d) is fung.\n", v1);
kill(v1, 9);
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
MTC_S32
Xapi_license_check()
{
    pid_t pid, ret_pid;
    MTC_CLOCK time_start_license_check;
    MTC_S32 status, ret;
    if ((pid = fork()) == 0)
    {
        xm_close_descriptors();
        main_reset_scheduler();
        execl("/opt/xensource/libexec/" "xha-lc",
              "xha-lc", (char *) ((void *)0));
        _exit(-1);
    }
    if (pid < 0)
    {
        log_message((4 | (1<<17)),
            "Xapimon: cannot fork xapi license checker. (%d)\n", (*__errno_location ()));
        ret = -1;
    }
    else
    {
        time_start_license_check = ({ struct timespec ts; clock_gettime(1, &ts); ((MTC_CLOCK) ((ts).tv_sec) * 1000 + (ts).tv_nsec / 1000 / 1000); });
        ret_pid = wait_pid_timeout(pid, &status,
                                   time_start_license_check, (ha_config.common.xapi_licensecheck_timeout) * (1000));
        if (ret_pid == pid)
        {
            switch (status)
            {
            case 0:
                ret = 0;
                break;
            default:
                log_message((4 | (1<<17)),
                            "Xapimon: Xapi license checker failed. (%d)\n", status);
                ret = -1;
                break;
            }
        }
        else
        {
            log_message((4 | (1<<17)),
                        "Xapimon: Xapi license checker (pid=%d) is fung.\n", pid);
            kill(pid, 9);
            ret = -1;
        }
    }
    return ret;
}

canonical_original_code:
int Xapi_license_check()
{
    int pid; int ret_pid;
    long long time_start_license_check;
    int status; int ret;
    if ((pid = fork()) == 0)
    {
        xm_close_descriptors();
        main_reset_scheduler();
        execl("/opt/xensource/libexec/" "xha-lc",
              "xha-lc", (char *) ((void *)0));
        _exit(-1);
    }
    if (pid < 0)
    {
        log_message((4 | (1<<17)),
            "Xapimon: cannot fork xapi license checker. (%d)\n", (*__errno_location ()));
        ret = -1;
    }
    else
    {
        time_start_license_check = ({ struct timespec ts; clock_gettime(1, &ts); ((MTC_CLOCK) ((ts).tv_sec) * 1000 + (ts).tv_nsec / 1000 / 1000); });
        ret_pid = wait_pid_timeout(pid, &status,
                                   time_start_license_check, (ha_config.common.xapi_licensecheck_timeout) * (1000));
        if (ret_pid == pid)
        {
            switch (status)
            {
            case 0:
                ret = 0;
                break;
            default:
                log_message((4 | (1<<17)),
                            "Xapimon: Xapi license checker failed. (%d)\n", status);
                ret = -1;
                break;
            }
        }
        else
        {
            log_message((4 | (1<<17)),
                        "Xapimon: Xapi license checker (pid=%d) is fung.\n", pid);
            kill(pid, 9);
            ret = -1;
        }
    }
    return ret;
}

variable_types: status int

variable_types: ret int


mstots

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


sigcatch

decompiled_code:
void __fastcall sigcatch(int a1)
{
sigset(a1, sigcatch);
if ( a1 == 15 )
{
dword_28B8 = 1;
}
else if ( a1 != 17 )
{
if ( a1 == 1 )
dword_28BC = 1;
else
dword_28C0 = a1;
}
}

canonical_decompiled_code:
void __fastcall func1(int a1)
{
sigset(a1, sigcatch);
if ( a1 == 15 )
{
dword_28B8 = 1;
}
else if ( a1 != 17 )
{
if ( a1 == 1 )
dword_28BC = 1;
else
dword_28C0 = a1;
}
}

original_code:
void
sigcatch(
    int signo)
{
    sigset(signo, sigcatch);
    switch (signo)
    {
    case 15:
        daemon_vars.terminate_requested = 1;
        break;
    case 17:
        break;
    case 1:
        daemon_vars.catch_SIGHUP = 1;
        break;
    default:
        daemon_vars.catch_unexpected_signo = signo;
        break;
    }
}

canonical_original_code:
void sigcatch(int signo)
{
    sigset(signo, sigcatch);
    switch (signo)
    {
    case 15:
        daemon_vars.terminate_requested = 1;
        break;
    case 17:
        break;
    case 1:
        daemon_vars.catch_SIGHUP = 1;
        break;
    default:
        daemon_vars.catch_unexpected_signo = signo;
        break;
    }
}

variable_types: signo int


decompiled_code:
void __fastcall post_phase_init(int a1)
{
unsigned int v1; // eax

if ( a1 == 1 )
{
v1 = pthread_create(&newthread, xhad_pthread_attr, main_sighandler, 0LL);
if ( v1 )
{
log_message(131076LL, "HA daemon cannot create signal handler thread (sys %d)\n", v1);
newthread = 0LL;
exit_status = 1100;
dword_28B8 = 1;
}
else
{
sigset(15, sigcatch);
sigset(17, sigcatch);
sigset(1, sigcatch);
}
}
}

canonical_decompiled_code:
void __fastcall func3(int a1)
{
unsigned int v1; // eax

if ( a1 == 1 )
{
v1 = pthread_create(&newthread, xhad_pthread_attr, main_sighandler, 0LL);
if ( v1 )
{
log_message(131076LL, "HA daemon cannot create signal handler thread (sys %d)\n", v1);
newthread = 0LL;
exit_status = 1100;
dword_28B8 = 1;
}
else
{
sigset(15, sigcatch);
sigset(17, sigcatch);
sigset(1, sigcatch);
}
}
}

original_code:
void
post_phase_init(
    int phase)
{
    MTC_S32 ret;
    if (phase == 1)
    {
        ret = pthread_create(&daemon_vars.sighandler_thread, xhad_pthread_attr, main_sighandler, ((void *)0));
        if (ret)
        {
            log_message((4 | (1<<17)), "HA daemon cannot create signal handler thread (sys %d)\n",
                        ret);
            daemon_vars.sighandler_thread = 0;
            exit_status = (1000 + 100 + 0);
            daemon_vars.terminate_requested = 1;
            return;
        }
        sigset(15, sigcatch);
        sigset(17, sigcatch);
        sigset(1, sigcatch);
    }
}

canonical_original_code:
void post_phase_init(int phase)
{
    int ret;
    if (phase == 1)
    {
        ret = pthread_create(&daemon_vars.sighandler_thread, xhad_pthread_attr, main_sighandler, ((void *)0));
        if (ret)
        {
            log_message((4 | (1<<17)), "HA daemon cannot create signal handler thread (sys %d)\n",
                        ret);
            daemon_vars.sighandler_thread = 0;
            exit_status = (1000 + 100 + 0);
            daemon_vars.terminate_requested = 1;
            return;
        }
        sigset(15, sigcatch);
        sigset(17, sigcatch);
        sigset(1, sigcatch);
    }
}

variable_types: phase int