Last active
May 4, 2019 15:27
-
-
Save FrankSpierings/2ad441ebbbace644ee6335371e93ff5c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import struct | |
import ctypes | |
import random | |
MIN = 0x20 | |
MAX = 0x7f | |
def process_bytes(b): | |
val = [0] *3 | |
if (b >= 0x23) and (b <= 0x82): | |
val[0] = ctypes.c_ubyte((MAX/2) -1).value | |
val[1] = ctypes.c_ubyte(MIN).value | |
val[2] = ctypes.c_ubyte(0 - val[0] - val[1] - b).value | |
result = ctypes.c_ubyte(0 - val[0] - val[1] - val[2]).value | |
elif (b >= 0x83 ) and (b <= 0xe2): | |
val[0] = ctypes.c_ubyte(MAX).value | |
val[1] = ctypes.c_ubyte(MAX).value | |
val[2] = ctypes.c_ubyte(0 - val[0] - val[1] - b).value | |
result = ctypes.c_ubyte(0 - val[0] - val[1] - val[2]).value | |
elif ((b >= 0x00) and (b <= 0x41)) or ((b >= 0xe2) and (b <= 0xff)) : | |
val[0] = ctypes.c_ubyte(MIN).value | |
val[1] = ctypes.c_ubyte(MAX).value | |
val[2] = ctypes.c_ubyte(0 - val[0] - val[1] - b).value | |
result = ctypes.c_ubyte(0 - val[0] - val[1] - val[2]).value | |
else: | |
raise RuntimeError("Can't convert value {0:02X}".format(b)) | |
return val | |
def test_process_bytes(): | |
for b in range(0,256): | |
v = process_byte(b) | |
t = ctypes.c_ubyte(0).value | |
for i in range(0, len(v)): | |
if (v[i] < MIN) or (v[i] > MAX): | |
raise ValueError("Illegal character '0x{0:02x}'' for input value '0x{1:02x}' in: '0x00 - 0x{2:02x} - 0x{3:02x} - 0x{4:02x}'".format(v[i], b, v[0], v[1], v[2])) | |
t = ctypes.c_ubyte(t - v[i]).value | |
if t != b: | |
raise ValueError("Illegal outcome: 0x{0:02x} for value 0x{1:02x}".format(t, b)) | |
def process_byte_overflow_times(values): | |
overflow = 0 | |
t=0 | |
for i in range(0, len(values)): | |
if t < values[i]: | |
overflow += 1 | |
t = ctypes.c_ubyte(t - values[i]).value | |
return overflow | |
def transpose_matrix(matrix): | |
words = [] | |
for calculation in range(0, 3): | |
value = 0 | |
for bytenr in reversed(range(0,4)): | |
value += matrix[bytenr][calculation] << (bytenr * 8) | |
words += [value] | |
return words | |
def process_words(word): | |
address = struct.pack('<I', word) | |
byte_matrix = [] | |
overflow = 0 | |
for b in ([ord(b) for b in address]): | |
if b+overflow > 0xff: | |
carry = 1 | |
else: | |
carry = 0 | |
val = process_bytes(ctypes.c_ubyte( b + overflow).value) | |
overflow = process_byte_overflow_times(val) | |
if carry == 1: | |
overflow += 1 | |
byte_matrix += [val] | |
return transpose_matrix(byte_matrix) | |
def test_process_words(): | |
testset = [0xff00ff00, 0x00000000, 0xffffffff, 0x00ff00ff] | |
for inval in testset: | |
outvals = process_words(inval) | |
outval = ctypes.c_uint(0 - outvals[0] - outvals[1] - outvals[2]).value | |
if outval != inval: | |
print i | |
raise ValueError("In 0x{0:08x} != out 0x{1:08x}".format(inval, outval)) | |
print("OK: 0x{0:08x}".format(outval)) | |
for i in range(0, 100): | |
inval = random.randint(0, 0xffffffff) | |
outvals = process_words(inval) | |
outval = ctypes.c_uint(0 - outvals[0] - outvals[1] - outvals[2]).value | |
if outval != inval: | |
print i | |
raise ValueError("In 0x{0:08x} != out 0x{1:08x}".format(inval, outval)) | |
print("OK: 0x{0:08x}".format(outval)) | |
def assemble_words(words): | |
lines = "" | |
for word in reversed(words): | |
values = process_words(word) | |
#Zero routine | |
lines += "push 0x20202020\n" | |
lines += "pop eax\n" | |
lines += "xor eax, 0x20202020\n" | |
first = True | |
for value in values: | |
lines += "sub eax, 0x{0:08x}\n".format(value) | |
lines += "push eax\n" | |
print lines | |
def test_assemble_words(): | |
inval = [random.randint(0, 0xffffffff) for x in range(0, 10)] | |
assemble_words(inval) | |
for val in inval: | |
print("0x{0:08x}".format(val)) | |
def encode_file(file): | |
with open(file, 'r') as f: | |
content = f.read() | |
mod = len(content) % 4 | |
if mod: | |
pad = "\x00" * ( 4 - mod) | |
content += pad | |
words = [struct.unpack("<I", content[i:i+4])[0] for i in range(0, len(content), 4)] | |
assemble_words(words) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment