decompiled_code:
int __fastcall detect_cdimage(_QWORD *a1, unsigned int a2)
{
unsigned __int64 v3; // rax
unsigned __int8 *v4; // r12
int v5; // esi
_QWORD *v6; // rbx
void *s1; // [rsp+8h] [rbp-20h] BYREF

v3 = get_buffer(a1, 0LL, 2352LL, &s1);
if ( v3 > 0x92F )
{
v4 = (unsigned __int8 *)s1;
LODWORD(v3) = memcmp(s1, &syncbytes, 0xCuLL);
if ( !(_DWORD)v3 )
{
LODWORD(v3) = v4[15];
if ( (_DWORD)v3 == 1 )
{
print_line(a2, "Raw CD image, Mode 1");
v5 = 16;
}
else
{
if ( (_DWORD)v3 != 2 )
return v3;
print_line(a2, "Raw CD image, Mode 2, assuming Form 1");
v5 = 24;
}
v6 = init_cdimage_source(a1[3], *a1 + v5);
analyze_source(v6, a2);
close_source(v6);
LODWORD(v3) = stop_detect();
}
}
return v3;
}

canonical_decompiled_code:
int __fastcall func1(_QWORD *a1, unsigned int a2)
{
unsigned __int64 v3; // rax
unsigned __int8 *v4; // r12
int v5; // esi
_QWORD *v6; // rbx
void *s1; // [rsp+8h] [rbp-20h] BYREF

v3 = get_buffer(a1, 0LL, 2352LL, &s1);
if ( v3 > 0x92F )
{
v4 = (unsigned __int8 *)s1;
LODWORD(v3) = memcmp(s1, &syncbytes, 0xCuLL);
if ( !(_DWORD)v3 )
{
LODWORD(v3) = v4[15];
if ( (_DWORD)v3 == 1 )
{
print_line(a2, "Raw CD image, Mode 1");
v5 = 16;
}
else
{
if ( (_DWORD)v3 != 2 )
return v3;
print_line(a2, "Raw CD image, Mode 2, assuming Form 1");
v5 = 24;
}
v6 = init_cdimage_source(a1[3], *a1 + v5);
analyze_source(v6, a2);
close_source(v6);
LODWORD(v3) = stop_detect();
}
}
return v3;
}

original_code:
void detect_cdimage(SECTION *section, int level)
{
  int mode, off;
  unsigned char *buf;
  SOURCE *s;
  if (get_buffer(section, 0, 2352, (void **)&buf) < 2352)
    return;
  if (memcmp(buf, syncbytes, 12) != 0)
    return;
  mode = buf[15];
  if (mode == 1) {
    print_line(level, "Raw CD image, Mode 1");
    off = 16;
  } else if (mode == 2) {
    print_line(level, "Raw CD image, Mode 2, assuming Form 1");
    off = 24;
  } else
    return;
  s = init_cdimage_source(section->source, section->pos + off);
  analyze_source(s, level);
  close_source(s);
  stop_detect();
}

canonical_original_code:
void detect_cdimage(struct section *section, int level)
{
  int mode; int off;
  unsigned char *buf;
  struct source *s;
  if (get_buffer(section, 0, 2352, (void **)&buf) < 2352)
    return;
  if (memcmp(buf, syncbytes, 12) != 0)
    return;
  mode = buf[15];
  if (mode == 1) {
    print_line(level, "Raw CD image, Mode 1");
    off = 16;
  } else if (mode == 2) {
    print_line(level, "Raw CD image, Mode 2, assuming Form 1");
    off = 24;
  } else
    return;
  s = init_cdimage_source(section->source, section->pos + off);
  analyze_source(s, level);
  close_source(s);
  stop_detect();
}

variable_types: struct section { unsigned long long pos; int flags; struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *source; } *

variable_types: level int

variable_types: mode int

variable_types: off int

variable_types:
buf
unsigned char *

user_defined_types: struct section { unsigned long long pos; int flags; struct source *source; }


repo: rumca-js/disktype

decompiled_code:
__int64 __fastcall print_kind(int a1, __int64 a2, int a3)
{
const char *v3; // rbx
char v5[264]; // [rsp+0h] [rbp-108h] BYREF

v3 = "Regular file";
if ( a1 )
{
v3 = "Block device";
if ( a1 != 1 )
{
v3 = "Character device";
if ( a1 != 2 )
v3 = "Unknown kind";
}
}
if ( !a3 )
return print_line(0LL, "%s, unknown size", v3);
format_size_verbose(v5);
return print_line(0LL, "%s, size %s", v3, v5);
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, __int64 a2, int a3)
{
const char *v3; // rbx
char v5[264]; // [rsp+0h] [rbp-108h] BYREF

v3 = "Regular file";
if ( a1 )
{
v3 = "Block device";
if ( a1 != 1 )
{
v3 = "Character device";
if ( a1 != 2 )
v3 = "Unknown kind";
}
}
if ( !a3 )
return print_line(0LL, "%s, unknown size", v3);
format_size_verbose(v5);
return print_line(0LL, "%s, size %s", v3, v5);
}

original_code:
static void print_kind(int filekind, u8 size, int size_known)
{
  char buf[256], *kindname;
  if (filekind == 0)
    kindname = "Regular file";
  else if (filekind == 1)
    kindname = "Block device";
  else if (filekind == 2)
    kindname = "Character device";
  else
    kindname = "Unknown kind";
  if (size_known) {
    format_size_verbose(buf, size);
    print_line(0, "%s, size %s", kindname, buf);
  } else {
    print_line(0, "%s, unknown size", kindname);
  }
}

canonical_original_code:
static void print_kind(int filekind, unsigned long long size, int size_known)
{
  char buf[256]; char *kindname;
  if (filekind == 0)
    kindname = "Regular file";
  else if (filekind == 1)
    kindname = "Block device";
  else if (filekind == 2)
    kindname = "Character device";
  else
    kindname = "Unknown kind";
  if (size_known) {
    format_size_verbose(buf, size);
    print_line(0, "%s, size %s", kindname, buf);
  } else {
    print_line(0, "%s, unknown size", kindname);
  }
}

variable_types: filekind int

variable_types:
size
unsigned long long

variable_types:
buf
char [256]

variable_types:
kindname
char *

return_type: void


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char **v3; // rbx
int result; // eax

if ( argc <= 1 )
{
fprintf(stderr, "Usage: %s <device/file>...\n", "disktype");
result = 1;
}
else
{
print_line(0LL, (const char *)&unk_36B, envp);
v3 = (char **)(argv + 1);
do
{
analyze_file(*v3);
print_line(0LL, (const char *)&unk_36B);
++v3;
}
while ( v3 != (char **)&argv[(unsigned int)(argc - 2) + 2] );
result = 0;
}
return result;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char **v3; // rbx
int result; // eax

if ( argc <= 1 )
{
fprintf(stderr, "Usage: %s <device/file>...\n", "disktype");
result = 1;
}
else
{
print_line(0LL, (const char *)&unk_36B, envp);
v3 = (char **)(argv + 1);
do
{
func1(*v3);
print_line(0LL, (const char *)&unk_36B);
++v3;
}
while ( v3 != (char **)&argv[(unsigned int)(argc - 2) + 2] );
result = 0;
}
return result;
}

original_code:
int main(int argc, char *argv[])
{
  int i;
  if (argc < 2) {
    fprintf(stderr, "Usage: %s <device/file>...\n", "disktype");
    return 1;
  }
  print_line(0, "");
  for (i = 1; i < argc; i++) {
    analyze_file(argv[i]);
    print_line(0, "");
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: i int

return_type: int


decompiled_code:
void __fastcall analyze_file(char *file)
{
int v1; // eax
const char *v2; // rdx
__off_t v3; // rbp
unsigned int v4; // er12
const char *v5; // rdx
__int64 v6; // rbx
int v7; // eax
unsigned int v8; // ebp
struct stat64 v9; // [rsp+0h] [rbp-A8h] BYREF

print_line(0LL, "--- %s", file);
if ( stat64(file, &v9) < 0 )
{
errore("Can't stat %.300s", file);
return;
}
v1 = v9.st_mode & 0xF000;
switch ( v1 )
{
case 0x8000:
v3 = v9.st_size;
print_kind(0, v9.st_size, 1);
if ( !v3 )
return;
v4 = 0;
LABEL_20:
v7 = open64(file, 0);
v8 = v7;
if ( v7 < 0 )
{
errore("Can't open %.300s", file);
return;
}
if ( v4 == 2 )
{
if ( isatty(v7) )
{
error((int)"%.300s: Is a TTY device", (int)file, v5);
return;
}
v6 = init_file_source(v8, 2LL);
}
else
{
v6 = init_file_source((unsigned int)v7, v4);
if ( !v4 )
goto LABEL_23;
}
print_kind(v4, *(_QWORD *)v6, *(_DWORD *)(v6 + 8));
LABEL_23:
analyze_source(v6, 0LL);
close_source(v6);
return;
case 0x6000:
v4 = 1;
goto LABEL_20;
case 0x2000:
v4 = 2;
goto LABEL_20;
}
v2 = "Is a directory";
if ( v1 != 0x4000 )
{
v2 = "Is a FIFO";
if ( v1 != 4096 )
{
v2 = "Is a socket";
if ( v1 != 49152 )
v2 = "Is an unknown kind of special file";
}
}
error((int)"%.300s: %s", (int)file, v2);
}

canonical_decompiled_code:
void __fastcall func1(char *file)
{
int v1; // eax
const char *v2; // rdx
__off_t v3; // rbp
unsigned int v4; // er12
const char *v5; // rdx
__int64 v6; // rbx
int v7; // eax
unsigned int v8; // ebp
struct stat64 v9; // [rsp+0h] [rbp-A8h] BYREF

print_line(0LL, "--- %s", file);
if ( stat64(file, &v9) < 0 )
{
errore("Can't stat %.300s", file);
return;
}
v1 = v9.st_mode & 0xF000;
switch ( v1 )
{
case 0x8000:
v3 = v9.st_size;
func0(0, v9.st_size, 1);
if ( !v3 )
return;
v4 = 0;
LABEL_20:
v7 = open64(file, 0);
v8 = v7;
if ( v7 < 0 )
{
errore("Can't open %.300s", file);
return;
}
if ( v4 == 2 )
{
if ( isatty(v7) )
{
error((int)"%.300s: Is a TTY device", (int)file, v5);
return;
}
v6 = init_file_source(v8, 2LL);
}
else
{
v6 = init_file_source((unsigned int)v7, v4);
if ( !v4 )
goto LABEL_23;
}
func0(v4, *(_QWORD *)v6, *(_DWORD *)(v6 + 8));
LABEL_23:
analyze_source(v6, 0LL);
close_source(v6);
return;
case 0x6000:
v4 = 1;
goto LABEL_20;
case 0x2000:
v4 = 2;
goto LABEL_20;
}
v2 = "Is a directory";
if ( v1 != 0x4000 )
{
v2 = "Is a FIFO";
if ( v1 != 4096 )
{
v2 = "Is a socket";
if ( v1 != 49152 )
v2 = "Is an unknown kind of special file";
}
}
error((int)"%.300s: %s", (int)file, v2);
}

original_code:
static void analyze_file(const char *filename)
{
  int fd, filekind;
  u8 filesize;
  struct stat sb;
  char *reason;
  SOURCE *s;
  print_line(0, "--- %s", filename);
  if (stat(filename, &sb) < 0) {
    errore("Can't stat %.300s", filename);
    return;
  }
  filekind = 0;
  filesize = 0;
  reason = ((void *)0);
  if (((((sb.st_mode)) & 0170000) == (0100000))) {
    filesize = sb.st_size;
    print_kind(filekind, filesize, 1);
  } else if (((((sb.st_mode)) & 0170000) == (0060000)))
    filekind = 1;
  else if (((((sb.st_mode)) & 0170000) == (0020000)))
    filekind = 2;
  else if (((((sb.st_mode)) & 0170000) == (0040000)))
    reason = "Is a directory";
  else if (((((sb.st_mode)) & 0170000) == (0010000)))
    reason = "Is a FIFO";
  else if (((((sb.st_mode)) & 0170000) == (0140000)))
    reason = "Is a socket";
  else
    reason = "Is an unknown kind of special file";
  if (reason != ((void *)0)) {
    error("%.300s: %s", filename, reason);
    return;
  }
  if (filekind == 0 && filesize == 0)
    return;
  fd = open(filename, 00);
  if (fd < 0) {
    errore("Can't open %.300s", filename);
    return;
  }
  if (filekind == 2) {
    if (isatty(fd)) {
      error("%.300s: Is a TTY device", filename);
      return;
    }
  }
  s = init_file_source(fd, filekind);
  if (filekind != 0)
    print_kind(filekind, s->size, s->size_known);
  analyze_source(s, 0);
  close_source(s);
}

canonical_original_code:
static void analyze_file(char *filename)
{
  int fd; int filekind;
  unsigned long long filesize;
  struct stat sb;
  char *reason;
  struct source *s;
  print_line(0, "--- %s", filename);
  if (stat(filename, &sb) < 0) {
    errore("Can't stat %.300s", filename);
    return;
  }
  filekind = 0;
  filesize = 0;
  reason = ((void *)0);
  if (((((sb.st_mode)) & 0170000) == (0100000))) {
    filesize = sb.st_size;
    print_kind(filekind, filesize, 1);
  } else if (((((sb.st_mode)) & 0170000) == (0060000)))
    filekind = 1;
  else if (((((sb.st_mode)) & 0170000) == (0020000)))
    filekind = 2;
  else if (((((sb.st_mode)) & 0170000) == (0040000)))
    reason = "Is a directory";
  else if (((((sb.st_mode)) & 0170000) == (0010000)))
    reason = "Is a FIFO";
  else if (((((sb.st_mode)) & 0170000) == (0140000)))
    reason = "Is a socket";
  else
    reason = "Is an unknown kind of special file";
  if (reason != ((void *)0)) {
    error("%.300s: %s", filename, reason);
    return;
  }
  if (filekind == 0 && filesize == 0)
    return;
  fd = open(filename, 00);
  if (fd < 0) {
    errore("Can't open %.300s", filename);
    return;
  }
  if (filekind == 2) {
    if (isatty(fd)) {
      error("%.300s: Is a TTY device", filename);
      return;
    }
  }
  s = init_file_source(fd, filekind);
  if (filekind != 0)
    print_kind(filekind, s->size, s->size_known);
  analyze_source(s, 0);
  close_source(s);
}

variable_types:
filename
char *

variable_types: fd int

variable_types:
filesize
unsigned long long

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

variable_types:
reason
char *

variable_types: struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *

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


decompiled_code:
size_t __fastcall get_buffer_real(__int64 a1, unsigned __int64 a2, size_t a3, unsigned __int64 a4, unsigned __int64 a5)
{
size_t v5; // rbx
size_t v6; // r14
size_t v7; // rax
size_t v8; // rbx
_QWORD *v9; // r15
_QWORD *v10; // rax
unsigned __int64 v11; // rdx
size_t v12; // rdx
const void *v13; // r13
const char *v14; // rdx
unsigned __int64 v15; // rax
size_t v16; // r12
unsigned __int64 v17; // rbp
_QWORD *v18; // rax
_QWORD *v19; // rbx
size_t v20; // rax
void *v22; // rdi
unsigned __int64 v23; // [rsp+8h] [rbp-60h]
unsigned __int64 v25; // [rsp+18h] [rbp-50h]
char *dest; // [rsp+20h] [rbp-48h]

dest = (char *)a4;
v5 = a3;
if ( a3 )
{
v6 = a3;
v5 = 0LL;
if ( a5 | a4 )
{
if ( *(_DWORD *)(a1 + 8) )
{
v7 = *(_QWORD *)a1;
if ( *(_QWORD *)a1 <= a2 )
return v5;
v8 = a3 + a2;
if ( v7 < a3 + a2 )
{
v6 = v7 - a2;
v8 = *(_QWORD *)a1;
}
}
else
{
v8 = a3 + a2;
}
v9 = *(_QWORD **)(a1 + 16);
if ( !v9 )
{
v9 = malloc(0x70uLL);
if ( !v9 )
bailout("Out of memory");
memset(v9, 0, 0x70uLL);
*(_QWORD *)(a1 + 16) = v9;
}
v22 = (void *)v9[13];
if ( v22 )
{
free(v22);
v9[13] = 0LL;
}
v17 = a2 & 0xFFFFFFFFFFFFF000LL;
v25 = (v8 - 1) & 0xFFFFFFFFFFFFF000LL;
if ( (a2 & 0xFFFFFFFFFFFFF000LL) == v25 )
{
v10 = ensure_chunk(a1, (__int64)v9, a2 & 0xFFFFFFFFFFFFF000LL);
v11 = v10[1];
v5 = 0LL;
if ( v11 > a2 )
{
v12 = v11 - a2;
v5 = v6;
if ( v12 <= v6 )
v5 = v12;
v13 = (const void *)(v10[3] + a2 - *v10);
if ( dest )
memcpy(dest, v13, v5);
if ( a5 )
*(_QWORD *)a5 = v13;
}
}
else if ( dest || (dest = (char *)malloc(v6), (v9[13] = dest) != 0LL) )
{
if ( v17 > v25 )
{
v23 = 0LL;
}
else
{
v23 = 0LL;
do
{
v18 = ensure_chunk(a1, (__int64)v9, v17);
v19 = v18;
if ( a2 > v17 )
{
v15 = v18[1];
v16 = 0LL;
if ( v15 > a2 )
{
v16 = v15 - a2;
memcpy(dest, (const void *)(v19[3] + (a2 & 0xFFF)), v15 - a2);
}
}
else
{
v16 = v6 - v23;
v20 = v18[2];
if ( v6 - v23 > v20 )
v16 = v20;
if ( v16 )
memcpy(&dest[v23], (const void *)v19[3], v16);
}
v23 += v16;
if ( v19[2] <= 0xFFFuLL )
break;
v17 += 4096LL;
}
while ( v25 >= v17 );
}
v5 = v23;
if ( v6 <= v23 )
v5 = v6;
if ( a5 )
*(_QWORD *)a5 = dest;
}
else
{
error((int)"Out of memory, still going", a2, v14);
v5 = 0LL;
}
}
}
return v5;
}

original_code:
u8 get_buffer_real(SOURCE *s, u8 pos, u8 len, void *inbuf, void **outbuf)
{
  CACHE *cache;
  CHUNK *c;
  u8 end, first_chunk, last_chunk, curr_chunk, got, tocopy;
  void *mybuf;
  if (len == 0 || (inbuf == ((void *)0) && outbuf == ((void *)0)))
    return 0;
  if (s->size_known && pos >= s->size) {
    return 0;
  }
  end = pos + len;
  if (s->size_known && end > s->size) {
    end = s->size;
    len = end - pos;
  }
  cache = (CACHE *)s->cache_head;
  if (cache == ((void *)0)) {
    cache = (CACHE *)malloc(sizeof(CACHE));
    if (cache == ((void *)0))
      bailout("Out of memory");
    memset(cache, 0, sizeof(CACHE));
    s->cache_head = (void *)cache;
  }
  if (cache->tempbuf != ((void *)0)) {
    free(cache->tempbuf);
    cache->tempbuf = ((void *)0);
  }
  first_chunk = pos & ~((1<<(12))-1);
  last_chunk = (end - 1) & ~((1<<(12))-1);
  if (last_chunk == first_chunk) {
    c = ensure_chunk(s, cache, first_chunk);
    if (pos >= c->end)
      return 0;
    len = (((len) < (c->end - pos)) ? (len) : (c->end - pos));
    mybuf = c->buf + (pos - c->start);
    if (inbuf)
      memcpy(inbuf, mybuf, len);
    if (outbuf)
      *outbuf = mybuf;
    return len;
  } else {
    if (inbuf) {
      mybuf = inbuf;
    } else {
      cache->tempbuf = malloc(len);
      if (cache->tempbuf == ((void *)0)) {
 error("Out of memory, still going");
 return 0;
      }
      mybuf = cache->tempbuf;
    }
    got = 0;
    for (curr_chunk = first_chunk; curr_chunk <= last_chunk;
  curr_chunk += (1<<(12))) {
      c = ensure_chunk(s, cache, curr_chunk);
      if (pos > curr_chunk) {
 if (c->end > pos) {
   tocopy = c->end - pos;
   memcpy(mybuf, c->buf + (pos & ((1<<(12))-1)), tocopy);
 } else
   tocopy = 0;
      } else {
 tocopy = (((c->len) < (len - got)) ? (c->len) : (len - got));
 if (tocopy)
   memcpy(mybuf + got, c->buf, tocopy);
      }
      got += tocopy;
      if (c->len < (1<<(12)))
 break;
    }
    len = (((len) < (got)) ? (len) : (got));
    if (outbuf)
      *outbuf = mybuf;
    return len;
  }
}

canonical_original_code:
unsigned long long get_buffer_real(struct source *s, unsigned long long pos, unsigned long long len, void *inbuf, void **outbuf)
{
  struct cache *cache;
  struct chunk *c;
  unsigned long long end; unsigned long long first_chunk; unsigned long long last_chunk; unsigned long long curr_chunk; unsigned long long got; unsigned long long tocopy;
  void *mybuf;
  if (len == 0 || (inbuf == ((void *)0) && outbuf == ((void *)0)))
    return 0;
  if (s->size_known && pos >= s->size) {
    return 0;
  }
  end = pos + len;
  if (s->size_known && end > s->size) {
    end = s->size;
    len = end - pos;
  }
  cache = (struct cache *)s->cache_head;
  if (cache == ((void *)0)) {
    cache = (struct cache *)malloc(sizeof(CACHE));
    if (cache == ((void *)0))
      bailout("Out of memory");
    memset(cache, 0, sizeof(CACHE));
    s->cache_head = (void *)cache;
  }
  if (cache->tempbuf != ((void *)0)) {
    free(cache->tempbuf);
    cache->tempbuf = ((void *)0);
  }
  first_chunk = pos & ~((1<<(12))-1);
  last_chunk = (end - 1) & ~((1<<(12))-1);
  if (last_chunk == first_chunk) {
    c = ensure_chunk(s, cache, first_chunk);
    if (pos >= c->end)
      return 0;
    len = (((len) < (c->end - pos)) ? (len) : (c->end - pos));
    mybuf = c->buf + (pos - c->start);
    if (inbuf)
      memcpy(inbuf, mybuf, len);
    if (outbuf)
      *outbuf = mybuf;
    return len;
  } else {
    if (inbuf) {
      mybuf = inbuf;
    } else {
      cache->tempbuf = malloc(len);
      if (cache->tempbuf == ((void *)0)) {
 error("Out of memory, still going");
 return 0;
      }
      mybuf = cache->tempbuf;
    }
    got = 0;
    for (curr_chunk = first_chunk; curr_chunk <= last_chunk;
  curr_chunk += (1<<(12))) {
      c = ensure_chunk(s, cache, curr_chunk);
      if (pos > curr_chunk) {
 if (c->end > pos) {
   tocopy = c->end - pos;
   memcpy(mybuf, c->buf + (pos & ((1<<(12))-1)), tocopy);
 } else
   tocopy = 0;
      } else {
 tocopy = (((c->len) < (len - got)) ? (c->len) : (len - got));
 if (tocopy)
   memcpy(mybuf + got, c->buf, tocopy);
      }
      got += tocopy;
      if (c->len < (1<<(12)))
 break;
    }
    len = (((len) < (got)) ? (len) : (got));
    if (outbuf)
      *outbuf = mybuf;
    return len;
  }
}

variable_types:
pos
unsigned long long

variable_types:
len
unsigned long long

variable_types:
inbuf
void *

variable_types:
outbuf
void **

variable_types: struct cache { struct chunk { unsigned long long start; void *buf; struct chunk *next; } *hashtab[-1]; void *tempbuf; } *

variable_types:
end
unsigned long long

variable_types:
got
unsigned long long

variable_types:
tocopy
unsigned long long

variable_types:
mybuf
void *

return_type: unsigned long long

user_defined_types: struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); }

user_defined_types: struct cache { struct chunk *hashtab[-1]; void *tempbuf; }


decompiled_code:
size_t __fastcall get_buffer(_QWORD *a1, __int64 a2, size_t a3, unsigned __int64 a4)
{
return get_buffer_real(a1[3], *a1 + a2, a3, 0LL, a4);
}

canonical_decompiled_code:
size_t __fastcall func1(_QWORD *a1, __int64 a2, size_t a3, unsigned __int64 a4)
{
return func0(a1[3], *a1 + a2, a3, 0LL, a4);
}

original_code:
u8 get_buffer(SECTION *section, u8 pos, u8 len, void **buf)
{
  SOURCE *s;
  s = section->source;
  pos += section->pos;
  return get_buffer_real(s, pos, len, ((void *)0), buf);
}

canonical_original_code:
unsigned long long get_buffer(struct section *section, unsigned long long pos, unsigned long long len, void **buf)
{
  struct source *s;
  s = section->source;
  pos += section->pos;
  return get_buffer_real(s, pos, len, ((void *)0), buf);
}

variable_types: struct section { unsigned long long pos; int flags; struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *source; } *

variable_types:
buf
void **


original_code:
void close_source(SOURCE *s)
{
  CACHE *cache;
  int hpos;
  CHUNK *chain, *trav, *nexttrav;
  cache = (CACHE *)s->cache_head;
  if (cache != ((void *)0)) {
    if (cache->tempbuf != ((void *)0))
      free(cache->tempbuf);
    for (hpos = 0; hpos < (13); hpos++) {
      chain = cache->hashtab[hpos];
      if (chain != ((void *)0)) {
 trav = chain;
 do {
   nexttrav = trav->next;
   free(trav->buf);
   free(trav);
   trav = nexttrav;
 } while (trav != chain);
      }
    }
  }
  if (s->close != ((void *)0))
    (*s->close)(s);
  free(s);
}

canonical_original_code:
void close_source(struct source *s)
{
  struct cache *cache;
  int hpos;
  struct chunk *chain; struct chunk *trav; struct chunk *nexttrav;
  cache = (struct cache *)s->cache_head;
  if (cache != ((void *)0)) {
    if (cache->tempbuf != ((void *)0))
      free(cache->tempbuf);
    for (hpos = 0; hpos < (13); hpos++) {
      chain = cache->hashtab[hpos];
      if (chain != ((void *)0)) {
 trav = chain;
 do {
   nexttrav = trav->next;
   free(trav->buf);
   free(trav);
   trav = nexttrav;
 } while (trav != chain);
      }
    }
  }
  if (s->close != ((void *)0))
    (*s->close)(s);
  free(s);
}

variable_types: hpos int

variable_types: struct chunk { unsigned long long start; void *buf; struct chunk *next; } *


decompiled_code:
int __fastcall close_file(__int64 a1)
{
int v1; // edi
int result; // eax

v1 = *(_DWORD *)(a1 + 88);
if ( v1 >= 0 )
result = close(v1);
return result;
}

canonical_decompiled_code:
int __fastcall func0(__int64 a1)
{
int v1; // edi
int result; // eax

v1 = *(_DWORD *)(a1 + 88);
if ( v1 >= 0 )
result = close(v1);
return result;
}

original_code:
static void close_file(SOURCE *s)
{
  int fd = ((FILE_SOURCE *)s)->fd;
  if (fd >= 0)
    close(fd);
}

canonical_original_code:
static void close_file(struct source *s)
{
  int fd = ((FILE_SOURCE *)s)->fd;
  if (fd >= 0)
    close(fd);
}

variable_types: fd int


