mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-18 11:33:59 +00:00
UEFI Target groundwork: runtime: extract Windows PE globals scan helper (#5361)
* runtime: extract Windows PE globals scan helper * Update src/runtime/os_windows_pe.go * run goimports
This commit is contained in:
@@ -7,44 +7,6 @@ const GOOS = "windows"
|
|||||||
//export GetModuleHandleExA
|
//export GetModuleHandleExA
|
||||||
func _GetModuleHandleExA(dwFlags uint32, lpModuleName unsafe.Pointer, phModule **exeHeader) bool
|
func _GetModuleHandleExA(dwFlags uint32, lpModuleName unsafe.Pointer, phModule **exeHeader) bool
|
||||||
|
|
||||||
// MS-DOS stub with PE header offset:
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
|
|
||||||
type exeHeader struct {
|
|
||||||
signature uint16
|
|
||||||
_ [58]byte // skip DOS header
|
|
||||||
peHeader uint32 // at offset 0x3C
|
|
||||||
}
|
|
||||||
|
|
||||||
// COFF file header:
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers
|
|
||||||
type peHeader struct {
|
|
||||||
magic uint32
|
|
||||||
machine uint16
|
|
||||||
numberOfSections uint16
|
|
||||||
timeDateStamp uint32
|
|
||||||
pointerToSymbolTable uint32
|
|
||||||
numberOfSymbols uint32
|
|
||||||
sizeOfOptionalHeader uint16
|
|
||||||
characteristics uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// COFF section header:
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
|
|
||||||
type peSection struct {
|
|
||||||
name [8]byte
|
|
||||||
virtualSize uint32
|
|
||||||
virtualAddress uint32
|
|
||||||
sizeOfRawData uint32
|
|
||||||
pointerToRawData uint32
|
|
||||||
pointerToRelocations uint32
|
|
||||||
pointerToLinenumbers uint32
|
|
||||||
numberOfRelocations uint16
|
|
||||||
numberOfLinenumbers uint16
|
|
||||||
characteristics uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
var module *exeHeader
|
|
||||||
|
|
||||||
// Mark global variables.
|
// Mark global variables.
|
||||||
// Unfortunately, the linker doesn't provide symbols for the start and end of
|
// Unfortunately, the linker doesn't provide symbols for the start and end of
|
||||||
// the data/bss sections. Therefore these addresses need to be determined at
|
// the data/bss sections. Therefore these addresses need to be determined at
|
||||||
@@ -57,9 +19,6 @@ func findGlobals(found func(start, end uintptr)) {
|
|||||||
const (
|
const (
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexa
|
// https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexa
|
||||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 0x00000002
|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 0x00000002
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
|
|
||||||
IMAGE_SCN_MEM_WRITE = 0x80000000
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if module == nil {
|
if module == nil {
|
||||||
@@ -72,23 +31,7 @@ func findGlobals(found func(start, end uintptr)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the PE header at offset 0x3C.
|
findGlobalsForPE(found)
|
||||||
pe := (*peHeader)(unsafe.Add(unsafe.Pointer(module), module.peHeader))
|
|
||||||
if gcAsserts && pe.magic != 0x00004550 { // 0x4550 is "PE"
|
|
||||||
runtimePanic("cannot find PE header")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate through sections.
|
|
||||||
section := (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(pe)) + uintptr(pe.sizeOfOptionalHeader) + unsafe.Sizeof(peHeader{})))
|
|
||||||
for i := 0; i < int(pe.numberOfSections); i++ {
|
|
||||||
if section.characteristics&IMAGE_SCN_MEM_WRITE != 0 {
|
|
||||||
// Found a writable section. Scan the entire section for roots.
|
|
||||||
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
|
|
||||||
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
|
|
||||||
found(start, end)
|
|
||||||
}
|
|
||||||
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type systeminfo struct {
|
type systeminfo struct {
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// MS-DOS stub with PE header offset:
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
|
||||||
|
type exeHeader struct {
|
||||||
|
signature uint16
|
||||||
|
_ [58]byte // skip DOS header
|
||||||
|
peHeader uint32 // at offset 0x3C
|
||||||
|
}
|
||||||
|
|
||||||
|
// COFF file header:
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers
|
||||||
|
type peHeader struct {
|
||||||
|
magic uint32
|
||||||
|
machine uint16
|
||||||
|
numberOfSections uint16
|
||||||
|
timeDateStamp uint32
|
||||||
|
pointerToSymbolTable uint32
|
||||||
|
numberOfSymbols uint32
|
||||||
|
sizeOfOptionalHeader uint16
|
||||||
|
characteristics uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// COFF section header:
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
|
||||||
|
type peSection struct {
|
||||||
|
name [8]byte
|
||||||
|
virtualSize uint32
|
||||||
|
virtualAddress uint32
|
||||||
|
sizeOfRawData uint32
|
||||||
|
pointerToRawData uint32
|
||||||
|
pointerToRelocations uint32
|
||||||
|
pointerToLinenumbers uint32
|
||||||
|
numberOfRelocations uint16
|
||||||
|
numberOfLinenumbers uint16
|
||||||
|
characteristics uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
var module *exeHeader
|
||||||
|
|
||||||
|
func findGlobalsForPE(found func(start, end uintptr)) {
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
|
||||||
|
const imageSCNMemWrite = 0x80000000
|
||||||
|
|
||||||
|
pe := (*peHeader)(unsafe.Add(unsafe.Pointer(module), module.peHeader))
|
||||||
|
if gcAsserts && pe.magic != 0x00004550 { // 0x4550 is "PE"
|
||||||
|
runtimePanic("cannot find PE header")
|
||||||
|
}
|
||||||
|
|
||||||
|
section := (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(pe)) + uintptr(pe.sizeOfOptionalHeader) + unsafe.Sizeof(peHeader{})))
|
||||||
|
for i := 0; i < int(pe.numberOfSections); i++ {
|
||||||
|
if section.characteristics&imageSCNMemWrite != 0 {
|
||||||
|
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
|
||||||
|
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
|
||||||
|
found(start, end)
|
||||||
|
}
|
||||||
|
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user