decompiled_code:
void *__fastcall tam_reader_thread(void *a1)
{
__int64 v1; // rbp
int v2; // er12
int v3; // eax
_DWORD v5[41]; // [rsp+0h] [rbp-138h] BYREF
char src[116]; // [rsp+A4h] [rbp-94h] BYREF
void *ptr; // [rsp+118h] [rbp-20h] BYREF

v1 = *((_QWORD *)a1 + 151);
while ( !*(_DWORD *)(v1 + 168) )
{
v2 = recv_message(*((unsigned int *)a1 + 300), &ptr);
fflush(stdout);
if ( v2 )
{
*((_DWORD *)a1 + 304) = 1;
break;
}
xml_to_message(ptr, v5);
free(ptr);
pthread_mutex_lock((pthread_mutex_t *)((char *)a1 + 1096));
fflush(stdout);
v3 = *((_DWORD *)a1 + 272);
*((_DWORD *)a1 + 272) = v3 + 1;
*((_DWORD *)a1 + v3 + 292) = v5[36];
pthread_mutex_unlock((pthread_mutex_t *)((char *)a1 + 1096));
sem_post((sem_t *)((char *)a1 + 1136));
dec_sem(v1 + 1440, v1 + 1488, v1 + 1448);
if ( v5[40] )
{
*(_DWORD *)(v1 + 168) = 1;
strcpy((char *)(v1 + 64), src);
*(_DWORD *)(v1 + 1632) = 0;
}
}
pthread_cond_broadcast((pthread_cond_t *)(v1 + 1680));
printf("(%d) reader ended\n", *((unsigned int *)a1 + 300));
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func0(void *a1)
{
__int64 v1; // rbp
int v2; // er12
int v3; // eax
_DWORD v5[41]; // [rsp+0h] [rbp-138h] BYREF
char src[116]; // [rsp+A4h] [rbp-94h] BYREF
void *ptr; // [rsp+118h] [rbp-20h] BYREF

v1 = *((_QWORD *)a1 + 151);
while ( !*(_DWORD *)(v1 + 168) )
{
v2 = recv_message(*((unsigned int *)a1 + 300), &ptr);
fflush(stdout);
if ( v2 )
{
*((_DWORD *)a1 + 304) = 1;
break;
}
xml_to_message(ptr, v5);
free(ptr);
pthread_mutex_lock((pthread_mutex_t *)((char *)a1 + 1096));
fflush(stdout);
v3 = *((_DWORD *)a1 + 272);
*((_DWORD *)a1 + 272) = v3 + 1;
*((_DWORD *)a1 + v3 + 292) = v5[36];
pthread_mutex_unlock((pthread_mutex_t *)((char *)a1 + 1096));
sem_post((sem_t *)((char *)a1 + 1136));
dec_sem(v1 + 1440, v1 + 1488, v1 + 1448);
if ( v5[40] )
{
*(_DWORD *)(v1 + 168) = 1;
strcpy((char *)(v1 + 64), src);
*(_DWORD *)(v1 + 1632) = 0;
}
}
pthread_cond_broadcast((pthread_cond_t *)(v1 + 1680));
printf("(%d) reader ended\n", *((unsigned int *)a1 + 300));
return 0LL;
}

original_code:
void * tam_reader_thread (void * args)
{
  client_t * client = args;
  context_t * context = client->context;
  cs_status_t recv_status;
  char * buffer;
  cs_message_t message;
  for (; !context->result.found;)
    {
      recv_status = recv_message (client->fd, &buffer);
      fflush (stdout);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   free (buffer);
   pthread_mutex_lock (&client->tasks_register.free_mutex);
   fflush (stdout);
   client->tasks_register.free_idx[client->tasks_register.free++] = message.task.idx;
   pthread_mutex_unlock (&client->tasks_register.free_mutex);
   sem_post (&client->tasks_register.empty);
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
   if (message.result)
     {
       context->result.found = !0;
       strcpy (context->result.password, message.password);
       context->continue_execute = 0;
     }
 }
      else
 {
   client->close = !0;
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("(%d) reader ended\n", client->fd);
  return ((void *)0);
}

canonical_original_code:
void *tam_reader_thread(void *args)
{
  struct client_s *client = args;
  struct context_s *context = client->context;
  enum cs_status_t recv_status;
  char *buffer;
  struct cs_message_t message;
  for (; !context->result.found;)
    {
      recv_status = recv_message (client->fd, &buffer);
      fflush (stdout);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   free (buffer);
   pthread_mutex_lock (&client->tasks_register.free_mutex);
   fflush (stdout);
   client->tasks_register.free_idx[client->tasks_register.free++] = message.task.idx;
   pthread_mutex_unlock (&client->tasks_register.free_mutex);
   sem_post (&client->tasks_register.empty);
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
   if (message.result)
     {
       context->result.found = !0;
       strcpy (context->result.password, message.password);
       context->continue_execute = 0;
     }
 }
      else
 {
   client->close = !0;
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("(%d) reader ended\n", client->fd);
  return ((void *)0);
}

variable_types:
args
void *

variable_types: struct client_s { struct tasks_register_s { struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; } tasks[-1]; int free; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } free_mutex; union sem_t { char __size[32]; long __align; } empty; int free_idx[-1]; } tasks_register; int fd; struct context_s { char *alph; int max_length; char *hash; struct brute_result_s { union pthread_mutex_t found_mutex; char password[-1]; int found; } result; int block_size; enum run_mode_t { RM_SINGLE=0, RM_MULTI=1, RM_CLIENT=2, RM_SERVER=3, RM_CLIENT_ASYNC=4, RM_SERVER_ASYNC=5, RM_SERVER_EPOLL=6 } run_mode; short port; struct in_addr { unsigned int s_addr; } addr; int n_cpus; int listener_socket; struct queue_s { struct task_s queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } queue; int tasks_in_process; union pthread_mutex_t tasks_in_process_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } tasks_in_process_sem; int threads; union pthread_mutex_t threads_mutex; union pthread_cond_t threads_sem; int continue_execute; union pthread_mutex_t continue_execute_mutex; union pthread_cond_t continue_execute_sem; int id; void *(*srv_client_thread)(struct context_s *, int); struct result_queue_s { struct result_s { struct brute_result_s result; int id; int idx; int final; } queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } result_queue; } *context; int close; int err; } *

variable_types: enum cs_status_t { S_SUCCESS=0, S_MEMORY_ERROR=1, S_RECV_ERROR=2, S_SEND_ERROR=3, S_CONNECTION_CLOSED=4 }

variable_types:
buffer
char *

variable_types: struct cs_message_t { enum cs_message_type_t { MT_SEND_JOB=0, MT_REPORT_RESULT=1 } type; char *alph; char *hash; struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; } task; int result; char password[-1]; }

return_type: void *

user_defined_types: struct cs_message_t { enum cs_message_type_t type; char *alph; char *hash; struct task_s task; int result; char password[-1]; }

user_defined_types: struct client_s { struct tasks_register_s tasks_register; int fd; struct context_s *context; int close; int err; }

user_defined_types: struct tasks_register_s { struct task_s tasks[-1]; int free; union pthread_mutex_t free_mutex; union sem_t empty; int free_idx[-1]; }


repo: FunkyCat/crypt-bruteforce

original_code:
void * tam_writer_thread (void * args)
{
  client_t * client = args;
  context_t * context = client->context;
  task_t task;
  cs_message_t message;
  int send_status;
  for (;;)
    {
      sem_wait (&client->tasks_register.empty);
      queue_pop (&context->queue, &task);
      if (task.final)
 {
   sem_post (&client->tasks_register.empty);
   queue_push (&context->queue, &task);
   break;
 }
      if (context->result.found)
 {
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
   sem_post (&client->tasks_register.empty);
   continue;
 }
      pthread_mutex_lock (&client->tasks_register.free_mutex);
      task.idx = client->tasks_register.free_idx[--client->tasks_register.free];
      pthread_mutex_unlock (&client->tasks_register.free_mutex);
      client->tasks_register.tasks[task.idx] = task;
      message.type = MT_SEND_JOB;
      message.alph = context->alph;
      message.hash = context->hash;
      message.task = task;
      printf ("(%d) task: [%d.%d] %s\n", client->fd, task.id, task.idx, task.password);
      fflush (stdout);
      send_status = send_message (client->fd, &message);
      if (send_status == -1)
 {
   fprintf (stderr, "error: send_message()\n");
   client->close = !0;
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("(%d) writer ended\n", client->fd);
  return ((void *)0);
}

canonical_original_code:
void *tam_writer_thread(void *args)
{
  struct client_s *client = args;
  struct context_s *context = client->context;
  struct task_s task;
  struct cs_message_t message;
  int send_status;
  for (;;)
    {
      sem_wait (&client->tasks_register.empty);
      queue_pop (&context->queue, &task);
      if (task.final)
 {
   sem_post (&client->tasks_register.empty);
   queue_push (&context->queue, &task);
   break;
 }
      if (context->result.found)
 {
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
   sem_post (&client->tasks_register.empty);
   continue;
 }
      pthread_mutex_lock (&client->tasks_register.free_mutex);
      task.idx = client->tasks_register.free_idx[--client->tasks_register.free];
      pthread_mutex_unlock (&client->tasks_register.free_mutex);
      client->tasks_register.tasks[task.idx] = task;
      message.type = MT_SEND_JOB;
      message.alph = context->alph;
      message.hash = context->hash;
      message.task = task;
      printf ("(%d) task: [%d.%d] %s\n", client->fd, task.id, task.idx, task.password);
      fflush (stdout);
      send_status = send_message (client->fd, &message);
      if (send_status == -1)
 {
   fprintf (stderr, "error: send_message()\n");
   client->close = !0;
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("(%d) writer ended\n", client->fd);
  return ((void *)0);
}

variable_types: struct context_s { char *alph; int max_length; char *hash; struct brute_result_s { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } found_mutex; char password[-1]; int found; } result; int block_size; enum run_mode_t { RM_SINGLE=0, RM_MULTI=1, RM_CLIENT=2, RM_SERVER=3, RM_CLIENT_ASYNC=4, RM_SERVER_ASYNC=5, RM_SERVER_EPOLL=6 } run_mode; short port; struct in_addr { unsigned int s_addr; } addr; int n_cpus; int listener_socket; struct queue_s { struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; } queue[-1]; union sem_t { char __size[32]; long __align; } full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } queue; int tasks_in_process; union pthread_mutex_t tasks_in_process_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } tasks_in_process_sem; int threads; union pthread_mutex_t threads_mutex; union pthread_cond_t threads_sem; int continue_execute; union pthread_mutex_t continue_execute_mutex; union pthread_cond_t continue_execute_sem; int id; void *(*srv_client_thread)(struct context_s *, int); struct result_queue_s { struct result_s { struct brute_result_s result; int id; int idx; int final; } queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } result_queue; } *

user_defined_types: struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data *cd; }

user_defined_types: struct context_s { char *alph; int max_length; char *hash; struct brute_result_s result; int block_size; enum run_mode_t run_mode; short port; struct in_addr addr; int n_cpus; int listener_socket; struct queue_s queue; int tasks_in_process; union pthread_mutex_t tasks_in_process_mutex; union pthread_cond_t tasks_in_process_sem; int threads; union pthread_mutex_t threads_mutex; union pthread_cond_t threads_sem; int continue_execute; union pthread_mutex_t continue_execute_mutex; union pthread_cond_t continue_execute_sem; int id; void *(*srv_client_thread)(struct context_s *, int); struct result_queue_s result_queue; }

