remove failed experiment

This commit is contained in:
Dobin Rutishauser
2024-06-16 07:04:53 +02:00
parent 6010dbb4c0
commit 46447af57b
-299
View File
@@ -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)