decompiled_code:
__int64 __fastcall read_file(__int64 a1, __off64_t a2, size_t a3, char *a4)
{
int v6; // er14
__int64 v7; // r13
int v8; // eax
ssize_t v10; // rax

v6 = *(_DWORD *)(a1 + 88);
if ( a2 == lseek64(v6, a2, 0) )
{
v7 = 0LL;
if ( a3 )
{
while ( 1 )
{
v10 = read(v6, a4, a3);
if ( v10 < 0 )
{
v8 = *_errno_location();
if ( v8 != 4 && v8 != 11 )
{
errore("Data read failed at position %llu", a2 + v7);
return v7;
}
}
else
{
if ( !v10 )
return v7;
a3 -= v10;
v7 += v10;
a4 += v10;
}
if ( !a3 )
return v7;
}
}
v7 = 0LL;
}
else
{
errore("Seek to %llu failed", a2);
v7 = 0LL;
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __off64_t a2, size_t a3, char *a4)
{
int v6; // er14
__int64 v7; // r13
int v8; // eax
ssize_t v10; // rax

v6 = *(_DWORD *)(a1 + 88);
if ( a2 == lseek64(v6, a2, 0) )
{
v7 = 0LL;
if ( a3 )
{
while ( 1 )
{
v10 = read(v6, a4, a3);
if ( v10 < 0 )
{
v8 = *_errno_location();
if ( v8 != 4 && v8 != 11 )
{
errore("Data read failed at position %llu", a2 + v7);
return v7;
}
}
else
{
if ( !v10 )
return v7;
a3 -= v10;
v7 += v10;
a4 += v10;
}
if ( !a3 )
return v7;
}
}
v7 = 0LL;
}
else
{
errore("Seek to %llu failed", a2);
v7 = 0LL;
}
return v7;
}

original_code:
static u8 read_file(SOURCE *s, u8 pos, u8 len, void *buf)
{
  off_t result_seek;
  ssize_t result_read;
  char *p;
  u8 got;
  int fd = ((FILE_SOURCE *)s)->fd;
  result_seek = lseek(fd, pos, 0);
  if (result_seek != pos) {
    errore("Seek to %llu failed", pos);
    return 0;
  }
  p = (char *)buf;
  got = 0;
  while (len > 0) {
    result_read = read(fd, p, len);
    if (result_read < 0) {
      if ((*__errno_location ()) == 4 || (*__errno_location ()) == 11)
 continue;
      errore("Data read failed at position %llu", pos + got);
      break;
    } else if (result_read == 0) {
      break;
    } else {
      len -= result_read;
      got += result_read;
      p += result_read;
    }
  }
  return got;
}

canonical_original_code:
static unsigned long long read_file(struct source *s, unsigned long long pos, unsigned long long len, void *buf)
{
  long result_seek;
  long result_read;
  char *p;
  unsigned long long got;
  int fd = ((FILE_SOURCE *)s)->fd;
  result_seek = lseek(fd, pos, 0);
  if (result_seek != pos) {
    errore("Seek to %llu failed", pos);
    return 0;
  }
  p = (char *)buf;
  got = 0;
  while (len > 0) {
    result_read = read(fd, p, len);
    if (result_read < 0) {
      if ((*__errno_location ()) == 4 || (*__errno_location ()) == 11)
 continue;
      errore("Data read failed at position %llu", pos + got);
      break;
    } else if (result_read == 0) {
      break;
    } else {
      len -= result_read;
      got += result_read;
      p += result_read;
    }
  }
  return got;
}

variable_types:
buf
void *

variable_types:
p
char *


decompiled_code:
_BOOL8 __fastcall analyze_file(__int64 a1, unsigned int a2)
{
return (unsigned int)analyze_cdaccess(*(unsigned int *)(a1 + 88), a1, a2) != 0;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(__int64 a1, unsigned int a2)
{
return (unsigned int)analyze_cdaccess(*(unsigned int *)(a1 + 88), a1, a2) != 0;
}

original_code:
static int analyze_file(SOURCE *s, int level)
{
  if (analyze_cdaccess(((FILE_SOURCE *)s)->fd, s, level))
    return 1;
  return 0;
}

canonical_original_code:
static int analyze_file(struct source *s, int level)
{
  if (analyze_cdaccess(((struct file_source *)s)->fd, s, level))
    return 1;
  return 0;
}

variable_types: struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *

variable_types: level int

user_defined_types: struct file_source { struct source c; int fd; }


original_code:
void analyze_recursive(SECTION *section, int level,
                       u8 rel_pos, u8 size, int flags)
{
  SOURCE *s;
  SECTION rs;
  if (rel_pos == 0 && (flags & (0x0001)) == 0)
    return;
  s = section->source;
  if (s->size_known && (section->pos + rel_pos >= s->size))
    return;
  rs.source = s;
  rs.pos = section->pos + rel_pos;
  rs.size = size;
  rs.flags = section->flags | flags;
  detect(&rs, level);
}

canonical_original_code:
void analyze_recursive(struct section *section, int level, unsigned long long rel_pos, unsigned long long size, int flags)
{
  struct source *s;
  struct section rs;
  if (rel_pos == 0 && (flags & (0x0001)) == 0)
    return;
  s = section->source;
  if (s->size_known && (section->pos + rel_pos >= s->size))
    return;
  rs.source = s;
  rs.pos = section->pos + rel_pos;
  rs.size = size;
  rs.flags = section->flags | flags;
  detect(&rs, level);
}

variable_types:
size
unsigned long long

variable_types: flags int

variable_types: struct section { unsigned long long pos; int flags; struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *source; }


decompiled_code:
void stop_detect()
{
stop_flag = 1;
}

canonical_decompiled_code:
void func1()
{
stop_flag = 1;
}

original_code:
void stop_detect(void)
{
  stop_flag = 1;
}

canonical_original_code:
void stop_detect()
{
  stop_flag = 1;
}


decompiled_code:
unsigned __int64 __fastcall detect_apple_partmap(__int64 a1, unsigned int a2)
{
unsigned __int64 result; // rax
int v3; // er14
int v4; // ebx
unsigned __int64 v5; // r15
__int64 v6; // r13
__int64 v7; // [rsp+18h] [rbp-180h] BYREF
char s[64]; // [rsp+20h] [rbp-178h] BYREF
char v9[312]; // [rsp+60h] [rbp-138h] BYREF

result = get_buffer(a1, 512LL, 512LL, &v7);
if ( result > 0x1FF )
{
result = get_be_short(v7);
if ( (_WORD)result == 21587 )
{
result = print_line(a2, "Old-style Apple partition map", 21587LL);
}
else if ( (unsigned __int16)result == 20557 )
{
v3 = get_be_long(v7 + 4);
result = print_line(a2, "Apple partition map, %d entries", (unsigned int)v3);
v4 = 1;
if ( v3 > 0 )
{
while ( 1 )
{
if ( (unsigned __int16)get_be_short(v7) == 20557 )
{
v5 = get_be_long(v7 + 8);
v6 = get_be_long(v7 + 12);
sprintf(s, " from %llu", v5);
format_blocky_size(v9, v6, 512LL, "sectors", s);
print_line(a2, "Partition %d: %s", (unsigned int)v4, v9);
get_string(v7 + 48, 32LL, v9);
result = print_line(a2 + 1, "Type \"%s\"", v9);
if ( v6 )
{
result = v3;
if ( v3 < v5 )
result = analyze_recursive(a1, a2 + 1, v5 << 9, v6 << 9, 0LL);
}
}
else
{
result = print_line(a2, "Partition %d: invalid signature, skipping", (unsigned int)v4);
}
if ( v3 < ++v4 )
break;
if ( v4 > 1 )
{
result = get_buffer(a1, v4 << 9, 512LL, &v7);
if ( result <= 0x1FF )
break;
}
}
}
}
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func0(__int64 a1, unsigned int a2)
{
unsigned __int64 result; // rax
int v3; // er14
int v4; // ebx
unsigned __int64 v5; // r15
__int64 v6; // r13
__int64 v7; // [rsp+18h] [rbp-180h] BYREF
char s[64]; // [rsp+20h] [rbp-178h] BYREF
char v9[312]; // [rsp+60h] [rbp-138h] BYREF

result = get_buffer(a1, 512LL, 512LL, &v7);
if ( result > 0x1FF )
{
result = get_be_short(v7);
if ( (_WORD)result == 21587 )
{
result = print_line(a2, "Old-style Apple partition map", 21587LL);
}
else if ( (unsigned __int16)result == 20557 )
{
v3 = get_be_long(v7 + 4);
result = print_line(a2, "Apple partition map, %d entries", (unsigned int)v3);
v4 = 1;
if ( v3 > 0 )
{
while ( 1 )
{
if ( (unsigned __int16)get_be_short(v7) == 20557 )
{
v5 = get_be_long(v7 + 8);
v6 = get_be_long(v7 + 12);
sprintf(s, " from %llu", v5);
format_blocky_size(v9, v6, 512LL, "sectors", s);
print_line(a2, "Partition %d: %s", (unsigned int)v4, v9);
get_string(v7 + 48, 32LL, v9);
result = print_line(a2 + 1, "Type \"%s\"", v9);
if ( v6 )
{
result = v3;
if ( v3 < v5 )
result = analyze_recursive(a1, a2 + 1, v5 << 9, v6 << 9, 0LL);
}
}
else
{
result = print_line(a2, "Partition %d: invalid signature, skipping", (unsigned int)v4);
}
if ( v3 < ++v4 )
break;
if ( v4 > 1 )
{
result = get_buffer(a1, v4 << 9, 512LL, &v7);
if ( result <= 0x1FF )
break;
}
}
}
}
}
return result;
}

original_code:
void detect_apple_partmap(SECTION *section, int level)
{
  int i, magic, count;
  char s[256], append[64];
  unsigned char *buf;
  u8 start, size;
  if (get_buffer(section, 512, 512, (void **)&buf) < 512)
    return;
  magic = get_be_short(buf);
  if (magic == 0x5453) {
    print_line(level, "Old-style Apple partition map");
    return;
  }
  if (magic != 0x504D)
    return;
  count = get_be_long(buf + 4);
  print_line(level, "Apple partition map, %d entries", count);
  for (i = 1; i <= count; i++) {
    if (i > 1 && get_buffer(section, i * 512, 512, (void **)&buf) < 512)
      return;
    if (get_be_short(buf) != 0x504D) {
      print_line(level, "Partition %d: invalid signature, skipping", i);
      continue;
    }
    start = get_be_long(buf + 8);
    size = get_be_long(buf + 12);
    sprintf(append, " from %llu", start);
    format_blocky_size(s, size, 512, "sectors", append);
    print_line(level, "Partition %d: %s",
        i, s);
    get_string(buf + 48, 32, s);
    print_line(level+1, "Type \"%s\"", s);
    if (start > count && size > 0) {
      analyze_recursive(section, level + 1,
   start * 512, size * 512, 0);
    }
  }
}

canonical_original_code:
void detect_apple_partmap(struct section *section, int level)
{
  int i; int magic; int count;
  char s[256]; char append[64];
  unsigned char *buf;
  unsigned long long start; unsigned long long size;
  if (get_buffer(section, 512, 512, (void **)&buf) < 512)
    return;
  magic = get_be_short(buf);
  if (magic == 0x5453) {
    print_line(level, "Old-style Apple partition map");
    return;
  }
  if (magic != 0x504D)
    return;
  count = get_be_long(buf + 4);
  print_line(level, "Apple partition map, %d entries", count);
  for (i = 1; i <= count; i++) {
    if (i > 1 && get_buffer(section, i * 512, 512, (void **)&buf) < 512)
      return;
    if (get_be_short(buf) != 0x504D) {
      print_line(level, "Partition %d: invalid signature, skipping", i);
      continue;
    }
    start = get_be_long(buf + 8);
    size = get_be_long(buf + 12);
    sprintf(append, " from %llu", start);
    format_blocky_size(s, size, 512, "sectors", append);
    print_line(level, "Partition %d: %s",
        i, s);
    get_string(buf + 48, 32, s);
    print_line(level+1, "Type \"%s\"", s);
    if (start > count && size > 0) {
      analyze_recursive(section, level + 1,
   start * 512, size * 512, 0);
    }
  }
}

variable_types: i int

variable_types: magic int

variable_types: count int

variable_types:
s
char [256]

variable_types:
append
char [64]

variable_types:
buf
unsigned char *

variable_types:
start
unsigned long long


decompiled_code:
unsigned __int64 __fastcall detect_apple_volume(__int64 a1, unsigned int a2)
{
unsigned __int64 result; // rax
__int16 v3; // bp
__int64 v4; // rbp
__int64 v5; // rax
__int64 v6; // r13
unsigned __int64 v7; // rbp
__int64 v8; // r14
unsigned __int64 v9; // r15
unsigned __int64 v10; // r14
int v11; // eax
unsigned __int16 v12; // bp
__int64 v13; // r13
unsigned __int16 v14; // r14
unsigned __int16 v15; // ax
unsigned __int64 v16; // [rsp+8h] [rbp-350h] BYREF
char v17[528]; // [rsp+10h] [rbp-348h] BYREF
char v18[312]; // [rsp+220h] [rbp-138h] BYREF

result = get_buffer(a1, 1024LL, 512LL, &v16);
if ( result > 0x1FF )
{
v3 = get_be_short(v16);
result = get_be_short(v16 + 2);
switch ( v3 )
{
case -11561:
result = print_line(a2, "MFS file system");
break;
case 16964:
print_line(a2, "HFS file system");
v12 = get_be_short(v16 + 18);
v13 = get_be_long(v16 + 20);
v14 = get_be_short(v16 + 28);
get_pstring(v16 + 36, v18);
format_ascii(v18, v17);
print_line(a2 + 1, "Volume name \"%s\"", v17);
format_blocky_size(v18, v12, v13, "blocks", 0LL);
print_line(a2 + 1, "Volume size %s", v18);
result = get_be_short(v16 + 124);
if ( (_WORD)result == 18475 )
{
print_line(a2, "HFS wrapper for HFS Plus");
v15 = get_be_short(v16 + 126);
result = analyze_recursive(a1, a2 + 1, v15 * v13 + ((unsigned __int64)v14 << 9), 0LL, 0LL);
}
break;
case 18475:
print_line(a2, "HFS Plus file system");
v4 = get_be_long(v16 + 40);
v5 = get_be_long(v16 + 44);
format_blocky_size(v18, v5, v4, "blocks", 0LL);
print_line(a2 + 1, "Volume size %s", v18);
v6 = v4 * get_be_long(v16 + 288);
v7 = get_be_long(v16 + 292) * v4;
if ( get_be_quad(v16 + 272) < v7 )
v7 = get_be_quad(v16 + 272);
result = get_buffer(a1, v6, 4096LL, &v16);
if ( result > 0xFFF )
{
v8 = get_be_long(v16 + 24);
result = get_be_short(v16 + 32);
v9 = (unsigned __int16)result;
if ( (unsigned __int16)result > 0xFFFu )
{
v10 = (unsigned __int16)result * (v8 + 1);
if ( v10 <= v7 )
{
result = get_buffer(a1, v10 - (unsigned __int16)result + v6, (unsigned __int16)result, &v16);
if ( result >= v9 )
{
result = v16;
if ( *(_BYTE *)(v16 + 8) == 0xFF )
{
result = get_be_short(v16 + 14);
if ( (unsigned __int16)result > 6u )
{
result = get_be_long(v16 + 16);
if ( result == 1 )
{
v11 = get_be_short(v16 + 20);
format_utf16_be(v16 + 22, (2 * v11) & 0x1FFFE, v17);
result = print_line(a2 + 1, "Volume name \"%s\"", v17);
}
}
}
}
}
}
}
break;
}
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func1(__int64 a1, unsigned int a2)
{
unsigned __int64 result; // rax
__int16 v3; // bp
__int64 v4; // rbp
__int64 v5; // rax
__int64 v6; // r13
unsigned __int64 v7; // rbp
__int64 v8; // r14
unsigned __int64 v9; // r15
unsigned __int64 v10; // r14
int v11; // eax
unsigned __int16 v12; // bp
__int64 v13; // r13
unsigned __int16 v14; // r14
unsigned __int16 v15; // ax
unsigned __int64 v16; // [rsp+8h] [rbp-350h] BYREF
char v17[528]; // [rsp+10h] [rbp-348h] BYREF
char v18[312]; // [rsp+220h] [rbp-138h] BYREF

result = get_buffer(a1, 1024LL, 512LL, &v16);
if ( result > 0x1FF )
{
v3 = get_be_short(v16);
result = get_be_short(v16 + 2);
switch ( v3 )
{
case -11561:
result = print_line(a2, "MFS file system");
break;
case 16964:
print_line(a2, "HFS file system");
v12 = get_be_short(v16 + 18);
v13 = get_be_long(v16 + 20);
v14 = get_be_short(v16 + 28);
get_pstring(v16 + 36, v18);
format_ascii(v18, v17);
print_line(a2 + 1, "Volume name \"%s\"", v17);
format_blocky_size(v18, v12, v13, "blocks", 0LL);
print_line(a2 + 1, "Volume size %s", v18);
result = get_be_short(v16 + 124);
if ( (_WORD)result == 18475 )
{
print_line(a2, "HFS wrapper for HFS Plus");
v15 = get_be_short(v16 + 126);
result = analyze_recursive(a1, a2 + 1, v15 * v13 + ((unsigned __int64)v14 << 9), 0LL, 0LL);
}
break;
case 18475:
print_line(a2, "HFS Plus file system");
v4 = get_be_long(v16 + 40);
v5 = get_be_long(v16 + 44);
format_blocky_size(v18, v5, v4, "blocks", 0LL);
print_line(a2 + 1, "Volume size %s", v18);
v6 = v4 * get_be_long(v16 + 288);
v7 = get_be_long(v16 + 292) * v4;
if ( get_be_quad(v16 + 272) < v7 )
v7 = get_be_quad(v16 + 272);
result = get_buffer(a1, v6, 4096LL, &v16);
if ( result > 0xFFF )
{
v8 = get_be_long(v16 + 24);
result = get_be_short(v16 + 32);
v9 = (unsigned __int16)result;
if ( (unsigned __int16)result > 0xFFFu )
{
v10 = (unsigned __int16)result * (v8 + 1);
if ( v10 <= v7 )
{
result = get_buffer(a1, v10 - (unsigned __int16)result + v6, (unsigned __int16)result, &v16);
if ( result >= v9 )
{
result = v16;
if ( *(_BYTE *)(v16 + 8) == 0xFF )
{
result = get_be_short(v16 + 14);
if ( (unsigned __int16)result > 6u )
{
result = get_be_long(v16 + 16);
if ( result == 1 )
{
v11 = get_be_short(v16 + 20);
format_utf16_be(v16 + 22, (2 * v11) & 0x1FFFE, v17);
result = print_line(a2 + 1, "Volume name \"%s\"", v17);
}
}
}
}
}
}
}
break;
}
}
return result;
}

original_code:
void detect_apple_volume(SECTION *section, int level)
{
  char s[256], t[514];
  unsigned char *buf;
  u2 magic, version, volnamelen;
  u4 blocksize, blockstart;
  u8 blockcount, offset;
  u8 catalogstart, cataloglength;
  u4 firstleafnode, nodesize;
  if (get_buffer(section, 1024, 512, (void **)&buf) < 512)
    return;
  magic = get_be_short(buf);
  version = get_be_short(buf + 2);
  if (magic == 0xD2D7) {
    print_line(level, "MFS file system");
  } else if (magic == 0x4244) {
    print_line(level, "HFS file system");
    blockcount = get_be_short(buf + 18);
    blocksize = get_be_long(buf + 20);
    blockstart = get_be_short(buf + 28);
    get_pstring(buf + 36, s);
    format_ascii(s, t);
    print_line(level + 1, "Volume name \"%s\"", t);
    format_blocky_size(s, blockcount, blocksize, "blocks", ((void *)0));
    print_line(level + 1, "Volume size %s", s);
    if (get_be_short(buf + 0x7c) == 0x482B) {
      print_line(level, "HFS wrapper for HFS Plus");
      offset = (u8)get_be_short(buf + 0x7e) * blocksize +
 (u8)blockstart * 512;
      analyze_recursive(section, level + 1,
   offset, 0, 0);
    }
  } else if (magic == 0x482B) {
    print_line(level, "HFS Plus file system");
    blocksize = get_be_long(buf + 40);
    blockcount = get_be_long(buf + 44);
    format_blocky_size(s, blockcount, blocksize, "blocks", ((void *)0));
    print_line(level + 1, "Volume size %s", s);
    catalogstart = get_be_long(buf + 288) * blocksize;
    cataloglength = get_be_long(buf + 292) * blocksize;
    if (cataloglength > get_be_quad(buf + 272))
      cataloglength = get_be_quad(buf + 272);
    if (get_buffer(section, catalogstart, 4096, (void **)&buf) < 4096)
      return;
    firstleafnode = get_be_long(buf + 24);
    nodesize = get_be_short(buf + 32);
    if (nodesize < 4096)
      return;
    if ((firstleafnode + 1) * nodesize > cataloglength)
      return;
    if (get_buffer(section, catalogstart + firstleafnode * nodesize,
     nodesize, (void **)&buf) < nodesize)
      return;
    if (buf[8] != 0xff)
      return;
    if (get_be_short(buf + 14) <= 6)
      return;
    if (get_be_long(buf + 16) != 1)
      return;
    volnamelen = get_be_short(buf + 20);
    format_utf16_be(buf + 22, volnamelen * 2, t);
    print_line(level + 1, "Volume name \"%s\"", t);
  }
}

canonical_original_code:
void detect_apple_volume(struct section *section, int level)
{
  char s[256]; char t[514];
  unsigned char *buf;
  unsigned short magic; unsigned short version; unsigned short volnamelen;
  unsigned long blocksize; unsigned long blockstart;
  unsigned long long blockcount; unsigned long long offset;
  unsigned long long catalogstart; unsigned long long cataloglength;
  unsigned long firstleafnode; unsigned long nodesize;
  if (get_buffer(section, 1024, 512, (void **)&buf) < 512)
    return;
  magic = get_be_short(buf);
  version = get_be_short(buf + 2);
  if (magic == 0xD2D7) {
    print_line(level, "MFS file system");
  } else if (magic == 0x4244) {
    print_line(level, "HFS file system");
    blockcount = get_be_short(buf + 18);
    blocksize = get_be_long(buf + 20);
    blockstart = get_be_short(buf + 28);
    get_pstring(buf + 36, s);
    format_ascii(s, t);
    print_line(level + 1, "Volume name \"%s\"", t);
    format_blocky_size(s, blockcount, blocksize, "blocks", ((void *)0));
    print_line(level + 1, "Volume size %s", s);
    if (get_be_short(buf + 0x7c) == 0x482B) {
      print_line(level, "HFS wrapper for HFS Plus");
      offset = (unsigned long long)get_be_short(buf + 0x7e) * blocksize +
 (unsigned long long)blockstart * 512;
      analyze_recursive(section, level + 1,
   offset, 0, 0);
    }
  } else if (magic == 0x482B) {
    print_line(level, "HFS Plus file system");
    blocksize = get_be_long(buf + 40);
    blockcount = get_be_long(buf + 44);
    format_blocky_size(s, blockcount, blocksize, "blocks", ((void *)0));
    print_line(level + 1, "Volume size %s", s);
    catalogstart = get_be_long(buf + 288) * blocksize;
    cataloglength = get_be_long(buf + 292) * blocksize;
    if (cataloglength > get_be_quad(buf + 272))
      cataloglength = get_be_quad(buf + 272);
    if (get_buffer(section, catalogstart, 4096, (void **)&buf) < 4096)
      return;
    firstleafnode = get_be_long(buf + 24);
    nodesize = get_be_short(buf + 32);
    if (nodesize < 4096)
      return;
    if ((firstleafnode + 1) * nodesize > cataloglength)
      return;
    if (get_buffer(section, catalogstart + firstleafnode * nodesize,
     nodesize, (void **)&buf) < nodesize)
      return;
    if (buf[8] != 0xff)
      return;
    if (get_be_short(buf + 14) <= 6)
      return;
    if (get_be_long(buf + 16) != 1)
      return;
    volnamelen = get_be_short(buf + 20);
    format_utf16_be(buf + 22, volnamelen * 2, t);
    print_line(level + 1, "Volume name \"%s\"", t);
  }
}

variable_types: struct section { unsigned long long pos; int flags; struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *source; } *

variable_types:
t
char [514]

variable_types:
magic
unsigned short

variable_types:
version
unsigned short

variable_types:
volnamelen
unsigned short

variable_types:
blocksize
unsigned long

variable_types:
blockstart
unsigned long

variable_types:
blockcount
unsigned long long

variable_types:
offset
unsigned long long

variable_types:
catalogstart
unsigned long long

variable_types:
cataloglength
unsigned long long

variable_types:
firstleafnode
unsigned long

variable_types:
nodesize
unsigned long


decompiled_code:
void __fastcall detect_udif(__int64 a1, unsigned int a2)
{
unsigned __int64 v3; // rsi
void *s1; // [rsp+8h] [rbp-10h] BYREF

v3 = *(_QWORD *)(a1 + 8);
if ( v3 > 0x3FF
&& !*(_DWORD *)(*(_QWORD *)(a1 + 24) + 24LL)
&& (unsigned __int64)get_buffer(a1, v3 - 512, 512LL, &s1) > 0x1FF
&& !memcmp(s1, "koly", 4uLL) )
{
print_line(a2, "Apple UDIF disk image, content detection may or may not work...");
}
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1, unsigned int a2)
{
unsigned __int64 v3; // rsi
void *s1; // [rsp+8h] [rbp-10h] BYREF

v3 = *(_QWORD *)(a1 + 8);
if ( v3 > 0x3FF
&& !*(_DWORD *)(*(_QWORD *)(a1 + 24) + 24LL)
&& (unsigned __int64)get_buffer(a1, v3 - 512, 512LL, &s1) > 0x1FF
&& !memcmp(s1, "koly", 4uLL) )
{
print_line(a2, "Apple UDIF disk image, content detection may or may not work...");
}
}

original_code:
void detect_udif(SECTION *section, int level)
{
  u8 pos;
  unsigned char *buf;
  if (section->size < 1024 || section->source->sequential)
    return;
  pos = section->size - 512;
  if (get_buffer(section, pos, 512, (void **)&buf) < 512)
    return;
  if (memcmp(buf, "koly", 4) == 0) {
    print_line(level, "Apple UDIF disk image, content detection may or may not work...");
  }
}

canonical_original_code:
void detect_udif(struct section *section, int level)
{
  unsigned long long pos;
  unsigned char *buf;
  if (section->size < 1024 || section->source->sequential)
    return;
  pos = section->size - 512;
  if (get_buffer(section, pos, 512, (void **)&buf) < 512)
    return;
  if (memcmp(buf, "koly", 4) == 0) {
    print_line(level, "Apple UDIF disk image, content detection may or may not work...");
  }
}

variable_types: level int

variable_types:
pos
unsigned long long


decompiled_code:
const char *__fastcall get_name_for_eltorito_platform(int a1)
{
const char *result; // rax

result = "x86";
if ( a1 )
{
result = "PowerPC";
if ( a1 != 1 )
{
result = "Macintosh";
if ( a1 != 2 )
{
result = "unknown";
if ( a1 == 239 )
result = "EFI";
}
}
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func0(int a1)
{
const char *result; // rax

result = "x86";
if ( a1 )
{
result = "PowerPC";
if ( a1 != 1 )
{
result = "Macintosh";
if ( a1 != 2 )
{
result = "unknown";
if ( a1 == 239 )
result = "EFI";
}
}
}
return result;
}

original_code:
static char * get_name_for_eltorito_platform(int id)
{
  if (id == 0)
    return "x86";
  if (id == 1)
    return "PowerPC";
  if (id == 2)
    return "Macintosh";
  if (id == 0xEF)
    return "EFI";
  return "unknown";
}

canonical_original_code:
static char *get_name_for_eltorito_platform(int id)
{
  if (id == 0)
    return "x86";
  if (id == 1)
    return "PowerPC";
  if (id == 2)
    return "Macintosh";
  if (id == 0xEF)
    return "EFI";
  return "unknown";
}

variable_types: id int

return_type: char *


decompiled_code:
unsigned __int64 __fastcall dump_boot_catalog(__int64 a1, __int64 a2, unsigned int a3)
{
unsigned __int64 result; // rax
unsigned int v4; // er15
int v5; // er12
int v6; // ebp
__int64 v7; // rdi
bool v8; // r13
int v9; // ebx
unsigned int v10; // er14
unsigned __int16 v11; // ax
const char *v12; // rdx
const char *v13; // r13
const char *v14; // rax
char v15; // al
__int64 v16; // [rsp+0h] [rbp-168h]
int v19; // [rsp+1Ch] [rbp-14Ch]
char v20[264]; // [rsp+20h] [rbp-148h] BYREF
__int64 v21[8]; // [rsp+128h] [rbp-40h] BYREF

result = get_buffer(a1, a2, 2048LL, v21);
if ( result > 0x7FF )
{
if ( *(_BYTE *)v21[0] != 1 || *(_BYTE *)(v21[0] + 30) != 85 || *(_BYTE *)(v21[0] + 31) != 0xAA )
return print_line(a3, "Validation entry missing");
v4 = *(unsigned __int8 *)(v21[0] + 1);
v5 = 2;
v6 = 1;
while ( 1 )
{
v9 = 32 * v6 % 2048;
if ( v6 < v5 )
{
if ( v6 == 1 )
{
v15 = *(_BYTE *)(v21[0] + v9);
if ( v15 != -120 && v15 )
return print_line(a3, "Initial/Default entry missing");
if ( *(_BYTE *)(v21[0] + v9 + 32) == 0x90 || *(_BYTE *)(v21[0] + v9 + 32) == 0x91 )
v5 = 3;
}
}
else
{
result = v21[0];
if ( *(_BYTE *)(v21[0] + v9) != 0x88 )
return result;
++v5;
if ( v6 != 1 )
{
v7 = v21[0];
v8 = *(_BYTE *)(v21[0] + v9) == 0x88;
LABEL_22:
v19 = *(_BYTE *)(v7 + v9 + 1) & 0xF;
v10 = *(unsigned __int8 *)(v7 + v9 + 4);
v16 = get_le_long(v9 + 8 + v7);
v11 = get_le_short(v21[0] + v9 + 6);
format_size(v20, (unsigned __int64)v11 << 9);
v12 = "Bootable";
if ( !v8 )
v12 = "Non-bootable";
print_line(a3, "%s %s image, starts at %lu, preloads %s", v12, media_types[v19], v16, v20);
v13 = (const char *)get_name_for_mbrtype(v10);
v14 = get_name_for_eltorito_platform(v4);
result = print_line(a3 + 1, "Platform 0x%02X (%s), System Type 0x%02X (%s)", v4, v14, v10, v13);
if ( v16 )
result = analyze_recursive(a1, a3 + 1, v16 << 11, 0LL, 0LL);
goto LABEL_16;
}
if ( (unsigned __int8)(*(_BYTE *)(v21[0] + v9 + 32) + 112) <= 1u )
{
v7 = v21[0];
v8 = *(_BYTE *)(v21[0] + v9) == 0x88;
v5 = 3;
goto LABEL_22;
}
}
v7 = v21[0];
result = *(unsigned __int8 *)(v21[0] + v9);
v8 = (_BYTE)result == 0x88;
if ( !(_BYTE)result || (_BYTE)result == 0x88 )
goto LABEL_22;
++v5;
if ( (_BYTE)result != 68 )
{
if ( (unsigned __int8)(result + 112) > 1u )
return print_line(a3, "Unknown entry type 0x%02X", (unsigned __int8)result);
v4 = *(unsigned __int8 *)(v21[0] + v9 + 1);
result = v6 + (unsigned int)(unsigned __int16)get_le_short(v9 + 2 + v21[0]) + 1;
v5 = result + (*(_BYTE *)(v21[0] + v9) == 0x90);
}
LABEL_16:
if ( v5 >= ++v6 )
{
if ( (v6 & 0x3F) != 0 )
continue;
result = get_buffer(a1, a2 + ((v6 / 64) << 11), 2048LL, v21);
if ( result > 0x7FF )
continue;
}
return result;
}
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func1(__int64 a1, __int64 a2, unsigned int a3)
{
unsigned __int64 result; // rax
unsigned int v4; // er15
int v5; // er12
int v6; // ebp
__int64 v7; // rdi
bool v8; // r13
int v9; // ebx
unsigned int v10; // er14
unsigned __int16 v11; // ax
const char *v12; // rdx
const char *v13; // r13
const char *v14; // rax
char v15; // al
__int64 v16; // [rsp+0h] [rbp-168h]
int v19; // [rsp+1Ch] [rbp-14Ch]
char v20[264]; // [rsp+20h] [rbp-148h] BYREF
__int64 v21[8]; // [rsp+128h] [rbp-40h] BYREF

result = get_buffer(a1, a2, 2048LL, v21);
if ( result > 0x7FF )
{
if ( *(_BYTE *)v21[0] != 1 || *(_BYTE *)(v21[0] + 30) != 85 || *(_BYTE *)(v21[0] + 31) != 0xAA )
return print_line(a3, "Validation entry missing");
v4 = *(unsigned __int8 *)(v21[0] + 1);
v5 = 2;
v6 = 1;
while ( 1 )
{
v9 = 32 * v6 % 2048;
if ( v6 < v5 )
{
if ( v6 == 1 )
{
v15 = *(_BYTE *)(v21[0] + v9);
if ( v15 != -120 && v15 )
return print_line(a3, "Initial/Default entry missing");
if ( *(_BYTE *)(v21[0] + v9 + 32) == 0x90 || *(_BYTE *)(v21[0] + v9 + 32) == 0x91 )
v5 = 3;
}
}
else
{
result = v21[0];
if ( *(_BYTE *)(v21[0] + v9) != 0x88 )
return result;
++v5;
if ( v6 != 1 )
{
v7 = v21[0];
v8 = *(_BYTE *)(v21[0] + v9) == 0x88;
LABEL_22:
v19 = *(_BYTE *)(v7 + v9 + 1) & 0xF;
v10 = *(unsigned __int8 *)(v7 + v9 + 4);
v16 = get_le_long(v9 + 8 + v7);
v11 = get_le_short(v21[0] + v9 + 6);
format_size(v20, (unsigned __int64)v11 << 9);
v12 = "Bootable";
if ( !v8 )
v12 = "Non-bootable";
print_line(a3, "%s %s image, starts at %lu, preloads %s", v12, media_types[v19], v16, v20);
v13 = (const char *)get_name_for_mbrtype(v10);
v14 = func0(v4);
result = print_line(a3 + 1, "Platform 0x%02X (%s), System Type 0x%02X (%s)", v4, v14, v10, v13);
if ( v16 )
result = analyze_recursive(a1, a3 + 1, v16 << 11, 0LL, 0LL);
goto LABEL_16;
}
if ( (unsigned __int8)(*(_BYTE *)(v21[0] + v9 + 32) + 112) <= 1u )
{
v7 = v21[0];
v8 = *(_BYTE *)(v21[0] + v9) == 0x88;
v5 = 3;
goto LABEL_22;
}
}
v7 = v21[0];
result = *(unsigned __int8 *)(v21[0] + v9);
v8 = (_BYTE)result == 0x88;
if ( !(_BYTE)result || (_BYTE)result == 0x88 )
goto LABEL_22;
++v5;
if ( (_BYTE)result != 68 )
{
if ( (unsigned __int8)(result + 112) > 1u )
return print_line(a3, "Unknown entry type 0x%02X", (unsigned __int8)result);
v4 = *(unsigned __int8 *)(v21[0] + v9 + 1);
result = v6 + (unsigned int)(unsigned __int16)get_le_short(v9 + 2 + v21[0]) + 1;
v5 = result + (*(_BYTE *)(v21[0] + v9) == 0x90);
}
LABEL_16:
if ( v5 >= ++v6 )
{
if ( (v6 & 0x3F) != 0 )
continue;
result = get_buffer(a1, a2 + ((v6 / 64) << 11), 2048LL, v21);
if ( result > 0x7FF )
continue;
}
return result;
}
}
return result;
}

original_code:
static void dump_boot_catalog(SECTION *section, u8 pos, int level)
{
  unsigned char *buf;
  int bootable, media, platform, system_type;
  u4 start, preload;
  int entry, maxentry, off;
  char s[256];
  if (get_buffer(section, pos, 2048, (void **)&buf) < 2048)
    return;
  if (buf[0] != 0x01 || buf[30] != 0x55 || buf[31] != 0xAA) {
    print_line(level, "Validation entry missing");
    return;
  }
  platform = buf[1];
  maxentry = 2;
  for (entry = 1; entry < maxentry + 1; entry++) {
    if ((entry & 63) == 0) {
      if (get_buffer(section, pos + (entry / 64) * 2048, 2048, (void **)&buf) < 2048)
        return;
    }
    off = (entry * 32) % 2048;
    if (entry >= maxentry) {
      if (buf[off] == 0x88)
        maxentry++;
      else
        break;
    }
    if (entry == 1) {
      if (!(buf[off] == 0x88 || buf[off] == 0x00)) {
        print_line(level, "Initial/Default entry missing");
        break;
      }
      if (buf[off + 32] == 0x90 || buf[off + 32] == 0x91)
        maxentry = 3;
    }
    if (buf[off] == 0x88 || buf[off] == 0x00) {
      bootable = (buf[off] == 0x88) ? 1 : 0;
      media = buf[off + 1] & 15;
      system_type = buf[off + 4];
      start = get_le_long(buf + off + 8);
      preload = get_le_short(buf + off + 6);
      format_size(s, preload * 512);
      print_line(level, "%s %s image, starts at %lu, preloads %s",
                 bootable ? "Bootable" : "Non-bootable",
                 media_types[media], start, s);
      print_line(level + 1, "Platform 0x%02X (%s), System Type 0x%02X (%s)",
                 platform, get_name_for_eltorito_platform(platform),
                 system_type, get_name_for_mbrtype(system_type));
      if (start > 0) {
        analyze_recursive(section, level + 1,
                          (u8)start * 2048, 0, 0);
      }
    } else if (buf[off] == 0x44) {
      maxentry++;
    } else if (buf[off] == 0x90 || buf[off] == 0x91) {
      platform = buf[off + 1];
      maxentry = entry + 1 + get_le_short(buf + off + 2)
               + ((buf[off] == 0x90) ? 1 : 0);
    } else {
      print_line(level, "Unknown entry type 0x%02X", buf[off]);
      break;
    }
  }
}

canonical_original_code:
static void dump_boot_catalog(struct section *section, unsigned long long pos, int level)
{
  unsigned char *buf;
  int bootable; int media; int platform; int system_type;
  unsigned long start; unsigned long preload;
  int entry; int maxentry; int off;
  char s[256];
  if (get_buffer(section, pos, 2048, (void **)&buf) < 2048)
    return;
  if (buf[0] != 0x01 || buf[30] != 0x55 || buf[31] != 0xAA) {
    print_line(level, "Validation entry missing");
    return;
  }
  platform = buf[1];
  maxentry = 2;
  for (entry = 1; entry < maxentry + 1; entry++) {
    if ((entry & 63) == 0) {
      if (get_buffer(section, pos + (entry / 64) * 2048, 2048, (void **)&buf) < 2048)
        return;
    }
    off = (entry * 32) % 2048;
    if (entry >= maxentry) {
      if (buf[off] == 0x88)
        maxentry++;
      else
        break;
    }
    if (entry == 1) {
      if (!(buf[off] == 0x88 || buf[off] == 0x00)) {
        print_line(level, "Initial/Default entry missing");
        break;
      }
      if (buf[off + 32] == 0x90 || buf[off + 32] == 0x91)
        maxentry = 3;
    }
    if (buf[off] == 0x88 || buf[off] == 0x00) {
      bootable = (buf[off] == 0x88) ? 1 : 0;
      media = buf[off + 1] & 15;
      system_type = buf[off + 4];
      start = get_le_long(buf + off + 8);
      preload = get_le_short(buf + off + 6);
      format_size(s, preload * 512);
      print_line(level, "%s %s image, starts at %lu, preloads %s",
                 bootable ? "Bootable" : "Non-bootable",
                 media_types[media], start, s);
      print_line(level + 1, "Platform 0x%02X (%s), System Type 0x%02X (%s)",
                 platform, get_name_for_eltorito_platform(platform),
                 system_type, get_name_for_mbrtype(system_type));
      if (start > 0) {
        analyze_recursive(section, level + 1,
                          (unsigned long long)start * 2048, 0, 0);
      }
    } else if (buf[off] == 0x44) {
      maxentry++;
    } else if (buf[off] == 0x90 || buf[off] == 0x91) {
      platform = buf[off + 1];
      maxentry = entry + 1 + get_le_short(buf + off + 2)
               + ((buf[off] == 0x90) ? 1 : 0);
    } else {
      print_line(level, "Unknown entry type 0x%02X", buf[off]);
      break;
    }
  }
}

variable_types:
buf
unsigned char *

variable_types: bootable int

variable_types: media int

variable_types: platform int

variable_types:
start
unsigned long

variable_types:
preload
unsigned long

variable_types: entry int

variable_types: maxentry int

variable_types: off int

variable_types:
s
char [256]


decompiled_code:
int __fastcall detect_iso(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rax
unsigned int v3; // er13
__int64 v4; // rbx
unsigned __int16 v5; // ax
__int64 v6; // rbx
unsigned int i; // er12
__int64 v8; // r15
__int64 v9; // rax
unsigned __int8 *v10; // r15
void *s1; // [rsp+8h] [rbp-240h] BYREF
char s[256]; // [rsp+10h] [rbp-238h] BYREF
char v14[312]; // [rsp+110h] [rbp-138h] BYREF

v2 = get_buffer(a1, 0x8000LL, 2048LL, &s1);
if ( v2 > 0x7FF )
{
LODWORD(v2) = memcmp(s1, &unk_893, 6uLL);
if ( !(_DWORD)v2 )
{
print_line(a2, "ISO9660 file system");
get_padded_string((char *)s1 + 40, 32LL, 32LL, v14);
v3 = a2 + 1;
print_line(a2 + 1, "Volume name \"%s\"", v14);
get_padded_string((char *)s1 + 318, 128LL, 32LL, v14);
if ( v14[0] )
print_line(v3, "Publisher \"%s\"", v14);
get_padded_string((char *)s1 + 446, 128LL, 32LL, v14);
if ( v14[0] )
print_line(v3, "Preparer \"%s\"", v14);
get_padded_string((char *)s1 + 574, 128LL, 32LL, v14);
if ( v14[0] )
print_line(v3, "Application \"%s\"", v14);
v4 = get_le_long((char *)s1 + 80);
v5 = get_le_short((char *)s1 + 128);
format_blocky_size(v14, v4, v5, "blocks", 0LL);
print_line(v3, "Data size %s", v14);
v6 = 34816LL;
for ( i = 17; ; ++i )
{
v2 = get_buffer(a1, v6, 2048LL, &s1);
if ( v2 <= 0x7FF )
break;
v10 = (unsigned __int8 *)s1;
if ( memcmp((char *)s1 + 1, "CD001", 5uLL) )
{
LODWORD(v2) = print_line(v3, "Signature missing in sector %d", i);
return v2;
}
LODWORD(v2) = *v10;
if ( (_BYTE)v2 == 0xFF )
return v2;
if ( (_BYTE)v2 == 2 )
{
format_utf16_be(v10 + 40, 32LL, s);
LODWORD(v9) = strlen(s) - 1;
if ( (int)v9 >= 0 )
{
v9 = (int)v9;
do
{
if ( s[v9] != 32 )
break;
s[v9--] = 0;
}
while ( (int)v9 >= 0 );
}
print_line(v3, "Joliet extension, volume name \"%s\"", s);
}
else if ( (unsigned __int8)v2 > 2u )
{
if ( (_BYTE)v2 == 3 )
print_line(v3, "Volume Partition Descriptor");
else
print_line(v3, "Descriptor type %d at sector %d", (unsigned __int8)v2, i);
}
else if ( (_BYTE)v2 )
{
print_line(v3, "Additional Primary Volume Descriptor", (unsigned __int8)v2);
}
else if ( !memcmp(v10 + 7, "EL TORITO SPECIFICATION", 0x17uLL) )
{
v8 = get_le_long(v10 + 71);
print_line(v3, "El Torito boot record, catalog at %llu", v8);
dump_boot_catalog(a1, v8 << 11, a2 + 2);
}
else
{
print_line(v3, "Boot record of unknown format");
}
v6 += 2048LL;
}
}
}
return v2;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rax
unsigned int v3; // er13
__int64 v4; // rbx
unsigned __int16 v5; // ax
__int64 v6; // rbx
unsigned int i; // er12
__int64 v8; // r15
__int64 v9; // rax
unsigned __int8 *v10; // r15
void *s1; // [rsp+8h] [rbp-240h] BYREF
char s[256]; // [rsp+10h] [rbp-238h] BYREF
char v14[312]; // [rsp+110h] [rbp-138h] BYREF

v2 = get_buffer(a1, 0x8000LL, 2048LL, &s1);
if ( v2 > 0x7FF )
{
LODWORD(v2) = memcmp(s1, &unk_893, 6uLL);
if ( !(_DWORD)v2 )
{
print_line(a2, "ISO9660 file system");
get_padded_string((char *)s1 + 40, 32LL, 32LL, v14);
v3 = a2 + 1;
print_line(a2 + 1, "Volume name \"%s\"", v14);
get_padded_string((char *)s1 + 318, 128LL, 32LL, v14);
if ( v14[0] )
print_line(v3, "Publisher \"%s\"", v14);
get_padded_string((char *)s1 + 446, 128LL, 32LL, v14);
if ( v14[0] )
print_line(v3, "Preparer \"%s\"", v14);
get_padded_string((char *)s1 + 574, 128LL, 32LL, v14);
if ( v14[0] )
print_line(v3, "Application \"%s\"", v14);
v4 = get_le_long((char *)s1 + 80);
v5 = get_le_short((char *)s1 + 128);
format_blocky_size(v14, v4, v5, "blocks", 0LL);
print_line(v3, "Data size %s", v14);
v6 = 34816LL;
for ( i = 17; ; ++i )
{
v2 = get_buffer(a1, v6, 2048LL, &s1);
if ( v2 <= 0x7FF )
break;
v10 = (unsigned __int8 *)s1;
if ( memcmp((char *)s1 + 1, "CD001", 5uLL) )
{
LODWORD(v2) = print_line(v3, "Signature missing in sector %d", i);
return v2;
}
LODWORD(v2) = *v10;
if ( (_BYTE)v2 == 0xFF )
return v2;
if ( (_BYTE)v2 == 2 )
{
format_utf16_be(v10 + 40, 32LL, s);
LODWORD(v9) = strlen(s) - 1;
if ( (int)v9 >= 0 )
{
v9 = (int)v9;
do
{
if ( s[v9] != 32 )
break;
s[v9--] = 0;
}
while ( (int)v9 >= 0 );
}
print_line(v3, "Joliet extension, volume name \"%s\"", s);
}
else if ( (unsigned __int8)v2 > 2u )
{
if ( (_BYTE)v2 == 3 )
print_line(v3, "Volume Partition Descriptor");
else
print_line(v3, "Descriptor type %d at sector %d", (unsigned __int8)v2, i);
}
else if ( (_BYTE)v2 )
{
print_line(v3, "Additional Primary Volume Descriptor", (unsigned __int8)v2);
}
else if ( !memcmp(v10 + 7, "EL TORITO SPECIFICATION", 0x17uLL) )
{
v8 = get_le_long(v10 + 71);
print_line(v3, "El Torito boot record, catalog at %llu", v8);
func1(a1, v8 << 11, a2 + 2);
}
else
{
print_line(v3, "Boot record of unknown format");
}
v6 += 2048LL;
}
}
}
return v2;
}

original_code:
void detect_iso(SECTION *section, int level)
{
  char s[256], t[256];
  int i, sector, type;
  u4 blocksize;
  u8 blocks, bcpos;
  unsigned char *buf;
  if (get_buffer(section, 32768, 2048, (void **)&buf) < 2048)
    return;
  if (memcmp(buf, "\001CD001", 6) != 0)
    return;
  print_line(level, "ISO9660 file system");
  get_padded_string(buf + 40, 32, ' ', s);
  print_line(level+1, "Volume name \"%s\"", s);
  get_padded_string(buf + 318, 128, ' ', s);
  if (s[0])
    print_line(level+1, "Publisher   \"%s\"", s);
  get_padded_string(buf + 446, 128, ' ', s);
  if (s[0])
    print_line(level+1, "Preparer    \"%s\"", s);
  get_padded_string(buf + 574, 128, ' ', s);
  if (s[0])
    print_line(level+1, "Application \"%s\"", s);
  blocks = get_le_long(buf + 80);
  blocksize = get_le_short(buf + 128);
  format_blocky_size(s, blocks, blocksize, "blocks", ((void *)0));
  print_line(level+1, "Data size %s", s);
  for (sector = 17; ; sector++) {
    if (get_buffer(section, sector * 2048, 2048, (void **)&buf) < 2048)
      return;
    if (memcmp(buf + 1, "CD001", 5) != 0) {
      print_line(level+1, "Signature missing in sector %d", sector);
      return;
    }
    type = buf[0];
    if (type == 255)
      break;
    switch (type) {
    case 0:
      if (memcmp(buf+7, "EL TORITO SPECIFICATION", 23) != 0) {
 print_line(level+1, "Boot record of unknown format");
 break;
      }
      bcpos = get_le_long(buf + 0x47);
      print_line(level+1, "El Torito boot record, catalog at %llu", bcpos);
      dump_boot_catalog(section, bcpos * 2048, level + 2);
      break;
    case 1:
      print_line(level+1, "Additional Primary Volume Descriptor");
      break;
    case 2:
      format_utf16_be(buf + 40, 32, t);
      for (i = strlen(t)-1; i >= 0 && t[i] == ' '; i--)
 t[i] = 0;
      print_line(level+1, "Joliet extension, volume name \"%s\"", t);
      break;
    case 3:
      print_line(level+1, "Volume Partition Descriptor");
      break;
    default:
      print_line(level+1, "Descriptor type %d at sector %d", type, sector);
      break;
    }
  }
}

canonical_original_code:
void detect_iso(struct section *section, int level)
{
  char s[256]; char t[256];
  int i; int sector; int type;
  unsigned long blocksize;
  unsigned long long blocks; unsigned long long bcpos;
  unsigned char *buf;
  if (get_buffer(section, 32768, 2048, (void **)&buf) < 2048)
    return;
  if (memcmp(buf, "\001CD001", 6) != 0)
    return;
  print_line(level, "ISO9660 file system");
  get_padded_string(buf + 40, 32, ' ', s);
  print_line(level+1, "Volume name \"%s\"", s);
  get_padded_string(buf + 318, 128, ' ', s);
  if (s[0])
    print_line(level+1, "Publisher   \"%s\"", s);
  get_padded_string(buf + 446, 128, ' ', s);
  if (s[0])
    print_line(level+1, "Preparer    \"%s\"", s);
  get_padded_string(buf + 574, 128, ' ', s);
  if (s[0])
    print_line(level+1, "Application \"%s\"", s);
  blocks = get_le_long(buf + 80);
  blocksize = get_le_short(buf + 128);
  format_blocky_size(s, blocks, blocksize, "blocks", ((void *)0));
  print_line(level+1, "Data size %s", s);
  for (sector = 17; ; sector++) {
    if (get_buffer(section, sector * 2048, 2048, (void **)&buf) < 2048)
      return;
    if (memcmp(buf + 1, "CD001", 5) != 0) {
      print_line(level+1, "Signature missing in sector %d", sector);
      return;
    }
    type = buf[0];
    if (type == 255)
      break;
    switch (type) {
    case 0:
      if (memcmp(buf+7, "EL TORITO SPECIFICATION", 23) != 0) {
 print_line(level+1, "Boot record of unknown format");
 break;
      }
      bcpos = get_le_long(buf + 0x47);
      print_line(level+1, "El Torito boot record, catalog at %llu", bcpos);
      dump_boot_catalog(section, bcpos * 2048, level + 2);
      break;
    case 1:
      print_line(level+1, "Additional Primary Volume Descriptor");
      break;
    case 2:
      format_utf16_be(buf + 40, 32, t);
      for (i = strlen(t)-1; i >= 0 && t[i] == ' '; i--)
 t[i] = 0;
      print_line(level+1, "Joliet extension, volume name \"%s\"", t);
      break;
    case 3:
      print_line(level+1, "Volume Partition Descriptor");
      break;
    default:
      print_line(level+1, "Descriptor type %d at sector %d", type, sector);
      break;
    }
  }
}

variable_types: struct section { unsigned long long pos; int flags; struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *source; } *

variable_types:
t
char [256]

variable_types: i int

variable_types: sector int

variable_types: type int

variable_types:
blocksize
unsigned long

variable_types:
blocks
unsigned long long

variable_types:
bcpos
unsigned long long


decompiled_code:
int __fastcall detect_cdrom_misc(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rax
char *v3; // rbp
char *v4; // rbx
void *s1[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = get_buffer(a1, 0LL, 2048LL, s1);
if ( v2 > 0x7FF )
{
if ( !memcmp(s1[0], "SEGA SEGAKATANA SEGA ENTERPRISES", 0x20uLL) )
print_line(a2, "Sega Dreamcast signature");
v3 = (char *)s1[0];
if ( !memcmp(s1[0], &unk_C00, 8uLL) && !memcmp(v3 + 40, "CD-ROM", 6uLL) )
print_line(a2, "3DO CD-ROM file system");
v2 = get_buffer(a1, 0x10000LL, 2048LL, s1);
if ( v2 > 0x7FF )
{
v4 = (char *)s1[0];
LODWORD(v2) = memcmp(s1[0], "MICROSOFT*XBOX*MEDIA", 0x14uLL);
if ( !(_DWORD)v2 )
{
LODWORD(v2) = memcmp(v4 + 2028, "MICROSOFT*XBOX*MEDIA", 0x14uLL);
if ( !(_DWORD)v2 )
LODWORD(v2) = print_line(a2, "Xbox DVD file system");
}
}
}
return v2;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rax
char *v3; // rbp
char *v4; // rbx
void *s1[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = get_buffer(a1, 0LL, 2048LL, s1);
if ( v2 > 0x7FF )
{
if ( !memcmp(s1[0], "SEGA SEGAKATANA SEGA ENTERPRISES", 0x20uLL) )
print_line(a2, "Sega Dreamcast signature");
v3 = (char *)s1[0];
if ( !memcmp(s1[0], &unk_C00, 8uLL) && !memcmp(v3 + 40, "CD-ROM", 6uLL) )
print_line(a2, "3DO CD-ROM file system");
v2 = get_buffer(a1, 0x10000LL, 2048LL, s1);
if ( v2 > 0x7FF )
{
v4 = (char *)s1[0];
LODWORD(v2) = memcmp(s1[0], "MICROSOFT*XBOX*MEDIA", 0x14uLL);
if ( !(_DWORD)v2 )
{
LODWORD(v2) = memcmp(v4 + 2028, "MICROSOFT*XBOX*MEDIA", 0x14uLL);
if ( !(_DWORD)v2 )
LODWORD(v2) = print_line(a2, "Xbox DVD file system");
}
}
}
return v2;
}

original_code:
void detect_cdrom_misc(SECTION *section, int level)
{
  unsigned char *buf;
  if (get_buffer(section, 0, 2048, (void **)&buf) < 2048)
    return;
  if (memcmp(buf, "SEGA SEGAKATANA SEGA ENTERPRISES", 32) == 0) {
    print_line(level, "Sega Dreamcast signature");
  }
  if (memcmp(buf, "\x01\x5a\x5a\x5a\x5a\x5a\x01\x00", 8) == 0 &&
      memcmp(buf + 0x28, "CD-ROM", 6) == 0) {
    print_line(level, "3DO CD-ROM file system");
  }
  if (get_buffer(section, 32*2048, 2048, (void **)&buf) < 2048)
    return;
  if (memcmp(buf, "MICROSOFT*XBOX*MEDIA", 20) == 0 &&
      memcmp(buf + 0x7ec, "MICROSOFT*XBOX*MEDIA", 20) == 0) {
    print_line(level, "Xbox DVD file system");
  }
}

canonical_original_code:
void detect_cdrom_misc(struct section *section, int level)
{
  unsigned char *buf;
  if (get_buffer(section, 0, 2048, (void **)&buf) < 2048)
    return;
  if (memcmp(buf, "SEGA SEGAKATANA SEGA ENTERPRISES", 32) == 0) {
    print_line(level, "Sega Dreamcast signature");
  }
  if (memcmp(buf, "\x01\x5a\x5a\x5a\x5a\x5a\x01\x00", 8) == 0 &&
      memcmp(buf + 0x28, "CD-ROM", 6) == 0) {
    print_line(level, "3DO CD-ROM file system");
  }
  if (get_buffer(section, 32*2048, 2048, (void **)&buf) < 2048)
    return;
  if (memcmp(buf, "MICROSOFT*XBOX*MEDIA", 20) == 0 &&
      memcmp(buf + 0x7ec, "MICROSOFT*XBOX*MEDIA", 20) == 0) {
    print_line(level, "Xbox DVD file system");
  }
}

variable_types: level int

variable_types:
buf
unsigned char *


decompiled_code:
const char *__fastcall get_name_for_type(void *s1)
{
int v1; // edx
const char *result; // rax
int v3; // edx
bool v4; // zf

v1 = memcmp(s1, "GEM", 3uLL);
result = "Standard GEMDOS";
if ( v1 )
{
v3 = memcmp(s1, "BGM", 3uLL);
result = "Big GEMDOS";
if ( v3 )
{
v4 = memcmp(s1, "XGM", 3uLL) == 0;
result = "Unknown";
if ( v4 )
result = "Extended";
}
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func0(void *s1)
{
int v1; // edx
const char *result; // rax
int v3; // edx
bool v4; // zf

v1 = memcmp(s1, "GEM", 3uLL);
result = "Standard GEMDOS";
if ( v1 )
{
v3 = memcmp(s1, "BGM", 3uLL);
result = "Big GEMDOS";
if ( v3 )
{
v4 = memcmp(s1, "XGM", 3uLL) == 0;
result = "Unknown";
if ( v4 )
result = "Extended";
}
}
return result;
}

original_code:
static char * get_name_for_type(char *type)
{
  if (memcmp(type, "GEM", 3) == 0)
    return "Standard GEMDOS";
  else if (memcmp(type, "BGM", 3) == 0)
    return "Big GEMDOS";
  else if (memcmp(type, "XGM", 3) == 0)
    return "Extended";
  return "Unknown";
}

canonical_original_code:
static char *get_name_for_type(char *type)
{
  if (memcmp(type, "GEM", 3) == 0)
    return "Standard GEMDOS";
  else if (memcmp(type, "BGM", 3) == 0)
    return "Big GEMDOS";
  else if (memcmp(type, "XGM", 3) == 0)
    return "Extended";
  return "Unknown";
}

variable_types:
type
char *


original_code:
static void detect_atari_partmap_ext(SECTION *section, u8 extbase, int level)
{
  unsigned char *buf;
  int extpartnum = 5;
  u8 tablebase, nexttablebase;
  int i, off, flags[4];
  u4 start, size, starts[4], sizes[4];
  char types[4][4], *type;
  char s[256], append[64];
  for (tablebase = extbase; tablebase; tablebase = nexttablebase) {
    if (get_buffer(section, tablebase << 9, 512, (void **)&buf) < 512)
      return;
    for (off = 0x1c6, i = 0; i < 4; i++, off += 12) {
      flags[i] = buf[off];
      get_string(buf + off + 1, 3, types[i]);
      starts[i] = get_be_long(buf + off + 4);
      sizes[i] = get_be_long(buf + off + 8);
    }
    nexttablebase = 0;
    for (i = 0; i < 4; i++) {
      start = starts[i];
      size = sizes[i];
      type = types[i];
      if ((flags[i] & 1) == 0)
 continue;
      if (memcmp(type, "XGM", 3) == 0) {
 nexttablebase = extbase + start;
      } else {
 sprintf(append, " from %lu", start);
 format_blocky_size(s, size, 512, "sectors", append);
 print_line(level, "Partition %d: %s",
     extpartnum, s);
 extpartnum++;
 print_line(level + 1, "Type \"%s\" (%s)", type,
     get_name_for_type(type));
 analyze_recursive(section, level + 1,
     (tablebase + start) * 512, (u8)size * 512, 0);
      }
    }
  }
}

canonical_original_code:
static void detect_atari_partmap_ext(struct section *section, unsigned long long extbase, int level)
{
  unsigned char *buf;
  int extpartnum = 5;
  unsigned long long tablebase; unsigned long long nexttablebase;
  int i; int off; int flags[4];
  unsigned long start; unsigned long size; unsigned long starts[4]; unsigned long sizes[4];
  char types[4][4]; char *type;
  char s[256]; char append[64];
  for (tablebase = extbase; tablebase; tablebase = nexttablebase) {
    if (get_buffer(section, tablebase << 9, 512, (void **)&buf) < 512)
      return;
    for (off = 0x1c6, i = 0; i < 4; i++, off += 12) {
      flags[i] = buf[off];
      get_string(buf + off + 1, 3, types[i]);
      starts[i] = get_be_long(buf + off + 4);
      sizes[i] = get_be_long(buf + off + 8);
    }
    nexttablebase = 0;
    for (i = 0; i < 4; i++) {
      start = starts[i];
      size = sizes[i];
      type = types[i];
      if ((flags[i] & 1) == 0)
 continue;
      if (memcmp(type, "XGM", 3) == 0) {
 nexttablebase = extbase + start;
      } else {
 sprintf(append, " from %lu", start);
 format_blocky_size(s, size, 512, "sectors", append);
 print_line(level, "Partition %d: %s",
     extpartnum, s);
 extpartnum++;
 print_line(level + 1, "Type \"%s\" (%s)", type,
     get_name_for_type(type));
 analyze_recursive(section, level + 1,
     (tablebase + start) * 512, (unsigned long long)size * 512, 0);
      }
    }
  }
}

variable_types:
extbase
unsigned long long

variable_types: extpartnum int

variable_types:
tablebase
unsigned long long

variable_types:
nexttablebase
unsigned long long

variable_types:
flags
int [4]

variable_types:
start
unsigned long

variable_types:
size
unsigned long

variable_types:
starts
unsigned long [4]

variable_types:
sizes
unsigned long [4]

variable_types:
types
char [4][4]

variable_types:
append
char [64]


original_code:
void detect_atari_partmap(SECTION *section, int level)
{
  unsigned char *buf;
  int i, off, used, flag, flags[4];
  u4 start, size, starts[4], sizes[4];
  char types[4][4], *type;
  u2 atari_csum;
  char s[256], append[64];
  if (section->pos != 0)
    return;
  if (get_buffer(section, 0, 512, (void **)&buf) < 512)
    return;
  atari_csum = 0;
  for (i = 0; i < 512; i += 2)
    atari_csum += get_be_short(buf + i);
  if (atari_csum != 0x1234)
    return;
  used = 0;
  for (off = 0x1c6, i = 0; i < 4; i++, off += 12) {
    flags[i] = buf[off];
    get_string(buf + off + 1, 3, types[i]);
    starts[i] = get_be_long(buf + off + 4);
    sizes[i] = get_be_long(buf + off + 8);
    if ((flags[i] & 1) && starts[i] != 0 && sizes[i] != 0)
      used = 1;
  }
  if (!used)
    return;
  print_line(level, "ATARI ST partition map");
  for (i = 0; i < 4; i++) {
    start = starts[i];
    size = sizes[i];
    flag = flags[i];
    type = types[i];
    if ((flag & 1) == 0)
      continue;
    sprintf(append, " from %lu", start);
    if (flag & 0x80)
      strcat(append, ", bootable");
    format_blocky_size(s, size, 512, "sectors", append);
    print_line(level, "Partition %d: %s",
        i+1, s);
    print_line(level + 1, "Type \"%s\" (%s)", type,
        get_name_for_type(type));
    if (memcmp(type, "XGM", 3) == 0) {
      detect_atari_partmap_ext(section, start, level + 1);
    } else {
      analyze_recursive(section, level + 1,
   (u8)start * 512, (u8)size * 512, 0);
    }
  }
}

canonical_original_code:
void detect_atari_partmap(struct section *section, int level)
{
  unsigned char *buf;
  int i; int off; int used; int flag; int flags[4];
  unsigned long start; unsigned long size; unsigned long starts[4]; unsigned long sizes[4];
  char types[4][4]; char *type;
  unsigned short atari_csum;
  char s[256]; char append[64];
  if (section->pos != 0)
    return;
  if (get_buffer(section, 0, 512, (void **)&buf) < 512)
    return;
  atari_csum = 0;
  for (i = 0; i < 512; i += 2)
    atari_csum += get_be_short(buf + i);
  if (atari_csum != 0x1234)
    return;
  used = 0;
  for (off = 0x1c6, i = 0; i < 4; i++, off += 12) {
    flags[i] = buf[off];
    get_string(buf + off + 1, 3, types[i]);
    starts[i] = get_be_long(buf + off + 4);
    sizes[i] = get_be_long(buf + off + 8);
    if ((flags[i] & 1) && starts[i] != 0 && sizes[i] != 0)
      used = 1;
  }
  if (!used)
    return;
  print_line(level, "ATARI ST partition map");
  for (i = 0; i < 4; i++) {
    start = starts[i];
    size = sizes[i];
    flag = flags[i];
    type = types[i];
    if ((flag & 1) == 0)
      continue;
    sprintf(append, " from %lu", start);
    if (flag & 0x80)
      strcat(append, ", bootable");
    format_blocky_size(s, size, 512, "sectors", append);
    print_line(level, "Partition %d: %s",
        i+1, s);
    print_line(level + 1, "Type \"%s\" (%s)", type,
        get_name_for_type(type));
    if (memcmp(type, "XGM", 3) == 0) {
      detect_atari_partmap_ext(section, start, level + 1);
    } else {
      analyze_recursive(section, level + 1,
   (unsigned long long)start * 512, (unsigned long long)size * 512, 0);
    }
  }
}

variable_types: struct section { unsigned long long pos; int flags; struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *source; } *

variable_types: i int

variable_types: off int

variable_types: used int

variable_types: flag int

variable_types:
s
char [256]


decompiled_code:
const char *__fastcall get_name_for_dostype(void *s1)
{
char *v1; // rbp
char **v2; // rbx

v1 = *(&amiga_dostypes + 2);
if ( !v1 )
return "Unknown";
v2 = &amiga_dostypes;
while ( memcmp(s1, *v2, 4uLL) )
{
v2 += 3;
v1 = v2[2];
if ( !v1 )
return "Unknown";
}
return v1;
}

canonical_decompiled_code:
const char *__fastcall func0(void *s1)
{
char *v1; // rbp
char **v2; // rbx

v1 = *(&amiga_dostypes + 2);
if ( !v1 )
return "Unknown";
v2 = &amiga_dostypes;
while ( memcmp(s1, *v2, 4uLL) )
{
v2 += 3;
v1 = v2[2];
if ( !v1 )
return "Unknown";
}
return v1;
}

original_code:
static char * get_name_for_dostype(const unsigned char *dostype)
{
  int i;
  for (i = 0; amiga_dostypes[i].name; i++)
    if (memcmp(dostype, amiga_dostypes[i].typecode, 4) == 0)
      return amiga_dostypes[i].name;
  return "Unknown";
}

canonical_original_code:
static char *get_name_for_dostype(unsigned char *dostype)
{
  int i;
  for (i = 0; amiga_dostypes[i].name; i++)
    if (memcmp(dostype, amiga_dostypes[i].typecode, 4) == 0)
      return amiga_dostypes[i].name;
  return "Unknown";
}

variable_types:
dostype
unsigned char *


decompiled_code:
void __fastcall format_dostype(char *s, unsigned __int8 *a2)
{
unsigned __int8 *v3; // rbx
unsigned __int8 v4; // dl

v3 = a2;
do
{
v4 = *v3;
if ( *v3 > 9u )
{
if ( v4 <= 0x1Fu )
{
sprintf(s, "0x%02x", v4);
s += strlen(s);
}
else
{
*s++ = v4;
}
}
else
{
*s = 92;
s[1] = v4 + 48;
s += 2;
}
++v3;
}
while ( v3 != a2 + 4 );
*s = 0;
}

canonical_decompiled_code:
void __fastcall func1(char *s, unsigned __int8 *a2)
{
unsigned __int8 *v3; // rbx
unsigned __int8 v4; // dl

v3 = a2;
do
{
v4 = *v3;
if ( *v3 > 9u )
{
if ( v4 <= 0x1Fu )
{
sprintf(s, "0x%02x", v4);
s += strlen(s);
}
else
{
*s++ = v4;
}
}
else
{
*s = 92;
s[1] = v4 + 48;
s += 2;
}
++v3;
}
while ( v3 != a2 + 4 );
*s = 0;
}

original_code:
static void format_dostype(char *buf, const unsigned char *dostype)
{
  int i;
  unsigned char c;
  char *p;
  p = buf;
  for (i = 0; i < 4; i++) {
    c = dostype[i];
    if (c < 10) {
      *p++ = '\\';
      *p++ = '0' + c;
    } else if (c < 32) {
      sprintf(p, "0x%02x", (int)c);
      p = strchr(p, 0);
    } else {
      *p++ = (char)c;
    }
  }
  *p = 0;
}

canonical_original_code:
static void format_dostype(char *buf, unsigned char *dostype)
{
  int i;
  unsigned char c;
  char *p;
  p = buf;
  for (i = 0; i < 4; i++) {
    c = dostype[i];
    if (c < 10) {
      *p++ = '\\';
      *p++ = '0' + c;
    } else if (c < 32) {
      sprintf(p, "0x%02x", (int)c);
      p = strchr(p, 0);
    } else {
      *p++ = (char)c;
    }
  }
  *p = 0;
}

variable_types:
buf
char *

variable_types:
c
unsigned char

variable_types:
p
char *


decompiled_code:
int __fastcall detect_amiga_partmap(__int64 a1, unsigned int a2)
{
__int64 i; // rbx
unsigned __int64 v3; // rax
unsigned __int64 v4; // rax
__int64 v5; // rbp
unsigned int j; // er15
__int64 v7; // rdx
char *v8; // rbx
__int64 v9; // rdx
__int64 v10; // rbx
__int64 v11; // rbx
__int64 v12; // r12
__int64 v13; // rbx
const char *v14; // rax
__int64 v16; // [rsp+8h] [rbp-190h]
char s[64]; // [rsp+10h] [rbp-188h] BYREF
char v18[264]; // [rsp+50h] [rbp-148h] BYREF
void *s1[8]; // [rsp+158h] [rbp-40h] BYREF

for ( i = 0LL; i != 16; ++i )
{
v3 = get_buffer(a1, i << 9, 512LL, s1);
if ( v3 <= 0x1FF )
break;
LODWORD(v3) = memcmp(s1[0], "RDSK", 4uLL);
if ( !(_DWORD)v3 )
{
if ( (_DWORD)i )
print_line(a2, "Amiga Rigid Disk partition map at sector %d", (unsigned int)i);
else
print_line(a2, "Amiga Rigid Disk partition map");
v4 = get_be_long((char *)s1[0] + 16);
if ( v4 <= 0xFF || (v4 & (v4 - 1)) != 0 )
{
LODWORD(v3) = print_line(a2 + 1, "Illegal block size %lu", v4);
}
else
{
if ( v4 != 512 )
print_line(a2 + 1, "Unusual block size %lu, not sure this will work...", v4);
v5 = get_be_long((char *)s1[0] + 28);
LODWORD(v3) = -1;
if ( v5 != 0xFFFFFFFFLL )
{
for ( j = 1; ; ++j )
{
if ( (unsigned __int64)get_buffer(a1, v5 << 9, 256LL, s1) <= 0xFF )
{
LODWORD(v3) = print_line(a2, "Partition %d: Can't read partition info block", v7);
return v3;
}
v8 = (char *)s1[0];
if ( memcmp(s1[0], "PART", 4uLL) )
break;
v5 = get_be_long(v8 + 16);
v10 = get_be_long((char *)s1[0] + 140);
v11 = get_be_long((char *)s1[0] + 148) * v10;
v12 = v11 * get_be_long((char *)s1[0] + 164);
v16 = get_be_long((char *)s1[0] + 168);
v13 = (v16 + 1 - get_be_long((char *)s1[0] + 164)) * v11;
snprintf(s, 0x3FuLL, " from %llu", v12);
format_blocky_size(v18, v13, 512LL, "sectors", s);
print_line(a2, "Partition %d: %s", j, v18);
get_pstring((char *)s1[0] + 36, v18);
if ( v18[0] )
print_line(a2 + 1, "Drive name \"%s\"", v18);
format_dostype(v18, (unsigned __int8 *)s1[0] + 192);
v14 = get_name_for_dostype((char *)s1[0] + 192);
print_line(a2 + 1, "Type \"%s\" (%s)", v18, v14);
if ( v13 && v12 )
analyze_recursive(a1, a2 + 1, v12 << 9, v13 << 9, 0LL);
LODWORD(v3) = -1;
if ( v5 == 0xFFFFFFFFLL )
return v3;
}
LODWORD(v3) = print_line(a2, "Partition %d: Invalid signature", v9);
}
}
return v3;
}
}
return v3;
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1, unsigned int a2)
{
__int64 i; // rbx
unsigned __int64 v3; // rax
unsigned __int64 v4; // rax
__int64 v5; // rbp
unsigned int j; // er15
__int64 v7; // rdx
char *v8; // rbx
__int64 v9; // rdx
__int64 v10; // rbx
__int64 v11; // rbx
__int64 v12; // r12
__int64 v13; // rbx
const char *v14; // rax
__int64 v16; // [rsp+8h] [rbp-190h]
char s[64]; // [rsp+10h] [rbp-188h] BYREF
char v18[264]; // [rsp+50h] [rbp-148h] BYREF
void *s1[8]; // [rsp+158h] [rbp-40h] BYREF

for ( i = 0LL; i != 16; ++i )
{
v3 = get_buffer(a1, i << 9, 512LL, s1);
if ( v3 <= 0x1FF )
break;
LODWORD(v3) = memcmp(s1[0], "RDSK", 4uLL);
if ( !(_DWORD)v3 )
{
if ( (_DWORD)i )
print_line(a2, "Amiga Rigid Disk partition map at sector %d", (unsigned int)i);
else
print_line(a2, "Amiga Rigid Disk partition map");
v4 = get_be_long((char *)s1[0] + 16);
if ( v4 <= 0xFF || (v4 & (v4 - 1)) != 0 )
{
LODWORD(v3) = print_line(a2 + 1, "Illegal block size %lu", v4);
}
else
{
if ( v4 != 512 )
print_line(a2 + 1, "Unusual block size %lu, not sure this will work...", v4);
v5 = get_be_long((char *)s1[0] + 28);
LODWORD(v3) = -1;
if ( v5 != 0xFFFFFFFFLL )
{
for ( j = 1; ; ++j )
{
if ( (unsigned __int64)get_buffer(a1, v5 << 9, 256LL, s1) <= 0xFF )
{
LODWORD(v3) = print_line(a2, "Partition %d: Can't read partition info block", v7);
return v3;
}
v8 = (char *)s1[0];
if ( memcmp(s1[0], "PART", 4uLL) )
break;
v5 = get_be_long(v8 + 16);
v10 = get_be_long((char *)s1[0] + 140);
v11 = get_be_long((char *)s1[0] + 148) * v10;
v12 = v11 * get_be_long((char *)s1[0] + 164);
v16 = get_be_long((char *)s1[0] + 168);
v13 = (v16 + 1 - get_be_long((char *)s1[0] + 164)) * v11;
snprintf(s, 0x3FuLL, " from %llu", v12);
format_blocky_size(v18, v13, 512LL, "sectors", s);
print_line(a2, "Partition %d: %s", j, v18);
get_pstring((char *)s1[0] + 36, v18);
if ( v18[0] )
print_line(a2 + 1, "Drive name \"%s\"", v18);
func1(v18, (unsigned __int8 *)s1[0] + 192);
v14 = func0((char *)s1[0] + 192);
print_line(a2 + 1, "Type \"%s\" (%s)", v18, v14);
if ( v13 && v12 )
analyze_recursive(a1, a2 + 1, v12 << 9, v13 << 9, 0LL);
LODWORD(v3) = -1;
if ( v5 == 0xFFFFFFFFLL )
return v3;
}
LODWORD(v3) = print_line(a2, "Partition %d: Invalid signature", v9);
}
}
return v3;
}
}
return v3;
}

original_code:
void detect_amiga_partmap(SECTION *section, int level)
{
  int i, off, found;
  unsigned char *buf;
  char s[256], append[64];
  u4 blocksize, part_ptr;
  u8 cylsize, start, size;
  for (off = 0, found = 0; off < 16; off++) {
    if (get_buffer(section, off * 512, 512, (void **)&buf) < 512)
      break;
    if (memcmp(buf, "RDSK", 4) == 0) {
      found = 1;
      break;
    }
  }
  if (!found)
    return;
  if (off == 0)
    print_line(level, "Amiga Rigid Disk partition map");
  else
    print_line(level, "Amiga Rigid Disk partition map at sector %d", off);
  blocksize = get_be_long(buf + 16);
  if (blocksize < 256 || (blocksize & (blocksize-1))) {
    print_line(level+1, "Illegal block size %lu", blocksize);
    return;
  } else if (blocksize != 512) {
    print_line(level+1, "Unusual block size %lu, not sure this will work...", blocksize);
  }
  part_ptr = get_be_long(buf + 28);
  for (i = 1; part_ptr != 0xffffffffUL; i++) {
    if (get_buffer(section, (u8)part_ptr * 512, 256,
     (void **)&buf) < 256) {
      print_line(level, "Partition %d: Can't read partition info block");
      break;
    }
    if (memcmp(buf, "PART", 4) != 0) {
      print_line(level, "Partition %d: Invalid signature");
      break;
    }
    part_ptr = get_be_long(buf + 16);
    cylsize = (u8)get_be_long(buf + 140) * (u8)get_be_long(buf + 148);
    start = get_be_long(buf + 164) * cylsize;
    size = (get_be_long(buf + 168) + 1 - get_be_long(buf + 164)) * cylsize;
    snprintf(append, 63, " from %llu", start);
    format_blocky_size(s, size, 512, "sectors", append);
    print_line(level, "Partition %d: %s",
               i, s);
    get_pstring(buf + 36, s);
    if (s[0])
      print_line(level + 1, "Drive name \"%s\"", s);
    format_dostype(s, buf + 192);
    print_line(level + 1, "Type \"%s\" (%s)", s,
               get_name_for_dostype(buf + 192));
    if (size > 0 && start > 0) {
      analyze_recursive(section, level + 1,
   start * 512, size * 512, 0);
    }
  }
}

canonical_original_code:
void detect_amiga_partmap(struct section *section, int level)
{
  int i; int off; int found;
  unsigned char *buf;
  char s[256]; char append[64];
  unsigned long blocksize; unsigned long part_ptr;
  unsigned long long cylsize; unsigned long long start; unsigned long long size;
  for (off = 0, found = 0; off < 16; off++) {
    if (get_buffer(section, off * 512, 512, (void **)&buf) < 512)
      break;
    if (memcmp(buf, "RDSK", 4) == 0) {
      found = 1;
      break;
    }
  }
  if (!found)
    return;
  if (off == 0)
    print_line(level, "Amiga Rigid Disk partition map");
  else
    print_line(level, "Amiga Rigid Disk partition map at sector %d", off);
  blocksize = get_be_long(buf + 16);
  if (blocksize < 256 || (blocksize & (blocksize-1))) {
    print_line(level+1, "Illegal block size %lu", blocksize);
    return;
  } else if (blocksize != 512) {
    print_line(level+1, "Unusual block size %lu, not sure this will work...", blocksize);
  }
  part_ptr = get_be_long(buf + 28);
  for (i = 1; part_ptr != 0xffffffffUL; i++) {
    if (get_buffer(section, (unsigned long long)part_ptr * 512, 256,
     (void **)&buf) < 256) {
      print_line(level, "Partition %d: Can't read partition info block");
      break;
    }
    if (memcmp(buf, "PART", 4) != 0) {
      print_line(level, "Partition %d: Invalid signature");
      break;
    }
    part_ptr = get_be_long(buf + 16);
    cylsize = (unsigned long long)get_be_long(buf + 140) * (unsigned long long)get_be_long(buf + 148);
    start = get_be_long(buf + 164) * cylsize;
    size = (get_be_long(buf + 168) + 1 - get_be_long(buf + 164)) * cylsize;
    snprintf(append, 63, " from %llu", start);
    format_blocky_size(s, size, 512, "sectors", append);
    print_line(level, "Partition %d: %s",
               i, s);
    get_pstring(buf + 36, s);
    if (s[0])
      print_line(level + 1, "Drive name \"%s\"", s);
    format_dostype(s, buf + 192);
    print_line(level + 1, "Type \"%s\" (%s)", s,
               get_name_for_dostype(buf + 192));
    if (size > 0 && start > 0) {
      analyze_recursive(section, level + 1,
   start * 512, size * 512, 0);
    }
  }
}

variable_types: level int

variable_types: found int

variable_types:
buf
unsigned char *

variable_types:
blocksize
unsigned long

variable_types:
cylsize
unsigned long long

variable_types:
start
unsigned long long

variable_types:
size
unsigned long long


decompiled_code:
int __fastcall detect_amiga_fs(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rax
const char *v3; // r12
void *v4; // r13
char **v5; // rbx
int v6; // ebp
unsigned int v7; // er14
char v9[264]; // [rsp+0h] [rbp-148h] BYREF
void *s1; // [rsp+108h] [rbp-40h] BYREF

v2 = get_buffer(a1, 0LL, 512LL, &s1);
if ( v2 > 0x1FF )
{
v3 = *(&amiga_dostypes + 2);
if ( v3 )
{
v4 = s1;
v5 = &amiga_dostypes;
v6 = 0;
while ( 1 )
{
LODWORD(v2) = memcmp(v4, *v5, 4uLL);
if ( !(_DWORD)v2 )
break;
++v6;
v5 += 3;
v3 = v5[2];
if ( !v3 )
return v2;
}
if ( LODWORD((&amiga_dostypes)[3 * v6 + 1]) )
{
print_line(a2, "%s", v3);
format_dostype(v9, (unsigned __int8 *)s1);
v7 = a2 + 1;
print_line(a2 + 1, "Type \"%s\"", v9);
v2 = *(_QWORD *)(a1 + 8);
if ( v2 == 901120 )
{
LODWORD(v2) = print_line(v7, "Size matches DD floppy");
}
else if ( v2 == 1802240 )
{
LODWORD(v2) = print_line(v7, "Size matches HD floppy");
}
}
else
{
format_dostype(v9, (unsigned __int8 *)v4);
LODWORD(v2) = print_line(a2, "Amiga type code \"%s\" (%s)", v9, v3);
}
}
}
return v2;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, unsigned int a2)
{
unsigned __int64 v2; // rax
const char *v3; // r12
void *v4; // r13
char **v5; // rbx
int v6; // ebp
unsigned int v7; // er14
char v9[264]; // [rsp+0h] [rbp-148h] BYREF
void *s1; // [rsp+108h] [rbp-40h] BYREF

v2 = get_buffer(a1, 0LL, 512LL, &s1);
if ( v2 > 0x1FF )
{
v3 = *(&amiga_dostypes + 2);
if ( v3 )
{
v4 = s1;
v5 = &amiga_dostypes;
v6 = 0;
while ( 1 )
{
LODWORD(v2) = memcmp(v4, *v5, 4uLL);
if ( !(_DWORD)v2 )
break;
++v6;
v5 += 3;
v3 = v5[2];
if ( !v3 )
return v2;
}
if ( LODWORD((&amiga_dostypes)[3 * v6 + 1]) )
{
print_line(a2, "%s", v3);
func1(v9, (unsigned __int8 *)s1);
v7 = a2 + 1;
print_line(a2 + 1, "Type \"%s\"", v9);
v2 = *(_QWORD *)(a1 + 8);
if ( v2 == 901120 )
{
LODWORD(v2) = print_line(v7, "Size matches DD floppy");
}
else if ( v2 == 1802240 )
{
LODWORD(v2) = print_line(v7, "Size matches HD floppy");
}
}
else
{
func1(v9, (unsigned __int8 *)v4);
LODWORD(v2) = print_line(a2, "Amiga type code \"%s\" (%s)", v9, v3);
}
}
}
return v2;
}

original_code:
void detect_amiga_fs(SECTION *section, int level)
{
  unsigned char *buf;
  int i, isfs;
  char s[256], *typename;
  if (get_buffer(section, 0, 512, (void **)&buf) < 512)
    return;
  isfs = 0;
  typename = ((void *)0);
  for (i = 0; amiga_dostypes[i].name; i++)
    if (memcmp(buf, amiga_dostypes[i].typecode, 4) == 0) {
      isfs = amiga_dostypes[i].isfs;
      typename = amiga_dostypes[i].name;
      break;
    }
  if (typename == ((void *)0))
    return;
  if (isfs) {
    print_line(level, "%s", typename);
    format_dostype(s, buf);
    print_line(level + 1, "Type \"%s\"", s);
    if (section->size == 512*11*2*80) {
      print_line(level+1, "Size matches DD floppy");
    } else if (section->size == 512*22*2*80) {
      print_line(level+1, "Size matches HD floppy");
    }
  } else {
    format_dostype(s, buf);
    print_line(level, "Amiga type code \"%s\" (%s)", s, typename);
  }
}

canonical_original_code:
void detect_amiga_fs(struct section *section, int level)
{
  unsigned char *buf;
  int i; int isfs;
  char s[256]; char *typename;
  if (get_buffer(section, 0, 512, (void **)&buf) < 512)
    return;
  isfs = 0;
  typename = ((void *)0);
  for (i = 0; amiga_dostypes[i].name; i++)
    if (memcmp(buf, amiga_dostypes[i].typecode, 4) == 0) {
      isfs = amiga_dostypes[i].isfs;
      typename = amiga_dostypes[i].name;
      break;
    }
  if (typename == ((void *)0))
    return;
  if (isfs) {
    print_line(level, "%s", typename);
    format_dostype(s, buf);
    print_line(level + 1, "Type \"%s\"", s);
    if (section->size == 512*11*2*80) {
      print_line(level+1, "Size matches DD floppy");
    } else if (section->size == 512*22*2*80) {
      print_line(level+1, "Size matches HD floppy");
    }
  } else {
    format_dostype(s, buf);
    print_line(level, "Amiga type code \"%s\" (%s)", s, typename);
  }
}

variable_types: struct section { unsigned long long pos; int flags; struct source { unsigned long long size; int size_known; void *cache_head; int sequential; unsigned long long seq_pos; int blocksize; struct source *foundation; int (*analyze)(struct source *s, int level); unsigned long long (*read_bytes)(struct source *s, unsigned long long pos, unsigned long long len, void *buf); int (*read_block)(struct source *s, unsigned long long pos, void *buf); void (*close)(struct source *s); } *source; } *

variable_types: isfs int

variable_types:
typename
char *


decompiled_code:
_BOOL8 __fastcall validate_tag(__int64 a1, __int64 a2)
{
int v2; // edx
__int64 v3; // rax
char v4; // cl
_BOOL8 result; // rax

v2 = 1;
v3 = 0LL;
v4 = 0;
while ( 1 )
{
if ( (_DWORD)v3 != 4 )
{
v4 += *(_BYTE *)(a1 + v3);
if ( v2 > 15 )
break;
}
++v3;
++v2;
}
result = 0LL;
if ( v4 == *(_BYTE *)(a1 + 4) && !*(_BYTE *)(a1 + 5) )
result = get_le_long(a1 + 12) == a2;
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func0(__int64 a1, __int64 a2)
{
int v2; // edx
__int64 v3; // rax
char v4; // cl
_BOOL8 result; // rax

v2 = 1;
v3 = 0LL;
v4 = 0;
while ( 1 )
{
if ( (_DWORD)v3 != 4 )
{
v4 += *(_BYTE *)(a1 + v3);
if ( v2 > 15 )
break;
}
++v3;
++v2;
}
result = 0LL;
if ( v4 == *(_BYTE *)(a1 + 4) && !*(_BYTE *)(a1 + 5) )
result = get_le_long(a1 + 12) == a2;
return result;
}

original_code:
static int validate_tag(unsigned char *buf, u4 sector)
{
  int cksum, i;
  cksum = 0;
  for (i = 0; i < 16; i++)
    if (i != 4)
      cksum += buf[i];
  if ((cksum & 0xFF) != buf[4])
    return 0;
  if (buf[5] != 0)
    return 0;
  if (get_le_long(buf + 12) != sector)
    return 0;
  return 1;
}

canonical_original_code:
static int validate_tag(unsigned char *buf, unsigned long sector)
{
  int cksum; int i;
  cksum = 0;
  for (i = 0; i < 16; i++)
    if (i != 4)
      cksum += buf[i];
  if ((cksum & 0xFF) != buf[4])
    return 0;
  if (buf[5] != 0)
    return 0;
  if (get_le_long(buf + 12) != sector)
    return 0;
  return 1;
}

variable_types:
sector
unsigned long

variable_types: cksum int

variable_types: i int