Metadata-Version: 2.4
Name: ByteOps
Version: 0.1.0
Summary: A minimalistic library for doing unsigned integer operations when reversing x86 code.
Home-page: https://github.com/fxb-cocacoding/byteops
Author: Felix Bilstein
Author-email: fxb@cocacoding.com
License: BSD 2-Clause
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: summary

## ByteOps

A library for doing logical and arithmetical operations based on x86 assembly.
It also contains code for the following operations for `BYTE`, `WORD`, `DWORD`, `QWORD`, `XMMWORD`, `YMMWORD` and `ZMMWORD`:

* `add`
* `sub`
* `mul`
* `and`
* `or`
* `xor`
* `not`
* `rol`
* `ror`
* `shl`
* `shr`

The library is used for reimplementing string decryption routines in the context of malware analysis.
It can save you time debugging where you needed to mask bytes or do modulo operations again and where not.
The code can also be used to copy a shift or rotate operation which tends to be ugly in python.

### Example:

Pseudocode from IDA

```C
strcpy(vStackString, "nAA:P<;n@XRFa=cXO;>@sxt?avd\x1DJX");
v28 = (char *)v62;
do
{
  vStackString[index] = 0x14 - ((index ^ (vStackString[index] + 0x67)) - 4);
  ++index;
}
while ( index != 31 );
vStackString[20] = 0;
```

Function in Python:

```python
from byteops import ByteOps

def decode():
    vStackString = bytes([
        0x6E, 0x41, 0x41, 0x3A, 0x50, 0x3C, 0x3B, 0x6E, 0x40, 0x58, 0x52, 0x46, 0x61, 0x3D, 0x63, 0x58,
        0x4F, 0x3B, 0x3E, 0x40, 0x73, 0x78, 0x74, 0x3F, 0x61, 0x76, 0x64, 0x1D, 0x4A, 0x58, 0x00, 0x00
    ])
    result = bytearray(31)
    for index in range(31):
        temp = bytes([vStackString[index]])
        index_bytes = index.to_bytes(1, 'little')

        # (vStackString[index] + 0x67)
        add_result = ByteOps.add_byte(temp, bytes.fromhex("67"))

        # (index ^ (vStackString[index] + 0x67))
        xor_result = ByteOps.xor_byte(index_bytes, add_result)

        # ((index ^ (vStackString[index] + 0x67)) - 4)
        sub_result = ByteOps.sub_byte(xor_result, bytes.fromhex("04"))

        # 0x14 - ((index ^ (vStackString[index] + 0x67)) - 4)
        final_result = ByteOps.sub_byte(bytes.fromhex("14"), sub_result)

        # first and also only byte to the result store
        if index < 20:
            result[index] = final_result[0]

    print("".join(chr(i) for i in result))

decode()
```

### Tests

The operations are tested with static values and a randomized test case where the implemented instructions are
tested against the Python implementation of the operation (mostly, the original operators).
The original result is masked, and it is expected to be identical to the "custom" implementation for e.g. add or sub.