user_defined_types: enum cs_message_type_t { MT_SEND_JOB=0, MT_REPORT_RESULT=1 }

user_defined_types: struct brute_result_s { union pthread_mutex_t found_mutex; char password[-1]; int found; }

user_defined_types: struct queue_s { struct task_s queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; }

user_defined_types: union pthread_cond_t { struct __pthread_cond_s __data; char __size[48]; long long __align; }

user_defined_types: struct result_queue_s { struct result_s queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


original_code:
void tasks_register_init (tasks_register_t * tasks_register)
{
  pthread_mutex_init (&tasks_register->free_mutex, ((void *)0));
  sem_init (&tasks_register->empty, 0, (8));
  tasks_register->free = (8);
  int i;
  for (i = 0; i < (8); i++)
    tasks_register->free_idx[i] = i;
}

canonical_original_code:
void tasks_register_init(struct tasks_register_s *tasks_register)
{
  pthread_mutex_init (&tasks_register->free_mutex, ((void *)0));
  sem_init (&tasks_register->empty, 0, (8));
  tasks_register->free = (8);
  int i;
  for (i = 0; i < (8); i++)
    tasks_register->free_idx[i] = i;
}

variable_types: struct tasks_register_s { struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; } tasks[-1]; int free; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } free_mutex; union sem_t { char __size[32]; long __align; } empty; int free_idx[-1]; } *

variable_types: i int

return_type: void


decompiled_code:
__int64 __fastcall tam_client_thread(__int64 a1, __int64 a2)
{
int v3; // edx
char *v4; // rax
__int64 *v5; // r13
char *v6; // rbp
__int64 v7[4]; // [rsp+10h] [rbp-538h] BYREF
pthread_t th; // [rsp+30h] [rbp-518h] BYREF
pthread_t newthread; // [rsp+38h] [rbp-510h] BYREF
char arg[1088]; // [rsp+40h] [rbp-508h] BYREF
int v11; // [rsp+480h] [rbp-C8h] BYREF
sem_t sem; // [rsp+4B0h] [rbp-98h] BYREF
char v13[32]; // [rsp+4D0h] [rbp-78h] BYREF
unsigned int v14; // [rsp+4F0h] [rbp-58h]
__int64 v15; // [rsp+4F8h] [rbp-50h]
int v16; // [rsp+500h] [rbp-48h]

printf("(%d) connected\n", a2);
fflush(stdout);
inc_sem(a1 + 1536, a1 + 1584, a1 + 1544);
memset(arg, 0, 0x4C8uLL);
v14 = a2;
v15 = a1;
tasks_register_init((__int64)arg);
pthread_create(&newthread, 0LL, tam_reader_thread, arg);
pthread_create(&th, 0LL, tam_writer_thread, arg);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 1640));
while ( *(_DWORD *)(a1 + 1632) )
{
if ( v16 )
break;
pthread_cond_wait((pthread_cond_t *)(a1 + 1680), (pthread_mutex_t *)(a1 + 1640));
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 1640));
shutdown(a2, 2);
close(a2);
sem_post(&sem);
printf("(%d) disconnected\n", (unsigned int)a2);
printf("(%d) wait for threads\n", (unsigned int)a2);
pthread_join(th, 0LL);
pthread_join(newthread, 0LL);
printf("(%d) pushing back\n", (unsigned int)a2);
if ( !*(_DWORD *)(a1 + 168) )
{
v7[0] = 0x101010101010101LL;
v7[1] = 0x101010101010101LL;
v7[2] = 0x101010101010101LL;
v7[3] = 0x101010101010101LL;
v3 = v11;
if ( v11 > 0 )
{
v4 = v13;
do
{
*((_DWORD *)v7 + *(int *)v4) = 0;
v4 += 4;
}
while ( v4 != &v13[4 * (v3 - 1) + 4] );
}
v5 = v7;
v6 = arg;
do
{
if ( *(_DWORD *)v5 )
{
printf("(%d) pushed back: [%d.%d] %s\n", v14, *((unsigned int *)v6 + 29), *((unsigned int *)v6 + 30), v6);
queue_push(a1 + 200, v6);
}
v5 = (__int64 *)((char *)v5 + 4);
v6 += 136;
}
while ( v6 != (char *)&v11 );
}
printf("(%d) ended\n", (unsigned int)a2);
dec_sem(a1 + 1536, a1 + 1584, a1 + 1544);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
int v3; // edx
char *v4; // rax
__int64 *v5; // r13
char *v6; // rbp
__int64 v7[4]; // [rsp+10h] [rbp-538h] BYREF
pthread_t th; // [rsp+30h] [rbp-518h] BYREF
pthread_t newthread; // [rsp+38h] [rbp-510h] BYREF
char arg[1088]; // [rsp+40h] [rbp-508h] BYREF
int v11; // [rsp+480h] [rbp-C8h] BYREF
sem_t sem; // [rsp+4B0h] [rbp-98h] BYREF
char v13[32]; // [rsp+4D0h] [rbp-78h] BYREF
unsigned int v14; // [rsp+4F0h] [rbp-58h]
__int64 v15; // [rsp+4F8h] [rbp-50h]
int v16; // [rsp+500h] [rbp-48h]

printf("(%d) connected\n", a2);
fflush(stdout);
inc_sem(a1 + 1536, a1 + 1584, a1 + 1544);
memset(arg, 0, 0x4C8uLL);
v14 = a2;
v15 = a1;
func2((__int64)arg);
pthread_create(&newthread, 0LL, tam_reader_thread, arg);
pthread_create(&th, 0LL, tam_writer_thread, arg);
pthread_mutex_lock((pthread_mutex_t *)(a1 + 1640));
while ( *(_DWORD *)(a1 + 1632) )
{
if ( v16 )
break;
pthread_cond_wait((pthread_cond_t *)(a1 + 1680), (pthread_mutex_t *)(a1 + 1640));
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 1640));
shutdown(a2, 2);
close(a2);
sem_post(&sem);
printf("(%d) disconnected\n", (unsigned int)a2);
printf("(%d) wait for threads\n", (unsigned int)a2);
pthread_join(th, 0LL);
pthread_join(newthread, 0LL);
printf("(%d) pushing back\n", (unsigned int)a2);
if ( !*(_DWORD *)(a1 + 168) )
{
v7[0] = 0x101010101010101LL;
v7[1] = 0x101010101010101LL;
v7[2] = 0x101010101010101LL;
v7[3] = 0x101010101010101LL;
v3 = v11;
if ( v11 > 0 )
{
v4 = v13;
do
{
*((_DWORD *)v7 + *(int *)v4) = 0;
v4 += 4;
}
while ( v4 != &v13[4 * (v3 - 1) + 4] );
}
v5 = v7;
v6 = arg;
do
{
if ( *(_DWORD *)v5 )
{
printf("(%d) pushed back: [%d.%d] %s\n", v14, *((unsigned int *)v6 + 29), *((unsigned int *)v6 + 30), v6);
queue_push(a1 + 200, v6);
}
v5 = (__int64 *)((char *)v5 + 4);
v6 += 136;
}
while ( v6 != (char *)&v11 );
}
printf("(%d) ended\n", (unsigned int)a2);
dec_sem(a1 + 1536, a1 + 1584, a1 + 1544);
return 0LL;
}

original_code:
void * tam_client_thread (context_t * context, int client_socket)
{
 printf ("(%d) connected\n", client_socket);
 fflush (stdout);
 inc_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  client_t client =
    {
      .fd = client_socket,
      .context = context,
      .close = 0,
      .err = 0,
    };
  tasks_register_init (&client.tasks_register);
  pthread_t reader_thread;
  pthread_create (&reader_thread, ((void *)0), tam_reader_thread, &client);
  pthread_t writer_thread;
  pthread_create (&writer_thread, ((void *)0), tam_writer_thread, &client);
  pthread_mutex_lock (&context->continue_execute_mutex);
  while (context->continue_execute != 0 && client.close == 0)
    {
      pthread_cond_wait (&context->continue_execute_sem, &context->continue_execute_mutex);
    }
  pthread_mutex_unlock (&context->continue_execute_mutex);
  shutdown (client_socket, 2);
  close (client_socket);
  sem_post (&client.tasks_register.empty);
  printf ("(%d) disconnected\n", client_socket);
  printf ("(%d) wait for threads\n", client_socket);
  pthread_join (writer_thread, ((void *)0));
  pthread_join (reader_thread, ((void *)0));
  printf ("(%d) pushing back\n", client_socket);
  if (!context->result.found)
    {
      int in_use [(8)];
      memset (in_use, !0, sizeof (in_use));
      int i;
      for (i = 0; i < client.tasks_register.free; i++)
 {
   in_use[client.tasks_register.free_idx[i]] = 0;
 }
      for (i = 0; i < (8); i++)
 {
   if (in_use[i] != 0)
     {
       printf ("(%d) pushed back: [%d.%d] %s\n", client.fd, client.tasks_register.tasks[i].id, client.tasks_register.tasks[i].idx, client.tasks_register.tasks[i].password);
       queue_push (&context->queue, &client.tasks_register.tasks[i]);
     }
 }
    }
  printf ("(%d) ended\n", client_socket);
  dec_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  return ((void *)0);
}

canonical_original_code:
void *tam_client_thread(struct context_s *context, int client_socket)
{
 printf ("(%d) connected\n", client_socket);
 fflush (stdout);
 inc_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  struct client_s client = {
      .fd = client_socket,
      .context = context,
      .close = 0,
      .err = 0,
    };
  tasks_register_init (&client.tasks_register);
  unsigned long reader_thread;
  pthread_create (&reader_thread, ((void *)0), tam_reader_thread, &client);
  unsigned long writer_thread;
  pthread_create (&writer_thread, ((void *)0), tam_writer_thread, &client);
  pthread_mutex_lock (&context->continue_execute_mutex);
  while (context->continue_execute != 0 && client.close == 0)
    {
      pthread_cond_wait (&context->continue_execute_sem, &context->continue_execute_mutex);
    }
  pthread_mutex_unlock (&context->continue_execute_mutex);
  shutdown (client_socket, 2);
  close (client_socket);
  sem_post (&client.tasks_register.empty);
  printf ("(%d) disconnected\n", client_socket);
  printf ("(%d) wait for threads\n", client_socket);
  pthread_join (writer_thread, ((void *)0));
  pthread_join (reader_thread, ((void *)0));
  printf ("(%d) pushing back\n", client_socket);
  if (!context->result.found)
    {
      int in_use[-1];
      memset (in_use, !0, sizeof (in_use));
      int i;
      for (i = 0; i < client.tasks_register.free; i++)
 {
   in_use[client.tasks_register.free_idx[i]] = 0;
 }
      for (i = 0; i < (8); i++)
 {
   if (in_use[i] != 0)
     {
       printf ("(%d) pushed back: [%d.%d] %s\n", client.fd, client.tasks_register.tasks[i].id, client.tasks_register.tasks[i].idx, client.tasks_register.tasks[i].password);
       queue_push (&context->queue, &client.tasks_register.tasks[i]);
     }
 }
    }
  printf ("(%d) ended\n", client_socket);
  dec_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  return ((void *)0);
}

