decompiled_code:
__int64 __fastcall BitcoinNetworkType_GetPublicKeyPrefix(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

original_code:
BitcoinKeyPrefix BitcoinNetworkType_GetPublicKeyPrefix(const struct BitcoinNetworkType *n)
{
 return n->public_key_prefix;
}

canonical_original_code:
unsigned int BitcoinNetworkType_GetPublicKeyPrefix(struct BitcoinNetworkType *n)
{
 return n->public_key_prefix;
}

variable_types: struct BitcoinNetworkType { char *name; char *hrp; unsigned int public_key_prefix; } *


repo: matja/bitcoin-tool

decompiled_code:
__int64 __fastcall BitcoinNetworkType_GetPrivateKeyPrefix(__int64 a1)
{
return *(unsigned int *)(a1 + 24);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return *(unsigned int *)(a1 + 24);
}

original_code:
BitcoinKeyPrefix BitcoinNetworkType_GetPrivateKeyPrefix(const struct BitcoinNetworkType *n)
{
 return n->private_key_prefix;
}

canonical_original_code:
unsigned int BitcoinNetworkType_GetPrivateKeyPrefix(struct BitcoinNetworkType *n)
{
 return n->private_key_prefix;
}

return_type: unsigned int

user_defined_types: struct BitcoinNetworkType { char *name; char *hrp; unsigned int public_key_prefix; }


decompiled_code:
char **__fastcall Bitcoin_GetNetworkTypeByName(char *s1)
{
const char *v1; // rsi
char **i; // r12

v1 = "bitcoin";
for ( i = network_types; ; v1 = *i )
{
if ( !strcmp(s1, v1) )
return i;
i += 4;
if ( i == (char **)&unk_520 )
break;
}
return 0LL;
}

canonical_decompiled_code:
char **__fastcall func2(char *s1)
{
const char *v1; // rsi
char **i; // r12

v1 = "bitcoin";
for ( i = network_types; ; v1 = *i )
{
if ( !strcmp(s1, v1) )
return i;
i += 4;
if ( i == (char **)&unk_520 )
break;
}
return 0LL;
}

original_code:
const struct BitcoinNetworkType *Bitcoin_GetNetworkTypeByName(const char *name)
{
 const struct BitcoinNetworkType *pn = network_types;
 while (pn != network_types + (sizeof(network_types)/sizeof(network_types[0]))) {
  if (strcmp(name, pn->name) == 0) {
   return pn;
  }
  pn++;
 }
 return ((void *)0);
}

canonical_original_code:
struct BitcoinNetworkType *Bitcoin_GetNetworkTypeByName(char *name)
{
 struct BitcoinNetworkType *pn = network_types;
 while (pn != network_types + (sizeof(network_types)/sizeof(network_types[0]))) {
  if (strcmp(name, pn->name) == 0) {
   return pn;
  }
  pn++;
 }
 return ((void *)0);
}

variable_types:
name
char *

return_type: struct BitcoinNetworkType { char *name; char *hrp; unsigned int public_key_prefix; } *


decompiled_code:
char **__fastcall Bitcoin_GetNetworkTypeByHrp(char *s1)
{
const char *v1; // rsi
char **i; // r12

v1 = "bc";
for ( i = network_types; ; v1 = i[1] )
{
if ( !strcmp(s1, v1) )
return i;
i += 4;
if ( i == (char **)&unk_520 )
break;
}
return 0LL;
}

canonical_decompiled_code:
char **__fastcall func3(char *s1)
{
const char *v1; // rsi
char **i; // r12

v1 = "bc";
for ( i = network_types; ; v1 = i[1] )
{
if ( !strcmp(s1, v1) )
return i;
i += 4;
if ( i == (char **)&unk_520 )
break;
}
return 0LL;
}

original_code:
const struct BitcoinNetworkType *Bitcoin_GetNetworkTypeByHrp(const char *hrp)
{
 const struct BitcoinNetworkType *pn = network_types;
 while (pn != network_types + (sizeof(network_types)/sizeof(network_types[0]))) {
  if (strcmp(hrp, pn->hrp) == 0) {
   return pn;
  }
  pn++;
 }
 return ((void *)0);
}

canonical_original_code:
struct BitcoinNetworkType *Bitcoin_GetNetworkTypeByHrp(char *hrp)
{
 struct BitcoinNetworkType *pn = network_types;
 while (pn != network_types + (sizeof(network_types)/sizeof(network_types[0]))) {
  if (strcmp(hrp, pn->hrp) == 0) {
   return pn;
  }
  pn++;
 }
 return ((void *)0);
}

variable_types:
hrp
char *


decompiled_code:
char **__fastcall Bitcoin_GetNetworkTypeByPrivateKeyPrefix(int a1)
{
int v1; // edx
char **result; // rax

v1 = 128;
result = network_types;
while ( a1 != v1 )
{
result += 4;
if ( result == (char **)&unk_520 )
return 0LL;
v1 = *((_DWORD *)result + 6);
}
return result;
}

canonical_decompiled_code:
char **__fastcall func4(int a1)
{
int v1; // edx
char **result; // rax

v1 = 128;
result = network_types;
while ( a1 != v1 )
{
result += 4;
if ( result == (char **)&unk_520 )
return 0LL;
v1 = *((_DWORD *)result + 6);
}
return result;
}

original_code:
const struct BitcoinNetworkType *Bitcoin_GetNetworkTypeByPrivateKeyPrefix(const BitcoinKeyPrefix prefix)
{
 const struct BitcoinNetworkType *pn = network_types;
 while (pn != network_types + (sizeof(network_types)/sizeof(network_types[0]))) {
  if (prefix == pn->private_key_prefix) {
   return pn;
  }
  pn++;
 }
 return ((void *)0);
}

canonical_original_code:
struct BitcoinNetworkType *Bitcoin_GetNetworkTypeByPrivateKeyPrefix(unsigned int prefix)
{
 struct BitcoinNetworkType *pn = network_types;
 while (pn != network_types + (sizeof(network_types)/sizeof(network_types[0]))) {
  if (prefix == pn->private_key_prefix) {
   return pn;
  }
  pn++;
 }
 return ((void *)0);
}

variable_types:
prefix
unsigned int


decompiled_code:
__int64 __fastcall Bitcoin_SHA256(__int64 a1, __int64 a2, __int64 a3)
{
_BYTE v5[136]; // [rsp+0h] [rbp-88h] BYREF

SHA256_Init(v5);
SHA256_Update(v5, a2, a3);
return SHA256_Final(a1, v5);
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, __int64 a3)
{
_BYTE v5[136]; // [rsp+0h] [rbp-88h] BYREF

SHA256_Init(v5);
SHA256_Update(v5, a2, a3);
return SHA256_Final(a1, v5);
}

original_code:
void Bitcoin_SHA256(struct BitcoinSHA256 *output, const void *input, size_t size)
{
 SHA256_CTX ctx;
 SHA256_Init(&ctx);
 SHA256_Update(&ctx, input, size);
 SHA256_Final(output->data, &ctx);
}

canonical_original_code:
void Bitcoin_SHA256(struct BitcoinSHA256 *output, void *input, unsigned long size)
{
 struct SHA256state_st ctx;
 SHA256_Init(&ctx);
 SHA256_Update(&ctx, input, size);
 SHA256_Final(output->data, &ctx);
}

variable_types: struct BitcoinSHA256 { unsigned char data[-1]; } *

variable_types:
input
void *

variable_types:
size
unsigned long

variable_types: struct SHA256state_st { unsigned int h[8]; unsigned int Nl; unsigned int data[16]; unsigned int num; }

return_type: void


decompiled_code:
__int64 __fastcall Bitcoin_DoubleSHA256(__int64 a1, __int64 a2, __int64 a3)
{
_BYTE v5[32]; // [rsp+0h] [rbp-A8h] BYREF
char v6[136]; // [rsp+20h] [rbp-88h] BYREF

SHA256_Init(v6);
SHA256_Update(v6, a2, a3);
SHA256_Final(v5, v6);
SHA256_Init(v6);
SHA256_Update(v6, v5, 32LL);
return SHA256_Final(a1, v6);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, __int64 a3)
{
_BYTE v5[32]; // [rsp+0h] [rbp-A8h] BYREF
char v6[136]; // [rsp+20h] [rbp-88h] BYREF

SHA256_Init(v6);
SHA256_Update(v6, a2, a3);
SHA256_Final(v5, v6);
SHA256_Init(v6);
SHA256_Update(v6, v5, 32LL);
return SHA256_Final(a1, v6);
}

original_code:
void Bitcoin_DoubleSHA256(struct BitcoinSHA256 *output, const void *input, size_t size)
{
 struct BitcoinSHA256 round1;
 SHA256_CTX ctx;
 SHA256_Init(&ctx);
 SHA256_Update(&ctx, input, size);
 SHA256_Final(round1.data, &ctx);
 SHA256_Init(&ctx);
 SHA256_Update(&ctx, &round1.data, (32));
 SHA256_Final(output->data, &ctx);
}

canonical_original_code:
void Bitcoin_DoubleSHA256(struct BitcoinSHA256 *output, void *input, unsigned long size)
{
 struct BitcoinSHA256 round1;
 struct SHA256state_st ctx;
 SHA256_Init(&ctx);
 SHA256_Update(&ctx, input, size);
 SHA256_Final(round1.data, &ctx);
 SHA256_Init(&ctx);
 SHA256_Update(&ctx, &round1.data, (32));
 SHA256_Final(output->data, &ctx);
}

variable_types: struct BitcoinSHA256 { unsigned char data[-1]; }

user_defined_types: struct SHA256state_st { unsigned int h[8]; unsigned int Nl; unsigned int data[16]; unsigned int num; }


decompiled_code:
__int64 __fastcall Bitcoin_RIPEMD160(__int64 a1, __int64 a2, __int64 a3)
{
_BYTE v5[120]; // [rsp+0h] [rbp-78h] BYREF

RIPEMD160_Init(v5);
RIPEMD160_Update(v5, a2, a3);
return RIPEMD160_Final(a1, v5);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, __int64 a3)
{
_BYTE v5[120]; // [rsp+0h] [rbp-78h] BYREF

RIPEMD160_Init(v5);
RIPEMD160_Update(v5, a2, a3);
return RIPEMD160_Final(a1, v5);
}

original_code:
void Bitcoin_RIPEMD160(struct BitcoinRIPEMD160 *output, const void *input, size_t size)
{
 RIPEMD160_CTX ctx;
 RIPEMD160_Init(&ctx);
 RIPEMD160_Update(&ctx, input, size);
 RIPEMD160_Final(output->data, &ctx);
}

canonical_original_code:
void Bitcoin_RIPEMD160(struct BitcoinRIPEMD160 *output, void *input, unsigned long size)
{
 struct RIPEMD160state_st ctx;
 RIPEMD160_Init(&ctx);
 RIPEMD160_Update(&ctx, input, size);
 RIPEMD160_Final(output->data, &ctx);
}

variable_types: struct BitcoinRIPEMD160 { unsigned char data[-1]; } *

variable_types: struct RIPEMD160state_st { unsigned int A; unsigned int Nl; unsigned int data[-1]; unsigned int num; }


decompiled_code:
char *__fastcall Combination_create(__int64 a1, int a2, int a3)
{
char *v3; // rbx
char *result; // rax
_DWORD *v5; // rdx

v3 = (char *)a3;
*(_DWORD *)a1 = a2;
*(_DWORD *)(a1 + 4) = a3;
result = (char *)malloc(4LL * a3);
*(_QWORD *)(a1 + 8) = result;
if ( (int)v3 > 0 )
{
v5 = result;
for ( result = 0LL; result != v3; ++result )
v5[(_QWORD)result] = (_DWORD)result;
}
return result;
}

canonical_decompiled_code:
char *__fastcall func0(__int64 a1, int a2, int a3)
{
char *v3; // rbx
char *result; // rax
_DWORD *v5; // rdx

v3 = (char *)a3;
*(_DWORD *)a1 = a2;
*(_DWORD *)(a1 + 4) = a3;
result = (char *)malloc(4LL * a3);
*(_QWORD *)(a1 + 8) = result;
if ( (int)v3 > 0 )
{
v5 = result;
for ( result = 0LL; result != v3; ++result )
v5[(_QWORD)result] = (_DWORD)result;
}
return result;
}

original_code:
void Combination_create(struct Combination *c, int n, int r)
{
 int i;
 c->n = n;
 c->r = r;
 c->k = malloc(sizeof(*c->k) * r);
 for (i=0; i < r; i++) {
  c->k[i] = i;
 }
}

variable_types: struct Combination { int n; int r; int *k; } *

variable_types: n int

variable_types: r int

variable_types: i int


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

canonical_decompiled_code:
void __fastcall func1(__int64 a1)
{
free(*(void **)(a1 + 8));
}

original_code:
void Combination_destroy(struct Combination *c)
{
 free(c->k);
}

user_defined_types: struct Combination { int n; int r; int *k; }


original_code:
int Combination_next(struct Combination *c)
{
 int i, j;
 for (i=c->r-1; i >= 0; i--) {
  c->k[i]++;
  for (j=i+1; j<c->r; j++) c->k[j] = c->k[j-1]+1;
  if (c->k[c->r-1] != c->n) break;
  if (!i) return 0;
 }
 return 1;
}

canonical_original_code:
int Combination_next(struct Combination *c)
{
 int i; int j;
 for (i=c->r-1; i >= 0; i--) {
  c->k[i]++;
  for (j=i+1; j<c->r; j++) c->k[j] = c->k[j-1]+1;
  if (c->k[c->r-1] != c->n) break;
  if (!i) return 0;
 }
 return 1;
}

variable_types: j int

return_type: int


decompiled_code:
__int64 __fastcall Bitcoin_EncodeBase58Check(_BYTE *a1, __int64 a2, _QWORD *a3, const void *a4, size_t a5)
{
char *v8; // rbp
__int64 v10; // [rsp+8h] [rbp-60h]
int v11[22]; // [rsp+10h] [rbp-58h] BYREF

v10 = a5 + 4;
v8 = (char *)malloc(a5 + 4);
Bitcoin_DoubleSHA256(v11, a4, a5);
memcpy(v8, a4, a5);
*(_DWORD *)&v8[a5] = v11[0];
LODWORD(a4) = Bitcoin_EncodeBase58(a1, a2, a3, v8, v10);
free(v8);
return (unsigned int)a4;
}

canonical_decompiled_code:
__int64 __fastcall func1(_BYTE *a1, __int64 a2, _QWORD *a3, const void *a4, size_t a5)
{
char *v8; // rbp
__int64 v10; // [rsp+8h] [rbp-60h]
int v11[22]; // [rsp+10h] [rbp-58h] BYREF

v10 = a5 + 4;
v8 = (char *)malloc(a5 + 4);
Bitcoin_DoubleSHA256(v11, a4, a5);
memcpy(v8, a4, a5);
*(_DWORD *)&v8[a5] = v11[0];
LODWORD(a4) = func0(a1, a2, a3, v8, v10);
free(v8);
return (unsigned int)a4;
}

original_code:
BitcoinResult Bitcoin_EncodeBase58Check(
 char *output, size_t output_size, size_t *encoded_output_size,
 const void *source, size_t source_size
)
{
 struct BitcoinSHA256 checksum;
 size_t buffer_size = source_size + 4;
 unsigned char *buffer = malloc(buffer_size);
 BitcoinResult result = 0;
 Bitcoin_DoubleSHA256(&checksum, source, source_size);
 memcpy(buffer, source, source_size);
 memcpy(buffer + source_size, &checksum, 4);
 result = Bitcoin_EncodeBase58(output, output_size, encoded_output_size, buffer, buffer_size);
 free(buffer);
 return result;
}

canonical_original_code:
enum BitcoinResult Bitcoin_EncodeBase58Check(char *output, unsigned long output_size, unsigned long *encoded_output_size, void *source, unsigned long source_size)
{
 struct BitcoinSHA256 checksum;
 unsigned long buffer_size = source_size + 4;
 unsigned char *buffer = malloc(buffer_size);
 enum BitcoinResult result = 0;
 Bitcoin_DoubleSHA256(&checksum, source, source_size);
 memcpy(buffer, source, source_size);
 memcpy(buffer + source_size, &checksum, 4);
 result = Bitcoin_EncodeBase58(output, output_size, encoded_output_size, buffer, buffer_size);
 free(buffer);
 return result;
}

variable_types:
output
char *

variable_types:
source
void *

variable_types:
buffer
unsigned char *

variable_types: enum BitcoinResult { BITCOIN_SUCCESS=0, BITCOIN_ERROR=1, BITCOIN_ERROR_NOT_IMPLEMENTED=2, BITCOIN_ERROR_PRIVATE_KEY_INVALID_FORMAT=3, BITCOIN_ERROR_PUBLIC_KEY_INVALID_FORMAT=4, BITCOIN_ERROR_OUTPUT_BUFFER_TOO_SMALL=5, BITCOIN_ERROR_CHECKSUM_FAILURE=6, BITCOIN_ERROR_INVALID_FORMAT=7, BITCOIN_ERROR_IMPOSSIBLE_CONVERSION=8, BITCOIN_ERROR_FILE=9, BITCOIN_ERROR_LIBRARY_FAILURE=10, BITCOIN_ERROR_END_OF_FILE=11 }

user_defined_types: struct BitcoinSHA256 { unsigned char data[-1]; }


decompiled_code:
__int64 __fastcall Bitcoin_DecodeBase58Check(char *a1, size_t a2, _QWORD *a3, _BYTE *a4, __int64 a5)
{
unsigned int v6; // er12
__int64 v8; // [rsp+8h] [rbp-40h] BYREF
int v9[14]; // [rsp+10h] [rbp-38h] BYREF

v6 = Bitcoin_DecodeBase58(a1, a2, &v8, a4, a5);
if ( v6 )
return v6;
Bitcoin_DoubleSHA256(v9, a1, v8 - 4);
if ( v9[0] != *(_DWORD *)&a1[v8 - 4] )
return 6LL;
*a3 = v8 - 4;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *a1, size_t a2, _QWORD *a3, _BYTE *a4, __int64 a5)
{
unsigned int v6; // er12
__int64 v8; // [rsp+8h] [rbp-40h] BYREF
int v9[14]; // [rsp+10h] [rbp-38h] BYREF

v6 = func2(a1, a2, &v8, a4, a5);
if ( v6 )
return v6;
Bitcoin_DoubleSHA256(v9, a1, v8 - 4);
if ( v9[0] != *(_DWORD *)&a1[v8 - 4] )
return 6LL;
*a3 = v8 - 4;
return 0LL;
}

original_code:
BitcoinResult Bitcoin_DecodeBase58Check(
 uint8_t *output, size_t output_buffer_size, size_t *decoded_output_size,
 const void *input, size_t input_size
)
{
 struct BitcoinSHA256 hash;
 size_t temp_decoded_output_size;
 BitcoinResult result = Bitcoin_DecodeBase58(
  output, output_buffer_size, &temp_decoded_output_size,
  input, input_size
 );
 if (result != BITCOIN_SUCCESS) {
  return result;
 }
 Bitcoin_DoubleSHA256(&hash, output,
  temp_decoded_output_size - 4
 );
 if (memcmp(hash.data
  ,output + temp_decoded_output_size - 4
  ,4)
 ) {
  return BITCOIN_ERROR_CHECKSUM_FAILURE;
 }
 *decoded_output_size = temp_decoded_output_size -
  4;
 return BITCOIN_SUCCESS;
}

canonical_original_code:
enum BitcoinResult Bitcoin_DecodeBase58Check(unsigned char *output, unsigned long output_buffer_size, unsigned long *decoded_output_size, void *input, unsigned long input_size)
{
 struct BitcoinSHA256 hash;
 unsigned long temp_decoded_output_size;
 enum BitcoinResult result = Bitcoin_DecodeBase58(
  output, output_buffer_size, &temp_decoded_output_size,
  input, input_size
 );
 if (result != BITCOIN_SUCCESS) {
  return result;
 }
 Bitcoin_DoubleSHA256(&hash, output,
  temp_decoded_output_size - 4
 );
 if (memcmp(hash.data
  ,output + temp_decoded_output_size - 4
  ,4)
 ) {
  return BITCOIN_ERROR_CHECKSUM_FAILURE;
 }
 *decoded_output_size = temp_decoded_output_size -
  4;
 return BITCOIN_SUCCESS;
}

variable_types:
output
unsigned char *

return_type: enum BitcoinResult { BITCOIN_SUCCESS=0, BITCOIN_ERROR=1, BITCOIN_ERROR_NOT_IMPLEMENTED=2, BITCOIN_ERROR_PRIVATE_KEY_INVALID_FORMAT=3, BITCOIN_ERROR_PUBLIC_KEY_INVALID_FORMAT=4, BITCOIN_ERROR_OUTPUT_BUFFER_TOO_SMALL=5, BITCOIN_ERROR_CHECKSUM_FAILURE=6, BITCOIN_ERROR_INVALID_FORMAT=7, BITCOIN_ERROR_IMPOSSIBLE_CONVERSION=8, BITCOIN_ERROR_FILE=9, BITCOIN_ERROR_LIBRARY_FAILURE=10, BITCOIN_ERROR_END_OF_FILE=11 }


decompiled_code:
__int64 __fastcall Bitcoin_FixBase58Check(void *src, __int64 a2, size_t *a3, char *a4, size_t a5, _QWORD *a6, void *srca, size_t n, int a9, int a10, int a11)
{
size_t v12; // rbx
void *v13; // rdi
void *v14; // rbp
unsigned int v15; // ebx
const char *v16; // r8
unsigned int v17; // er13
_BYTE *v18; // r14
_BYTE *v19; // r15
__int64 v20; // rsi
__int64 v21; // rax
__int64 v22; // rdx
const char *v23; // rsi
int v24; // eax
int v25; // er8
__int64 v26; // rdx
__int64 v27; // rcx
_BOOL4 v28; // edi
unsigned int v29; // eax
__int64 v30; // rax
__int64 v31; // rdx
int v32; // eax
void *v33; // r13
double v34; // xmm0_8
double v36; // xmm0_8
double v37; // xmm0_8
__int64 v41; // [rsp+20h] [rbp-78h]
size_t v43; // [rsp+30h] [rbp-68h]
size_t v44; // [rsp+30h] [rbp-68h]
char v45[8]; // [rsp+50h] [rbp-48h] BYREF
__int64 v46; // [rsp+58h] [rbp-40h]

v12 = a2 + (unsigned int)a11;
if ( a9 != 1 )
{
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
"up to ",
(unsigned int)a9,
"s");
if ( v12 >= n )
{
v13 = malloc(v12 + 1);
v14 = v13;
*a3 = n;
if ( !a9 )
{
free(v13);
v37 = 0.0;
v41 = 0LL;
goto LABEL_42;
}
goto LABEL_4;
}
LABEL_38:
applog(
4LL,
"Bitcoin_FixBase58Check",
"output buffer is not large enough (%u) to store changed input text (%u)",
(unsigned int)n,
(unsigned int)v12);
return 5LL;
}
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
(const char *)&unk_AF3,
1LL,
(const char *)&unk_AF3);
if ( v12 < n )
goto LABEL_38;
v14 = malloc(v12 + 1);
*a3 = n;
LABEL_4:
v15 = 0;
v16 = (const char *)&unk_AF3;
v41 = 0LL;
v17 = 1;
v18 = src;
while ( 2 )
{
applog(2LL, "Bitcoin_FixBase58Check", "Changing %d character%s ...", v17, v16);
Combination_create(v45, (unsigned int)n, v17);
v19 = malloc(v17);
while ( 2 )
{
memcpy(v18, srca, n);
memset(v19, 0, v17);
while ( 2 )
{
if ( v17 )
{
v20 = v46;
v21 = 0LL;
do
{
v18[*(int *)(v20 + 4 * v21)] = base58_digits[(char)v19[v21]];
v22 = v21++;
}
while ( v15 != v22 );
v41 += v15 + 1LL;
}
while ( 1 )
{
v23 = (const char *)a5;
if ( !(unsigned int)Bitcoin_DecodeBase58Check(a4, a5, a6, v18, n) )
break;
v24 = (unsigned __int8)*v19;
v25 = 0;
v26 = (unsigned int)(v24 + 1);
*v19 = v24 + 1;
if ( v17 )
goto LABEL_13;
}
memcpy(v14, srca, n);
*((_BYTE *)v14 + n) = 0;
applog(3LL, "Bitcoin_FixBase58Check", "from: %s", (const char *)v14);
v43 = *a3;
memcpy(v14, v18, *a3);
*((_BYTE *)v14 + v43) = 0;
applog(3LL, "Bitcoin_FixBase58Check", " to: %s", (const char *)v14);
v44 = *a3;
memset(v14, 32, *a3);
*((_BYTE *)v14 + v44) = 0;
if ( !v17 )
{
v33 = v19;
applog(3LL, "Bitcoin_FixBase58Check", " %s", (const char *)v14);
++*v19;
LABEL_32:
Combination_destroy(v45);
free(v33);
free(v14);
if ( v41 < 0 )
v34 = (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1))
+ (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1));
else
v34 = (double)(int)v41;
applog(
3LL,
"Bitcoin_FixBase58Check",
"Base58Check input has been corrected after %llu combinations (%f%% chance of error).",
v41,
v34 * 2.328306436538696e-10 * 100.0);
return 0LL;
}
v30 = 0LL;
do
{
v31 = *(int *)(v46 + v30);
v30 += 4LL;
*((_BYTE *)v14 + v31) = 94;
}
while ( 4LL * (v17 - 1) + 4 != v30 );
v23 = "Bitcoin_FixBase58Check";
applog(3LL, "Bitcoin_FixBase58Check", " %s", (const char *)v14);
v32 = (unsigned __int8)*v19;
v25 = 1;
v26 = (unsigned int)(v32 + 1);
*v19 = v32 + 1;
LABEL_13:
v27 = 0LL;
v28 = 0;
v29 = 0;
while ( 1 )
{
++v29;
if ( (_BYTE)v26 == 58 )
break;
if ( v17 <= v29 )
goto LABEL_20;
v26 = (unsigned __int8)v19[v29];
LABEL_16:
++v27;
}
v19[v27] = 0;
v28 = v15 == v27;
if ( v17 > v29 )
{
v23 = &v19[v29];
v26 = (unsigned int)(unsigned __int8)(*v23)++ + 1;
goto LABEL_16;
}
LABEL_20:
if ( !(v25 | v28) )
continue;
break;
}
if ( v25 )
{
v33 = v19;
goto LABEL_32;
}
if ( (unsigned int)Combination_next(v45, v23, v26, v27) )
continue;
break;
}
++v17;
++v15;
Combination_destroy(v45);
free(v19);
if ( a9 >= v17 )
{
v16 = (const char *)&unk_AF3;
if ( v17 != 1 )
v16 = "s";
continue;
}
break;
}
free(v14);
if ( v41 < 0 )
v36 = (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1)) + (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1));
else
v36 = (double)(int)v41;
v37 = v36 * 2.328306436538696e-10 * 100.0;
LABEL_42:
applog(
3LL,
"Bitcoin_FixBase58Check",
"Failed to find any combination of changing the Base58Check input that results in a valid checksum. %llu combinations"
" were tried. (%f%% chance of error).",
v41,
v37);
return 6LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(void *src, __int64 a2, size_t *a3, char *a4, size_t a5, _QWORD *a6, void *srca, size_t n, int a9, int a10, int a11)
{
size_t v12; // rbx
void *v13; // rdi
void *v14; // rbp
unsigned int v15; // ebx
const char *v16; // r8
unsigned int v17; // er13
_BYTE *v18; // r14
_BYTE *v19; // r15
__int64 v20; // rsi
__int64 v21; // rax
__int64 v22; // rdx
const char *v23; // rsi
int v24; // eax
int v25; // er8
__int64 v26; // rdx
__int64 v27; // rcx
_BOOL4 v28; // edi
unsigned int v29; // eax
__int64 v30; // rax
__int64 v31; // rdx
int v32; // eax
void *v33; // r13
double v34; // xmm0_8
double v36; // xmm0_8
double v37; // xmm0_8
__int64 v41; // [rsp+20h] [rbp-78h]
size_t v43; // [rsp+30h] [rbp-68h]
size_t v44; // [rsp+30h] [rbp-68h]
char v45[8]; // [rsp+50h] [rbp-48h] BYREF
__int64 v46; // [rsp+58h] [rbp-40h]

v12 = a2 + (unsigned int)a11;
if ( a9 != 1 )
{
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
"up to ",
(unsigned int)a9,
"s");
if ( v12 >= n )
{
v13 = malloc(v12 + 1);
v14 = v13;
*a3 = n;
if ( !a9 )
{
free(v13);
v37 = 0.0;
v41 = 0LL;
goto LABEL_42;
}
goto LABEL_4;
}
LABEL_38:
applog(
4LL,
"Bitcoin_FixBase58Check",
"output buffer is not large enough (%u) to store changed input text (%u)",
(unsigned int)n,
(unsigned int)v12);
return 5LL;
}
applog(
2LL,
"Bitcoin_FixBase58Check",
"Attempting to fix Base58Check input by changing %s%d character%s ...",
(const char *)&unk_AF3,
1LL,
(const char *)&unk_AF3);
if ( v12 < n )
goto LABEL_38;
v14 = malloc(v12 + 1);
*a3 = n;
LABEL_4:
v15 = 0;
v16 = (const char *)&unk_AF3;
v41 = 0LL;
v17 = 1;
v18 = src;
while ( 2 )
{
applog(2LL, "Bitcoin_FixBase58Check", "Changing %d character%s ...", v17, v16);
Combination_create(v45, (unsigned int)n, v17);
v19 = malloc(v17);
while ( 2 )
{
memcpy(v18, srca, n);
memset(v19, 0, v17);
while ( 2 )
{
if ( v17 )
{
v20 = v46;
v21 = 0LL;
do
{
v18[*(int *)(v20 + 4 * v21)] = base58_digits[(char)v19[v21]];
v22 = v21++;
}
while ( v15 != v22 );
v41 += v15 + 1LL;
}
while ( 1 )
{
v23 = (const char *)a5;
if ( !(unsigned int)func3(a4, a5, a6, v18, n) )
break;
v24 = (unsigned __int8)*v19;
v25 = 0;
v26 = (unsigned int)(v24 + 1);
*v19 = v24 + 1;
if ( v17 )
goto LABEL_13;
}
memcpy(v14, srca, n);
*((_BYTE *)v14 + n) = 0;
applog(3LL, "Bitcoin_FixBase58Check", "from: %s", (const char *)v14);
v43 = *a3;
memcpy(v14, v18, *a3);
*((_BYTE *)v14 + v43) = 0;
applog(3LL, "Bitcoin_FixBase58Check", " to: %s", (const char *)v14);
v44 = *a3;
memset(v14, 32, *a3);
*((_BYTE *)v14 + v44) = 0;
if ( !v17 )
{
v33 = v19;
applog(3LL, "Bitcoin_FixBase58Check", " %s", (const char *)v14);
++*v19;
LABEL_32:
Combination_destroy(v45);
free(v33);
free(v14);
if ( v41 < 0 )
v34 = (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1))
+ (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1));
else
v34 = (double)(int)v41;
applog(
3LL,
"Bitcoin_FixBase58Check",
"Base58Check input has been corrected after %llu combinations (%f%% chance of error).",
v41,
v34 * 2.328306436538696e-10 * 100.0);
return 0LL;
}
v30 = 0LL;
do
{
v31 = *(int *)(v46 + v30);
v30 += 4LL;
*((_BYTE *)v14 + v31) = 94;
}
while ( 4LL * (v17 - 1) + 4 != v30 );
v23 = "Bitcoin_FixBase58Check";
applog(3LL, "Bitcoin_FixBase58Check", " %s", (const char *)v14);
v32 = (unsigned __int8)*v19;
v25 = 1;
v26 = (unsigned int)(v32 + 1);
*v19 = v32 + 1;
LABEL_13:
v27 = 0LL;
v28 = 0;
v29 = 0;
while ( 1 )
{
++v29;
if ( (_BYTE)v26 == 58 )
break;
if ( v17 <= v29 )
goto LABEL_20;
v26 = (unsigned __int8)v19[v29];
LABEL_16:
++v27;
}
v19[v27] = 0;
v28 = v15 == v27;
if ( v17 > v29 )
{
v23 = &v19[v29];
v26 = (unsigned int)(unsigned __int8)(*v23)++ + 1;
goto LABEL_16;
}
LABEL_20:
if ( !(v25 | v28) )
continue;
break;
}
if ( v25 )
{
v33 = v19;
goto LABEL_32;
}
if ( (unsigned int)Combination_next(v45, v23, v26, v27) )
continue;
break;
}
++v17;
++v15;
Combination_destroy(v45);
free(v19);
if ( a9 >= v17 )
{
v16 = (const char *)&unk_AF3;
if ( v17 != 1 )
v16 = "s";
continue;
}
break;
}
free(v14);
if ( v41 < 0 )
v36 = (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1)) + (double)(int)(v41 & 1 | ((unsigned __int64)v41 >> 1));
else
v36 = (double)(int)v41;
v37 = v36 * 2.328306436538696e-10 * 100.0;
LABEL_42:
applog(
3LL,
"Bitcoin_FixBase58Check",
"Failed to find any combination of changing the Base58Check input that results in a valid checksum. %llu combinations"
" were tried. (%f%% chance of error).",
v41,
v37);
return 6LL;
}

