Skip to content

Instantly share code, notes, and snippets.

@FrankSpierings
Last active May 4, 2019 15:27
Show Gist options
  • Save FrankSpierings/2ad441ebbbace644ee6335371e93ff5c to your computer and use it in GitHub Desktop.
Save FrankSpierings/2ad441ebbbace644ee6335371e93ff5c to your computer and use it in GitHub Desktop.
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