variable_types: struct client_s { struct tasks_register_s { struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; } tasks[-1]; int free; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } free_mutex; union sem_t { char __size[32]; long __align; } empty; int free_idx[-1]; } tasks_register; int fd; struct context_s { char *alph; int max_length; char *hash; struct brute_result_s { union pthread_mutex_t found_mutex; char password[-1]; int found; } result; int block_size; enum run_mode_t { RM_SINGLE=0, RM_MULTI=1, RM_CLIENT=2, RM_SERVER=3, RM_CLIENT_ASYNC=4, RM_SERVER_ASYNC=5, RM_SERVER_EPOLL=6 } run_mode; short port; struct in_addr { unsigned int s_addr; } addr; int n_cpus; int listener_socket; struct queue_s { struct task_s queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } queue; int tasks_in_process; union pthread_mutex_t tasks_in_process_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } tasks_in_process_sem; int threads; union pthread_mutex_t threads_mutex; union pthread_cond_t threads_sem; int continue_execute; union pthread_mutex_t continue_execute_mutex; union pthread_cond_t continue_execute_sem; int id; void *(*srv_client_thread)(struct context_s *, int); struct result_queue_s { struct result_s { struct brute_result_s result; int id; int idx; int final; } queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } result_queue; } *context; int close; int err; }


decompiled_code:
__int64 __fastcall server_async_mode(__int64 a1)
{
*(_QWORD *)(a1 + 1736) = tam_client_thread;
init_sem(a1 + 1632, 1LL, a1 + 1680, a1 + 1640);
return server(a1);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
*(_QWORD *)(a1 + 1736) = tam_client_thread;
init_sem(a1 + 1632, 1LL, a1 + 1680, a1 + 1640);
return server(a1);
}

original_code:
void server_async_mode (context_t * context)
{
  context->srv_client_thread = tam_client_thread;
  init_sem (&context->continue_execute, 1, &context->continue_execute_sem, &context->continue_execute_mutex);
  server (context);
}

canonical_original_code:
void server_async_mode(struct context_s *context)
{
  context->srv_client_thread = tam_client_thread;
  init_sem (&context->continue_execute, 1, &context->continue_execute_sem, &context->continue_execute_mutex);
  server (context);
}

user_defined_types: enum run_mode_t { RM_SINGLE=0, RM_MULTI=1, RM_CLIENT=2, RM_SERVER=3, RM_CLIENT_ASYNC=4, RM_SERVER_ASYNC=5, RM_SERVER_EPOLL=6 }

user_defined_types: union sem_t { char __size[32]; long __align; }

user_defined_types: struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; }

user_defined_types: struct result_s { struct brute_result_s result; int id; int idx; int final; }

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }

user_defined_types: struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; }


decompiled_code:
void *__fastcall cam_checker_thread(void *a1)
{
__int64 v2; // [rsp+0h] [rbp-20208h] BYREF
char dest[104]; // [rsp+28h] [rbp-201E0h] BYREF
int v4; // [rsp+90h] [rbp-20178h]
unsigned int v5; // [rsp+98h] [rbp-20170h]
unsigned int v6; // [rsp+9Ch] [rbp-2016Ch]
int v7; // [rsp+A0h] [rbp-20168h]
char v8[112]; // [rsp+B0h] [rbp-20158h] BYREF
int v9; // [rsp+120h] [rbp-200E8h]
unsigned int v10; // [rsp+124h] [rbp-200E4h]
unsigned int v11; // [rsp+128h] [rbp-200E0h]
char *v12; // [rsp+130h] [rbp-200D8h]
char s[131272]; // [rsp+140h] [rbp-200C8h] BYREF

memset(s, 0, 0x200A0uLL);
puts("checker");
inc_sem((char *)a1 + 1536, (char *)a1 + 1584, (char *)a1 + 1544);
while ( 1 )
{
queue_pop((char *)a1 + 200, v8);
if ( v9 )
break;
v12 = s;
v5 = v10;
v6 = v11;
v7 = 0;
printf("C. check task: [%d.%d] %s\n", v10, v11, v8);
*((_DWORD *)a1 + 42) = 0;
if ( (unsigned int)brute_block_iterative(v8, &check_password, a1) )
{
v4 = 1;
strcpy(dest, (const char *)a1 + 64);
}
else
{
v4 = 0;
}
result_queue_push((char *)a1 + 1744, &v2);
}
queue_push((char *)a1 + 200, v8);
dec_sem((char *)a1 + 1536, (char *)a1 + 1584, (char *)a1 + 1544);
puts("Checker ended.");
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func0(void *a1)
{
__int64 v2; // [rsp+0h] [rbp-20208h] BYREF
char dest[104]; // [rsp+28h] [rbp-201E0h] BYREF
int v4; // [rsp+90h] [rbp-20178h]
unsigned int v5; // [rsp+98h] [rbp-20170h]
unsigned int v6; // [rsp+9Ch] [rbp-2016Ch]
int v7; // [rsp+A0h] [rbp-20168h]
char v8[112]; // [rsp+B0h] [rbp-20158h] BYREF
int v9; // [rsp+120h] [rbp-200E8h]
unsigned int v10; // [rsp+124h] [rbp-200E4h]
unsigned int v11; // [rsp+128h] [rbp-200E0h]
char *v12; // [rsp+130h] [rbp-200D8h]
char s[131272]; // [rsp+140h] [rbp-200C8h] BYREF

memset(s, 0, 0x200A0uLL);
puts("checker");
inc_sem((char *)a1 + 1536, (char *)a1 + 1584, (char *)a1 + 1544);
while ( 1 )
{
queue_pop((char *)a1 + 200, v8);
if ( v9 )
break;
v12 = s;
v5 = v10;
v6 = v11;
v7 = 0;
printf("C. check task: [%d.%d] %s\n", v10, v11, v8);
*((_DWORD *)a1 + 42) = 0;
if ( (unsigned int)brute_block_iterative(v8, &check_password, a1) )
{
v4 = 1;
strcpy(dest, (const char *)a1 + 64);
}
else
{
v4 = 0;
}
result_queue_push((char *)a1 + 1744, &v2);
}
queue_push((char *)a1 + 200, v8);
dec_sem((char *)a1 + 1536, (char *)a1 + 1584, (char *)a1 + 1544);
puts("Checker ended.");
return 0LL;
}

original_code:
void * cam_checker_thread (void * args)
{
  context_t * context = args;
  struct crypt_data cd = { .initialized = 0 };
  task_t task;
  result_t result;
  printf ("checker\n");
  inc_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  for (;;)
    {
      queue_pop (&context->queue, &task);
      if (task.final)
 {
   queue_push (&context->queue, &task);
   break;
 }
      task.cd = &cd;
      result.id = task.id;
      result.idx = task.idx;
      result.final = 0;
      printf ("C. check task: [%d.%d] %s\n", task.id, task.idx, task.password);
      context->result.found = 0;
      if (brute_block_iterative (&task, check_password, context))
 {
   result.result.found = !0;
   strcpy (result.result.password, context->result.password);
 }
      else
 {
   result.result.found = 0;
 }
      result_queue_push (&context->result_queue, &result);
    }
  dec_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  printf ("Checker ended.\n");
  return ((void *)0);
}

canonical_original_code:
void *cam_checker_thread(void *args)
{
  struct context_s *context = args;
  struct crypt_data cd = { .initialized = 0 };
  struct task_s task;
  struct result_s result;
  printf ("checker\n");
  inc_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  for (;;)
    {
      queue_pop (&context->queue, &task);
      if (task.final)
 {
   queue_push (&context->queue, &task);
   break;
 }
      task.cd = &cd;
      result.id = task.id;
      result.idx = task.idx;
      result.final = 0;
      printf ("C. check task: [%d.%d] %s\n", task.id, task.idx, task.password);
      context->result.found = 0;
      if (brute_block_iterative (&task, check_password, context))
 {
   result.result.found = !0;
   strcpy (result.result.password, context->result.password);
 }
      else
 {
   result.result.found = 0;
 }
      result_queue_push (&context->result_queue, &result);
    }
  dec_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  printf ("Checker ended.\n");
  return ((void *)0);
}

variable_types: struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; }

variable_types: struct result_s { struct brute_result_s { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } found_mutex; char password[-1]; int found; } result; int id; int idx; int final; }


decompiled_code:
void *__fastcall cam_reader_thread(void *a1)
{
__int64 v1; // rbx
__int64 v3; // [rsp+0h] [rbp-138h] BYREF
void *v4; // [rsp+8h] [rbp-130h]
void *v5; // [rsp+10h] [rbp-128h]
char v6[116]; // [rsp+18h] [rbp-120h] BYREF
unsigned int v7; // [rsp+8Ch] [rbp-ACh]
unsigned int v8; // [rsp+90h] [rbp-A8h]
void *ptr; // [rsp+118h] [rbp-20h] BYREF

v1 = *((_QWORD *)a1 + 1);
puts("reader");
while ( !(unsigned int)recv_message(*(unsigned int *)a1, &ptr) )
{
xml_to_message(ptr, &v3);
printf("R. recv task: [%d.%d] %s\n", v7, v8, v6);
free(ptr);
if ( *(_QWORD *)(v1 + 16) )
free(v5);
else
*(_QWORD *)(v1 + 16) = v5;
if ( *(_QWORD *)v1 )
free(v4);
else
*(_QWORD *)v1 = v4;
queue_push(v1 + 200, v6);
}
pthread_mutex_lock((pthread_mutex_t *)(v1 + 1640));
*(_DWORD *)(v1 + 1632) = 0;
pthread_mutex_unlock((pthread_mutex_t *)(v1 + 1640));
pthread_cond_broadcast((pthread_cond_t *)(v1 + 1680));
puts("Reader ended.");
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func1(void *a1)
{
__int64 v1; // rbx
__int64 v3; // [rsp+0h] [rbp-138h] BYREF
void *v4; // [rsp+8h] [rbp-130h]
void *v5; // [rsp+10h] [rbp-128h]
char v6[116]; // [rsp+18h] [rbp-120h] BYREF
unsigned int v7; // [rsp+8Ch] [rbp-ACh]
unsigned int v8; // [rsp+90h] [rbp-A8h]
void *ptr; // [rsp+118h] [rbp-20h] BYREF

v1 = *((_QWORD *)a1 + 1);
puts("reader");
while ( !(unsigned int)recv_message(*(unsigned int *)a1, &ptr) )
{
xml_to_message(ptr, &v3);
printf("R. recv task: [%d.%d] %s\n", v7, v8, v6);
free(ptr);
if ( *(_QWORD *)(v1 + 16) )
free(v5);
else
*(_QWORD *)(v1 + 16) = v5;
if ( *(_QWORD *)v1 )
free(v4);
else
*(_QWORD *)v1 = v4;
queue_push(v1 + 200, v6);
}
pthread_mutex_lock((pthread_mutex_t *)(v1 + 1640));
*(_DWORD *)(v1 + 1632) = 0;
pthread_mutex_unlock((pthread_mutex_t *)(v1 + 1640));
pthread_cond_broadcast((pthread_cond_t *)(v1 + 1680));
puts("Reader ended.");
return 0LL;
}

original_code:
void * cam_reader_thread (void * args)
{
  char * buffer;
  cs_message_t message;
  cs_status_t recv_status;
  server_t * server = args;
  context_t * context = server->context;
  printf ("reader\n");
  for (;;)
    {
      recv_status = recv_message (server->fd, &buffer);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   printf ("R. recv task: [%d.%d] %s\n", message.task.id, message.task.idx, message.task.password);
   free (buffer);
   if (context->hash == ((void *)0))
     {
       context->hash = message.hash;
     }
   else
     {
       free (message.hash);
     }
   if (context->alph == ((void *)0))
     {
       context->alph = message.alph;
     }
   else
     {
       free (message.alph);
     }
   queue_push (&context->queue, &message.task);
 }
      else
 {
   pthread_mutex_lock (&context->continue_execute_mutex);
   context->continue_execute = 0;
   pthread_mutex_unlock (&context->continue_execute_mutex);
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("Reader ended.\n");
  return ((void *)0);
}

canonical_original_code:
void *cam_reader_thread(void *args)
{
  char *buffer;
  struct cs_message_t message;
  enum cs_status_t recv_status;
  struct server_s *server = args;
  struct context_s *context = server->context;
  printf ("reader\n");
  for (;;)
    {
      recv_status = recv_message (server->fd, &buffer);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   printf ("R. recv task: [%d.%d] %s\n", message.task.id, message.task.idx, message.task.password);
   free (buffer);
   if (context->hash == ((void *)0))
     {
       context->hash = message.hash;
     }
   else
     {
       free (message.hash);
     }
   if (context->alph == ((void *)0))
     {
       context->alph = message.alph;
     }
   else
     {
       free (message.alph);
     }
   queue_push (&context->queue, &message.task);
 }
      else
 {
   pthread_mutex_lock (&context->continue_execute_mutex);
   context->continue_execute = 0;
   pthread_mutex_unlock (&context->continue_execute_mutex);
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("Reader ended.\n");
  return ((void *)0);
}

variable_types: struct server_s { int fd; struct context_s { char *alph; int max_length; char *hash; struct brute_result_s { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } found_mutex; char password[-1]; int found; } result; int block_size; enum run_mode_t { RM_SINGLE=0, RM_MULTI=1, RM_CLIENT=2, RM_SERVER=3, RM_CLIENT_ASYNC=4, RM_SERVER_ASYNC=5, RM_SERVER_EPOLL=6 } run_mode; short port; struct in_addr { unsigned int s_addr; } addr; int n_cpus; int listener_socket; struct queue_s { struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; } queue[-1]; union sem_t { char __size[32]; long __align; } full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } queue; int tasks_in_process; union pthread_mutex_t tasks_in_process_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } tasks_in_process_sem; int threads; union pthread_mutex_t threads_mutex; union pthread_cond_t threads_sem; int continue_execute; union pthread_mutex_t continue_execute_mutex; union pthread_cond_t continue_execute_sem; int id; void *(*srv_client_thread)(struct context_s *, int); struct result_queue_s { struct result_s { struct brute_result_s result; int id; int idx; int final; } queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } result_queue; } *context; } *

user_defined_types: struct cs_message_t { enum cs_message_type_t type; char *alph; char *hash; struct task_s task; int result; char password[-1]; }

user_defined_types: enum cs_status_t { S_SUCCESS=0, S_MEMORY_ERROR=1, S_RECV_ERROR=2, S_SEND_ERROR=3, S_CONNECTION_CLOSED=4 }

user_defined_types: struct server_s { int fd; struct context_s *context; }


decompiled_code:
void *__fastcall cam_writer_thread(void *a1)
{
__int64 v1; // rbx
int v3[40]; // [rsp+0h] [rbp-1D8h] BYREF
int v4; // [rsp+A0h] [rbp-138h]
char dest[108]; // [rsp+A4h] [rbp-134h] BYREF
char v6[40]; // [rsp+110h] [rbp-C8h] BYREF
char src[104]; // [rsp+138h] [rbp-A0h] BYREF
int v8; // [rsp+1A0h] [rbp-38h]
int v9; // [rsp+1A8h] [rbp-30h]
int v10; // [rsp+1ACh] [rbp-2Ch]
int v11; // [rsp+1B0h] [rbp-28h]

v1 = *((_QWORD *)a1 + 1);
puts("writer");
while ( 1 )
{
result_queue_pop(v1 + 1744, v6);
if ( v11 )
break;
v3[0] = 1;
v3[35] = v9;
v3[36] = v10;
if ( v8 )
{
v4 = 1;
strcpy(dest, src);
}
else
{
v4 = 0;
}
if ( (int)send_message(*(unsigned int *)a1, v3) <= 0 )
{
pthread_mutex_lock((pthread_mutex_t *)(v1 + 1640));
*(_DWORD *)(v1 + 1632) = 0;
pthread_mutex_unlock((pthread_mutex_t *)(v1 + 1640));
break;
}
}
pthread_cond_broadcast((pthread_cond_t *)(v1 + 1680));
puts("Writer ended.");
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func2(void *a1)
{
__int64 v1; // rbx
int v3[40]; // [rsp+0h] [rbp-1D8h] BYREF
int v4; // [rsp+A0h] [rbp-138h]
char dest[108]; // [rsp+A4h] [rbp-134h] BYREF
char v6[40]; // [rsp+110h] [rbp-C8h] BYREF
char src[104]; // [rsp+138h] [rbp-A0h] BYREF
int v8; // [rsp+1A0h] [rbp-38h]
int v9; // [rsp+1A8h] [rbp-30h]
int v10; // [rsp+1ACh] [rbp-2Ch]
int v11; // [rsp+1B0h] [rbp-28h]

v1 = *((_QWORD *)a1 + 1);
puts("writer");
while ( 1 )
{
result_queue_pop(v1 + 1744, v6);
if ( v11 )
break;
v3[0] = 1;
v3[35] = v9;
v3[36] = v10;
if ( v8 )
{
v4 = 1;
strcpy(dest, src);
}
else
{
v4 = 0;
}
if ( (int)send_message(*(unsigned int *)a1, v3) <= 0 )
{
pthread_mutex_lock((pthread_mutex_t *)(v1 + 1640));
*(_DWORD *)(v1 + 1632) = 0;
pthread_mutex_unlock((pthread_mutex_t *)(v1 + 1640));
break;
}
}
pthread_cond_broadcast((pthread_cond_t *)(v1 + 1680));
puts("Writer ended.");
return 0LL;
}

original_code:
void * cam_writer_thread (void * args)
{
  result_t result;
  server_t * server = args;
  context_t * context = server->context;
  cs_message_t message;
  int send_status;
  printf ("writer\n");
  for (;;)
    {
      result_queue_pop (&context->result_queue, &result);
      if (result.final)
 {
   break;
 }
      message.type = MT_REPORT_RESULT;
      message.task.id = result.id;
      message.task.idx = result.idx;
      if (result.result.found)
 {
   message.result = !0;
   strcpy (message.password, result.result.password);
 }
      else
 {
   message.result = 0;
 }
      if ((send_status = send_message (server->fd, &message)) <= 0)
 {
   pthread_mutex_lock (&context->continue_execute_mutex);
   context->continue_execute = 0;
   pthread_mutex_unlock (&context->continue_execute_mutex);
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("Writer ended.\n");
  return ((void *)0);
}

canonical_original_code:
void *cam_writer_thread(void *args)
{
  struct result_s result;
  struct server_s *server = args;
  struct context_s *context = server->context;
  struct cs_message_t message;
  int send_status;
  printf ("writer\n");
  for (;;)
    {
      result_queue_pop (&context->result_queue, &result);
      if (result.final)
 {
   break;
 }
      message.type = MT_REPORT_RESULT;
      message.task.id = result.id;
      message.task.idx = result.idx;
      if (result.result.found)
 {
   message.result = !0;
   strcpy (message.password, result.result.password);
 }
      else
 {
   message.result = 0;
 }
      if ((send_status = send_message (server->fd, &message)) <= 0)
 {
   pthread_mutex_lock (&context->continue_execute_mutex);
   context->continue_execute = 0;
   pthread_mutex_unlock (&context->continue_execute_mutex);
   break;
 }
    }
  pthread_cond_broadcast (&context->continue_execute_sem);
  printf ("Writer ended.\n");
  return ((void *)0);
}

user_defined_types: struct context_s { char *alph; int max_length; char *hash; struct brute_result_s result; int block_size; enum run_mode_t run_mode; short port; struct in_addr addr; int n_cpus; int listener_socket; struct queue_s queue; int tasks_in_process; union pthread_mutex_t tasks_in_process_mutex; union pthread_cond_t tasks_in_process_sem; int threads; union pthread_mutex_t threads_mutex; union pthread_cond_t threads_sem; int continue_execute; union pthread_mutex_t continue_execute_mutex; union pthread_cond_t continue_execute_sem; int id; void *(*srv_client_thread)(struct context_s *, int); struct result_queue_s result_queue; }

user_defined_types: struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data *cd; }


decompiled_code:
int __fastcall client_async_mode(void *arg)
{
__int64 v2; // rax
int v3; // ebp
int fd; // [rsp+Ch] [rbp-1ACh]
int v6[44]; // [rsp+20h] [rbp-198h] BYREF
int v7[34]; // [rsp+D0h] [rbp-E8h] BYREF
pthread_t th; // [rsp+158h] [rbp-60h] BYREF
pthread_t v9; // [rsp+160h] [rbp-58h] BYREF
pthread_t newthread; // [rsp+168h] [rbp-50h] BYREF
int arga; // [rsp+170h] [rbp-48h] BYREF
void *v12; // [rsp+178h] [rbp-40h]

v2 = sysconf(84);
*((_DWORD *)arg + 48) = v2;
printf("n_cpus = %d\n", v2);
*(_QWORD *)arg = 0LL;
*((_QWORD *)arg + 2) = 0LL;
queue_init((char *)arg + 200);
result_queue_init((char *)arg + 1744);
init_sem((char *)arg + 1632, 1LL, (char *)arg + 1680, (char *)arg + 1640);
init_sem((char *)arg + 1536, 0LL, (char *)arg + 1584, (char *)arg + 1544);
fd = cli_create_socket((unsigned int)*((__int16 *)arg + 92), *((unsigned int *)arg + 47));
if ( fd < 0 )
return fwrite("error: cli_create_socket()\n", 1uLL, 0x1BuLL, stderr);
arga = fd;
v12 = arg;
pthread_create(&newthread, 0LL, cam_reader_thread, &arga);
pthread_create(&v9, 0LL, cam_writer_thread, &arga);
if ( *((int *)arg + 48) > 0 )
{
v3 = 0;
do
{
pthread_create(&th, 0LL, cam_checker_thread, arg);
pthread_detach(th);
++v3;
}
while ( *((_DWORD *)arg + 48) > v3 );
}
pthread_mutex_lock((pthread_mutex_t *)arg + 41);
while ( *((_DWORD *)arg + 408) )
pthread_cond_wait((pthread_cond_t *)arg + 35, (pthread_mutex_t *)arg + 41);
pthread_mutex_unlock((pthread_mutex_t *)arg + 41);
close(fd);
memset(v7, 0, sizeof(v7));
v7[28] = 1;
queue_push((char *)arg + 200, v7);
memset(v6, 0, 0xA8uLL);
v6[40] = 1;
result_queue_push((char *)arg + 1744, v6);
puts("Server closed connection");
puts("Waiting for reader thread");
pthread_join(newthread, 0LL);
puts("Waiting for writer thread");
pthread_join(v9, 0LL);
puts("Waiting for checker threads.");
pthread_mutex_lock((pthread_mutex_t *)((char *)arg + 1544));
while ( *((_DWORD *)arg + 384) )
pthread_cond_wait((pthread_cond_t *)arg + 33, (pthread_mutex_t *)((char *)arg + 1544));
pthread_mutex_unlock((pthread_mutex_t *)((char *)arg + 1544));
return puts("End.");
}

canonical_decompiled_code:
int __fastcall func3(void *arg)
{
__int64 v2; // rax
int v3; // ebp
int fd; // [rsp+Ch] [rbp-1ACh]
int v6[44]; // [rsp+20h] [rbp-198h] BYREF
int v7[34]; // [rsp+D0h] [rbp-E8h] BYREF
pthread_t th; // [rsp+158h] [rbp-60h] BYREF
pthread_t v9; // [rsp+160h] [rbp-58h] BYREF
pthread_t newthread; // [rsp+168h] [rbp-50h] BYREF
int arga; // [rsp+170h] [rbp-48h] BYREF
void *v12; // [rsp+178h] [rbp-40h]

v2 = sysconf(84);
*((_DWORD *)arg + 48) = v2;
printf("n_cpus = %d\n", v2);
*(_QWORD *)arg = 0LL;
*((_QWORD *)arg + 2) = 0LL;
queue_init((char *)arg + 200);
result_queue_init((char *)arg + 1744);
init_sem((char *)arg + 1632, 1LL, (char *)arg + 1680, (char *)arg + 1640);
init_sem((char *)arg + 1536, 0LL, (char *)arg + 1584, (char *)arg + 1544);
fd = cli_create_socket((unsigned int)*((__int16 *)arg + 92), *((unsigned int *)arg + 47));
if ( fd < 0 )
return fwrite("error: cli_create_socket()\n", 1uLL, 0x1BuLL, stderr);
arga = fd;
v12 = arg;
pthread_create(&newthread, 0LL, cam_reader_thread, &arga);
pthread_create(&v9, 0LL, cam_writer_thread, &arga);
if ( *((int *)arg + 48) > 0 )
{
v3 = 0;
do
{
pthread_create(&th, 0LL, cam_checker_thread, arg);
pthread_detach(th);
++v3;
}
while ( *((_DWORD *)arg + 48) > v3 );
}
pthread_mutex_lock((pthread_mutex_t *)arg + 41);
while ( *((_DWORD *)arg + 408) )
pthread_cond_wait((pthread_cond_t *)arg + 35, (pthread_mutex_t *)arg + 41);
pthread_mutex_unlock((pthread_mutex_t *)arg + 41);
close(fd);
memset(v7, 0, sizeof(v7));
v7[28] = 1;
queue_push((char *)arg + 200, v7);
memset(v6, 0, 0xA8uLL);
v6[40] = 1;
result_queue_push((char *)arg + 1744, v6);
puts("Server closed connection");
puts("Waiting for reader thread");
pthread_join(newthread, 0LL);
puts("Waiting for writer thread");
pthread_join(v9, 0LL);
puts("Waiting for checker threads.");
pthread_mutex_lock((pthread_mutex_t *)((char *)arg + 1544));
while ( *((_DWORD *)arg + 384) )
pthread_cond_wait((pthread_cond_t *)arg + 33, (pthread_mutex_t *)((char *)arg + 1544));
pthread_mutex_unlock((pthread_mutex_t *)((char *)arg + 1544));
return puts("End.");
}

original_code:
void client_async_mode (context_t * context)
{
  context->n_cpus = (int) sysconf (_SC_NPROCESSORS_ONLN);
  printf ("n_cpus = %d\n", context->n_cpus);
  context->alph = ((void *)0);
  context->hash = ((void *)0);
  queue_init (&context->queue);
  result_queue_init (&context->result_queue);
  init_sem (&context->continue_execute, 1, &context->continue_execute_sem, &context->continue_execute_mutex);
  init_sem (&context->threads, 0, &context->threads_sem, &context->threads_mutex);
  int server_socket = cli_create_socket (context->port, context->addr);
  if (server_socket < 0)
    {
      fprintf (stderr, "error: cli_create_socket()\n");
      return;
    }
  server_t server = {
    .fd = server_socket,
    .context = context,
  };
  pthread_t reader_thread;
  pthread_create (&reader_thread, ((void *)0), cam_reader_thread, &server);
  pthread_t writer_thread;
  pthread_create (&writer_thread, ((void *)0), cam_writer_thread, &server);
  int i;
  pthread_t checker_thread;
  for (i = 0; i < context->n_cpus; i++)
    {
      pthread_create (&checker_thread, ((void *)0), cam_checker_thread, context);
      pthread_detach (checker_thread);
    }
  pthread_mutex_lock (&context->continue_execute_mutex);
  while (context->continue_execute != 0)
    {
      pthread_cond_wait (&context->continue_execute_sem, &context->continue_execute_mutex);
    }
  pthread_mutex_unlock (&context->continue_execute_mutex);
  close (server_socket);
  task_t end_task = { .final = !0 };
  queue_push (&context->queue, &end_task);
  result_t end_result = { .final = !0 };
  result_queue_push (&context->result_queue, &end_result);
  printf ("Server closed connection\n");
  printf ("Waiting for reader thread\n");
  pthread_join (reader_thread, ((void *)0));
  printf ("Waiting for writer thread\n");
  pthread_join (writer_thread, ((void *)0));
  printf ("Waiting for checker threads.\n");
  pthread_mutex_lock (&context->threads_mutex);
  while (context->threads)
    {
      pthread_cond_wait (&context->threads_sem, &context->threads_mutex);
    }
  pthread_mutex_unlock (&context->threads_mutex);
  printf ("End.\n");
}

canonical_original_code:
void client_async_mode(struct context_s *context)
{
  context->n_cpus = (int) sysconf (_SC_NPROCESSORS_ONLN);
  printf ("n_cpus = %d\n", context->n_cpus);
  context->alph = ((void *)0);
  context->hash = ((void *)0);
  queue_init (&context->queue);
  result_queue_init (&context->result_queue);
  init_sem (&context->continue_execute, 1, &context->continue_execute_sem, &context->continue_execute_mutex);
  init_sem (&context->threads, 0, &context->threads_sem, &context->threads_mutex);
  int server_socket = cli_create_socket (context->port, context->addr);
  if (server_socket < 0)
    {
      fprintf (stderr, "error: cli_create_socket()\n");
      return;
    }
  struct server_s server = {
    .fd = server_socket,
    .context = context,
  };
  unsigned long reader_thread;
  pthread_create (&reader_thread, ((void *)0), cam_reader_thread, &server);
  unsigned long writer_thread;
  pthread_create (&writer_thread, ((void *)0), cam_writer_thread, &server);
  int i;
  unsigned long checker_thread;
  for (i = 0; i < context->n_cpus; i++)
    {
      pthread_create (&checker_thread, ((void *)0), cam_checker_thread, context);
      pthread_detach (checker_thread);
    }
  pthread_mutex_lock (&context->continue_execute_mutex);
  while (context->continue_execute != 0)
    {
      pthread_cond_wait (&context->continue_execute_sem, &context->continue_execute_mutex);
    }
  pthread_mutex_unlock (&context->continue_execute_mutex);
  close (server_socket);
  struct task_s end_task = { .final = !0 };
  queue_push (&context->queue, &end_task);
  struct result_s end_result = { .final = !0 };
  result_queue_push (&context->result_queue, &end_result);
  printf ("Server closed connection\n");
  printf ("Waiting for reader thread\n");
  pthread_join (reader_thread, ((void *)0));
  printf ("Waiting for writer thread\n");
  pthread_join (writer_thread, ((void *)0));
  printf ("Waiting for checker threads.\n");
  pthread_mutex_lock (&context->threads_mutex);
  while (context->threads)
    {
      pthread_cond_wait (&context->threads_sem, &context->threads_mutex);
    }
  pthread_mutex_unlock (&context->threads_mutex);
  printf ("End.\n");
}

variable_types: struct server_s { int fd; struct context_s { char *alph; int max_length; char *hash; struct brute_result_s { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } found_mutex; char password[-1]; int found; } result; int block_size; enum run_mode_t { RM_SINGLE=0, RM_MULTI=1, RM_CLIENT=2, RM_SERVER=3, RM_CLIENT_ASYNC=4, RM_SERVER_ASYNC=5, RM_SERVER_EPOLL=6 } run_mode; short port; struct in_addr { unsigned int s_addr; } addr; int n_cpus; int listener_socket; struct queue_s { struct task_s { char password[-1]; int left; int right; int final; int id; int idx; struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; } *cd; } queue[-1]; union sem_t { char __size[32]; long __align; } full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } queue; int tasks_in_process; union pthread_mutex_t tasks_in_process_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } tasks_in_process_sem; int threads; union pthread_mutex_t threads_mutex; union pthread_cond_t threads_sem; int continue_execute; union pthread_mutex_t continue_execute_mutex; union pthread_cond_t continue_execute_sem; int id; void *(*srv_client_thread)(struct context_s *, int); struct result_queue_s { struct result_s { struct brute_result_s result; int id; int idx; int final; } queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; } result_queue; } *context; }

