import binascii | |
import pefile | |
import subprocess | |
import sys | |
import os | |
ror = lambda val, r_bits, max_bits: \ | |
((val & (2**max_bits-1)) >> r_bits%max_bits) | \ | |
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) | |
def rightRotate(n, d): | |
return (n >> d)|(n << (8 - d)) & 0xFFFFFFFF | |
def getEncryptedData(filename, starting_offset, ending_offset): | |
pe = pefile.PE(filename) | |
encrypted_pe_header = [] | |
print("[!] Searching PE sections for .data") | |
for section in pe.sections: | |
if b".data" in section.Name: | |
offset = section.VirtualAddress | |
start = offset + starting_offset | |
end = offset + ending_offset | |
for byte in section.get_data()[start - offset:end - offset]: | |
if type(byte) != int: | |
encrypted_pe_header.append(ord(byte)) | |
else: | |
# python3 automatically has it as an ordinal | |
encrypted_pe_header.append(byte) | |
return encrypted_pe_header | |
def grabResourceFromFile(target_file, output_file): | |
bashCommand = "wrestool --name=1 --type=2 -R -x %s" % (target_file) | |
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) | |
output, error = process.communicate() | |
if error == None: | |
print("[!] Dumping resource section from {}".format(target_file)) | |
file = open(output_file, 'wb') | |
file.write(output) | |
file.close() | |
else: | |
print("Error with running wrestool {}".format(error)) | |
exit(-1) | |
def main(): | |
target_file = "AudioSes.dll" | |
output_file = "extracted.dll" | |
pe_header = [] | |
bufferSize = 239 | |
BMP_HeaderSize = 298 | |
key = 0xC5 | |
encrypted_pe_header = getEncryptedData(target_file, 0x08, 0xF7) | |
for i in range(bufferSize): | |
temp = encrypted_pe_header[i] ^ key | |
key = rightRotate(key, 1) & 0xff | |
if sys.version_info.major >= 3: | |
# dont hexlify as py3 | |
pe_header.append(temp) | |
else: | |
pe_header.append(binascii.hexlify(chr(temp))) | |
grabResourceFromFile(target_file, output_file) | |
print("\n[!] Replacing first {} bytes of resource dump.".format(BMP_HeaderSize)) | |
print(pe_header) | |
with open(output_file, 'r+b') as f: | |
f.seek(0) | |
for byte in range(len(pe_header)): | |
if type(pe_header[byte]) != int: | |
f.write(binascii.unhexlify(pe_header[byte])) | |
else: | |
# if python3 dont unhexlify, just convert int to byte | |
f.write(bytes([pe_header[byte]])) | |
print("\n[!] Replaced first {} bytes of file".format(bufferSize)) | |
# Now we have to delete remainging trail 0xff's from 239-298 offset | |
f.seek(BMP_HeaderSize) | |
data = f.read(os.path.getsize(output_file)) | |
f.seek(bufferSize) | |
f.write(data) | |
# Delete the last few trailing null bytes at the end of the file | |
f.seek(-(BMP_HeaderSize-bufferSize), os.SEEK_END) | |
f.truncate() | |
print("[!] Finished truncating trailing bytes") | |
f.close() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment