Skip to content

Instantly share code, notes, and snippets.

@ryancor
Last active April 30, 2024 08:42
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryancor/a4f243d72b9d9f5b2f5e1b3f67feda61 to your computer and use it in GitHub Desktop.
Save ryancor/a4f243d72b9d9f5b2f5e1b3f67feda61 to your computer and use it in GitHub Desktop.
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