user_defined_types: struct brute_result_s { union pthread_mutex_t found_mutex; char password[-1]; int found; }


original_code:
int tm_client_process (int client, context_t * context)
{
  char * buffer;
  cs_message_t message;
  cs_status_t recv_status;
  int send_status;
  task_t task;
  int ret = 0;
  message.alph = context->alph;
  for (;;)
    {
      queue_pop (&context->queue, &task);
      if (task.final)
 {
   queue_push (&context->queue, &task);
   return 0;
 }
      if (context->result.found)
 {
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
   continue;
 }
      message.type = MT_SEND_JOB;
      message.alph = context->alph;
      message.hash = context->hash;
      message.task = task;
      printf ("(%d) task: %s [%d; %d)\n", client, message.task.password, message.task.left, message.task.right);
      send_status = send_message (client, &message);
      if (send_status == -1)
 {
   fprintf (stderr, "error: send_message()\n");
   ret = -1;
   break;
 }
      else if (send_status == 0)
 {
   break;
 }
      recv_status = recv_message (client, &buffer);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   free (buffer);
   if (message.result)
     {
       context->result.found = !0;
       strcpy (context->result.password, message.password);
     }
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
 }
      else if (recv_status == S_CONNECTION_CLOSED)
 {
   free (buffer);
   break;
 }
      else
 {
   free (buffer);
   ret = -1;
   fprintf (stderr, "error: recv_message()\n");
   break;
 }
    }
  queue_push (&context->queue, &task);
  return ret;
}

canonical_original_code:
int tm_client_process(int client, struct context_s *context)
{
  char *buffer;
  struct cs_message_t message;
  enum cs_status_t recv_status;
  int send_status;
  struct task_s task;
  int ret = 0;
  message.alph = context->alph;
  for (;;)
    {
      queue_pop (&context->queue, &task);
      if (task.final)
 {
   queue_push (&context->queue, &task);
   return 0;
 }
      if (context->result.found)
 {
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
   continue;
 }
      message.type = MT_SEND_JOB;
      message.alph = context->alph;
      message.hash = context->hash;
      message.task = task;
      printf ("(%d) task: %s [%d; %d)\n", client, message.task.password, message.task.left, message.task.right);
      send_status = send_message (client, &message);
      if (send_status == -1)
 {
   fprintf (stderr, "error: send_message()\n");
   ret = -1;
   break;
 }
      else if (send_status == 0)
 {
   break;
 }
      recv_status = recv_message (client, &buffer);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   free (buffer);
   if (message.result)
     {
       context->result.found = !0;
       strcpy (context->result.password, message.password);
     }
   dec_sem (&context->tasks_in_process, &context->tasks_in_process_sem, &context->tasks_in_process_mutex);
 }
      else if (recv_status == S_CONNECTION_CLOSED)
 {
   free (buffer);
   break;
 }
      else
 {
   free (buffer);
   ret = -1;
   fprintf (stderr, "error: recv_message()\n");
   break;
 }
    }
  queue_push (&context->queue, &task);
  return ret;
}

