mirror of
https://github.com/dobin/SuperMega
synced 2026-06-02 17:27:10 +00:00
remove failed experiment
This commit is contained in:
-299
@@ -1,299 +0,0 @@
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from model.defs import *
|
||||
from pe.superpe import SuperPe
|
||||
from log import setup_logging
|
||||
|
||||
logger = logging.getLogger("Relokator")
|
||||
|
||||
|
||||
class Relokator():
|
||||
|
||||
|
||||
def getSectionIndexByDataDir(self, dirIndex):
|
||||
addr = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[dirIndex].VirtualAddress
|
||||
|
||||
i = 0
|
||||
for sect in self.pe.sections:
|
||||
if addr >= sect.VirtualAddress and addr < (sect.VirtualAddress + sect.Misc_VirtualSize):
|
||||
return i
|
||||
i += 1
|
||||
|
||||
logger.error(f'Could not find section with directory index {dirIndex}!')
|
||||
return -1
|
||||
|
||||
|
||||
def getRemainingRelocsDirectorySize(self):
|
||||
relocsIndex = self.getSectionIndexByDataDir(SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC)
|
||||
out = self.pe.sections[relocsIndex].SizeOfRawData - self.pe.sections[relocsIndex].Misc_VirtualSize
|
||||
return out
|
||||
|
||||
|
||||
def addImageBaseRelocations(self, pageRva, relocs):
|
||||
assert pageRva > 0
|
||||
|
||||
if not self.pe.has_relocs():
|
||||
logger.error("No .reloc section")
|
||||
raise(Exception("No .reloc section"))
|
||||
|
||||
if self.is_64():
|
||||
imageBaseRelocType = SuperPe.IMAGE_REL_BASED_DIR64
|
||||
else:
|
||||
# Not really used
|
||||
imageBaseRelocType = SuperPe.IMAGE_REL_BASED_HIGHLOW
|
||||
|
||||
relocsSize = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size
|
||||
relocsIndex = self.getSectionIndexByDataDir(SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC)
|
||||
addr = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress
|
||||
sizeOfReloc = 2 * len(relocs) + 2 * 4
|
||||
|
||||
if sizeOfReloc >= self.getRemainingRelocsDirectorySize():
|
||||
self.logger.warning('WARNING! Cannot add any more relocations to this file. Probably TLS Callback execution technique wont work.')
|
||||
self.logger.warning(' Will try disabling relocations on output file. Expect corrupted executable though!')
|
||||
|
||||
self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0
|
||||
self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0
|
||||
return
|
||||
|
||||
relocDirRva = self.pe.sections[relocsIndex].VirtualAddress
|
||||
self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size += sizeOfReloc
|
||||
|
||||
# VirtualAddress
|
||||
self.pe.set_dword_at_rva(addr + relocsSize, pageRva)
|
||||
|
||||
# SizeOfBlock
|
||||
self.pe.set_dword_at_rva(addr + relocsSize + 4, sizeOfReloc)
|
||||
|
||||
logger.info(f'Adding {len(relocs)} relocations for Page RVA 0x{pageRva:X} - size of block: 0x{sizeOfReloc:X}')
|
||||
i = 0
|
||||
for reloc in relocs:
|
||||
#reloc_offset = (reloc - pageRva)
|
||||
reloc_offset = reloc
|
||||
reloc_type = imageBaseRelocType << 12
|
||||
relocWord = (reloc_type | reloc_offset)
|
||||
|
||||
#if reloc == 0:
|
||||
# reloc_type = 0
|
||||
# relocWord = 0
|
||||
# reloc_offset = 0
|
||||
logger.info(f'\tReloc{i} for addr 0x{reloc:X}: 0x{relocWord:X} - 0x{reloc_offset:X} - type: {imageBaseRelocType}')
|
||||
self.pe.set_qword_at_rva(relocDirRva + relocsSize + 8 + i * 2, relocWord)
|
||||
#self.pe.set_qword_at_rva(relocDirRva + relocsSize + 8 + i * 2, reloc)
|
||||
i += 1
|
||||
|
||||
|
||||
def overwriteImageBaseRelocations(self, pageRva, relocs):
|
||||
assert pageRva > 0
|
||||
imageBaseRelocType = SuperPe.IMAGE_REL_BASED_DIR64
|
||||
|
||||
addr = self.pe.OPTIONAL_HEADER.DATA_DIRECTORY[SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress
|
||||
print("Set at: 0x{:X} / 0x{:X}: 0x{:X}".format(
|
||||
addr,
|
||||
self.pe.get_offset_from_rva(addr),
|
||||
pageRva))
|
||||
self.pe.set_dword_at_rva(addr, pageRva)
|
||||
self.pe.set_bytes_at_offset(
|
||||
self.pe.get_offset_from_rva(addr + 4),
|
||||
b'\x00' * 4
|
||||
)
|
||||
|
||||
|
||||
def mywrite(self, filename):
|
||||
file_data = bytearray(self.pe.__data__)
|
||||
f = open(filename, "wb+")
|
||||
f.write(file_data)
|
||||
f.close()
|
||||
|
||||
|
||||
def main(filename: str, current_base: int):
|
||||
setup_logging(logging.DEBUG)
|
||||
print("Handling: {}".format(filename))
|
||||
superpe = SuperPe(filename)
|
||||
|
||||
r = {}
|
||||
relocation: PeRelocEntry
|
||||
for relocation in superpe.get_base_relocs():
|
||||
if relocation.base_rva in r:
|
||||
r[relocation.base_rva] += 1
|
||||
else:
|
||||
r[relocation.base_rva] = 1
|
||||
|
||||
#print("Base: 0x{:X} RVA: 0x{:X} Offset: {} Type: {}".format(
|
||||
# relocation.base_rva,
|
||||
# relocation.rva,
|
||||
# relocation.offset,
|
||||
# relocation.type,
|
||||
#))
|
||||
|
||||
#sum = 0
|
||||
#for base, count in r.items():
|
||||
# print("0x{:X}: {}".format(base, count))
|
||||
# sum += count
|
||||
#print("Sum: {}".format(sum))
|
||||
|
||||
print("Image Base : 0x{:X}".format(superpe.get_image_base()))
|
||||
print("Current Base: 0x{:X}".format(current_base))
|
||||
diff = current_base - superpe.get_image_base()
|
||||
print("Diff : 0x{:X}".format(diff))
|
||||
|
||||
code_section = superpe.get_code_section()
|
||||
print("Text section start: 0x{:X} size: {}".format(
|
||||
code_section.VirtualAddress,
|
||||
code_section.SizeOfRawData
|
||||
))
|
||||
|
||||
if False:
|
||||
text_start = code_section.VirtualAddress
|
||||
text_end = text_start + 4096 # 10000 # code_section.SizeOfRawData
|
||||
|
||||
# entry point rva: E'1D78
|
||||
# page: E'1000
|
||||
# jumps to: 00000001400E'21B0
|
||||
|
||||
|
||||
# Relocs show
|
||||
interval = 32
|
||||
page_vaddr = text_start
|
||||
relocs = []
|
||||
|
||||
mypage = 0xE2000
|
||||
page_vaddr = mypage
|
||||
text_end = page_vaddr + 0x1000
|
||||
while page_vaddr < text_end:
|
||||
print("Relocations for page: 0x{:X}".format(
|
||||
page_vaddr
|
||||
))
|
||||
|
||||
i = 1
|
||||
while i < 4096:
|
||||
# data is 8 bytes (quad word)
|
||||
data = superpe.pe.get_qword_at_rva(page_vaddr + i)
|
||||
patch_data = data - diff
|
||||
if patch_data > 0:
|
||||
print(" Relocation: 0x{:X} 0x{:X} \tData: 0x{:X} \tPatched: 0x{:X}".format(
|
||||
i+page_vaddr,
|
||||
i,
|
||||
data,
|
||||
patch_data
|
||||
))
|
||||
relocs.append(i)
|
||||
|
||||
i += int(4096 / interval)
|
||||
page_vaddr += 4096
|
||||
else:
|
||||
mypage = 0x1000 #0x14B000
|
||||
relocs = [
|
||||
0x8,
|
||||
0x16,
|
||||
#0,
|
||||
]
|
||||
|
||||
if False:
|
||||
superpe.addImageBaseRelocations(mypage, relocs)
|
||||
superpe.write_pe_to_file("tmp/myproc.exe")
|
||||
#superpe.overwriteImageBaseRelocations(mypage, relocs)
|
||||
else:
|
||||
#superpe.overwriteImageBaseRelocations(mypage, relocs)
|
||||
relocs = []
|
||||
entries_count = 0x8C
|
||||
step = int(4096/entries_count)
|
||||
|
||||
page_vaddr = mypage
|
||||
text_end = page_vaddr + 0x1000
|
||||
while page_vaddr < text_end:
|
||||
print("Relocations for page: 0x{:X}".format(
|
||||
page_vaddr
|
||||
))
|
||||
|
||||
i = 16
|
||||
while i < 4096:
|
||||
# data is 8 bytes (quad word)
|
||||
data = superpe.pe.get_qword_at_rva(page_vaddr + i)
|
||||
patch_data = data - diff
|
||||
if patch_data > 0:
|
||||
print(" Relocation: 0x{:X} 0x{:X} \tData: 0x{:X} \tPatched: 0x{:X}".format(
|
||||
i+page_vaddr,
|
||||
i,
|
||||
data,
|
||||
patch_data
|
||||
))
|
||||
relocs.append(i)
|
||||
superpe.pe.set_qword_at_rva(page_vaddr+i, patch_data)
|
||||
else:
|
||||
print(" SKIP Relocation: 0x{:X} 0x{:X} \tData: 0x{:X} \tPatched: 0x{:X}".format(
|
||||
i+page_vaddr,
|
||||
i,
|
||||
data,
|
||||
patch_data
|
||||
))
|
||||
i += step
|
||||
|
||||
if len(relocs) >= entries_count:
|
||||
break
|
||||
page_vaddr += 4096
|
||||
|
||||
print("Added relocs: 0x{:X}".format(len(relocs)))
|
||||
|
||||
relocsSize = superpe.pe.OPTIONAL_HEADER.DATA_DIRECTORY[
|
||||
SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].Size
|
||||
relocsIndex = superpe.getSectionIndexByDataDir(
|
||||
SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC)
|
||||
addr = superpe.pe.OPTIONAL_HEADER.DATA_DIRECTORY[
|
||||
SuperPe.IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress
|
||||
|
||||
print("-> Relocs size: 0x{:X} Index: {} Addr: 0x{:X} = 0x{:X}".format(
|
||||
relocsSize, relocsIndex, addr, superpe.pe.get_offset_from_rva(addr)
|
||||
))
|
||||
superpe.pe.set_dword_at_rva(addr, mypage)
|
||||
|
||||
addr_entries = addr + 8
|
||||
i = 0
|
||||
for reloc in relocs:
|
||||
#reloc_offset = (reloc - pageRva)
|
||||
reloc_offset = reloc
|
||||
reloc_type = SuperPe.IMAGE_REL_BASED_DIR64 << 12
|
||||
relocWord = (reloc_type | reloc_offset)
|
||||
|
||||
#if reloc == 0:
|
||||
# reloc_type = 0
|
||||
# relocWord = 0
|
||||
# reloc_offset = 0
|
||||
logger.info(f'\tReloc{i} for addr 0x{reloc:X}: 0x{relocWord:X} - 0x{reloc_offset:X}')
|
||||
superpe.pe.set_word_at_rva(addr_entries + i * 2, relocWord)
|
||||
#self.pe.set_qword_at_rva(relocDirRva + relocsSize + 8 + i * 2, reloc)
|
||||
i += 1
|
||||
|
||||
#superpe.pe.set_qword_at_rva(addr, 0x0011223344556677)
|
||||
#superpe.pe.set_qword_at_rva(0x11D00, 0x0011223344556677)
|
||||
#superpe.pe.set_dword_at_offset(0x11B600, 0x00112233)
|
||||
#superpe.pe.set_qword_at_rva(0x1000, 0x0011223344556677) # works!
|
||||
|
||||
if False:
|
||||
# print
|
||||
relocation: PeRelocEntry
|
||||
n = 0
|
||||
for base_reloc in superpe.pe.DIRECTORY_ENTRY_BASERELOC:
|
||||
for entry in base_reloc.entries:
|
||||
if n > 5:
|
||||
break
|
||||
|
||||
print("Base: 0x{:X} RVA: 0x{:X}".format(
|
||||
entry.base_rva,
|
||||
entry.rva,
|
||||
))
|
||||
|
||||
n += 1
|
||||
|
||||
superpe.mywrite("tmp/myproc.exe")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
print("./relokator <filename> <base>")
|
||||
exit(1)
|
||||
|
||||
filename = sys.argv[1]
|
||||
current_base = int(sys.argv[2], 16)
|
||||
main(filename, current_base)
|
||||
|
||||
Reference in New Issue
Block a user