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)
|
return kernel32.VirtualAlloc(address, length, flags, protection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
munmap(address Pointer, length Int) -> Int {
|
||||||
|
return kernel32.VirtualFree(address, length, 0x4000)
|
||||||
|
}
|
||||||
|
|
||||||
exit(code Int) {
|
exit(code Int) {
|
||||||
kernel32.ExitProcess(code)
|
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:
|
case DLLCALL:
|
||||||
size := 4
|
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.SubRegisterNumber(code, x64.RSP, 32)
|
||||||
code = x64.CallAtAddress(code, 0x00_00_00_00)
|
code = x64.CallAtAddress(code, 0x00_00_00_00)
|
||||||
position := len(code) - size
|
position := len(code) - size
|
||||||
code = x64.AddRegisterNumber(code, x64.RSP, 32)
|
code = x64.MoveRegisterRegister(code, x64.RSP, x64.R15)
|
||||||
|
|
||||||
label := x.Data.(*Label)
|
label := x.Data.(*Label)
|
||||||
pointer := &Pointer{
|
pointer := &Pointer{
|
||||||
|
@ -50,7 +50,6 @@ func (r *Result) finalize() ([]byte, []byte, dll.List) {
|
|||||||
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0)
|
final.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 0)
|
||||||
final.Syscall()
|
final.Syscall()
|
||||||
case "windows":
|
case "windows":
|
||||||
final.RegisterNumber(asm.SUB, x64.RSP, 8)
|
|
||||||
final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 0)
|
final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 0)
|
||||||
final.DLLCall("kernel32.ExitProcess")
|
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.RegisterNumber(asm.MOVE, x64.SyscallInputRegisters[1], 1)
|
||||||
final.Syscall()
|
final.Syscall()
|
||||||
case "windows":
|
case "windows":
|
||||||
final.RegisterNumber(asm.SUB, x64.RSP, 8)
|
|
||||||
final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 1)
|
final.RegisterNumber(asm.MOVE, windows.X64InputRegisters[0], 1)
|
||||||
final.Label(asm.DLLCALL, "kernel32.ExitProcess")
|
final.DLLCall("kernel32.ExitProcess")
|
||||||
}
|
}
|
||||||
|
|
||||||
code, data := final.Finalize(dlls)
|
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.
|
// Append adds a function for the given DLL if it doesn't exist yet.
|
||||||
func (list List) Append(dllName string, funcName string) List {
|
func (list List) Append(dllName string, funcName string) List {
|
||||||
for _, dll := range list {
|
for i, dll := range list {
|
||||||
if dll.Name != dllName {
|
if dll.Name != dllName {
|
||||||
continue
|
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 list
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(list, DLL{Name: dllName, Functions: []string{funcName}})
|
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.
|
// Index returns the position of the given function name.
|
||||||
func (list List) Index(dllName string, funcName string) int {
|
func (list List) Index(dllName string, funcName string) int {
|
||||||
index := 0
|
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)
|
dataStart, dataPadding := exe.Align(codeStart+len(code), config.Align)
|
||||||
importsStart, importsPadding := exe.Align(dataStart+len(data), 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)
|
imports := make([]uint64, 0)
|
||||||
dllData := make([]byte, 0)
|
dllData := make([]byte, 0)
|
||||||
dllImports := []DLLImport{}
|
dllImports := []DLLImport{}
|
||||||
@ -125,7 +131,7 @@ func Write(writer io.Writer, code []byte, data []byte, dlls dll.List) {
|
|||||||
SizeOfImage: uint32(imageSize),
|
SizeOfImage: uint32(imageSize),
|
||||||
SizeOfHeaders: config.CodeOffset, // section bodies begin here
|
SizeOfHeaders: config.CodeOffset, // section bodies begin here
|
||||||
CheckSum: 0,
|
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
|
DllCharacteristics: IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA | IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE, // IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
||||||
SizeOfStackReserve: 0x100000,
|
SizeOfStackReserve: 0x100000,
|
||||||
SizeOfStackCommit: 0x1000,
|
SizeOfStackCommit: 0x1000,
|
||||||
|
Loading…
Reference in New Issue
Block a user