original_code:
BitcoinResult Bitcoin_FixBase58Check(
 char *fixed_output, size_t fixed_output_buffer_size, size_t *fixed_output_size,
 uint8_t *output, size_t output_buffer_size, size_t *decoded_output_size,
 const char *input, size_t input_size,
 unsigned change_chars,
 unsigned remove_chars,
 unsigned insert_chars
)
{
 uint64_t change_count = 0;
 size_t required_fixed_output_size = fixed_output_buffer_size + insert_chars;
 BitcoinResult result;
 static const unsigned radix = 58;
 unsigned i, j, overflow;
 char *format_output = ((void *)0);
 struct Combination c;
 unsigned n, r, done = 0;
 char *digits;
 applog(APPLOG_NOTICE, __func__,
  "Attempting to fix Base58Check input by changing %s%d character%s ...",
  change_chars == 1 ? "" : "up to ",
  (int)change_chars,
  change_chars == 1 ? "" : "s"
 );
 if (required_fixed_output_size < input_size) {
  applog(APPLOG_ERROR, __func__,
   "output buffer is not large enough (%u) to store changed"
   " input text (%u)",
   (unsigned)input_size,
   (unsigned)required_fixed_output_size
  );
  return BITCOIN_ERROR_OUTPUT_BUFFER_TOO_SMALL;
 }
 format_output = malloc(required_fixed_output_size + 1);
 *fixed_output_size = input_size;
 for (r = 1; r <= change_chars && !done; r++) {
  applog(APPLOG_NOTICE, __func__,
   "Changing %d character%s ...",
   r,
   r == 1 ? "" : "s"
  );
  n = input_size;
  Combination_create(&c, n, r);
  digits = malloc(r);
  do {
   memcpy(fixed_output, input, input_size);
   memset(digits, 0, r);
   overflow = 0;
   while (!overflow && !done) {
    int carry = 0;
    for (i=0; i < r; i++) {
     fixed_output[c.k[i]] = base58_digits[(int)digits[i]];
     change_count++;
    }
    result = Bitcoin_DecodeBase58Check(output, output_buffer_size,
     decoded_output_size, fixed_output, input_size
    );
    if (result == BITCOIN_SUCCESS) {
     memcpy(format_output, input, input_size);
     format_output[input_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "from: %s", format_output
     );
     memcpy(format_output, fixed_output, *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "  to: %s", format_output
     );
     memset(format_output, ' ', *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     for (j=0; j < r; j++) {
      format_output[c.k[j]] = '^';
     }
     applog(APPLOG_WARNING, __func__,
      "      %s", format_output
     );
     done = 1;
    }
    digits[0]++;
    for (i=0; i < r; i++) {
     if (carry) {
      digits[i] += carry;
      carry = 0;
     }
     if (digits[i] == radix) {
      digits[i] = 0;
      carry = 1;
      overflow = i == r-1;
     } else {
      carry = 0;
     }
    }
   }
  } while (!done && Combination_next(&c));
  Combination_destroy(&c);
  free(digits);
 }
 free(format_output);
 if (!done) {
  applog(APPLOG_WARNING, __func__,
   "Failed to find any combination of changing the Base58Check input"
   " that results in a valid checksum. %llu combinations were tried."
   " (%f%% chance of error).",
   (long long unsigned)change_count,
   ((double)change_count / ((unsigned long long)1 << 32)) * 100
  );
  return BITCOIN_ERROR_CHECKSUM_FAILURE;
 }
 applog(APPLOG_WARNING, __func__,
  "Base58Check input has been corrected after %llu combinations "
  " (%f%% chance of error).",
  (long long unsigned)change_count,
  ((double)change_count / ((unsigned long long)1 << 32)) * 100
 );
 return BITCOIN_SUCCESS;
}

canonical_original_code:
enum BitcoinResult Bitcoin_FixBase58Check(char *fixed_output, unsigned long fixed_output_buffer_size, unsigned long *fixed_output_size, unsigned char *output, unsigned long output_buffer_size, unsigned long *decoded_output_size, char *input, unsigned long input_size, unsigned int change_chars, unsigned int remove_chars, unsigned int insert_chars)
{
 unsigned long change_count = 0;
 unsigned long required_fixed_output_size = fixed_output_buffer_size + insert_chars;
 enum BitcoinResult result;
 static unsigned int radix = 58;
 unsigned int i; unsigned int j; unsigned int overflow;
 char *format_output = ((void *)0);
 struct Combination c;
 unsigned int n; unsigned int r; unsigned int done = 0;
 char *digits;
 applog(APPLOG_NOTICE, __func__,
  "Attempting to fix Base58Check input by changing %s%d character%s ...",
  change_chars == 1 ? "" : "up to ",
  (int)change_chars,
  change_chars == 1 ? "" : "s"
 );
 if (required_fixed_output_size < input_size) {
  applog(APPLOG_ERROR, __func__,
   "output buffer is not large enough (%u) to store changed"
   " input text (%u)",
   (unsigned int)input_size,
   (unsigned int)required_fixed_output_size
  );
  return BITCOIN_ERROR_OUTPUT_BUFFER_TOO_SMALL;
 }
 format_output = malloc(required_fixed_output_size + 1);
 *fixed_output_size = input_size;
 for (r = 1; r <= change_chars && !done; r++) {
  applog(APPLOG_NOTICE, __func__,
   "Changing %d character%s ...",
   r,
   r == 1 ? "" : "s"
  );
  n = input_size;
  Combination_create(&c, n, r);
  digits = malloc(r);
  do {
   memcpy(fixed_output, input, input_size);
   memset(digits, 0, r);
   overflow = 0;
   while (!overflow && !done) {
    int carry = 0;
    for (i=0; i < r; i++) {
     fixed_output[c.k[i]] = base58_digits[(int)digits[i]];
     change_count++;
    }
    result = Bitcoin_DecodeBase58Check(output, output_buffer_size,
     decoded_output_size, fixed_output, input_size
    );
    if (result == BITCOIN_SUCCESS) {
     memcpy(format_output, input, input_size);
     format_output[input_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "from: %s", format_output
     );
     memcpy(format_output, fixed_output, *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     applog(APPLOG_WARNING, __func__,
      "  to: %s", format_output
     );
     memset(format_output, ' ', *fixed_output_size);
     format_output[*fixed_output_size] = '\0';
     for (j=0; j < r; j++) {
      format_output[c.k[j]] = '^';
     }
     applog(APPLOG_WARNING, __func__,
      "      %s", format_output
     );
     done = 1;
    }
    digits[0]++;
    for (i=0; i < r; i++) {
     if (carry) {
      digits[i] += carry;
      carry = 0;
     }
     if (digits[i] == radix) {
      digits[i] = 0;
      carry = 1;
      overflow = i == r-1;
     } else {
      carry = 0;
     }
    }
   }
  } while (!done && Combination_next(&c));
  Combination_destroy(&c);
  free(digits);
 }
 free(format_output);
 if (!done) {
  applog(APPLOG_WARNING, __func__,
   "Failed to find any combination of changing the Base58Check input"
   " that results in a valid checksum. %llu combinations were tried."
   " (%f%% chance of error).",
   (unsigned long long)change_count,
   ((double)change_count / ((unsigned long long)1 << 32)) * 100
  );
  return BITCOIN_ERROR_CHECKSUM_FAILURE;
 }
 applog(APPLOG_WARNING, __func__,
  "Base58Check input has been corrected after %llu combinations "
  " (%f%% chance of error).",
  (unsigned long long)change_count,
  ((double)change_count / ((unsigned long long)1 << 32)) * 100
 );
 return BITCOIN_SUCCESS;
}

variable_types:
input
char *

variable_types:
radix
unsigned int

variable_types:
i
unsigned int

variable_types:
j
unsigned int

variable_types:
overflow
unsigned int

variable_types: struct Combination { int n; int r; int *k; }

variable_types:
n
unsigned int

variable_types:
r
unsigned int

variable_types:
done
unsigned int

variable_types:
digits
char *

variable_types: carry int

user_defined_types: enum BitcoinResult { BITCOIN_SUCCESS=0, BITCOIN_ERROR=1, BITCOIN_ERROR_NOT_IMPLEMENTED=2, BITCOIN_ERROR_PRIVATE_KEY_INVALID_FORMAT=3, BITCOIN_ERROR_PUBLIC_KEY_INVALID_FORMAT=4, BITCOIN_ERROR_OUTPUT_BUFFER_TOO_SMALL=5, BITCOIN_ERROR_CHECKSUM_FAILURE=6, BITCOIN_ERROR_INVALID_FORMAT=7, BITCOIN_ERROR_IMPOSSIBLE_CONVERSION=8, BITCOIN_ERROR_FILE=9, BITCOIN_ERROR_LIBRARY_FAILURE=10, BITCOIN_ERROR_END_OF_FILE=11 }


repo: matlo/GIMX

decompiled_code:
__int64 __fastcall button2event(__int64 (__fastcall *a1)(_BYTE *), _BYTE *a2, __int16 a3, unsigned __int16 a4, unsigned __int16 a5, char a6)
{
__int16 v6; // dx
__int64 result; // rax

v6 = a5 & a3;
result = (__int64)a1;
if ( (a4 & a5) != v6 )
{
a2[2] = a6;
*a2 = (v6 == 0) + 8;
result = a1(a2);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 (__fastcall *a1)(_BYTE *), _BYTE *a2, __int16 a3, unsigned __int16 a4, unsigned __int16 a5, char a6)
{
__int16 v6; // dx
__int64 result; // rax

v6 = a5 & a3;
result = (__int64)a1;
if ( (a4 & a5) != v6 )
{
a2[2] = a6;
*a2 = (v6 == 0) + 8;
result = a1(a2);
}
return result;
}

original_code:
static inline void button2event(int (*callback)(GE_Event*), GE_Event* event, unsigned short buttons,
    unsigned short pbuttons, unsigned short button_mask, uint8_t button_id)
{
  unsigned short value;
  if((value = (buttons & button_mask)) ^ (pbuttons & button_mask))
  {
    event->type = value ? GE_JOYBUTTONDOWN : GE_JOYBUTTONUP;
    event->jbutton.button = button_id;
    callback(event);
  }
}

canonical_original_code:
static inline void button2event(int (*callback)(union GE_Event *), union GE_Event *event, unsigned short buttons, unsigned short pbuttons, unsigned short button_mask, unsigned char button_id)
{
  unsigned short value;
  if((value = (buttons & button_mask)) ^ (pbuttons & button_mask))
  {
    event->type = value ? GE_JOYBUTTONDOWN : GE_JOYBUTTONUP;
    event->jbutton.button = button_id;
    callback(event);
  }
}

variable_types: int (*)(union GE_Event { struct { unsigned char type; unsigned char which; }; struct GE_KeyboardEvent { unsigned char type; unsigned char which; unsigned short keysym; } key; struct GE_MouseMotionEvent { unsigned char type; unsigned char which; short xrel; short yrel; } motion; struct GE_MouseButtonEvent { unsigned char type; unsigned char which; unsigned char button; } button; struct GE_JoyAxisEvent { unsigned char type; unsigned char which; unsigned char axis; short value; } jaxis; struct GE_JoyHatEvent { unsigned char type; unsigned char which; unsigned char hat; unsigned char value; } jhat; struct GE_JoyButtonEvent { unsigned char type; unsigned char which; unsigned char button; unsigned char state; } jbutton; struct GE_JoyRumbleEvent { unsigned char type; unsigned char which; unsigned short weak; unsigned short strong; } jrumble; struct GE_JoyConstantForceEvent { unsigned char type; unsigned char which; short level; } jconstant; struct GE_JoyConditionForceEvent { unsigned char type; unsigned char which; struct { unsigned short left; unsigned short right; } saturation; struct { short left; short right; } coefficient; short center; unsigned short deadband; } jcondition; struct GE_JoyPeriodicForceEvent { unsigned char type; unsigned char which; struct { int direction; unsigned short period; short magnitude; short offset; } sine; } jperiodic; } *)

variable_types:
event
union GE_Event *

variable_types:
buttons
unsigned short

variable_types:
pbuttons
unsigned short

variable_types:
value
unsigned short

user_defined_types: union GE_Event { struct { unsigned char type; unsigned char which; }; struct GE_KeyboardEvent key; struct GE_MouseMotionEvent motion; struct GE_MouseButtonEvent button; struct GE_JoyAxisEvent jaxis; struct GE_JoyHatEvent jhat; struct GE_JoyButtonEvent jbutton; struct GE_JoyRumbleEvent jrumble; struct GE_JoyConstantForceEvent jconstant; struct GE_JoyConditionForceEvent jcondition; struct GE_JoyPeriodicForceEvent jperiodic; }


original_code:
void xOnePad2event(int adapter_id __attribute__((unused)), s_report* current, s_report* previous,
    int joystick_id, int (*callback)(GE_Event*))
{
  GE_Event event = { .jbutton = { .which = joystick_id } };
  if(current->xone.input.type == 0x20)
  {
    s_report_xone* xone_current = &current->xone;
    s_report_xone* xone_previous = &previous->xone;
    unsigned short buttons = xone_current->input.buttons;
    unsigned short prevButtons = xone_previous->input.buttons;
    button2event(callback, &event, buttons, prevButtons, 0x0100, 11);
    button2event(callback, &event, buttons, prevButtons, 0x0200, 13);
    button2event(callback, &event, buttons, prevButtons, 0x0400, 14);
    button2event(callback, &event, buttons, prevButtons, 0x0800, 12);
    button2event(callback, &event, buttons, prevButtons, 0x0004, 7);
    button2event(callback, &event, buttons, prevButtons, 0x0008, 6);
    button2event(callback, &event, buttons, prevButtons, 0x4000, 9);
    button2event(callback, &event, buttons, prevButtons, 0x8000, 10);
    button2event(callback, &event, buttons, prevButtons, 0x1000, 4);
    button2event(callback, &event, buttons, prevButtons, 0x2000, 5);
    button2event(callback, &event, buttons, prevButtons, 0x0010, 0);
    button2event(callback, &event, buttons, prevButtons, 0x0020, 1);
    button2event(callback, &event, buttons, prevButtons, 0x0040, 2);
    button2event(callback, &event, buttons, prevButtons, 0x0080, 3);
    event.type = GE_JOYAXISMOTION;
    axis2event(callback, &event, xone_current->input.xaxis, xone_previous->input.xaxis, 0, 0);
    axis2event(callback, &event, xone_current->input.yaxis, xone_previous->input.yaxis, 1, 1);
    axis2event(callback, &event, xone_current->input.zaxis, xone_previous->input.zaxis, 0, 3);
    axis2event(callback, &event, xone_current->input.taxis, xone_previous->input.taxis, 1, 4);
    trigger2event(callback, &event, xone_current->input.ltrigger, xone_previous->input.ltrigger, 2);
    trigger2event(callback, &event, xone_current->input.rtrigger, xone_previous->input.rtrigger, 5);
  }
  else if(current->xone.input.type == 0x07)
  {
    s_report_xone* xone_current = &current->xone;
    s_report_xone* xone_previous = &previous->xone;
    unsigned short buttons = xone_current->guide.button;
    unsigned short prevButtons = xone_previous->guide.button;
    button2event(callback, &event, buttons, prevButtons, 0x01, 8);
  }
}

canonical_original_code:
void xOnePad2event(int adapter_id, union s_report *current, union s_report *previous, int joystick_id, int (*callback)(union GE_Event *))
{
  union GE_Event event = { .jbutton = { .which = joystick_id } };
  if(current->xone.input.type == 0x20)
  {
    struct s_report_xone *xone_current = &current->xone;
    struct s_report_xone *xone_previous = &previous->xone;
    unsigned short buttons = xone_current->input.buttons;
    unsigned short prevButtons = xone_previous->input.buttons;
    button2event(callback, &event, buttons, prevButtons, 0x0100, 11);
    button2event(callback, &event, buttons, prevButtons, 0x0200, 13);
    button2event(callback, &event, buttons, prevButtons, 0x0400, 14);
    button2event(callback, &event, buttons, prevButtons, 0x0800, 12);
    button2event(callback, &event, buttons, prevButtons, 0x0004, 7);
    button2event(callback, &event, buttons, prevButtons, 0x0008, 6);
    button2event(callback, &event, buttons, prevButtons, 0x4000, 9);
    button2event(callback, &event, buttons, prevButtons, 0x8000, 10);
    button2event(callback, &event, buttons, prevButtons, 0x1000, 4);
    button2event(callback, &event, buttons, prevButtons, 0x2000, 5);
    button2event(callback, &event, buttons, prevButtons, 0x0010, 0);
    button2event(callback, &event, buttons, prevButtons, 0x0020, 1);
    button2event(callback, &event, buttons, prevButtons, 0x0040, 2);
    button2event(callback, &event, buttons, prevButtons, 0x0080, 3);
    event.type = GE_JOYAXISMOTION;
    axis2event(callback, &event, xone_current->input.xaxis, xone_previous->input.xaxis, 0, 0);
    axis2event(callback, &event, xone_current->input.yaxis, xone_previous->input.yaxis, 1, 1);
    axis2event(callback, &event, xone_current->input.zaxis, xone_previous->input.zaxis, 0, 3);
    axis2event(callback, &event, xone_current->input.taxis, xone_previous->input.taxis, 1, 4);
    trigger2event(callback, &event, xone_current->input.ltrigger, xone_previous->input.ltrigger, 2);
    trigger2event(callback, &event, xone_current->input.rtrigger, xone_previous->input.rtrigger, 5);
  }
  else if(current->xone.input.type == 0x07)
  {
    struct s_report_xone *xone_current = &current->xone;
    struct s_report_xone *xone_previous = &previous->xone;
    unsigned short buttons = xone_current->guide.button;
    unsigned short prevButtons = xone_previous->guide.button;
    button2event(callback, &event, buttons, prevButtons, 0x01, 8);
  }
}

variable_types: union s_report { struct s_report_joystick { short X; short Y; short Z; short Rz; unsigned short Hat; unsigned short Bt; } js; struct s_report_ds2 { unsigned char head; unsigned char Bt1; unsigned char Bt2; char Z; char Rz; char X; char Y; } ds2; struct s_report_ds3 { unsigned char report_id; unsigned char unused1; unsigned char buttons1; unsigned char buttons2; unsigned char buttons3; unsigned char unused2; char X; char Y; char Z; char Rz; unsigned char unknown1[4]; unsigned char up; unsigned char right; unsigned char down; unsigned char left; unsigned char l2; unsigned char r2; unsigned char l1; unsigned char r1; unsigned char triangle; unsigned char circle; unsigned char cross; unsigned char square; unsigned char unknown2[15]; unsigned char acc_x[2]; unsigned char acc_y[2]; unsigned char acc_z[2]; unsigned char gyro[2]; } ds3; struct s_report_ds4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short ButtonsAndCounter; unsigned char Rx; unsigned char Ry; unsigned short _time; unsigned char battery_level; struct s_motion_acc { short x; short y; short z; } motion_acc; struct s_motion_gyro { short roll; short yaw; short pitch; } motion_gyro; unsigned char _unknown1[5]; unsigned char ext; unsigned char _unknown2[2]; unsigned char packets; struct s_trackpad_packet { unsigned char counter; struct s_trackpad_finger { unsigned char id; unsigned char coords[3]; } finger1; struct s_trackpad_finger finger2; } packet1; struct s_trackpad_packet packet2; struct s_trackpad_packet packet3; struct s_trackpad_packet packet4; unsigned char _unknown5[2]; } ds4; struct s_report_xbox { unsigned char type; unsigned char size; unsigned char buttons; unsigned char ununsed2; unsigned char btnA; unsigned char btnB; unsigned char btnX; unsigned char btnY; unsigned char btnBlack; unsigned char btnWhite; unsigned char ltrigger; unsigned char rtrigger; short xaxis; short yaxis; short zaxis; short taxis; } xbox; struct s_report_x360 { unsigned char type; unsigned char size; unsigned short buttons; unsigned char ltrigger; unsigned char rtrigger; short xaxis; short yaxis; short zaxis; short taxis; unsigned char unused[6]; } x360; struct s_report_xone { union { unsigned char type; struct { unsigned char type; unsigned char unknown; unsigned char counter; unsigned char size; unsigned short buttons; unsigned short ltrigger; unsigned short rtrigger; short xaxis; short yaxis; short zaxis; short taxis; } input; struct { unsigned char type; unsigned char unknown1; unsigned char counter; unsigned char size; unsigned char button; unsigned char unknown2; } guide; }; } xone; struct s_report_t300rsPs4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short Buttons; unsigned char unused0[35]; unsigned short wheel; unsigned short gasPedal; unsigned short brakePedal; unsigned short unknown1; unsigned char unknown2; unsigned short unknown3; unsigned char unused1[10]; } t300rsPs4; struct s_report_g27Ps3 { unsigned char hatAndButtons; unsigned short buttons; unsigned short buttonsAndWheel; unsigned char gasPedal; unsigned char brakePedal; unsigned char clutchPedal; struct { unsigned char x; unsigned char y; unsigned char b; } shifter; } g27Ps3; struct s_report_g29Ps4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short Buttons; unsigned char unused0[35]; unsigned short wheel; unsigned short gasPedal; unsigned short brakePedal; unsigned short clutchPedal; unsigned char Buttons2; unsigned short unknown3; unsigned char Buttons3; unsigned char unused1[9]; } g29Ps4; struct s_report_dfPs2 { unsigned short buttonsAndWheel; unsigned char buttons; unsigned char unknown; unsigned char hat; unsigned char gasPedal; unsigned char brakePedal; } dfPs2; struct s_report_dfpPs2 { unsigned short buttonsAndWheel; unsigned short hatAndButtons; unsigned char unknown1; unsigned char gasPedal; unsigned char brakePedal; unsigned char unknown2; } dfpPs2; struct s_report_gtfPs2 { unsigned short buttonsAndWheel; unsigned char; unsigned char pedals; unsigned char gasPedal; unsigned char brakePedal; unsigned char; } gtfPs2; } *

