---
# System prepended metadata

title: 'Pyc Analysis [16 July]'
tags: [decompiler]

---

---
tags: decompiler
---

# Pyc Analysis [16 July]

- Different Python versions perform better in different aspects
    - Async functions trouble some more than other


Stats Summary:

| **Python Version:** | Py3.8 | Py3.7 | Py3.6 | Py2.7 |
| -------- | -------- | -------- | -------- | -------- | 
| **Success rate:** | 7/28    | 13/28     | 18/28     | 22/24 |
> Not counting async functions towards python 2.7

## Version variations

- Python 3.6 performs better than python 3.7 and 3.8
- However, cannot substitute python 3.6 with 3.7 and 3.8 (see [MWE 1/3](https://hackmd.io/@aliahad97/rkPmyJCpO#Error-13)).
- Cases where Python 2.7 and 3.6 fail while 3.7 and 3.8 pass (see [MWE 1/8](https://hackmd.io/@aliahad97/rkPmyJCpO#Error-18))
- Migration is not always the solution since in some cases all python 3 fail and each of them have different bytecode
- Async introduces a whole new range of issues


### Python variation:

#### Python 3.6 fail:
Bytecode variation for [MWE 1/3](https://hackmd.io/@aliahad97/rkPmyJCpO#Error-13):

For code:
```python=
def _on_item_clicked():
    for x in items():
        if x:
            if is_modified:
                if not is_selected:
                    deselect()
            else:
                deselect()
        else:
            select()
```
Bytecode:
![](https://i.imgur.com/KOYGS7m.jpg)
<- Python 3.8 on left | Python 3.6 on right ->

**Key takeaways:**
- Fix the following:
    - Change Setup loop
    - Fix offsets
    - Change header to python 3.8 bytecode
- Should decompyle

#### Python 3.6 and 2.7 fail:
Bytecode variation for [MWE 1/8](https://hackmd.io/@aliahad97/rkPmyJCpO#Error-18):

For code:
```python=
def __setitem__(self, key, value, unrepr=False):
    if not self.main.stringify:
        if a:
            pass
        elif b:
            x= 1
        else:
            x= 2
```
Bytecode for 3.6 and 2.7:
![](https://i.imgur.com/8A6Ypvr.jpg)

Both fail.
<- Python 3.6 on left | Python 2.7 on right ->

Bytecode for 3.6 and 3.8:
![](https://i.imgur.com/QdBH75z.jpg)
<- Python 3.6 on left | Python 3.8 on right ->

**Key takeaways:**
- Fix the following:
    - Migrate python 2.7 to 3
    - Change header to python 3.8 bytecode
- Should decompyle

#### All python3 fail:
Bytecode variation for [MWE 1/15](https://hackmd.io/@aliahad97/BJNrSJ0pd#Error-115):

For code:
```python=
def remove_sections():
    return x
    for start in sections:
        pass
```

Bytecode for 3.6 and 2.7:
![](https://i.imgur.com/WVl8kkZ.png)

<- Python 3.6 on left | Python 2.7 on right ->

Bytecode for 3.6 and 3.8:

![](https://i.imgur.com/wPscUKA.png)

<- Python 3.6 on left | Python 3.8 on right ->

**Key takeaways:**
- Migrating from different Python 3 versions to 2.7 is complex
- Cases as such require approach different from migration
- Fix the following:
    - Remove bytecode below return statement
- Should decompyle

#### Async functions and python versions

MWEs related to async:
- [MWE 1/11](https://hackmd.io/@aliahad97/BJNrSJ0pd#Error-111)
- [MWE 1/12](https://hackmd.io/@aliahad97/BJNrSJ0pd#Error-112)
- [MWE 1/13](https://hackmd.io/@aliahad97/BJNrSJ0pd#Error-113)
- [MWE 1/14](https://hackmd.io/@aliahad97/BJNrSJ0pd#Error-114)

| **Python Version:** | Py3.8 | Py3.7 | Py3.6 | Py2.7 |
| -------- | -------- | -------- | -------- | -------- | 
| **Success rate:** | 1/4    | 3/4     | 1/4     | N/A |

For code in python 3.6:
```python=
async def flatten(self):
    l = []
    async for result in self:
        l.append(result)
    return l
```
> Note: This fails to decompyle

Bytecode with and without async:
![](https://i.imgur.com/kvKRsE1.jpg)

Bytecode for 3.6 and 3.7:
![](https://i.imgur.com/SQ46fpQ.jpg)
<- Python 3.6 on left | Python 3.7 on right ->

Here Python 3.7 Passes in decompilation.

Overall Python 3.7 performs best for async functions.

**Key takeaways:**
- Async functions add a range of code that would be absent otherwise
- Python 3.7 performs best
- There is no case where other python versions pass for async functions when python 3.7 fails
- Fix the following:
    - Migrate to python 3.7 by changing highlighted bytecode
    - Change header to python 3.7
- Should decompyle