Improved Windows support
This commit is contained in:
parent
e9a0494aa7
commit
6b48ee0a48
10
examples/winapi/winapi.q
Normal file
10
examples/winapi/winapi.q
Normal file
@ -0,0 +1,10 @@
|
||||
import mem
|
||||
|
||||
main() {
|
||||
text := mem.alloc(4)
|
||||
text[0] = 'H'
|
||||
text[1] = 'i'
|
||||
text[2] = '!'
|
||||
user32.MessageBoxA(0, text, text, 0x00240040)
|
||||
mem.free(text, 4)
|
||||
}
|
5
lib/mem/alloc_windows.q
Normal file
5
lib/mem/alloc_windows.q
Normal file
@ -0,0 +1,5 @@
|
||||
import sys
|
||||
|
||||
alloc(length Int) -> Pointer {
|
||||
return sys.mmap(0, length, 0x0004, 0x3000)
|
||||
}
|
@ -8,6 +8,10 @@ mmap(address Int, length Int, protection Int, flags Int) -> Pointer {
|
||||
return kernel32.VirtualAlloc(address, length, flags, protection)
|
||||
}
|
||||
|
||||
munmap(address Pointer, length Int) -> Int {
|
||||
return kernel32.VirtualFree(address, length, 0x4000)
|
||||
}
|
||||
|
||||
exit(code Int) {
|
||||
kernel32.ExitProcess(code)
|
||||
}
|
6
src/arch/x64/AlignStack.go
Normal file
6
src/arch/x64/AlignStack.go
Normal file
@ -0,0 +1,6 @@
|
||||
package x64
|
||||
|
||||
// AlignStack aligns RSP on a 16-byte boundary.
|
||||
func AlignStack(code []byte) []byte {
|
||||
return append(code, 0x48, 0x83, 0xE4, 0xF0)
|
||||
}
|
@ -126,11 +126,13 @@ func (a Assembler) Finalize(dlls dll.List) ([]byte, []byte) {
|
||||
|
||||
case DLLCALL:
|
||||
size := 4
|
||||
|
||||
// TODO: R15 could be in use.
|
||||
code = x64.MoveRegisterRegister(code, x64.R15, x64.RSP)
|
||||
code = x64.AlignStack(code)
|
||||
code = x64.SubRegisterNumber(code, x64.RSP, 32)
|
||||
code = x64.CallAtAddress(code, 0x00_00_00_00)
|
||||
position := len(code) - size
|
||||
code = x64.AddRegisterNumber(code, x64.RSP, 32)
|
||||
code = x64.MoveRegisterRegister(code, x64.RSP, x64.R15)
|
||||
|
||||
label := x.Data.(*Label)
|
||||
pointer := &Pointer{
|
||||
|
@ -50,7 +50,6 @@ func (r *Result) finalize() ([]byte, []byte, dll.List) {
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0)
|
||||
final.Syscall()
|
||||
case "windows":
|
||||
final.RegisterNumber(asm.SUB, x64.RSP, 8)
|
||||
final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 0)
|
||||
final.DLLCall("kernel32.ExitProcess")
|
||||
}
|
||||
@ -83,9 +82,8 @@ func (r *Result) finalize() ([]byte, []byte, dll.List) {
|
||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1)
|
||||
final.Syscall()
|
||||
case "windows":
|
||||
final.RegisterNumber(asm.SUB, x64.RSP, 8)
|
||||
final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 1)
|
||||
final.Label(asm.DLLCALL, "kernel32.ExitProcess")
|
||||
final.DLLCall("kernel32.ExitProcess")
|
||||
}
|
||||
|
||||
code, data := final.Finalize(dlls)
|
||||
|
@ -5,7 +5,7 @@ type List []DLL
|
||||
|
||||
// Append adds a function for the given DLL if it doesn't exist yet.
|
||||
func (list List) Append(dllName string, funcName string) List {
|
||||
for _, dll := range list {
|
||||
for i, dll := range list {
|
||||
if dll.Name != dllName {
|
||||
continue
|
||||
}
|
||||
@ -16,13 +16,24 @@ func (list List) Append(dllName string, funcName string) List {
|
||||
}
|
||||
}
|
||||
|
||||
dll.Functions = append(dll.Functions, funcName)
|
||||
list[i].Functions = append(list[i].Functions, funcName)
|
||||
return list
|
||||
}
|
||||
|
||||
return append(list, DLL{Name: dllName, Functions: []string{funcName}})
|
||||
}
|
||||
|
||||
// Contains returns true if the library exists.
|
||||
func (list List) Contains(dllName string) bool {
|
||||
for _, dll := range list {
|
||||
if dll.Name == dllName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Index returns the position of the given function name.
|
||||
func (list List) Index(dllName string, funcName string) int {
|
||||
index := 0
|
||||
|
@ -31,6 +31,12 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) {
|
||||
dataStart, dataPadding := exe.Align(codeStart+len(code), config.Align)
|
||||
importsStart, importsPadding := exe.Align(dataStart+len(data), config.Align)
|
||||
|
||||
subSystem := IMAGE_SUBSYSTEM_WINDOWS_CUI
|
||||
|
||||
if dlls.Contains("user32") {
|
||||
subSystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
|
||||
}
|
||||
|
||||
imports := make([]uint64, 0)
|
||||
dllData := make([]byte, 0)
|
||||
dllImports := []DLLImport{}
|
||||
@ -125,7 +131,7 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) {
|
||||
SizeOfImage: uint32(imageSize),
|
||||
SizeOfHeaders: config.CodeOffset, // section bodies begin here
|
||||
CheckSum: 0,
|
||||
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI,
|
||||
Subsystem: uint16(subSystem),
|
||||
DllCharacteristics: IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA | IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE, // IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
||||
SizeOfStackReserve: 0x100000,
|
||||
SizeOfStackCommit: 0x1000,
|
||||
|
Loading…
Reference in New Issue
Block a user