1 Star 0 Fork 0

lr2000/alpha3

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
encode.py 7.12 KB
一键复制 编辑 原始数据 按行查看 历史
berendjanwever 提交于 2010-01-10 12:30 . Initial check-in.
import ALPHA3
import math
# A generic encoding routine used by various decoders:
def encodeData(decoder, data, encoding_function, valid_values, pre_xor=True, terminating_char=""):
assert decoder, "Decoder is missing or empty"
assert data.find("\0") == -1, "Shellcode must be NULL free"
# Older encoders use a terminating char:
if terminating_char != "":
terminating_value = ord(terminating_char)
if terminating_value in valid_values:
valid_values.remove(terminating_value)
data += "\0" # A NULL will mark the end of the shellcode.
# The shellcode is encoded after the decoder. But because the last byte of the
# decoder is the negative offset of a jump that restarts the decoder loop and
# negative offsets translate into non-alphanumeric chars, this byte is also
# encoded (and will be the first to be decoded, so the jump will be decoded
# when the codepath hits it). All this means that the last two bytes of the
# decoder are part of the encoded data:
encoded_data = decoder[-2:]
decoder = decoder[:-2]
destination_index = 1
for c in data:
data_byte = ord(c);
# pre-xor A with B and encode the result into two bytes:
status = "encoding data (%d%%)" % int(100 * destination_index / len(data))
if pre_xor:
# The decoder stores decoded data using the XOR instruction. Originally, the
# decoder would pre-xor each data byte (A) with the value of the byte where it
# should be stored (B) before storing the byte. This meant that A would become
# A ^ B before the decoder stores it B ^= A ^ B (== A). However, this can be
# done while encoding, as well, saving a few bytes in the decoder:
pre_xor_byte = ord(encoded_data[destination_index])
bx, by = encoding_function(data_byte ^ pre_xor_byte, status, valid_values)
else:
bx, by = encoding_function(data_byte, status, valid_values)
encoded_data += chr(bx) + chr(by)
destination_index += 1
return decoder + encoded_data + terminating_char
# An encoding using in x86 ascii mixedcase decoders
def bx_IMUL_30_XOR_by(value, status, valid_values):
for bx in valid_values:
bx_IMUL_30 = (bx * 0x30) & 0xFF
for by in valid_values:
bx_IMUL_30_XOR_by = bx_IMUL_30 ^ by
if bx_IMUL_30_XOR_by == value:
ALPHA3.PrintVerboseStatus()
return [bx, by]
ALPHA3.PrintVerboseStatus(status, "%02X * 30 ^ %02X == %02X" % (
bx, by, bx_IMUL_30_XOR_by))
raise AssertionError("Cannot encode %02X" % (value,))
# An encoding used by old x86 unicode decoders:
def bx_IMUL_10_ADD_by(value, status, valid_values):
for bx in valid_values:
bx_IMUL_10 = (bx * 0x10) & 0xFF
for by in valid_values:
bx_IMUL_10_ADD_by = (bx_IMUL_10 + by) & 0xFF
if bx_IMUL_10_ADD_by == value:
ALPHA3.PrintVerboseStatus()
return [bx, by]
ALPHA3.PrintVerboseStatus(status, "%02X * 10 + %02X == %02X" % (
bx, by, bx_IMUL_10_ADD_by))
raise AssertionError("Cannot encode %02X" % (value,))
def wyx_IMUL_30_SHR_8_XOR_bx(value, status, valid_values):
for bx in valid_values:
for by in valid_values:
wyx = (by << 8) + bx
wyx_IMUL_30 = (wyx * 0x30) & 0xFFFF
wyx_IMUL_30_SHR_8 = wyx_IMUL_30 >> 8
wyx_IMUL_30_SHR_8_XOR_bx = wyx_IMUL_30_SHR_8 ^ bx
if wyx_IMUL_30_SHR_8_XOR_bx == value:
ALPHA3.PrintVerboseStatus()
return [bx, by]
ALPHA3.PrintVerboseStatus(status, "%02X %02X: ((%04X * 30) >> 8) ^ %02X == %02X" % (
bx, by, wyx, bx, wyx_IMUL_30_SHR_8_XOR_bx))
raise AssertionError("Cannot encode %02X" % (value,))
def dwx_IMUL_by(value, status, valid_values):
for by in valid_values:
dwx, carry = makeValid(0, 4, valid_values)
while not carry:
dwx_IMUL_by = (dwx * by) & 0xFFFFFFFF
if dwx_IMUL_by == value:
ALPHA3.PrintVerboseStatus()
return [dwx, by]
ALPHA3.PrintVerboseStatus(status, "%08X * %02X == %08X" % (
dwx, by, dwx_IMUL_by))
# How far off the desired value is the result now?
diff = value - dwx_IMUL_by
if diff < 0:
# the result is too small:
if diff % by == 0:
# It is a whole number of times by smaller: increase dwxX to get
# the right result:
dwx -= int(diff / by)
else:
# It is a off by an ammount that cannot lead to the solution easily.
# Cause another integer overflow to try another solution:
dwx += int(math.floor((diff + 0x100000000) / by))
else:
# It is too large, cause an integer overflow to resolve that:
dwx += int(math.floor((0x100000000 - diff) / by))
# Whatever modifications have been made to dwx may have caused it to
# become non-alphanumeric. If so, find the smallest alphanumeric number
# that is larger than dwx and use that:
dwx, carry = makeValid(int(dwx), 4, valid_values)
def dwx_IMUL_30_XOR_dwy(value, status, valid_values):
dwx, carry = makeValid(0, 4, valid_values)
dwy, carry = makeValid(0, 4, valid_values)
for byte in range(0, 4):
byte_mask = 0xFF << (byte * 8)
while 1:
dwx_IMUL_30_XOR_dwy = ((dwx * 0x30) ^ dwy) & 0xFFFFFFFF
ALPHA3.PrintVerboseStatus(status, "%08X * 30 ^ %08X == %08X" % (
dwx, dwy, dwx_IMUL_30_XOR_dwy))
if (dwx_IMUL_30_XOR_dwy & byte_mask) == (value & byte_mask):
break # OK: next byte
x_byte = (dwx & byte_mask) >> (byte * 8)
next_x_byte, carry = makeValid(x_byte + 1, 1, valid_values)
dwx = (dwx & (0xFFFFFFFF ^ byte_mask)) ^ (next_x_byte << (byte * 8))
if carry:
y_byte = (dwy & byte_mask) >> (byte * 8)
next_y_byte, carry = makeValid(y_byte + 1, 1, valid_values)
dwy = (dwy & (0xFFFFFFFF ^ byte_mask)) ^ (next_y_byte << (byte * 8))
assert carry == 0, "Cannot encode value!" # Should never happen!
ALPHA3.PrintVerboseStatus()
return [dwx, dwy]
def isValid(value, bytes, valid_values):
for i in range(0, bytes):
byte = (value >> (i * 8)) & 0xFF
if byte not in valid_values:
return False
return True
def makeValid(value, bytes, valid_values):
carry = 0
result = 0
for i in range(0, bytes):
byte = ((value >> (i * 8)) & 0xFF) + carry
carry = 0
if byte not in valid_values:
for valid_byte in valid_values:
if valid_byte > byte:
byte = valid_byte
break
else:
byte = 0x30
carry = 1
result += byte << (i * 8)
if (value >> (bytes * 8)) > 0:
carry = 1
return result, carry
def toString(value, bytes):
s = ""
for i in range(0, bytes):
byte = (value >> (i * 8)) & 0xFF
s += chr(byte)
return s
def injectCodes(data, codes):
for code in codes:
start_code = data.find("@")
assert start_code != -1, "More codes than places to store them!"
end_code = start_code + 1
while data[end_code] == "@":
end_code += 1
encoded_code = toString(code, end_code - start_code)
data = data[:start_code] + encoded_code + data[end_code:]
assert data.find("@") == -1, "Not enough codes to satisfy decoder!"
return data
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/lr2001/alpha3.git
git@gitee.com:lr2001/alpha3.git
lr2001
alpha3
alpha3
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385