---
# System prepended metadata

title: Other decompilers
tags: [decompiler]

---

---
tags: decompiler
title: Other decompilers
---

# Unpyc37
Total: 5356
Exception raised: 33 (Explicit errors)
Attribution error: 37

Total exceptions: 80

debugging: `Traceback (most recent call last):`

How to find implicit errors?

- Inconsistencies in bytecode functions: 4086
- prune out those that are still equivalent? 
    - Find jump instructions diff

Example:

:::spoiler
Example 1 (15660): 
```

def _download_impl(self, url, pathfmt):
    
    while True:
        if tries:
            if response:
                response.close()
                response = None
            self.log.warning("%s (%s/%s)", msg, tries, self.retries+1)
            if tries > self.retries:
                return False
            time.sleep(tries)

        tries += 1
        file_header = None

        # collect HTTP headers
        headers = {"Accept": "*/*"}
        #   file-specific headers
        extra = kwdict.get("_http_headers")
        if extra:
            headers.update(extra)
        #   general headers
        if self.headers:
            headers.update(self.headers)
        #   partial content
        file_size = pathfmt.part_size()
        if file_size:
            headers["Range"] = "bytes={}-".format(file_size)

        # connect to (remote) source
        try:
            response = self.session.request(
                kwdict.get("_http_method", "GET"), url,
                stream=True,
                headers=headers,
                data=kwdict.get("_http_data"),
                timeout=self.timeout,
                proxies=self.proxies,
                verify=self.verify,
            )
        except (ConnectionError, Timeout) as exc:
            msg = str(exc)
            continue
        except Exception as exc:
            self.log.warning(exc)
            return False

        # check response
        code = response.status_code
        if code == 200:  # OK
            offset = 0
            size = response.headers.get("Content-Length")
        elif code == 206:  # Partial Content
            offset = file_size
            size = response.headers["Content-Range"].rpartition("/")[2]
        elif code == 416 and file_size:  # Requested Range Not Satisfiable
            break
        else:
            msg = "'{} {}' for '{}'".format(code, response.reason, url)
            tmp = code == 429 or 500 <= code < 600 ## LOOK HEREEE!!!!! XXX
            if tmp:  # Server Error
                continue
            self.log.warning(msg)
            return False

        # check for invalid responses
        validate = kwdict.get("_http_validate")
        if validate:
            result = validate(response)
            if isinstance(result, str):
                url = result
                tries -= 1
                continue
            if not result:
                self.log.warning("Invalid response")
                return False

        # set missing filename extension from MIME type
        if not pathfmt.extension:
            pathfmt.set_extension(self._find_extension(response))
            if pathfmt.exists():
                pathfmt.temppath = ""
                return True

        # check file size
        size = text.parse_int(size, None)
        if size is not None:
            if self.minsize and size < self.minsize:
                self.log.warning(
                    "File size smaller than allowed minimum (%s < %s)",
                    size, self.minsize)
                return False
            if self.maxsize and size > self.maxsize:
                self.log.warning(
                    "File size larger than allowed maximum (%s > %s)",
                    size, self.maxsize)
                return False

        content = response.iter_content(self.chunk_size)

        # check filename extension against file header
        if adjust_extension and not offset and \
                pathfmt.extension in FILE_SIGNATURES:
            try:
                file_header = next(
                    content if response.raw.chunked
                    else response.iter_content(16), b"")
            except (RequestException, SSLError, OpenSSLError) as exc:
                msg = str(exc)
                print()
                continue
            if self._adjust_extension(pathfmt, file_header) and \
                    pathfmt.exists():
                pathfmt.temppath = ""
                return True

        # set open mode
        if not offset:
            mode = "w+b"
            if file_size:
                self.log.debug("Unable to resume partial download")
        else:
            mode = "r+b"
            self.log.debug("Resuming download at byte %d", offset)

        # download content
        self.downloading = True
        with pathfmt.open(mode) as fp:
            if file_header:
                fp.write(file_header)
                offset += len(file_header)
            elif offset:
                if adjust_extension and \
                        pathfmt.extension in FILE_SIGNATURES:
                    self._adjust_extension(pathfmt, fp.read(16))
                fp.seek(offset)

            self.out.start(pathfmt.path)
            try:
                self.receive(fp, content, size, offset)
            except (RequestException, SSLError, OpenSSLError) as exc:
                msg = str(exc)
                print()
                continue

            # check file size
            if size and fp.tell() < size:
                msg = "file size mismatch ({} < {})".format(
                    fp.tell(), size)
                print()
                continue

        break

    self.downloading = False
    if self.mtime:
        kwdict.setdefault("_mtime", response.headers.get("Last-Modified"))
    else:
        kwdict["_mtime"] = None

    return True

```
:::

# Uncompyle2
Total: 22222

Parse errors (explicit): 36

Implicit errors? 

# Pycdc

## Segmentation fault

Segmentation fault
Errors:
### Py27 
pattern1:
```
if x:
    return 
#z=z
return {a: b}
```

pattern2:

```
if cmd == '':
    return self.default(line)
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```
pattern3:

```
assert X
#z=z
for i in x:
    pass
```

pattern4: 

```
if not _winreg:
    return
#z=z
def enum_types(mimedb):
    pass
```

pattern5:

```
if not _winreg:
    return
#z=z
for i in x:
    pass
```
Pattern6:
```
assert unicodedata.unidata_version == '3.2.0'
#z=z
def in_table_a1(code):
    pass
```
Pattern7:
```
if not hasattr(os, 'utime'):
    return
#z=z
try:
    os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
except EnvironmentError as e:
    raise ExtractError('could not change modification time')

```

