From 5a9dc5e791ddca0c0ae3f7fe1074d7ecad6ffaef Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Sun, 1 Jul 2018 20:17:46 +0200 Subject: [PATCH] [SDK] Add gen_baseaddress.py This tool was already used to calculate the last baseaddress update. It is based on baseaddress.sh that has been floating around. CORE-11382 --- sdk/cmake/baseaddress.cmake | 5 +- sdk/cmake/baseaddress_dwarf.cmake | 5 +- sdk/cmake/baseaddress_msvc.cmake | 5 +- sdk/tools/gen_baseaddress.py | 278 ++++++++++++++++++++++++++++++ 4 files changed, 287 insertions(+), 6 deletions(-) create mode 100644 sdk/tools/gen_baseaddress.py diff --git a/sdk/cmake/baseaddress.cmake b/sdk/cmake/baseaddress.cmake index 5ba0611cbd4..dae966b723e 100644 --- a/sdk/cmake/baseaddress.cmake +++ b/sdk/cmake/baseaddress.cmake @@ -1,3 +1,4 @@ +# Generated by sdk/tools/gen_baseaddress.py set(baseaddress_ntdll 0x7c920000) # should be above 0x7c920000 set(baseaddress_kernel32 0x7c6b0000) set(baseaddress_msvcrt 0x7c5f0000) @@ -62,7 +63,7 @@ set(baseaddress_sfc_os 0x79bf0000) set(baseaddress_snmpapi 0x79bc0000) set(baseaddress_spoolss 0x79b80000) set(baseaddress_usp10 0x79b00000) -# Extra found dlls +# Extra dlls set(baseaddress_acgenral 0x79ad0000) set(baseaddress_aclayers 0x79aa0000) set(baseaddress_acledit 0x79a70000) @@ -342,7 +343,7 @@ set(baseaddress_xinput1_3 0x73680000) set(baseaddress_xinput9_1_0 0x73650000) set(baseaddress_xmllite 0x73610000) set(baseaddress_zipfldr 0x73570000) -# Extra found files +# Extra files set(baseaddress_access 0x734f0000) set(baseaddress_appwiz 0x73470000) set(baseaddress_cmicpl 0x73430000) diff --git a/sdk/cmake/baseaddress_dwarf.cmake b/sdk/cmake/baseaddress_dwarf.cmake index 5b66282d4f7..98d98b2eee2 100644 --- a/sdk/cmake/baseaddress_dwarf.cmake +++ b/sdk/cmake/baseaddress_dwarf.cmake @@ -1,3 +1,4 @@ +# Generated by sdk/tools/gen_baseaddress.py set(baseaddress_ntdll 0x7c920000) # should be above 0x7c920000 set(baseaddress_kernel32 0x7c650000) set(baseaddress_msvcrt 0x7c530000) @@ -62,7 +63,7 @@ set(baseaddress_sfc_os 0x79060000) set(baseaddress_snmpapi 0x79020000) set(baseaddress_spoolss 0x78fd0000) set(baseaddress_usp10 0x78f30000) -# Extra found dlls +# Extra dlls set(baseaddress_acgenral 0x78f00000) set(baseaddress_aclayers 0x78ec0000) set(baseaddress_acledit 0x78e90000) @@ -342,7 +343,7 @@ set(baseaddress_xinput1_3 0x71520000) set(baseaddress_xinput9_1_0 0x714f0000) set(baseaddress_xmllite 0x71490000) set(baseaddress_zipfldr 0x713a0000) -# Extra found files +# Extra files set(baseaddress_access 0x71310000) set(baseaddress_appwiz 0x71290000) set(baseaddress_cmicpl 0x71250000) diff --git a/sdk/cmake/baseaddress_msvc.cmake b/sdk/cmake/baseaddress_msvc.cmake index b4aa6468c19..fc9d2cd7a18 100644 --- a/sdk/cmake/baseaddress_msvc.cmake +++ b/sdk/cmake/baseaddress_msvc.cmake @@ -1,3 +1,4 @@ +# Generated by sdk/tools/gen_baseaddress.py set(baseaddress_ntdll 0x7c920000) # should be above 0x7c920000 set(baseaddress_kernel32 0x7c700000) set(baseaddress_msvcrt 0x7c680000) @@ -62,7 +63,7 @@ set(baseaddress_sfc_os 0x7a640000) set(baseaddress_snmpapi 0x7a620000) set(baseaddress_spoolss 0x7a5f0000) set(baseaddress_usp10 0x7a590000) -# Extra found dlls +# Extra dlls set(baseaddress_acgenral 0x7a570000) set(baseaddress_aclayers 0x7a550000) set(baseaddress_acledit 0x7a530000) @@ -342,7 +343,7 @@ set(baseaddress_xinput1_3 0x75b20000) set(baseaddress_xinput9_1_0 0x75b00000) set(baseaddress_xmllite 0x75ad0000) set(baseaddress_zipfldr 0x75a80000) -# Extra found files +# Extra files set(baseaddress_access 0x75a00000) set(baseaddress_appwiz 0x75990000) set(baseaddress_cmicpl 0x75960000) diff --git a/sdk/tools/gen_baseaddress.py b/sdk/tools/gen_baseaddress.py new file mode 100644 index 00000000000..204cfe23f2b --- /dev/null +++ b/sdk/tools/gen_baseaddress.py @@ -0,0 +1,278 @@ +''' +PROJECT: ReactOS baseaddress updater +LICENSE: MIT (https://spdx.org/licenses/MIT) +PURPOSE: Update baseaddresses of all modules +COPYRIGHT: Copyright 2017,2018 Mark Jansen (mark.jansen@reactos.org) +''' + +# FIXME: user32 always at 0x77a20000 + +import os +import struct +import sys +try: + import pefile +except ImportError: + print '# Please install pefile from pip or https://github.com/erocarrera/pefile' + print '# Using fallback' + print + +DLL_EXTENSIONS = ( + '.dll' +) + +OTHER_EXTENSIONS = ( + '.acm', '.ax', '.cpl', '.drv', '.ocx' +) + +PRIORITIES = ( + 'ntdll.dll', + 'kernel32.dll', + 'msvcrt.dll', + 'advapi32.dll', + 'gdi32.dll', + 'user32.dll', + 'dhcpcsvc.dll', + 'dnsapi.dll', + 'icmp.dll', + 'iphlpapi.dll', + 'ws2_32.dll', + 'ws2help.dll', + 'shlwapi.dll', + 'rpcrt4.dll', + 'comctl32.dll', + 'ole32.dll', + 'winspool.drv', + 'winmm.dll', + 'comdlg32.dll', + 'shell32.dll', + 'lz32.dll', + 'version.dll', + 'oleaut32.dll', + 'setupapi.dll', + 'mpr.dll', + 'crypt32.dll', + 'wininet.dll', + 'urlmon.dll', + 'psapi.dll', + 'imm32.dll', + 'msvfw32.dll', + 'dbghelp.dll', + 'devmgr.dll', + 'msacm32.dll', + 'netapi32.dll', + 'powrprof.dll', + 'secur32.dll', + 'wintrust.dll', + 'avicap32.dll', + 'cabinet.dll', + 'dsound.dll', + 'glu32.dll', + 'opengl32.dll', + 'riched20.dll', + 'smdll.dll', + 'userenv.dll', + 'uxtheme.dll', + 'cryptui.dll', + 'csrsrv.dll', + 'basesrv.dll', + 'winsrv.dll', + 'dplayx.dll', + 'gdiplus.dll', + 'msimg32.dll', + 'mswsock.dll', + 'oledlg.dll', + 'rasapi32.dll', + 'rsaenh.dll', + 'samlib.dll', + 'sensapi.dll', + 'sfc_os.dll', + 'snmpapi.dll', + 'spoolss.dll', + 'usp10.dll', +) + +EXCLUDE = ( + 'bmfd.dll', + 'bootvid.dll', + 'freeldr_pe.dll', + 'ftfd.dll', + 'fusion.dll', + 'hal.dll', + 'halaacpi.dll', + 'halacpi.dll', + 'halapic.dll', + 'kbda1.dll', + 'kbda2.dll', + 'kbda3.dll', + 'kbdal.dll', + 'kbdarme.dll', + 'kbdarmw.dll', + 'kbdaze.dll', + 'kbdazel.dll', + 'kbdbe.dll', + 'kbdbga.dll', + 'kbdbgm.dll', + 'kbdbgt.dll', + 'kbdblr.dll', + 'kbdbr.dll', + 'kbdbur.dll', + 'kbdcan.dll', + 'kbdcr.dll', + 'kbdcz.dll', + 'kbdcz1.dll', + 'kbdda.dll', + 'kbddv.dll', + 'kbdes.dll', + 'kbdest.dll', + 'kbdfc.dll', + 'kbdfi.dll', + 'kbdfr.dll', + 'kbdgeo.dll', + 'kbdgerg.dll', + 'kbdgneo.dll', + 'kbdgr.dll', + 'kbdgrist.dll', + 'kbdhe.dll', + 'kbdheb.dll', + 'kbdhu.dll', + 'kbdic.dll', + 'kbdinasa.dll', + 'kbdinben.dll', + 'kbdindev.dll', + 'kbdinguj.dll', + 'kbdinmal.dll', + 'kbdir.dll', + 'kbdit.dll', + 'kbdja.dll', + 'kbdkaz.dll', + 'kbdko.dll', + 'kbdla.dll', + 'kbdlt1.dll', + 'kbdlv.dll', + 'kbdmac.dll', + 'kbdne.dll', + 'kbdno.dll', + 'kbdpl.dll', + 'kbdpl1.dll', + 'kbdpo.dll', + 'kbdro.dll', + 'kbdru.dll', + 'kbdru1.dll', + 'kbdsg.dll', + 'kbdsk.dll', + 'kbdsk1.dll', + 'kbdsw.dll', + 'kbdtat.dll', + 'kbdth0.dll', + 'kbdth1.dll', + 'kbdth2.dll', + 'kbdth3.dll', + 'kbdtuf.dll', + 'kbdtuq.dll', + 'kbduk.dll', + 'kbdur.dll', + 'kbdurs.dll', + 'kbdus.dll', + 'kbdusa.dll', + 'kbdusl.dll', + 'kbdusr.dll', + 'kbdusx.dll', + 'kbduzb.dll', + 'kbdvntc.dll', + 'kbdycc.dll', + 'kbdycl.dll', + 'kdcom.dll', + 'kdvbox.dll', + 'setupldr_pe.dll', + 'vgaddi.dll', + 'dllexport_test_dll1.dll', + 'dllexport_test_dll2.dll', + 'dllimport_test.dll', + 'MyEventProvider.dll', + 'w32kdll_2k3sp2.dll', + 'w32kdll_ros.dll', + 'w32kdll_xpsp2.dll', +) + + +def size_of_image_fallback(filename): + with open(filename, 'rb') as fin: + if fin.read(2) != 'MZ': + print filename, 'No dos header found!' + return 0 + fin.seek(0x3C) + e_lfanew = struct.unpack('i', fin.read(4))[0] + fin.seek(e_lfanew) + if fin.read(4) != 'PE\0\0': + print filename, 'No PE header found!' + return 0 + fin.seek(e_lfanew + 0x18) + pe_magic = struct.unpack('h', fin.read(2))[0] + if pe_magic != 0x10b: + print filename, 'is not a 32 bit exe!' + return 0 + fin.seek(e_lfanew + 0x50) + pe_size_of_image = struct.unpack('i', fin.read(4))[0] + return pe_size_of_image + +def size_of_image(filename): + if 'pefile' in globals(): + return pefile.PE(filename, fast_load=True).OPTIONAL_HEADER.SizeOfImage + return size_of_image_fallback(filename) + +def onefile(current_address, filename, size): + name, ext = os.path.splitext(filename) + postfix = '' + if ext in('.acm', '.drv') and filename != 'winspool.drv': + name = filename + if current_address == 0: + current_address = 0x7c920000 + postfix = ' # should be above 0x%08x' % current_address + else: + current_address = (current_address - size - 0x2000 - 0xffff) & 0xffff0000 + print 'set(baseaddress_%-30s 0x%08x)%s' % (name, current_address, postfix) + return current_address + +def run_dir(target): + print '# Generated from', target + print '# Generated by sdk/tools/gen_baseaddress.py' + found_dlls = {} + found_files = {} + for root, _, files in os.walk(target): + for dll in [filename for filename in files if filename.endswith(DLL_EXTENSIONS)]: + if not dll in EXCLUDE and not dll.startswith('api-ms-win-'): + found_dlls[dll] = size_of_image(os.path.join(root, dll)) + extrafiles = [filename for filename in files if filename.endswith(OTHER_EXTENSIONS)] + for extrafile in extrafiles: + if not extrafile in EXCLUDE: + found_files[extrafile] = size_of_image(os.path.join(root, extrafile)) + + current_address = 0 + for curr in PRIORITIES: + if curr in found_dlls: + current_address = onefile(current_address, curr, found_dlls[curr]) + del found_dlls[curr] + elif curr in found_files: + current_address = onefile(current_address, curr, found_files[curr]) + del found_files[curr] + else: + print '# Did not find', curr, '!' + + print '# Extra dlls' + for curr in sorted(found_dlls): + current_address = onefile(current_address, curr, found_dlls[curr]) + print '# Extra files' + for curr in sorted(found_files): + current_address = onefile(current_address, curr, found_files[curr]) + +def main(dirs): + if len(dirs) < 1: + trydir = os.getcwd() + print '# No path specified, trying', trydir + dirs = [trydir] + for onedir in dirs: + run_dir(onedir) + +if __name__ == '__main__': + main(sys.argv[1:])