variable_types: client int

variable_types: ret int

return_type: int

user_defined_types: enum cs_message_type_t { MT_SEND_JOB=0, MT_REPORT_RESULT=1 }

user_defined_types: struct queue_s { struct task_s queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; }


decompiled_code:
__int64 __fastcall tm_client_thread(__int64 a1, unsigned int a2)
{
inc_sem(a1 + 1536, a1 + 1584, a1 + 1544);
printf("(%d) connected\n", a2);
if ( (int)tm_client_process(a2, a1) < 0 )
fwrite("error: tm_client_process()\n", 1uLL, 0x1BuLL, stderr);
printf("(%d) disconnected\n", a2);
close(a2);
dec_sem(a1 + 1536, a1 + 1584, a1 + 1544);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int a2)
{
inc_sem(a1 + 1536, a1 + 1584, a1 + 1544);
printf("(%d) connected\n", a2);
if ( (int)func0(a2, a1) < 0 )
fwrite("error: tm_client_process()\n", 1uLL, 0x1BuLL, stderr);
printf("(%d) disconnected\n", a2);
close(a2);
dec_sem(a1 + 1536, a1 + 1584, a1 + 1544);
return 0LL;
}

original_code:
void * tm_client_thread (context_t * context, int client_socket)
{
  inc_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  printf ("(%d) connected\n", client_socket);
  if (tm_client_process (client_socket, context) < 0)
    {
      fprintf (stderr, "error: tm_client_process()\n");
    }
  printf ("(%d) disconnected\n", client_socket);
  close (client_socket);
  dec_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  return ((void *)0);
}

canonical_original_code:
void *tm_client_thread(struct context_s *context, int client_socket)
{
  inc_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  printf ("(%d) connected\n", client_socket);
  if (tm_client_process (client_socket, context) < 0)
    {
      fprintf (stderr, "error: tm_client_process()\n");
    }
  printf ("(%d) disconnected\n", client_socket);
  close (client_socket);
  dec_sem (&context->threads, &context->threads_sem, &context->threads_mutex);
  return ((void *)0);
}

user_defined_types: union pthread_cond_t { struct __pthread_cond_s __data; char __size[48]; long long __align; }

user_defined_types: struct result_queue_s { struct result_s queue[-1]; union sem_t full; union sem_t empty; int head; int tail; union pthread_mutex_t head_mutex; union pthread_mutex_t tail_mutex; }


decompiled_code:
__int64 __fastcall server_mode(__int64 a1)
{
*(_QWORD *)(a1 + 1736) = tm_client_thread;
return server();
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
*(_QWORD *)(a1 + 1736) = tm_client_thread;
return server();
}

original_code:
void server_mode (context_t * context)
{
  context->srv_client_thread = tm_client_thread;
  server (context);
}

canonical_original_code:
void server_mode(struct context_s *context)
{
  context->srv_client_thread = tm_client_thread;
  server (context);
}

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