variable_types:
previous
union s_report *

variable_types: union GE_Event { struct { unsigned char type; unsigned char which; }; struct GE_KeyboardEvent { unsigned char type; unsigned char which; unsigned short keysym; } key; struct GE_MouseMotionEvent { unsigned char type; unsigned char which; short xrel; short yrel; } motion; struct GE_MouseButtonEvent { unsigned char type; unsigned char which; unsigned char button; } button; struct GE_JoyAxisEvent { unsigned char type; unsigned char which; unsigned char axis; short value; } jaxis; struct GE_JoyHatEvent { unsigned char type; unsigned char which; unsigned char hat; unsigned char value; } jhat; struct GE_JoyButtonEvent { unsigned char type; unsigned char which; unsigned char button; unsigned char state; } jbutton; struct GE_JoyRumbleEvent { unsigned char type; unsigned char which; unsigned short weak; unsigned short strong; } jrumble; struct GE_JoyConstantForceEvent { unsigned char type; unsigned char which; short level; } jconstant; struct GE_JoyConditionForceEvent { unsigned char type; unsigned char which; struct { unsigned short left; unsigned short right; } saturation; struct { short left; short right; } coefficient; short center; unsigned short deadband; } jcondition; struct GE_JoyPeriodicForceEvent { unsigned char type; unsigned char which; struct { int direction; unsigned short period; short magnitude; short offset; } sine; } jperiodic; }