Pattern 8:
```
try:
    if a:
        return b
    #z=z
except OSError as msg:
    raise URLError(msg)
```
Pattern 9:
```
if a:
    if b:
        if c:
            k = k + 1
        # z=z
    temp = temp + 1

```

### Py34
Infinitely runs:
Pattern 3:
```
assert action_tuples
z=z
for action, args, option_string in action_tuples:
    take_action(action, args, option_string)
```
Pattern 10:
```
while True: # change to temp
    if action is None:
        extras.append(arg_strings[start_index])
        # return start_index + 1
    if a:
        arg_count = match_argument(action, 'A')
    else:
        break
```
pattern2:

```
if cmd == '':
    return self.default(line)
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```

Pattern6:
```
assert unicodedata.unidata_version == '3.2.0'
#z=z
def in_table_a1(code):
    pass
```

### py35
pattern2:

```
if cmd == '':
    return self.default(line)
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```

Pattern6:
```
assert unicodedata.unidata_version == '3.2.0'
#z=z
def in_table_a1(code):
    pass
```
Pattern 11:
```
assert x
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```

pattern4: 

```
if not _winreg:
    return
#z=z
def enum_types(mimedb):
    pass
```
Pattern 8:
```
try:
    if a:
        return b
    #z=z
except OSError as msg:
    raise URLError(msg)
```
pattern3:

```
assert X
#z=z
for i in x:
    pass
```
Pattern 12:
```
if a:
    b = b +1
else:
    return
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```
Pattern 13:
```
try:
    if fut is not None:
        # assign following boolean to a variable
        assert self._read_fut is fut or not (self._read_fut is None and
                                            self._closing)
except ConnectionAbortedError as exc:
    pass
```
### py36

Pattern 8:
```
try:
    if a:
        return b
    #z=z
except OSError as msg:
    raise URLError(msg)
```
pattern3:

```
assert X
#z=z
for i in x:
    pass
```
Pattern 10:
```
while True: # change to temp
    if action is None:
        extras.append(arg_strings[start_index])
        # return start_index + 1
    if a:
        arg_count = match_argument(action, 'A')
    else:
        break
```

Pattern 11:
```
assert x
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```

pattern2:

```
if cmd == '':
    return self.default(line)
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```

Pattern6:
```
assert unicodedata.unidata_version == '3.2.0'
#z=z
def in_table_a1(code):
    pass
```
Pattern 13:
```
try:
    if fut is not None:
        # assign following boolean to a variable
        assert self._read_fut is fut or not (self._read_fut is None and
                                            self._closing)
except ConnectionAbortedError as exc:
    pass
```
pattern4: 

```
if not _winreg:
    return
#z=z
def enum_types(mimedb):
    pass
```
Pattern 8:
```
try:
    if a:
        return b
    #z=z
except OSError as msg:
    raise URLError(msg)
```

### py37
Pattern6:
```
assert unicodedata.unidata_version == '3.2.0'
#z=z
def in_table_a1(code):
    pass
```
pattern3:

```
assert X
#z=z
for i in x:
    pass
```
Pattern 10:
```
while True: # change to temp
    if action is None:
        extras.append(arg_strings[start_index])
        # return start_index + 1
    if a:
        arg_count = match_argument(action, 'A')
    else:
        break
```
Pattern 11:
```
assert x
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```

pattern2:

```
if cmd == '':
    return self.default(line)
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```
pattern4: 

```
if not _winreg:
    return
#z=z
def enum_types(mimedb):
    pass
```
Pattern 8:
```
try:
    if a:
        return b
    #z=z
except OSError as msg:
    raise URLError(msg)
```
Pattern 13:
```
try:
    if fut is not None:
        # assign following boolean to a variable
        assert self._read_fut is fut or not (self._read_fut is None and
                                            self._closing)
except ConnectionAbortedError as exc:
    pass
```

pattern5:

```
if not _winreg:
    return
#z=z
for i in x:
    pass
```

Pattern 14:
```
# tmp =(2, 7) < version_info[:2] < (3, 2)
if (2, 7) < version_info[:2] < (3, 2): #tmp:
    import collections
    def callable(x):
        return isinstance(x, collections.Callable)
else:

    callable = callable
```

### py38
Pattern 11:
Pattern6:
```
assert unicodedata.unidata_version == '3.2.0'
#z=z
def in_table_a1(code):
    pass
```
```
assert x
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```

pattern 15:

```
for i in x:
    if a:
        raise URLError(msg)
    #z=z
```
Pattern 14:
```
# tmp =(2, 7) < version_info[:2] < (3, 2)
if (2, 7) < version_info[:2] < (3, 2): #tmp:
    import collections
    def callable(x):
        return isinstance(x, collections.Callable)
else:

    callable = callable
```
pattern2:

```
if cmd == '':
    return self.default(line)
#z=z
try:
    func = getattr(self, 'do_' + cmd)
except AttributeError:
    return self.default(line)
```
Pattern 10:
```
while True: # change to temp
    if action is None:
        extras.append(arg_strings[start_index])
        # return start_index + 1
    if a:
        arg_count = match_argument(action, 'A')
    else:
        break
```
Pattern 16:
```
for line in source.split("\n"):
        line = line.strip()
        if line and line[0] != '#':
            break               # comment this
```
pattern4: 

```
if not _winreg:
    return
#z=z
def enum_types(mimedb):
    pass
```
Pattern 17:
```
for kind in ('episode', 'clip'):
        common_data = (cache.get(current_key) or list(cache.values())[0])[kind]
        break # remove
```