A library for doing logical and arithmetical operations based on x86 assembly, mostly for the use in agentic-driven reverse engineering.
At the time of creation, LLMs tended to mess up the word-sized when generating Python code.
Non-frontier models still tend to do this at the time of writing.
The naming convention of the operations appears long, but the clear names seem to help LLMs to understand the operations easier/faster.
It also contains code for the following operations for BYTE, WORD, DWORD, QWORD, XMMWORD, YMMWORD and ZMMWORD:
addsubmulandorxornotrolrorshlshr
The library is used for reimplementing string decryption routines in the context of malware analysis. It can save you time debugging where you or the agent 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.
Just via pip:
pip install byteops
Pseudocode from IDA
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:
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()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.