variable_types: struct s_report_xone { union { unsigned char type; struct { unsigned char type; unsigned char unknown; unsigned char counter; unsigned char size; unsigned short buttons; unsigned short ltrigger; unsigned short rtrigger; short xaxis; short yaxis; short zaxis; short taxis; } input; struct { unsigned char type; unsigned char unknown1; unsigned char counter; unsigned char size; unsigned char button; unsigned char unknown2; } guide; }; } *

variable_types:
prevButtons
unsigned short

user_defined_types: union s_report { struct s_report_joystick js; struct s_report_ds2 ds2; struct s_report_ds3 ds3; struct s_report_ds4 ds4; struct s_report_xbox xbox; struct s_report_x360 x360; struct s_report_xone xone; struct s_report_t300rsPs4 t300rsPs4; struct s_report_g27Ps3 g27Ps3; struct s_report_g29Ps4 g29Ps4; struct s_report_dfPs2 dfPs2; struct s_report_dfpPs2 dfpPs2; struct s_report_gtfPs2 gtfPs2; }

user_defined_types: struct s_report_ds4 { unsigned char report_id; unsigned char X; unsigned char Y; unsigned char Z; unsigned char Rz; unsigned char HatAndButtons; unsigned short ButtonsAndCounter; unsigned char Rx; unsigned char Ry; unsigned short _time; unsigned char battery_level; struct s_motion_acc motion_acc; struct s_motion_gyro motion_gyro; unsigned char _unknown1[5]; unsigned char ext; unsigned char _unknown2[2]; unsigned char packets; struct s_trackpad_packet packet1; struct s_trackpad_packet packet2; struct s_trackpad_packet packet3; struct s_trackpad_packet packet4; unsigned char _unknown5[2]; }