decompiled_code:
__int64 __fastcall cm_socket_cycle(unsigned int a1, __int64 a2)
{
int v2; // eax
__int64 result; // rax
int v4; // [rsp+0h] [rbp-138h] BYREF
__int64 v5; // [rsp+8h] [rbp-130h]
__int64 v6; // [rsp+10h] [rbp-128h]
char v7[104]; // [rsp+18h] [rbp-120h] BYREF
unsigned int v8; // [rsp+80h] [rbp-B8h]
unsigned int v9; // [rsp+84h] [rbp-B4h]
int v10; // [rsp+A0h] [rbp-98h]
char dest[116]; // [rsp+A4h] [rbp-94h] BYREF
void *ptr; // [rsp+118h] [rbp-20h] BYREF

while ( 1 )
{
v2 = recv_message(a1, &ptr);
if ( v2 )
break;
xml_to_message(ptr, &v4);
printf("task: %s [%d; %d)... ", v7, v8, v9);
free(ptr);
*(_QWORD *)(a2 + 16) = v6;
*(_QWORD *)a2 = v5;
*(_DWORD *)(a2 + 168) = 0;
check_multithread(v7, a2);
free(*(void **)(a2 + 16));
free(*(void **)a2);
v4 = 1;
if ( *(_DWORD *)(a2 + 168) )
{
printf("found: %s\n", (const char *)(a2 + 64));
v10 = 1;
strcpy(dest, (const char *)(a2 + 64));
}
else
{
puts("not found");
v10 = 0;
}
if ( (int)send_message(a1, &v4) <= 0 )
{
fwrite("error: send_message()\n", 1uLL, 0x16uLL, stderr);
return 0xFFFFFFFFLL;
}
}
if ( v2 == 4 )
{
puts("Server closed connection");
result = 0LL;
}
else
{
fwrite("error: recv_message()\n", 1uLL, 0x16uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1, __int64 a2)
{
int v2; // eax
__int64 result; // rax
int v4; // [rsp+0h] [rbp-138h] BYREF
__int64 v5; // [rsp+8h] [rbp-130h]
__int64 v6; // [rsp+10h] [rbp-128h]
char v7[104]; // [rsp+18h] [rbp-120h] BYREF
unsigned int v8; // [rsp+80h] [rbp-B8h]
unsigned int v9; // [rsp+84h] [rbp-B4h]
int v10; // [rsp+A0h] [rbp-98h]
char dest[116]; // [rsp+A4h] [rbp-94h] BYREF
void *ptr; // [rsp+118h] [rbp-20h] BYREF

while ( 1 )
{
v2 = recv_message(a1, &ptr);
if ( v2 )
break;
xml_to_message(ptr, &v4);
printf("task: %s [%d; %d)... ", v7, v8, v9);
free(ptr);
*(_QWORD *)(a2 + 16) = v6;
*(_QWORD *)a2 = v5;
*(_DWORD *)(a2 + 168) = 0;
check_multithread(v7, a2);
free(*(void **)(a2 + 16));
free(*(void **)a2);
v4 = 1;
if ( *(_DWORD *)(a2 + 168) )
{
printf("found: %s\n", (const char *)(a2 + 64));
v10 = 1;
strcpy(dest, (const char *)(a2 + 64));
}
else
{
puts("not found");
v10 = 0;
}
if ( (int)send_message(a1, &v4) <= 0 )
{
fwrite("error: send_message()\n", 1uLL, 0x16uLL, stderr);
return 0xFFFFFFFFLL;
}
}
if ( v2 == 4 )
{
puts("Server closed connection");
result = 0LL;
}
else
{
fwrite("error: recv_message()\n", 1uLL, 0x16uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int cm_socket_cycle (int socket, context_t * context)
{
  char * buffer;
  cs_message_t message;
  cs_status_t recv_status;
  int send_status;
  for (;;)
    {
      recv_status = recv_message (socket, &buffer);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   printf ("task: %s [%d; %d)... ", message.task.password, message.task.left, message.task.right);
   free (buffer);
   context->hash = message.hash;
   context->alph = message.alph;
   context->result.found = 0;
   check_multithread (&message.task, context);
   free (context->hash);
   free (context->alph);
   message.type = MT_REPORT_RESULT;
   if (context->result.found)
     {
       printf ("found: %s\n", context->result.password);
       message.result = !0;
       strcpy (message.password, context->result.password);
     }
   else
     {
       printf ("not found\n");
       message.result = 0;
     }
   if ((send_status = send_message (socket, &message)) <= 0)
     {
       fprintf (stderr, "error: send_message()\n");
       return -1;
     }
 }
      else if (recv_status == S_CONNECTION_CLOSED)
 {
   printf ("Server closed connection\n");
   return 0;
 }
      else
 {
   fprintf (stderr, "error: recv_message()\n");
   return -1;
 }
    }
  return 0;
}

canonical_original_code:
int cm_socket_cycle(int socket, struct context_s *context)
{
  char *buffer;
  struct cs_message_t message;
  enum cs_status_t recv_status;
  int send_status;
  for (;;)
    {
      recv_status = recv_message (socket, &buffer);
      if (recv_status == S_SUCCESS)
 {
   xml_to_message (buffer, &message);
   printf ("task: %s [%d; %d)... ", message.task.password, message.task.left, message.task.right);
   free (buffer);
   context->hash = message.hash;
   context->alph = message.alph;
   context->result.found = 0;
   check_multithread (&message.task, context);
   free (context->hash);
   free (context->alph);
   message.type = MT_REPORT_RESULT;
   if (context->result.found)
     {
       printf ("found: %s\n", context->result.password);
       message.result = !0;
       strcpy (message.password, context->result.password);
     }
   else
     {
       printf ("not found\n");
       message.result = 0;
     }
   if ((send_status = send_message (socket, &message)) <= 0)
     {
       fprintf (stderr, "error: send_message()\n");
       return -1;
     }
 }
      else if (recv_status == S_CONNECTION_CLOSED)
 {
   printf ("Server closed connection\n");
   return 0;
 }
      else
 {
   fprintf (stderr, "error: recv_message()\n");
   return -1;
 }
    }
  return 0;
}

variable_types: socket int

user_defined_types: enum run_mode_t { RM_SINGLE=0, RM_MULTI=1, RM_CLIENT=2, RM_SERVER=3, RM_CLIENT_ASYNC=4, RM_SERVER_ASYNC=5, RM_SERVER_EPOLL=6 }

user_defined_types: union sem_t { char __size[32]; long __align; }


decompiled_code:
int __fastcall client_mode(__int64 a1)
{
__int64 v1; // rax
signed int v2; // eax
int v3; // ebp
int result; // eax

v1 = sysconf(84);
*(_DWORD *)(a1 + 192) = v1;
printf("n_cpus = %d\n", v1);
v2 = cli_create_socket((unsigned int)*(__int16 *)(a1 + 184), *(unsigned int *)(a1 + 188));
if ( v2 < 0 )
return fwrite("error: cm_create_socket()\n", 1uLL, 0x1AuLL, stderr);
v3 = v2;
if ( (int)cm_socket_cycle(v2, a1) < 0 )
result = fwrite("error: cm_socket_cycle()\n", 1uLL, 0x19uLL, stderr);
else
result = close(v3);
return result;
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1)
{
__int64 v1; // rax
signed int v2; // eax
int v3; // ebp
int result; // eax

v1 = sysconf(84);
*(_DWORD *)(a1 + 192) = v1;
printf("n_cpus = %d\n", v1);
v2 = cli_create_socket((unsigned int)*(__int16 *)(a1 + 184), *(unsigned int *)(a1 + 188));
if ( v2 < 0 )
return fwrite("error: cm_create_socket()\n", 1uLL, 0x1AuLL, stderr);
v3 = v2;
if ( (int)func0(v2, a1) < 0 )
result = fwrite("error: cm_socket_cycle()\n", 1uLL, 0x19uLL, stderr);
else
result = close(v3);
return result;
}

original_code:
void client_mode (context_t * context)
{
  context->n_cpus = (int) sysconf (_SC_NPROCESSORS_ONLN);
  printf ("n_cpus = %d\n", context->n_cpus);
  int sock = cli_create_socket (context->port, context->addr);
  if (sock < 0)
    {
      fprintf (stderr, "error: cm_create_socket()\n");
      return;
    }
  if (cm_socket_cycle (sock, context) < 0)
    {
      fprintf (stderr, "error: cm_socket_cycle()\n");
      return;
    }
  close (sock);
}

canonical_original_code:
void client_mode(struct context_s *context)
{
  context->n_cpus = (int) sysconf (_SC_NPROCESSORS_ONLN);
  printf ("n_cpus = %d\n", context->n_cpus);
  int sock = cli_create_socket (context->port, context->addr);
  if (sock < 0)
    {
      fprintf (stderr, "error: cm_create_socket()\n");
      return;
    }
  if (cm_socket_cycle (sock, context) < 0)
    {
      fprintf (stderr, "error: cm_socket_cycle()\n");
      return;
    }
  close (sock);
}

variable_types: sock int

user_defined_types: struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; }

user_defined_types: struct result_s { struct brute_result_s result; int id; int idx; int final; }


original_code:
void multi_mode (context_t * context)
{
  context->n_cpus = (int) sysconf (_SC_NPROCESSORS_ONLN);
  printf ("n_cpus = %d\n", context->n_cpus);
  int length;
  for (length = 1; length <= context->max_length; length++)
    {
      task_t task;
      memset (task.password, context->alph[0], sizeof (task.password));
      task.password[length] = (char)0;
      task.final = 0;
      task.left = 0;
      task.right = length;
      if (check_multithread (&task, context))
 {
   break;
 }
    }
}

canonical_original_code:
void multi_mode(struct context_s *context)
{
  context->n_cpus = (int) sysconf (_SC_NPROCESSORS_ONLN);
  printf ("n_cpus = %d\n", context->n_cpus);
  int length;
  for (length = 1; length <= context->max_length; length++)
    {
      struct task_s task;
      memset (task.password, context->alph[0], sizeof (task.password));
      task.password[length] = (char)0;
      task.final = 0;
      task.left = 0;
      task.right = length;
      if (check_multithread (&task, context))
 {
   break;
 }
    }
}

variable_types: length int

user_defined_types: struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; }

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


original_code:
void single_mode (context_t * context)
{
  int length;
  struct crypt_data cd = { .initialized = 0 };
  for (length = 1; length <= context->max_length; length++)
    {
      task_t task;
      memset (task.password, context->alph[0], sizeof (task.password));
      task.password[length] = (char)0;
      task.final = 0;
      task.left = 0;
      task.right = length;
      task.cd = &cd;
      if (brute_block_iterative (&task, check_password, context))
 {
   break;
 }
    }
}

canonical_original_code:
void single_mode(struct context_s *context)
{
  int length;
  struct crypt_data cd = { .initialized = 0 };
  for (length = 1; length <= context->max_length; length++)
    {
      struct task_s task;
      memset (task.password, context->alph[0], sizeof (task.password));
      task.password[length] = (char)0;
      task.final = 0;
      task.left = 0;
      task.right = length;
      task.cd = &cd;
      if (brute_block_iterative (&task, check_password, context))
 {
   break;
 }
    }
}

variable_types: struct crypt_data { char keysched[-1]; char sb0[32768]; char sb1[32768]; char sb2[32768]; char sb3[32768]; char crypt_3_buf[14]; char current_salt[2]; long current_saltbits; int direction; }


repo: FurryFuttock/micro-pv

original_code:
static void dump_regs(struct pt_regs *regs)
{
    micropv_printk("src/traps.c", 101,"-------------------- REGISTER FILE --------------------");
    micropv_printk("src/traps.c", 102,"RIP: %04lx:%016lx ", regs->cs & 0xffff, regs->ip);
    micropv_printk("src/traps.c", 103,"RSP: %04lx:%016lx  EFLAGS: %08lx", regs->ss, regs->sp, regs->flags);
    micropv_printk("src/traps.c", 105,"RAX: %016lx RBX: %016lx RCX: %016lx", regs->ax, regs->bx, regs->cx);
    micropv_printk("src/traps.c", 107,"RDX: %016lx RSI: %016lx RDI: %016lx", regs->dx, regs->si, regs->di);
    micropv_printk("src/traps.c", 109,"RBP: %016lx R08: %016lx R09: %016lx", regs->bp, regs->r8, regs->r9);
    micropv_printk("src/traps.c", 111,"R10: %016lx R11: %016lx R12: %016lx", regs->r10, regs->r11, regs->r12);
    micropv_printk("src/traps.c", 113,"R13: %016lx R14: %016lx R15: %016lx", regs->r13, regs->r14, regs->r15);
}

variable_types: struct pt_regs { unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; unsigned long bx; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long ax; unsigned long cx; unsigned long dx; unsigned long si; unsigned long di; unsigned long orig_ax; unsigned long ip; unsigned long cs; unsigned long flags; unsigned long sp; unsigned long ss; } *


decompiled_code:
__int64 __fastcall do_stack_walk(__int64 a1)
{
micropv_printk("src/traps.c", 148LL, "-------------------- STACK WALK --------------------");
micropv_printk("src/traps.c", 150LL, "base is %#lx ", a1);
return micropv_printk("src/traps.c", 151LL, "caller is %#lx", *(_QWORD *)(a1 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
micropv_printk("src/traps.c", 148LL, "-------------------- STACK WALK --------------------");
micropv_printk("src/traps.c", 150LL, "base is %#lx ", a1);
return micropv_printk("src/traps.c", 151LL, "caller is %#lx", *(_QWORD *)(a1 + 8));
}

original_code:
static void do_stack_walk(unsigned long frame_base)
{
    micropv_printk("src/traps.c", 148,"-------------------- STACK WALK    --------------------");
    unsigned long *frame = (void*) frame_base;
    micropv_printk("src/traps.c", 150,"base is %#lx ", frame_base);
    micropv_printk("src/traps.c", 151,"caller is %#lx", frame[1]);
}

variable_types:
frame
unsigned long *


variable_types:
addr
unsigned long

variable_types:
i
unsigned long

variable_types:
hexchar
char [16]

variable_types:
buffer
char [68]

variable_types: j int


decompiled_code:
__int64 __fastcall dump_context(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm4_8
double v10; // xmm5_8

dump_regs(a1);
dump_fp_regs(a2, a3, a4, a5, v9, v10, a8, a9);
do_stack_walk(*(_QWORD *)(a1 + 32));
dump_mem(*(_QWORD *)(a1 + 152));
dump_mem(*(_QWORD *)(a1 + 32));
dump_mem(*(_QWORD *)(a1 + 128));
return HYPERVISOR_sched_op(2);
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm4_8
double v10; // xmm5_8

func2(a1);
func3(a2, a3, a4, a5, v9, v10, a8, a9);
func4(*(_QWORD *)(a1 + 32));
func5(*(_QWORD *)(a1 + 152));
func5(*(_QWORD *)(a1 + 32));
func5(*(_QWORD *)(a1 + 128));
return func1(2);
}

original_code:
static void dump_context(struct pt_regs *regs)
{
    dump_regs(regs);
    dump_fp_regs(regs);
    do_stack_walk(regs->bp);
    dump_mem(regs->sp);
    dump_mem(regs->bp);
    dump_mem(regs->ip);
    struct sched_shutdown sched_shutdown = { .reason = 3 };
    HYPERVISOR_sched_op(2, &sched_shutdown);
}

variable_types: struct sched_shutdown { unsigned int reason; }

user_defined_types: struct pt_regs { unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; unsigned long bx; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long ax; unsigned long cx; unsigned long dx; unsigned long si; unsigned long di; unsigned long orig_ax; unsigned long ip; unsigned long cs; unsigned long flags; unsigned long sp; unsigned long ss; }


decompiled_code:
__int64 __fastcall do_divide_error(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 207LL, "%s", "do_divide_error");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 207LL, "%s", "do_divide_error");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_divide_error(struct pt_regs *regs) { micropv_printk("src/traps.c", 207,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_debug(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 208LL, "%s", "do_debug");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 208LL, "%s", "do_debug");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_debug(struct pt_regs *regs) { micropv_printk("src/traps.c", 208,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_int3(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 209LL, "%s", "do_int3");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 209LL, "%s", "do_int3");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_int3(struct pt_regs *regs) { micropv_printk("src/traps.c", 209,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_overflow(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 210LL, "%s", "do_overflow");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 210LL, "%s", "do_overflow");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_overflow(struct pt_regs *regs) { micropv_printk("src/traps.c", 210,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_bounds(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 211LL, "%s", "do_bounds");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 211LL, "%s", "do_bounds");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_bounds(struct pt_regs *regs) { micropv_printk("src/traps.c", 211,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_invalid_op(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 212LL, "%s", "do_invalid_op");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 212LL, "%s", "do_invalid_op");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_invalid_op(struct pt_regs *regs) { micropv_printk("src/traps.c", 212,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_device_not_available(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v10; // xmm0_8
double v11; // xmm4_8
double v12; // xmm5_8

if ( micropv_traps_fp_callback )
return micropv_traps_fp_callback();
v10 = micropv_printk("src/traps.c", 222LL, "%s", "do_device_not_available");
return dump_context(a1, v10, a3, a4, a5, v11, v12, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func13(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v10; // xmm0_8
double v11; // xmm4_8
double v12; // xmm5_8

if ( micropv_traps_fp_callback )
return micropv_traps_fp_callback();
v10 = micropv_printk("src/traps.c", 222LL, "%s", "do_device_not_available");
return func6(a1, v10, a3, a4, a5, v11, v12, a8, a9);
}

original_code:
void do_device_not_available(struct pt_regs *regs)
{
    if (micropv_traps_fp_callback)
        micropv_traps_fp_callback(regs);
    else
    {
        micropv_printk("src/traps.c", 222,"%s", __FUNCTION__);
        dump_context(regs);
    }
}


decompiled_code:
__int64 __fastcall do_coprocessor_segment_overrun(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 227LL, "%s", "do_coprocessor_segment_overrun");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 227LL, "%s", "do_coprocessor_segment_overrun");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_coprocessor_segment_overrun(struct pt_regs *regs) { micropv_printk("src/traps.c", 227,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_invalid_TSS(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 228LL, "%s", "do_invalid_TSS");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 228LL, "%s", "do_invalid_TSS");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_invalid_TSS(struct pt_regs *regs) { micropv_printk("src/traps.c", 228,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_segment_not_present(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 229LL, "%s", "do_segment_not_present");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 229LL, "%s", "do_segment_not_present");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_segment_not_present(struct pt_regs *regs) { micropv_printk("src/traps.c", 229,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_stack_segment(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 230LL, "%s", "do_stack_segment");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func17(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 230LL, "%s", "do_stack_segment");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_stack_segment(struct pt_regs *regs) { micropv_printk("src/traps.c", 230,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_general_protection(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
char v9; // al
double v10; // xmm0_8
double v11; // xmm4_8
double v12; // xmm5_8
__int64 result; // rax

v9 = **(_BYTE **)(a1 + 128);
if ( v9 == -6 )
{
result = micropv_interrupt_disable();
++*(_QWORD *)(a1 + 128);
}
else if ( v9 == -5 )
{
result = micropv_interrupt_enable();
++*(_QWORD *)(a1 + 128);
}
else
{
v10 = micropv_printk("src/traps.c", 245LL, "%s", "do_general_protection");
result = dump_context(a1, v10, a3, a4, a5, v11, v12, a8, a9);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func18(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
char v9; // al
double v10; // xmm0_8
double v11; // xmm4_8
double v12; // xmm5_8
__int64 result; // rax

v9 = **(_BYTE **)(a1 + 128);
if ( v9 == -6 )
{
result = micropv_interrupt_disable();
++*(_QWORD *)(a1 + 128);
}
else if ( v9 == -5 )
{
result = micropv_interrupt_enable();
++*(_QWORD *)(a1 + 128);
}
else
{
v10 = micropv_printk("src/traps.c", 245LL, "%s", "do_general_protection");
result = func6(a1, v10, a3, a4, a5, v11, v12, a8, a9);
}
return result;
}

original_code:
void do_general_protection(struct pt_regs *regs)
{
    if (*(unsigned char *)regs->ip == 0xfa)
    {
        micropv_interrupt_disable();
        regs->ip++;
    }
    else if (*(unsigned char *)regs->ip == 0xfb)
    {
        micropv_interrupt_enable();
        regs->ip++;
    }
    else
    {
        micropv_printk("src/traps.c", 245,"%s", __FUNCTION__);
        dump_context(regs);
    }
}


decompiled_code:
__int64 __fastcall do_page_fault(const void **a1, __int64 a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9, double a10)
{
double v10; // xmm0_8
double v11; // xmm0_8
double v12; // xmm4_8
double v13; // xmm5_8
const void *v15; // [rsp+8h] [rbp-20h] BYREF

v10 = micropv_printk("src/traps.c", 252LL, "%s", "do_page_fault");
v15 = *(const void **)(hypervisor_shared_info + 16LL);
if ( handling_pg_fault_5 == 1 )
{
micropv_printk("src/traps.c", 262LL, "Page fault in pagetable walk (access to invalid memory?).", v10);
HYPERVISOR_sched_op(2);
}
++handling_pg_fault_5;
v11 = micropv_printk(
"src/traps.c",
269LL,
"Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx",
v15,
a1[16],
a1,
a1[19],
&v15,
a2);
dump_context((__int64)a1, v11, a4, a5, a6, v12, v13, a9, a10);
return (unsigned int)--handling_pg_fault_5;
}

canonical_decompiled_code:
__int64 __fastcall func19(const void **a1, __int64 a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9, double a10)
{
double v10; // xmm0_8
double v11; // xmm0_8
double v12; // xmm4_8
double v13; // xmm5_8
const void *v15; // [rsp+8h] [rbp-20h] BYREF

v10 = micropv_printk("src/traps.c", 252LL, "%s", "do_page_fault");
v15 = *(const void **)(hypervisor_shared_info + 16LL);
if ( handling_pg_fault_5 == 1 )
{
micropv_printk("src/traps.c", 262LL, "Page fault in pagetable walk (access to invalid memory?).", v10);
func1(2);
}
++handling_pg_fault_5;
v11 = micropv_printk(
"src/traps.c",
269LL,
"Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx",
v15,
a1[16],
a1,
a1[19],
&v15,
a2);
func6((__int64)a1, v11, a4, a5, a6, v12, v13, a9, a10);
return (unsigned int)--handling_pg_fault_5;
}

original_code:
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
    micropv_printk("src/traps.c", 252,"%s", __FUNCTION__);
    unsigned long addr = (hypervisor_shared_info->vcpu_info[0].arch.cr2);
    static volatile int handling_pg_fault = 0;
    if(handling_pg_fault == 1)
    {
        micropv_printk("src/traps.c", 262,"Page fault in pagetable walk (access to invalid memory?).");
        struct sched_shutdown sched_shutdown = { .reason = 3 };
        HYPERVISOR_sched_op(2, &sched_shutdown);
    }
    handling_pg_fault++;
    __asm__ __volatile__("": : :"memory");
    micropv_printk("src/traps.c", 269,"Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx", (void *)addr, (void *)regs->ip, regs, (void *)regs->sp, &addr, error_code);
    dump_context(regs);
    handling_pg_fault--;
}

canonical_original_code:
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
    micropv_printk("src/traps.c", 252,"%s", __FUNCTION__);
    unsigned long addr = (hypervisor_shared_info->vcpu_info[0].arch.cr2);
    static int handling_pg_fault = 0;
    if(handling_pg_fault == 1)
    {
        micropv_printk("src/traps.c", 262,"Page fault in pagetable walk (access to invalid memory?).");
        struct sched_shutdown sched_shutdown = { .reason = 3 };
        HYPERVISOR_sched_op(2, &sched_shutdown);
    }
    handling_pg_fault++;
    __asm__ __volatile__("": : :"memory");
    micropv_printk("src/traps.c", 269,"Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp %p, code %lx", (void *)addr, (void *)regs->ip, regs, (void *)regs->sp, &addr, error_code);
    dump_context(regs);
    handling_pg_fault--;
}

user_defined_types: struct sched_shutdown { unsigned int reason; }


decompiled_code:
__int64 __fastcall do_coprocessor_error(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 278LL, "%s", "do_coprocessor_error");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func20(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 278LL, "%s", "do_coprocessor_error");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_coprocessor_error(struct pt_regs *regs) { micropv_printk("src/traps.c", 278,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_simd_coprocessor_error(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 281LL, "%s", "do_simd_coprocessor_error");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func21(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 281LL, "%s", "do_simd_coprocessor_error");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code:
void do_simd_coprocessor_error(struct pt_regs *regs)
{
    micropv_printk("src/traps.c", 281,"%s", __FUNCTION__);
    dump_context(regs);
}


decompiled_code:
__int64 __fastcall do_alignment_check(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 285LL, "%s", "do_alignment_check");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func22(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 285LL, "%s", "do_alignment_check");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_alignment_check(struct pt_regs *regs) { micropv_printk("src/traps.c", 285,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_spurious_interrupt_bug(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 286LL, "%s", "do_spurious_interrupt_bug");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func23(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 286LL, "%s", "do_spurious_interrupt_bug");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_spurious_interrupt_bug(struct pt_regs *regs) { micropv_printk("src/traps.c", 286,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 __fastcall do_machine_check(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 287LL, "%s", "do_machine_check");
return dump_context(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

canonical_decompiled_code:
__int64 __fastcall func24(__int64 a1, double a2, double a3, double a4, double a5, double a6, double a7, double a8, double a9)
{
double v9; // xmm0_8
double v10; // xmm4_8
double v11; // xmm5_8

v9 = micropv_printk("src/traps.c", 287LL, "%s", "do_machine_check");
return func6(a1, v9, a3, a4, a5, v10, v11, a8, a9);
}

original_code: void do_machine_check(struct pt_regs *regs) { micropv_printk("src/traps.c", 287,"%s", __FUNCTION__); dump_context(regs); }


decompiled_code:
__int64 xentraps_init()
{
return HYPERVISOR_set_trap_table(&trap_table);
}

canonical_decompiled_code:
__int64 func25()
{
return func0(&trap_table);
}

original_code:
void xentraps_init(void)
{
    HYPERVISOR_set_trap_table(trap_table);
}

canonical_original_code:
void xentraps_init()
{
    HYPERVISOR_set_trap_table(trap_table);
}


decompiled_code:
__int64 __fastcall xengnttab_map(__int64 a1, __int16 a2, int a3, __int64 a4)
{
__int64 v5; // [rsp+0h] [rbp-28h] BYREF
int v6; // [rsp+8h] [rbp-20h]
int v7; // [rsp+Ch] [rbp-1Ch]
__int16 v8; // [rsp+10h] [rbp-18h]
__int16 v9; // [rsp+12h] [rbp-16h]
int v10; // [rsp+14h] [rbp-14h]
__int64 v11; // [rsp+18h] [rbp-10h]

v5 = a4;
v6 = 2;
v7 = a3;
v8 = a2;
HYPERVISOR_grant_table_op(0, (__int64)&v5, 1u);
if ( v9 )
return 0xFFFFFFFFLL;
*(_DWORD *)a1 = v10;
*(_QWORD *)(a1 + 8) = v11;
return 0LL;
}

original_code:
static int xengnttab_map(micropv_grant_handle_t *handle, int dom_friend, grant_ref_t ref, void *addr, int readonly)
{
    gnttab_map_grant_ref_t map_op;
    map_op.host_addr = (uint64_t)addr;
    map_op.flags = (1<<(1));
    map_op.ref = ref;
    map_op.dom = dom_friend;
    HYPERVISOR_grant_table_op(0, &map_op, 1);
    if (map_op.status != (0))
    {
        return -1;
    }
    else
    {
        handle->handle = map_op.handle;
        handle->dev_bus_addr = map_op.dev_bus_addr;
        return 0;
    }
}

canonical_original_code:
static int xengnttab_map(struct micropv_grant_handle_t *handle, int dom_friend, unsigned int ref, void *addr, int readonly)
{
    struct gnttab_map_grant_ref map_op;
    map_op.host_addr = (unsigned long)addr;
    map_op.flags = (1<<(1));
    map_op.ref = ref;
    map_op.dom = dom_friend;
    HYPERVISOR_grant_table_op(0, &map_op, 1);
    if (map_op.status != (0))
    {
        return -1;
    }
    else
    {
        handle->handle = map_op.handle;
        handle->dev_bus_addr = map_op.dev_bus_addr;
        return 0;
    }
}

variable_types: struct micropv_grant_handle_t { unsigned int handle; unsigned long dev_bus_addr; } *

variable_types:
ref
unsigned int

variable_types:
addr
void *

variable_types: readonly int

variable_types: struct gnttab_map_grant_ref { unsigned long host_addr; unsigned int flags; unsigned int ref; unsigned short dom; short status; unsigned int handle; unsigned long dev_bus_addr; }


decompiled_code:
__int64 __fastcall xengnttab_unmap(__int64 a1, __int64 a2)
{
__int64 v3[2]; // [rsp+0h] [rbp-20h] BYREF
int v4; // [rsp+10h] [rbp-10h]

v3[0] = a2;
v3[1] = *(_QWORD *)(a1 + 8);
v4 = *(_DWORD *)a1;
return HYPERVISOR_grant_table_op(1u, (__int64)v3, 1u);
}

original_code:
static void xengnttab_unmap(micropv_grant_handle_t *handle, void *addr)
{
    gnttab_unmap_grant_ref_t unmap_op;
    unmap_op.host_addr = (uint64_t)addr;
    unmap_op.dev_bus_addr = handle->dev_bus_addr;
    unmap_op.handle = handle->handle;
    HYPERVISOR_grant_table_op(1, &unmap_op, 1);
}

canonical_original_code:
static void xengnttab_unmap(struct micropv_grant_handle_t *handle, void *addr)
{
    struct gnttab_unmap_grant_ref unmap_op;
    unmap_op.host_addr = (unsigned long)addr;
    unmap_op.dev_bus_addr = handle->dev_bus_addr;
    unmap_op.handle = handle->handle;
    HYPERVISOR_grant_table_op(1, &unmap_op, 1);
}

variable_types: struct gnttab_unmap_grant_ref { unsigned long host_addr; unsigned long dev_bus_addr; unsigned int handle; short status; }

user_defined_types: struct micropv_grant_handle_t { unsigned int handle; unsigned long dev_bus_addr; }