user_defined_types: struct s_trackpad_packet { unsigned char counter; struct s_trackpad_finger finger1; struct s_trackpad_finger finger2; }


original_code:
void bt_flip_addr(bd_addr_t dest, bd_addr_t src){
    dest[0] = src[5];
    dest[1] = src[4];
    dest[2] = src[3];
    dest[3] = src[2];
    dest[4] = src[1];
    dest[5] = src[0];
}

canonical_original_code:
void bt_flip_addr(unsigned char dest[6], unsigned char src[6]){
    dest[0] = src[5];
    dest[1] = src[4];
    dest[2] = src[3];
    dest[3] = src[2];
    dest[4] = src[1];
    dest[5] = src[0];
}

variable_types:
dest
unsigned char [6]

variable_types:
src
unsigned char [6]


hexdump

decompiled_code:
int __fastcall hexdump(unsigned __int8 *a1, int a2)
{
__int64 v2; // rbp
unsigned __int8 *v3; // rbx
__int64 v4; // rsi

if ( a2 > 0 )
{
v2 = (__int64)&a1[a2 - 1 + 1];
v3 = a1;
do
{
v4 = *v3++;
printf("%02X ", v4);
}
while ( v3 != (unsigned __int8 *)v2 );
}
return putchar(10);
}

canonical_decompiled_code:
int __fastcall func5(unsigned __int8 *a1, int a2)
{
__int64 v2; // rbp
unsigned __int8 *v3; // rbx
__int64 v4; // rsi

if ( a2 > 0 )
{
v2 = (__int64)&a1[a2 - 1 + 1];
v3 = a1;
do
{
v4 = *v3++;
printf("%02X ", v4);
}
while ( v3 != (unsigned __int8 *)v2 );
}
return putchar(10);
}

original_code:
void hexdump(void *data, int size){
    int i;
    for (i=0; i<size;i++){
        printf("%02X ", ((uint8_t *)data)[i]);
    }
    printf("\n");
}

canonical_original_code:
void hexdump(void *data, int size){
    int i;
    for (i=0; i<size;i++){
        printf("%02X ", ((unsigned char *)data)[i]);
    }
    printf("\n");
}

variable_types:
data
void *

variable_types: size int

variable_types: i int


decompiled_code:
char *__fastcall bd_addr_to_str(unsigned __int8 *a1)
{
sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", *a1, a1[1], a1[2], a1[3], a1[4], a1[5]);
return bd_addr_to_str_buffer;
}

canonical_decompiled_code:
char *__fastcall func7(unsigned __int8 *a1)
{
sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", *a1, a1[1], a1[2], a1[3], a1[4], a1[5]);
return bd_addr_to_str_buffer;
}

original_code:
char * bd_addr_to_str(bd_addr_t addr){
    sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
    return (char *) bd_addr_to_str_buffer;
}

canonical_original_code:
char *bd_addr_to_str(unsigned char addr[6]){
    sprintf(bd_addr_to_str_buffer, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
    return (char *) bd_addr_to_str_buffer;
}

variable_types:
addr
unsigned char [6]

return_type: char *


decompiled_code:
int __fastcall print_bd_addr(unsigned __int8 *a1)
{
char *v1; // rax

v1 = bd_addr_to_str(a1);
return printf("%s", v1);
}

canonical_decompiled_code:
int __fastcall func8(unsigned __int8 *a1)
{
char *v1; // rax

v1 = func7(a1);
return printf("%s", v1);
}

original_code:
void print_bd_addr( bd_addr_t addr){
    printf("%s", bd_addr_to_str(addr));
}

canonical_original_code:
void print_bd_addr(unsigned char addr[6]){
    printf("%s", bd_addr_to_str(addr));
}


original_code:
int sscan_bd_addr(uint8_t * addr_string, bd_addr_t addr){
 unsigned int bd_addr_buffer[6];
 int i;
    for (i = 0; i < 6; i++) {
        bd_addr_buffer[i] = 0;
    }
    int result = sscanf( (char *) addr_string, "%2x:%2x:%2x:%2x:%2x:%2x", &bd_addr_buffer[0], &bd_addr_buffer[1], &bd_addr_buffer[2],
      &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]);
 if (result == 6){
  for (i = 0; i < 6; i++) {
   addr[i] = (uint8_t) bd_addr_buffer[i];
  }
 }
 return (result == 6);
}

canonical_original_code:
int sscan_bd_addr(unsigned char *addr_string, unsigned char addr[6]){
 unsigned int bd_addr_buffer[6];
 int i;
    for (i = 0; i < 6; i++) {
        bd_addr_buffer[i] = 0;
    }
    int result = sscanf( (char *) addr_string, "%2x:%2x:%2x:%2x:%2x:%2x", &bd_addr_buffer[0], &bd_addr_buffer[1], &bd_addr_buffer[2],
      &bd_addr_buffer[3], &bd_addr_buffer[4], &bd_addr_buffer[5]);
 if (result == 6){
  for (i = 0; i < 6; i++) {
   addr[i] = (unsigned char) bd_addr_buffer[i];
  }
 }
 return (result == 6);
}

variable_types: result int


decompiled_code:
__int64 __fastcall crc8(_BYTE *a1, __int16 a2)
{
__int64 result; // rax
__int64 v3; // rdx
unsigned __int8 v4; // al

if ( !a2 )
return 0xFFFFFFFFLL;
LOBYTE(result) = -1;
v3 = (__int64)&a1[(unsigned __int16)(a2 - 1) + 1];
do
{
v4 = *a1++ ^ result;
result = (unsigned __int8)crc8table[v4];
}
while ( a1 != (_BYTE *)v3 );
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(_BYTE *a1, __int16 a2)
{
__int64 result; // rax
__int64 v3; // rdx
unsigned __int8 v4; // al

if ( !a2 )
return 0xFFFFFFFFLL;
LOBYTE(result) = -1;
v3 = (__int64)&a1[(unsigned __int16)(a2 - 1) + 1];
do
{
v4 = *a1++ ^ result;
result = (unsigned __int8)crc8table[v4];
}
while ( a1 != (_BYTE *)v3 );
return result;
}

original_code:
uint8_t crc8(uint8_t *data, uint16_t len)
{
    uint16_t count;
    uint8_t crc = 0xFF;
    for (count = 0; count < len; count++)
        crc = crc8table[crc ^ data[count]];
    return crc;
}

canonical_original_code:
unsigned char crc8(unsigned char *data, unsigned short len)
{
    unsigned short count;
    unsigned char crc = 0xFF;
    for (count = 0; count < len; count++)
        crc = crc8table[crc ^ data[count]];
    return crc;
}

variable_types:
data
unsigned char *

variable_types:
len
unsigned short

variable_types:
count
unsigned short

variable_types:
crc
unsigned char

return_type: unsigned char


decompiled_code:
bool __fastcall crc8_check(_BYTE *a1, __int16 a2)
{
char v2; // al
char v3; // cl

v2 = crc8(a1, a2);
return crc8table[(unsigned __int8)(v3 ^ v2)] != -49;
}

canonical_decompiled_code:
bool __fastcall func11(_BYTE *a1, __int16 a2)
{
char v2; // al
char v3; // cl

v2 = func10(a1, a2);
return crc8table[(unsigned __int8)(v3 ^ v2)] != -49;
}

original_code:
uint8_t crc8_check(uint8_t *data, uint16_t len, uint8_t check_sum)
{
    uint8_t crc;
    crc = crc8(data, len);
    crc = crc8table[crc ^ check_sum];
    if (crc == 0xCF)
        return 0;
    else
        return 1;
}

canonical_original_code:
unsigned char crc8_check(unsigned char *data, unsigned short len, unsigned char check_sum)
{
    unsigned char crc;
    crc = crc8(data, len);
    crc = crc8table[crc ^ check_sum];
    if (crc == 0xCF)
        return 0;
    else
        return 1;
}


decompiled_code:
__int64 __fastcall crc8_calc(_BYTE *a1, __int16 a2)
{
return (unsigned int)~crc8(a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func12(_BYTE *a1, __int16 a2)
{
return (unsigned int)~func10(a1, a2);
}

original_code:
uint8_t crc8_calc(uint8_t *data, uint16_t len)
{
    return 0xFF - crc8(data, len);
}

canonical_original_code:
unsigned char crc8_calc(unsigned char *data, unsigned short len)
{
    return 0xFF - crc8(data, len);
}


decompiled_code:
__int64 __fastcall mgmt_set_local_name(int fd, __int16 a2)
{
__int16 buf[140]; // [rsp+20h] [rbp-118h] BYREF

memset(buf, 0, 0x108uLL);
buf[0] = 15;
buf[1] = a2;
buf[2] = 260;
buf[132] = 0;
strcpy((char *)&buf[3], "Wireless Controller");
if ( write(fd, buf, 0x10AuLL) >= 0 )
return 0LL;
perror("write");
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, __int16 a2)
{
__int16 buf[140]; // [rsp+20h] [rbp-118h] BYREF

memset(buf, 0, 0x108uLL);
buf[0] = 15;
buf[1] = a2;
buf[2] = 260;
buf[132] = 0;
strcpy((char *)&buf[3], "Wireless Controller");
if ( write(fd, buf, 0x10AuLL) >= 0 )
return 0LL;
perror("write");
return 0xFFFFFFFFLL;
}

original_code:
static int mgmt_set_local_name(int sk, uint16_t index)
{
  char buf[6 + sizeof(struct mgmt_cp_set_local_name)];
  struct mgmt_hdr *hdr = (void *) buf;
  struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];
  memset(buf, 0, sizeof(buf));
  hdr->opcode = (0x000F);
  hdr->index = (index);
  hdr->len = (sizeof(*cp));
  char name[] = "Wireless Controller";
  memcpy(cp->name, name, sizeof(name));
  if (write(sk, buf, sizeof(buf)) < 0)
  {
    perror("write");
    return -1;
  }
  return 0;
}

canonical_original_code:
static int mgmt_set_local_name(int sk, unsigned short index)
{
  char buf[-1];
  struct mgmt_hdr *hdr = (void *) buf;
  struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];
  memset(buf, 0, sizeof(buf));
  hdr->opcode = (0x000F);
  hdr->index = (index);
  hdr->len = (sizeof(*cp));
  char name[] = "Wireless Controller";
  memcpy(cp->name, name, sizeof(name));
  if (write(sk, buf, sizeof(buf)) < 0)
  {
    perror("write");
    return -1;
  }
  return 0;
}

variable_types: sk int

variable_types:
index
unsigned short

variable_types:
buf
char [-1]

variable_types: struct mgmt_hdr { unsigned short opcode; unsigned short index; unsigned short len; } *

variable_types: struct mgmt_cp_set_local_name { unsigned char name[-1]; unsigned char short_name[-1]; } *

variable_types:
name
char []


bacpy

decompiled_code:
__int64 __fastcall bacpy(__int64 a1, __int64 a2)
{
__int64 result; // rax

*(_DWORD *)a1 = *(_DWORD *)a2;
result = *(unsigned __int16 *)(a2 + 4);
*(_WORD *)(a1 + 4) = result;
return result;
}

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

*(_DWORD *)a1 = *(_DWORD *)a2;
result = *(unsigned __int16 *)(a2 + 4);
*(_WORD *)(a1 + 4) = result;
return result;
}

original_code:
static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
{
 memcpy(dst, src, sizeof(bdaddr_t));
}

canonical_original_code:
static inline void bacpy(struct bdaddr_t *dst, struct bdaddr_t *src)
{
 memcpy(dst, src, sizeof(bdaddr_t));
}

variable_types: struct bdaddr_t { unsigned char b[6]; } *

variable_types:
src
struct bdaddr_t *


decompiled_code:
__int64 mgmt_create()
{
int v0; // eax
unsigned int v1; // er12
int v3; // edi
int v4; // [rsp+Ah] [rbp-Eh] BYREF
__int16 v5; // [rsp+Eh] [rbp-Ah]

v0 = socket(31, 526339, 1);
if ( v0 < 0 )
{
v1 = -1;
perror("socket");
}
else
{
v1 = v0;
v4 = -65505;
v5 = 3;
if ( bind(v0, (const struct sockaddr *)&v4, 6u) < 0 )
{
perror("bind");
v3 = v1;
v1 = -1;
close(v3);
}
}
return v1;
}

canonical_decompiled_code:
__int64 func8()
{
int v0; // eax
unsigned int v1; // er12
int v3; // edi
int v4; // [rsp+Ah] [rbp-Eh] BYREF
__int16 v5; // [rsp+Eh] [rbp-Ah]

v0 = socket(31, 526339, 1);
if ( v0 < 0 )
{
v1 = -1;
perror("socket");
}
else
{
v1 = v0;
v4 = -65505;
v5 = 3;
if ( bind(v0, (const struct sockaddr *)&v4, 6u) < 0 )
{
perror("bind");
v3 = v1;
v1 = -1;
close(v3);
}
}
return v1;
}

original_code:
int mgmt_create(void)
{
  struct sockaddr_hci addr;
  int sk;
  sk = socket(31, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 1);
  if (sk < 0)
  {
    perror("socket");
    return -1;
  }
  memset(&addr, 0, sizeof(addr));
  addr.hci_family = 31;
  addr.hci_dev = 0xffff;
  addr.hci_channel = 3;
  if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0)
  {
    perror("bind");
    close(sk);
    return -1;
  }
  return sk;
}

canonical_original_code:
int mgmt_create()
{
  struct sockaddr_hci addr;
  int sk;
  sk = socket(31, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 1);
  if (sk < 0)
  {
    perror("socket");
    return -1;
  }
  memset(&addr, 0, sizeof(addr));
  addr.hci_family = 31;
  addr.hci_dev = 0xffff;
  addr.hci_channel = 3;
  if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0)
  {
    perror("bind");
    close(sk);
    return -1;
  }
  return sk;
}

variable_types: struct sockaddr_hci { unsigned short hci_family; unsigned short hci_dev; unsigned short hci_channel; }

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }


decompiled_code:
__int64 __fastcall bt_mgmt_adapter_init(__int16 a1)
{
int v1; // eax
int v2; // ebp
int v3; // edi
__int64 result; // rax
char v5[12]; // [rsp+4h] [rbp-44h] BYREF
__m128i v6[3]; // [rsp+10h] [rbp-38h] BYREF

v1 = mgmt_create();
if ( v1 < 0 )
{
fwrite("can't open a management socket\n", 1uLL, 0x1FuLL, stderr);
result = 0xFFFFFFFFLL;
}
else
{
v2 = v1;
step = 1;
if ( (int)mgmt_set_mode_constprop_0(v1, a1, 5) < 0 )
{
fwrite("set_powered failed\n", 1uLL, 0x13uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
if ( (int)mgmt_read_evt(v2) < 0 )
goto LABEL_13;
step = 3;
if ( (int)mgmt_set_local_name(v2, a1) < 0 )
{
fwrite("set_local_name failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
if ( (int)mgmt_read_evt(v2) < 0 )
goto LABEL_13;
step = 2;
if ( (int)mgmt_set_mode_constprop_0(v2, a1, 7) < 0 )
{
fwrite("set_connectable failed\n", 1uLL, 0x17uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
if ( (int)mgmt_read_evt(v2) < 0 )
goto LABEL_13;
step = 4;
if ( (int)read_link_keys_constprop_0(a1, (__int64)v5, v6) >= 0 )
{
if ( (int)mgmt_load_link_keys_constprop_0(v2, a1, (__int64)v5, v6) >= 0 )
{
v3 = v2;
if ( (int)mgmt_read_evt(v2) >= 0 )
{
close(v2);
return 0LL;
}
goto LABEL_14;
}
fwrite("load_link_keys failed\n", 1uLL, 0x16uLL, stderr);
LABEL_13:
v3 = v2;
LABEL_14:
close(v3);
return 0xFFFFFFFFLL;
}
fwrite("read_link_keys failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int16 a1)
{
int v1; // eax
int v2; // ebp
int v3; // edi
__int64 result; // rax
char v5[12]; // [rsp+4h] [rbp-44h] BYREF
__m128i v6[3]; // [rsp+10h] [rbp-38h] BYREF

v1 = func8();
if ( v1 < 0 )
{
fwrite("can't open a management socket\n", 1uLL, 0x1FuLL, stderr);
result = 0xFFFFFFFFLL;
}
else
{
v2 = v1;
step = 1;
if ( (int)func5(v1, a1, 5) < 0 )
{
fwrite("set_powered failed\n", 1uLL, 0x13uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
if ( (int)func3(v2) < 0 )
goto LABEL_13;
step = 3;
if ( (int)func0(v2, a1) < 0 )
{
fwrite("set_local_name failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
if ( (int)func3(v2) < 0 )
goto LABEL_13;
step = 2;
if ( (int)func5(v2, a1, 7) < 0 )
{
fwrite("set_connectable failed\n", 1uLL, 0x17uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
else
{
if ( (int)func3(v2) < 0 )
goto LABEL_13;
step = 4;
if ( (int)func7(a1, (__int64)v5, v6) >= 0 )
{
if ( (int)func4(v2, a1, (__int64)v5, v6) >= 0 )
{
v3 = v2;
if ( (int)func3(v2) >= 0 )
{
close(v2);
return 0LL;
}
goto LABEL_14;
}
fwrite("load_link_keys failed\n", 1uLL, 0x16uLL, stderr);
LABEL_13:
v3 = v2;
LABEL_14:
close(v3);
return 0xFFFFFFFFLL;
}
fwrite("read_link_keys failed\n", 1uLL, 0x16uLL, stderr);
close(v2);
result = 0xFFFFFFFFLL;
}
}
}
}
return result;
}

original_code:
int bt_mgmt_adapter_init(uint16_t index)
{
  int sk;
  if((sk = mgmt_create()) < 0)
  {
    fprintf(stderr, "can't open a management socket\n");
    return -1;
  }
  step = E_SET_POWERED;
  if(mgmt_set_mode(sk, index, 0x0005, 1) < 0)
  {
    fprintf(stderr, "set_powered failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_LOCAL_NAME;
  if(mgmt_set_local_name(sk, index) < 0)
  {
    fprintf(stderr, "set_local_name failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_CONNECTABLE;
  if(mgmt_set_mode(sk, index, 0x0007, 1) < 0)
  {
    fprintf(stderr, "set_connectable failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_LOAD_LINK_KEYS;
  bdaddr_t bdaddrs[2];
  unsigned char keys[2][16];
  if(read_link_keys(index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "read_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_load_link_keys(sk, index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "load_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  close(sk);
  return 0;
}

canonical_original_code:
int bt_mgmt_adapter_init(unsigned short index)
{
  int sk;
  if((sk = mgmt_create()) < 0)
  {
    fprintf(stderr, "can't open a management socket\n");
    return -1;
  }
  step = E_SET_POWERED;
  if(mgmt_set_mode(sk, index, 0x0005, 1) < 0)
  {
    fprintf(stderr, "set_powered failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_LOCAL_NAME;
  if(mgmt_set_local_name(sk, index) < 0)
  {
    fprintf(stderr, "set_local_name failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_SET_CONNECTABLE;
  if(mgmt_set_mode(sk, index, 0x0007, 1) < 0)
  {
    fprintf(stderr, "set_connectable failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  step = E_LOAD_LINK_KEYS;
  struct bdaddr_t bdaddrs[2];
  unsigned char keys[2][16];
  if(read_link_keys(index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "read_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_load_link_keys(sk, index, 2, bdaddrs, keys) < 0)
  {
    fprintf(stderr, "load_link_keys failed\n");
    close(sk);
    return -1;
  }
  if(mgmt_read_evt(sk) < 0)
  {
    close(sk);
    return -1;
  }
  close(sk);
  return 0;
}

variable_types: struct bdaddr_t { unsigned char b[6]; } [2]

variable_types:
keys
unsigned char [2][16]


original_code:
int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length)
{
  unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8,
        seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00,
        pskey & 0xff, pskey >> 8,
        (length / 2) & 0xff, (length / 2) >> 8,
        stores & 0xff, stores >> 8, 0x00, 0x00 };
  unsigned char cp[254], rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + length - 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  memcpy(value, rp + 17, length);
  return 0;
}

canonical_original_code:
int csr_read_pskey_complex(int dd, unsigned short seqnum, unsigned short pskey, unsigned short stores, unsigned char *value, unsigned short length)
{
  unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8,
        seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00,
        pskey & 0xff, pskey >> 8,
        (length / 2) & 0xff, (length / 2) >> 8,
        stores & 0xff, stores >> 8, 0x00, 0x00 };
  unsigned char cp[254]; unsigned char rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + length - 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  memcpy(value, rp + 17, length);
  return 0;
}

variable_types: dd int

variable_types:
seqnum
unsigned short

variable_types:
pskey
unsigned short

variable_types:
stores
unsigned short

variable_types:
value
unsigned char *

variable_types:
length
unsigned short

variable_types:
cmd
unsigned char []

variable_types:
cp
unsigned char [254]

variable_types:
rp
unsigned char [254]

variable_types: struct hci_request { unsigned short ogf; unsigned short ocf; int event; void *cparam; int clen; void *rparam; int rlen; }


decompiled_code:
__int64 __fastcall csr_read_pskey_uint16(unsigned int a1, __int16 a2, __int16 a3, __int16 a4, _WORD *a5)
{
__int64 result; // rax
__int16 v7; // [rsp+Eh] [rbp-Ah] BYREF

v7 = 0;
LODWORD(result) = csr_read_pskey_complex(a1, a2, a3, a4, &v7, 2u);
*a5 = (unsigned __int8)v7 + (HIBYTE(v7) << 8);
return (unsigned int)result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1, __int16 a2, __int16 a3, __int16 a4, _WORD *a5)
{
__int64 result; // rax
__int16 v7; // [rsp+Eh] [rbp-Ah] BYREF

v7 = 0;
LODWORD(result) = func0(a1, a2, a3, a4, &v7, 2u);
*a5 = (unsigned __int8)v7 + (HIBYTE(v7) << 8);
return (unsigned int)result;
}

original_code:
int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t *value)
{
  uint8_t array[2] = { 0x00, 0x00 };
  int err;
  err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 2);
  *value = array[0] + (array[1] << 8);
  return err;
}

canonical_original_code:
int csr_read_pskey_uint16(int dd, unsigned short seqnum, unsigned short pskey, unsigned short stores, unsigned short *value)
{
  unsigned char array[2] = { 0x00, 0x00 };
  int err;
  err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 2);
  *value = array[0] + (array[1] << 8);
  return err;
}

variable_types:
value
unsigned short *

variable_types:
array
unsigned char [2]

variable_types: err int


decompiled_code:
const char *__fastcall csr_chipvertostr(__int16 a1, unsigned __int16 a2)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = "BlueCore01a";
break;
case 1:
result = "BlueCore01b (ES)";
if ( a2 != 100 )
result = "BlueCore01b";
break;
case 2:
result = "BlueCore02-External (ES2)";
if ( a2 != 137 )
{
result = "BlueCore02-External";
if ( a2 != 138 )
{
result = "BlueCore02";
if ( a2 == 40 )
result = "BlueCore02-ROM/Audio/Flash";
}
}
break;
case 3:
if ( a2 == 48 )
{
result = "BlueCore4-ROM";
}
else if ( a2 > 0x30u )
{
result = "BlueCore3-MM";
if ( a2 != 67 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 226 )
result = "BlueCore3-Flash";
}
}
else
{
result = "BlueCore3-ROM";
if ( a2 != 21 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 38 )
result = "BlueCore4-External";
}
}
break;
case 7:
result = "CSR8510";
if ( a2 )
result = "CSR8510 or later";
break;
default:
result = "Unknown";
break;
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func2(__int16 a1, unsigned __int16 a2)
{
const char *result; // rax

switch ( a1 )
{
case 0:
result = "BlueCore01a";
break;
case 1:
result = "BlueCore01b (ES)";
if ( a2 != 100 )
result = "BlueCore01b";
break;
case 2:
result = "BlueCore02-External (ES2)";
if ( a2 != 137 )
{
result = "BlueCore02-External";
if ( a2 != 138 )
{
result = "BlueCore02";
if ( a2 == 40 )
result = "BlueCore02-ROM/Audio/Flash";
}
}
break;
case 3:
if ( a2 == 48 )
{
result = "BlueCore4-ROM";
}
else if ( a2 > 0x30u )
{
result = "BlueCore3-MM";
if ( a2 != 67 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 226 )
result = "BlueCore3-Flash";
}
}
else
{
result = "BlueCore3-ROM";
if ( a2 != 21 )
{
result = "BlueCore3 or BlueCore4";
if ( a2 == 38 )
result = "BlueCore4-External";
}
}
break;
case 7:
result = "CSR8510";
if ( a2 )
result = "CSR8510 or later";
break;
default:
result = "Unknown";
break;
}
return result;
}

original_code:
char *csr_chipvertostr(uint16_t ver, uint16_t rev)
{
  switch (ver) {
  case 0x00:
    return "BlueCore01a";
  case 0x01:
    switch (rev) {
    case 0x64:
      return "BlueCore01b (ES)";
    case 0x65:
    default:
      return "BlueCore01b";
    }
    break;
  case 0x02:
    switch (rev) {
    case 0x89:
      return "BlueCore02-External (ES2)";
    case 0x8a:
      return "BlueCore02-External";
    case 0x28:
      return "BlueCore02-ROM/Audio/Flash";
    default:
      return "BlueCore02";
    }
    break;
  case 0x03:
    switch (rev) {
    case 0x43:
      return "BlueCore3-MM";
    case 0x15:
      return "BlueCore3-ROM";
    case 0xe2:
      return "BlueCore3-Flash";
    case 0x26:
      return "BlueCore4-External";
    case 0x30:
      return "BlueCore4-ROM";
    default:
      return "BlueCore3 or BlueCore4";
    }
    break;
  case 0x07:
    switch (rev) {
    case 0x00:
      return "CSR8510";
    default:
      return "CSR8510 or later";
    }
    break;
  default:
    return "Unknown";
  }
}

canonical_original_code:
char *csr_chipvertostr(unsigned short ver, unsigned short rev)
{
  switch (ver) {
  case 0x00:
    return "BlueCore01a";
  case 0x01:
    switch (rev) {
    case 0x64:
      return "BlueCore01b (ES)";
    case 0x65:
    default:
      return "BlueCore01b";
    }
    break;
  case 0x02:
    switch (rev) {
    case 0x89:
      return "BlueCore02-External (ES2)";
    case 0x8a:
      return "BlueCore02-External";
    case 0x28:
      return "BlueCore02-ROM/Audio/Flash";
    default:
      return "BlueCore02";
    }
    break;
  case 0x03:
    switch (rev) {
    case 0x43:
      return "BlueCore3-MM";
    case 0x15:
      return "BlueCore3-ROM";
    case 0xe2:
      return "BlueCore3-Flash";
    case 0x26:
      return "BlueCore4-External";
    case 0x30:
      return "BlueCore4-ROM";
    default:
      return "BlueCore3 or BlueCore4";
    }
    break;
  case 0x07:
    switch (rev) {
    case 0x00:
      return "CSR8510";
    default:
      return "CSR8510 or later";
    }
    break;
  default:
    return "Unknown";
  }
}

variable_types:
ver
unsigned short

variable_types:
rev
unsigned short


original_code:
int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value)
{
  unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00,
        seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  unsigned char cp[254], rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  *value = rp[11] + (rp[12] << 8);
  return 0;
}

canonical_original_code:
int csr_read_varid_uint16(int dd, unsigned short seqnum, unsigned short varid, unsigned short *value)
{
  unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00,
        seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  unsigned char cp[254]; unsigned char rp[254];
  struct hci_request rq;
  memset(&cp, 0, sizeof(cp));
  cp[0] = 0xc2;
  memcpy(cp + 1, cmd, sizeof(cmd));
  memset(&rq, 0, sizeof(rq));
  rq.ogf = 0x3f;
  rq.ocf = 0x00;
  rq.event = 0xFF;
  rq.cparam = cp;
  rq.clen = sizeof(cmd) + 1;
  rq.rparam = rp;
  rq.rlen = sizeof(rp);
  if (hci_send_req(dd, &rq, 2000) < 0)
    return -1;
  if (rp[0] != 0xc2) {
    (*__errno_location ()) = 5;
    return -1;
  }
  if ((rp[9] + (rp[10] << 8)) != 0) {
    (*__errno_location ()) = 6;
    return -1;
  }
  *value = rp[11] + (rp[12] << 8);
  return 0;
}

variable_types:
varid
unsigned short

user_defined_types: struct hci_request { unsigned short ogf; unsigned short ocf; int event; void *cparam; int clen; void *rparam; int rlen; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v4; // [rsp+0h] [rbp-Ch] BYREF

if ( argc <= 1 )
return 0;
if ( (int)_isoc99_sscanf(argv[1], "hci%d", &v4) > 0 )
cmd_revision_constprop_0(v4);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v4; // [rsp+0h] [rbp-Ch] BYREF

if ( argc <= 1 )
return 0;
if ( (int)_isoc99_sscanf(argv[1], "hci%d", &v4) > 0 )
func5(v4);
return 0;
}

original_code:
int main(int argc, char *argv[])
{
  int i;
  if(argc > 1 && sscanf(argv[1], "hci%d", &i) > 0)
  {
    cmd_revision(0, i, ((void *)0));
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: i int


decompiled_code:
__int64 l2cap_abs_get()
{
return l2cap_abs[bt_abs_value];
}

canonical_decompiled_code:
__int64 func0()
{
return l2cap_abs[bt_abs_value];
}

original_code:
s_l2cap_abs * l2cap_abs_get()
{
  return l2cap_abs[bt_abs_value];
}

canonical_original_code:
struct s_l2cap_abs *l2cap_abs_get()
{
  return l2cap_abs[bt_abs_value];
}

return_type: struct s_l2cap_abs { int (*connect)(char *bdaddr_src, char *bdaddr_dest, unsigned short psm, int options, void *user, int (*callback)(void *user), int (*close_callback)(void *user)); int (*listen)(void *user, char *bdaddr_adapter, unsigned short psm, int options, int (*read_callback)(int channel, struct bdaddr_t { unsigned char b[6]; } *src), int (*close_callback)(void *user)); int (*send)(int channel, unsigned char *buf, int len, int blocking); int (*recv)(int channel, unsigned char *buf, int len); int (*close)(int channel); void (*add_source)(int channel, void *user, int (*read_callback)(void *user), int (*packet_callback)(void *user, int psm, unsigned char *buf, int len), int (*close_callback)(void *user)); int (*disconnect)(int channel); } *

user_defined_types: struct s_l2cap_abs { int (*connect)(char *bdaddr_src, char *bdaddr_dest, unsigned short psm, int options, void *user, int (*callback)(void *user), int (*close_callback)(void *user)); int (*listen)(void *user, char *bdaddr_adapter, unsigned short psm, int options, int (*read_callback)(int channel, struct bdaddr_t *src), int (*close_callback)(void *user)); int (*send)(int channel, unsigned char *buf, int len, int blocking); int (*recv)(int channel, unsigned char *buf, int len); int (*close)(int channel); void (*add_source)(int channel, void *user, int (*read_callback)(void *user), int (*packet_callback)(void *user, int psm, unsigned char *buf, int len), int (*close_callback)(void *user)); int (*disconnect)(int channel); }


decompiled_code:
void __fastcall l2cap_abs_register(int a1, __int64 a2)
{
l2cap_abs[a1] = a2;
}

canonical_decompiled_code:
void __fastcall func1(int a1, __int64 a2)
{
l2cap_abs[a1] = a2;
}

original_code:
void l2cap_abs_register(e_bt_abs index, s_l2cap_abs * value)
{
  l2cap_abs[index] = value;
}

canonical_original_code:
void l2cap_abs_register(enum e_bt_abs index, struct s_l2cap_abs *value)
{
  l2cap_abs[index] = value;
}

variable_types: enum e_bt_abs { E_BT_ABS_BTSTACK=0, E_BT_ABS_BLUEZ=1, E_BT_ABS_MAX=2 }

variable_types: struct s_l2cap_abs { int (*connect)(char *bdaddr_src, char *bdaddr_dest, unsigned short psm, int options, void *user, int (*callback)(void *user), int (*close_callback)(void *user)); int (*listen)(void *user, char *bdaddr_adapter, unsigned short psm, int options, int (*read_callback)(int channel, struct bdaddr_t { unsigned char b[6]; } *src), int (*close_callback)(void *user)); int (*send)(int channel, unsigned char *buf, int len, int blocking); int (*recv)(int channel, unsigned char *buf, int len); int (*close)(int channel); void (*add_source)(int channel, void *user, int (*read_callback)(void *user), int (*packet_callback)(void *user, int psm, unsigned char *buf, int len), int (*close_callback)(void *user)); int (*disconnect)(int channel); } *


decompiled_code:
__int64 __fastcall is_device_opened(char *s2)
{
const char **v1; // rbx

v1 = (const char **)&unk_8C8;
while ( !*v1 || strcmp(*v1, s2) )
{
v1 += 6;
if ( v1 == (const char **)((char *)&unk_8C8 + 384) )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *s2)
{
const char **v1; // rbx

v1 = (const char **)&unk_8C8;
while ( !*v1 || strcmp(*v1, s2) )
{
v1 += 6;
if ( v1 == (const char **)((char *)&unk_8C8 + 384) )
return 0LL;
}
return 1LL;
}

original_code:
static uint8_t is_device_opened(const char* device)
{
  unsigned int i;
  for(i = 0; i < sizeof(devices) / sizeof(*devices); ++i)
  {
    if(devices[i].path && !strcmp(devices[i].path, device))
    {
      return 1;
    }
  }
  return 0;
}

canonical_original_code:
static unsigned char is_device_opened(char *device)
{
  unsigned int i;
  for(i = 0; i < sizeof(devices) / sizeof(*devices); ++i)
  {
    if(devices[i].path && !strcmp(devices[i].path, device))
    {
      return 1;
    }
  }
  return 0;
}

variable_types:
device
char *

variable_types:
i
unsigned int


decompiled_code:
__int64 __fastcall gpppcprog_send(unsigned int a1, char a2, __int64 a3, unsigned __int16 a4)
{
unsigned __int16 v4; // r14
char *v7; // r15
__int64 result; // rax
unsigned __int16 v9; // bx
unsigned __int16 v10; // dx
const void *v11; // rsi
__int64 v12; // rdi
__int128 dest[4]; // [rsp+0h] [rbp-88h] BYREF
char v14; // [rsp+40h] [rbp-48h]

v4 = a4;
if ( (int)check_device_constprop_0(a1, 0x8Fu, "gpppcprog_send") < 0 )
return 0xFFFFFFFFLL;
v7 = (char *)&devices + 48 * (int)a1;
result = 0LL;
if ( !*((_DWORD *)v7 + 4) )
{
v14 = 0;
v9 = 0;
dest[0] = 0LL;
dest[1] = 0LL;
BYTE1(dest[0]) = a2;
WORD1(dest[0]) = v4;
BYTE4(dest[0]) = 1;
dest[2] = 0LL;
dest[3] = 0LL;
do
{
if ( a4 )
{
v10 = a4 - v9;
v11 = (const void *)(a3 + v9);
v9 = a4;
memcpy((char *)dest + 5, v11, v10);
}
v12 = *(_QWORD *)v7;
if ( *((_QWORD *)v7 + 4) )
{
if ( (unsigned int)ghid_write(v12, dest, 65LL) == -1 )
return 0xFFFFFFFFLL;
++*((_DWORD *)v7 + 4);
}
else if ( (unsigned int)ghid_write_timeout(v12, dest, 65LL, 1000LL) == -1 )
{
return 0xFFFFFFFFLL;
}
BYTE4(dest[0]) = 0;
}
while ( v9 < a4 );
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(unsigned int a1, char a2, __int64 a3, unsigned __int16 a4)
{
unsigned __int16 v4; // r14
char *v7; // r15
__int64 result; // rax
unsigned __int16 v9; // bx
unsigned __int16 v10; // dx
const void *v11; // rsi
__int64 v12; // rdi
__int128 dest[4]; // [rsp+0h] [rbp-88h] BYREF
char v14; // [rsp+40h] [rbp-48h]

v4 = a4;
if ( (int)func4(a1, 0x8Fu, "gpppcprog_send") < 0 )
return 0xFFFFFFFFLL;
v7 = (char *)&devices + 48 * (int)a1;
result = 0LL;
if ( !*((_DWORD *)v7 + 4) )
{
v14 = 0;
v9 = 0;
dest[0] = 0LL;
dest[1] = 0LL;
BYTE1(dest[0]) = a2;
WORD1(dest[0]) = v4;
BYTE4(dest[0]) = 1;
dest[2] = 0LL;
dest[3] = 0LL;
do
{
if ( a4 )
{
v10 = a4 - v9;
v11 = (const void *)(a3 + v9);
v9 = a4;
memcpy((char *)dest + 5, v11, v10);
}
v12 = *(_QWORD *)v7;
if ( *((_QWORD *)v7 + 4) )
{
if ( (unsigned int)ghid_write(v12, dest, 65LL) == -1 )
return 0xFFFFFFFFLL;
++*((_DWORD *)v7 + 4);
}
else if ( (unsigned int)ghid_write_timeout(v12, dest, 65LL, 1000LL) == -1 )
{
return 0xFFFFFFFFLL;
}
BYTE4(dest[0]) = 0;
}
while ( v9 < a4 );
result = 1LL;
}
return result;
}

original_code:
static int8_t gpppcprog_send(int id, uint8_t type, uint8_t * data, uint16_t length)
{
  if(check_device(id, "pcprog.c", 143, __func__) < 0) { return -1; }
  if (devices[id].pending > 0)
  {
    return 0;
  }
  s_gppReport report =
  {
    .reportId = 0x00,
    .header =
    {
      .type = type,
      .length = length,
      .first = 1
    }
  };
  uint16_t sndLen;
  uint16_t i = 0;
  do
  {
    if (length)
    {
      sndLen = (((i + sizeof(report.data)) < length) ? sizeof(report.data) : (uint16_t)(length - i));
      memcpy(report.data, data + i, sndLen);
      i += sndLen;
    }
    if(devices[id].fp_write) {
      if (ghid_write(devices[id].device, (unsigned char*)&report, sizeof(report)) == -1)
      {
        return -1;
      }
      ++devices[id].pending;
    }
    else {
      if (ghid_write_timeout(devices[id].device, (unsigned char*)&report, sizeof(report), 1000) == -1)
        return -1;
    }
    report.header.first = 0;
  }
  while (i < length);
  return 1;
}

canonical_original_code:
static char gpppcprog_send(int id, unsigned char type, unsigned char *data, unsigned short length)
{
  if(check_device(id, "pcprog.c", 143, __func__) < 0) { return -1; }
  if (devices[id].pending > 0)
  {
    return 0;
  }
  struct s_gppReport report = {
    .reportId = 0x00,
    .header =
    {
      .type = type,
      .length = length,
      .first = 1
    }
  };
  unsigned short sndLen;
  unsigned short i = 0;
  do
  {
    if (length)
    {
      sndLen = (((i + sizeof(report.data)) < length) ? sizeof(report.data) : (unsigned short)(length - i));
      memcpy(report.data, data + i, sndLen);
      i += sndLen;
    }
    if(devices[id].fp_write) {
      if (ghid_write(devices[id].device, (unsigned char *)&report, sizeof(report)) == -1)
      {
        return -1;
      }
      ++devices[id].pending;
    }
    else {
      if (ghid_write_timeout(devices[id].device, (unsigned char *)&report, sizeof(report), 1000) == -1)
        return -1;
    }
    report.header.first = 0;
  }
  while (i < length);
  return 1;
}

variable_types: id int

variable_types:
type
unsigned char

variable_types:
data
unsigned char *

variable_types:
length
unsigned short

variable_types: struct s_gppReport { unsigned char reportId; struct s_gppReportHeader { unsigned char type; unsigned short length; unsigned char first; } header; unsigned char data[-1]; }

variable_types:
sndLen
unsigned short

variable_types:
i
unsigned short

return_type: char

user_defined_types: struct s_gppReport { unsigned char reportId; struct s_gppReportHeader header; unsigned char data[-1]; }


decompiled_code:
void *__fastcall gpppcprog_get_ids(_DWORD *a1)
{
*a1 = nb_usb_ids;
return &usb_ids;
}

canonical_decompiled_code:
void *__fastcall func7(_DWORD *a1)
{
*a1 = nb_usb_ids;
return &usb_ids;
}

original_code:
const GCAPI_USB_IDS * gpppcprog_get_ids(unsigned int * nb)
{
  *nb = nb_usb_ids;
  return usb_ids;
}

canonical_original_code:
struct GCAPI_USB_IDS *gpppcprog_get_ids(unsigned int *nb)
{
  *nb = nb_usb_ids;
  return usb_ids;
}

variable_types:
nb
unsigned int *

return_type: struct GCAPI_USB_IDS { unsigned short vid; unsigned short pid; char *name; } *


decompiled_code:
__int64 __fastcall gppcprog_connect(signed int a1, char *a2)
{
__int64 v2; // rax
__int64 *v3; // rbx
__int64 result; // rax
__int64 v5; // r15
_WORD *v6; // r13
char *v7; // r12
__int64 v8; // rax
__int64 *v9; // [rsp+8h] [rbp-60h]
__int64 v10; // [rsp+10h] [rbp-58h]
__int64 v11; // [rsp+20h] [rbp-48h]

if ( (int)check_device_constprop_0(a1, 0xCAu, "gppcprog_connect") < 0 )
return 0xFFFFFFFFLL;
if ( !a2 )
{
v10 = ghid_enumerate(0LL, 0LL);
if ( v10 )
{
v5 = v10;
v11 = a1;
v9 = (__int64 *)((char *)&devices + 48 * a1);
do
{
v6 = &usb_ids;
do
{
if ( *(_WORD *)v5 == *v6 && *(_WORD *)(v5 + 2) == v6[1] )
{
v7 = *(char **)(v5 + 16);
if ( !(unsigned __int8)is_device_opened(v7) )
{
v8 = ghid_open_path(v7);
*v9 = v8;
if ( v8 )
{
*((_QWORD *)&devices + 6 * a1 + 1) = strdup(*(const char **)(v5 + 16));
goto LABEL_11;
}
}
}
v6 += 8;
}
while ( v6 != (_WORD *)((char *)&usb_ids + 256) );
if ( *v9 )
break;
v5 = *(_QWORD *)(v5 + 24);
}
while ( v5 );
}
else
{
v11 = a1;
}
LABEL_11:
ghid_free_enumeration(v10);
if ( *((_QWORD *)&devices + 6 * v11) )
goto LABEL_6;
return 0xFFFFFFFFLL;
}
if ( (unsigned __int8)is_device_opened(a2) )
return 0xFFFFFFFFLL;
v2 = ghid_open_path(a2);
v3 = (__int64 *)((char *)&devices + 48 * a1);
*v3 = v2;
if ( !v2 )
return 0xFFFFFFFFLL;
v3[1] = (__int64)strdup(a2);
LABEL_6:
result = gpppcprog_send(a1, 7, 0LL, 0);
if ( (char)result > 0 )
result = 1LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(signed int a1, char *a2)
{
__int64 v2; // rax
__int64 *v3; // rbx
__int64 result; // rax
__int64 v5; // r15
_WORD *v6; // r13
char *v7; // r12
__int64 v8; // rax
__int64 *v9; // [rsp+8h] [rbp-60h]
__int64 v10; // [rsp+10h] [rbp-58h]
__int64 v11; // [rsp+20h] [rbp-48h]

if ( (int)func4(a1, 0xCAu, "gppcprog_connect") < 0 )
return 0xFFFFFFFFLL;
if ( !a2 )
{
v10 = ghid_enumerate(0LL, 0LL);
if ( v10 )
{
v5 = v10;
v11 = a1;
v9 = (__int64 *)((char *)&devices + 48 * a1);
do
{
v6 = &usb_ids;
do
{
if ( *(_WORD *)v5 == *v6 && *(_WORD *)(v5 + 2) == v6[1] )
{
v7 = *(char **)(v5 + 16);
if ( !(unsigned __int8)func2(v7) )
{
v8 = ghid_open_path(v7);
*v9 = v8;
if ( v8 )
{
*((_QWORD *)&devices + 6 * a1 + 1) = strdup(*(const char **)(v5 + 16));
goto LABEL_11;
}
}
}
v6 += 8;
}
while ( v6 != (_WORD *)((char *)&usb_ids + 256) );
if ( *v9 )
break;
v5 = *(_QWORD *)(v5 + 24);
}
while ( v5 );
}
else
{
v11 = a1;
}
LABEL_11:
ghid_free_enumeration(v10);
if ( *((_QWORD *)&devices + 6 * v11) )
goto LABEL_6;
return 0xFFFFFFFFLL;
}
if ( (unsigned __int8)func2(a2) )
return 0xFFFFFFFFLL;
v2 = ghid_open_path(a2);
v3 = (__int64 *)((char *)&devices + 48 * a1);
*v3 = v2;
if ( !v2 )
return 0xFFFFFFFFLL;
v3[1] = (__int64)strdup(a2);
LABEL_6:
result = func5(a1, 7, 0LL, 0);
if ( (char)result > 0 )
result = 1LL;
return result;
}

original_code:
int8_t gppcprog_connect(int id, const char * path)
{
  if(check_device(id, "pcprog.c", 202, __func__) < 0) { return -1; }
  int r = 0;
  if(path)
  {
    if(is_device_opened(path))
    {
      return -1;
    }
    devices[id].device = ghid_open_path(path);
    if(devices[id].device != ((void *)0))
    {
      devices[id].path = strdup(path);
    }
  }
  else
  {
    struct ghid_device_info *devs, *cur_dev;
    devs = ghid_enumerate(0x0000, 0x0000);
    for(cur_dev = devs; cur_dev != ((void *)0); cur_dev = cur_dev->next)
    {
      unsigned int i;
      for(i = 0; i < sizeof(usb_ids) / sizeof(*usb_ids); ++i)
      {
        if(cur_dev->vendor_id == usb_ids[i].vid && cur_dev->product_id == usb_ids[i].pid)
        {
          if(!is_device_opened(cur_dev->path))
          {
            if ((devices[id].device = ghid_open_path(cur_dev->path)) != ((void *)0))
            {
              devices[id].path = strdup(cur_dev->path);
              break;
            }
          }
        }
      }
      if(devices[id].device != ((void *)0))
      {
        break;
      }
    }
    ghid_free_enumeration(devs);
  }
  if (devices[id].device == ((void *)0))
  {
    return -1;
  }
  r = gpppcprog_send(id, 0x07, ((void *)0), 0);
  if (r <= 0)
  {
    return r;
  }
  return 1;
}

canonical_original_code:
char gppcprog_connect(int id, char *path)
{
  if(check_device(id, "pcprog.c", 202, __func__) < 0) { return -1; }
  int r = 0;
  if(path)
  {
    if(is_device_opened(path))
    {
      return -1;
    }
    devices[id].device = ghid_open_path(path);
    if(devices[id].device != ((void *)0))
    {
      devices[id].path = strdup(path);
    }
  }
  else
  {
    struct ghid_device_info *devs; struct ghid_device_info *cur_dev;
    devs = ghid_enumerate(0x0000, 0x0000);
    for(cur_dev = devs; cur_dev != ((void *)0); cur_dev = cur_dev->next)
    {
      unsigned int i;
      for(i = 0; i < sizeof(usb_ids) / sizeof(*usb_ids); ++i)
      {
        if(cur_dev->vendor_id == usb_ids[i].vid && cur_dev->product_id == usb_ids[i].pid)
        {
          if(!is_device_opened(cur_dev->path))
          {
            if ((devices[id].device = ghid_open_path(cur_dev->path)) != ((void *)0))
            {
              devices[id].path = strdup(cur_dev->path);
              break;
            }
          }
        }
      }
      if(devices[id].device != ((void *)0))
      {
        break;
      }
    }
    ghid_free_enumeration(devs);
  }
  if (devices[id].device == ((void *)0))
  {
    return -1;
  }
  r = gpppcprog_send(id, 0x07, ((void *)0), 0);
  if (r <= 0)
  {
    return r;
  }
  return 1;
}

variable_types:
path
char *

variable_types: r int

variable_types: struct ghid_device_info { unsigned short vendor_id; unsigned short product_id; unsigned short bcdDevice; int interface_number; char *path; struct ghid_device_info *next; } *


decompiled_code:
void __fastcall gppcprog_disconnect(unsigned int a1)
{
char *v1; // rbx

if ( (int)check_device_constprop_0(a1, 0x10Fu, "gppcprog_disconnect") >= 0 )
{
v1 = (char *)&devices + 48 * (int)a1;
if ( *(_QWORD *)v1 )
{
*((_QWORD *)v1 + 4) = 0LL;
*((_DWORD *)v1 + 4) = 0;
gpppcprog_send(a1, 8, 0LL, 0);
ghid_close(*(_QWORD *)v1);
*(_QWORD *)v1 = 0LL;
free(*((void **)v1 + 1));
*((_QWORD *)v1 + 1) = 0LL;
}
}
}

canonical_decompiled_code:
void __fastcall func9(unsigned int a1)
{
char *v1; // rbx

if ( (int)func4(a1, 0x10Fu, "gppcprog_disconnect") >= 0 )
{
v1 = (char *)&devices + 48 * (int)a1;
if ( *(_QWORD *)v1 )
{
*((_QWORD *)v1 + 4) = 0LL;
*((_DWORD *)v1 + 4) = 0;
func5(a1, 8, 0LL, 0);
ghid_close(*(_QWORD *)v1);
*(_QWORD *)v1 = 0LL;
free(*((void **)v1 + 1));
*((_QWORD *)v1 + 1) = 0LL;
}
}
}

original_code:
void gppcprog_disconnect(int id)
{
  if(check_device(id, "pcprog.c", 271, __func__) < 0) { return ; }
  if (devices[id].device != ((void *)0))
  {
    devices[id].fp_write = ((void *)0);
    devices[id].pending = 0;
    gpppcprog_send(id, 0x08, ((void *)0), 0);
    ghid_close(devices[id].device);
    devices[id].device = ((void *)0);
    free(devices[id].path);
    devices[id].path = ((void *)0);
  }
  return;
}


decompiled_code:
__int64 __fastcall gpppcprog_input(unsigned int a1, __m128i *a2, unsigned int a3)
{
__int64 v4; // rdi
int v5; // eax
bool v6; // zf
__int64 result; // rax
__m128i v8; // xmm1
__m128i v9; // xmm2
__int16 v10; // ax
__int128 v11; // [rsp+0h] [rbp-68h] BYREF
__int128 v12; // [rsp+10h] [rbp-58h] BYREF
__int128 v13; // [rsp+20h] [rbp-48h]
__int128 v14; // [rsp+30h] [rbp-38h]
char v15; // [rsp+40h] [rbp-28h]

if ( (int)check_device_constprop_0(a1, 0x127u, "gpppcprog_input") < 0 )
return 0xFFFFFFFFLL;
v15 = 0;
v11 = 0LL;
v4 = *((_QWORD *)&devices + 6 * (int)a1);
v12 = 0LL;
v13 = 0LL;
v14 = 0LL;
if ( !v4 )
return 0xFFFFFFFFLL;
if ( !a2 )
return 0xFFFFFFFFLL;
v5 = ghid_read_timeout(v4, &v11, 65LL, a3);
v6 = v5 == 0;
if ( v5 < 0 )
return 0xFFFFFFFFLL;
result = 0LL;
if ( !v6 && (_BYTE)v11 == 1 )
{
v8 = _mm_loadu_si128((const __m128i *)((char *)&v11 + 7));
v9 = _mm_loadu_si128((const __m128i *)((char *)&v12 + 7));
a2[2].m128i_i32[0] = *(_DWORD *)((char *)&v13 + 7);
v10 = *(_WORD *)((char *)&v13 + 11);
*a2 = v8;
a2[2].m128i_i16[2] = v10;
LOBYTE(v10) = BYTE13(v13);
a2[1] = v9;
a2[2].m128i_i8[6] = v10;
result = 1LL;
}
return result;
}

original_code:
int8_t gpppcprog_input(int id, GCAPI_REPORT *report, int timeout)
{
  if(check_device(id, "pcprog.c", 295, __func__) < 0) { return -1; }
  int bytesReceived;
  uint8_t rcvBuf[65] = {};
  if (devices[id].device == ((void *)0) || report == ((void *)0))
    return (-1);
  bytesReceived = ghid_read_timeout(devices[id].device, rcvBuf, sizeof(rcvBuf), timeout);
  if (bytesReceived < 0)
  {
    return (-1);
  }
  else if (bytesReceived && rcvBuf[0] == 0x01)
  {
    *report = *(GCAPI_REPORT *)(rcvBuf + 7);
    return (1);
  }
  return (0);
}

canonical_original_code:
char gpppcprog_input(int id, struct GCAPI_REPORT *report, int timeout)
{
  if(check_device(id, "pcprog.c", 295, __func__) < 0) { return -1; }
  int bytesReceived;
  unsigned char rcvBuf[65] = {};
  if (devices[id].device == ((void *)0) || report == ((void *)0))
    return (-1);
  bytesReceived = ghid_read_timeout(devices[id].device, rcvBuf, sizeof(rcvBuf), timeout);
  if (bytesReceived < 0)
  {
    return (-1);
  }
  else if (bytesReceived && rcvBuf[0] == 0x01)
  {
    *report = *(struct GCAPI_REPORT *)(rcvBuf + 7);
    return (1);
  }
  return (0);
}

variable_types: struct GCAPI_REPORT { unsigned char controller; unsigned char console; unsigned char led[4]; unsigned char rumble[2]; unsigned char battery_level; struct { char value; } input[30]; } *

variable_types: timeout int

variable_types: bytesReceived int

variable_types:
rcvBuf
unsigned char [65]


decompiled_code:
__int64 __fastcall gpppcprog_start_async(unsigned int a1, _QWORD *a2)
{
_QWORD *v2; // rbx
__int64 v3; // rdi
__int64 result; // rax
__int64 v5[9]; // [rsp+0h] [rbp-48h] BYREF

if ( (int)check_device_constprop_0(a1, 0x168u, "gpppcprog_start_async") < 0 )
goto LABEL_4;
v2 = (_QWORD *)((char *)&devices + 48 * (int)a1);
v3 = *v2;
v2[3] = *a2;
v2[4] = a2[1];
v2[5] = a2[2];
v5[0] = (__int64)read_callback;
v5[1] = (__int64)write_callback;
v5[2] = (__int64)close_callback;
v5[3] = a2[3];
v5[4] = a2[4];
if ( (int)ghid_register(v3, v2, v5) < 0 )
LABEL_4:
result = 0xFFFFFFFFLL;
else
result = (unsigned int)((int)ghid_poll(*v2) >> 31);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned int a1, _QWORD *a2)
{
_QWORD *v2; // rbx
__int64 v3; // rdi
__int64 result; // rax
__int64 v5[9]; // [rsp+0h] [rbp-48h] BYREF

if ( (int)func4(a1, 0x168u, "gpppcprog_start_async") < 0 )
goto LABEL_4;
v2 = (_QWORD *)((char *)&devices + 48 * (int)a1);
v3 = *v2;
v2[3] = *a2;
v2[4] = a2[1];
v2[5] = a2[2];
v5[0] = (__int64)read_callback;
v5[1] = (__int64)write_callback;
v5[2] = (__int64)close_callback;
v5[3] = a2[3];
v5[4] = a2[4];
if ( (int)ghid_register(v3, v2, v5) < 0 )
LABEL_4:
result = 0xFFFFFFFFLL;
else
result = (unsigned int)((int)ghid_poll(*v2) >> 31);
return result;
}

original_code:
int8_t gpppcprog_start_async(int id, const GHID_CALLBACKS * callbacks)
{
  if(check_device(id, "pcprog.c", 360, __func__) < 0) { return -1; }
  devices[id].fp_read = callbacks->fp_read;
  devices[id].fp_write = callbacks->fp_write;
  devices[id].fp_close = callbacks->fp_close;
  GHID_CALLBACKS ghid_callbacks = {
          .fp_read = read_callback,
          .fp_write = write_callback,
          .fp_close = close_callback,
          .fp_register = callbacks->fp_register,
          .fp_remove = callbacks->fp_remove,
  };
  int ret = ghid_register(devices[id].device, devices + id, &ghid_callbacks);
  if (ret < 0) {
    return -1;
  }
  ret = ghid_poll(devices[id].device);
  if (ret < 0) {
    return -1;
  }
  return 0;
}

canonical_original_code:
char gpppcprog_start_async(int id, struct GHID_CALLBACKS *callbacks)
{
  if(check_device(id, "pcprog.c", 360, __func__) < 0) { return -1; }
  devices[id].fp_read = callbacks->fp_read;
  devices[id].fp_write = callbacks->fp_write;
  devices[id].fp_close = callbacks->fp_close;
  struct GHID_CALLBACKS ghid_callbacks = {
          .fp_read = read_callback,
          .fp_write = write_callback,
          .fp_close = close_callback,
          .fp_register = callbacks->fp_register,
          .fp_remove = callbacks->fp_remove,
  };
  int ret = ghid_register(devices[id].device, devices + id, &ghid_callbacks);
  if (ret < 0) {
    return -1;
  }
  ret = ghid_poll(devices[id].device);
  if (ret < 0) {
    return -1;
  }
  return 0;
}

variable_types: struct GHID_CALLBACKS { int (*fp_read)(void *user, void *buf, int status); int (*fp_write)(void *user, int status); int (*fp_close)(void *user); int (*fp_register)(int fd, void *user, struct GPOLL_CALLBACKS { int (*fp_read)(void *user); int (*fp_write)(void *user); int (*fp_close)(void *user); } *callbacks); int (*fp_remove)(int fd); } *

variable_types: ret int

user_defined_types: struct GHID_CALLBACKS { int (*fp_read)(void *user, void *buf, int status); int (*fp_write)(void *user, int status); int (*fp_close)(void *user); int (*fp_register)(int fd, void *user, struct GPOLL_CALLBACKS *callbacks); int (*fp_remove)(int fd); }