Implemented loading of multiple DLLs

This commit is contained in:
Eduard Urbach 2024-08-17 15:34:42 +02:00
parent c3699ac6ac
commit 771b993dd8
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
4 changed files with 57 additions and 57 deletions

View File

@ -154,7 +154,24 @@ func write(writer io.Writer, code []byte, data []byte) error {
case "mac": case "mac":
macho.Write(buffer, code, data) macho.Write(buffer, code, data)
case "windows": case "windows":
pe.Write(buffer, code, data) dlls := []pe.DLL{
{
Name: "kernel32.dll",
Functions: []string{
"ExitProcess",
"GetStdHandle",
"WriteFile",
},
},
{
Name: "user32.dll",
Functions: []string{
"MessageBoxA",
},
},
}
pe.Write(buffer, code, data, dlls)
default: default:
return fmt.Errorf("unsupported platform '%s'", config.TargetOS) return fmt.Errorf("unsupported platform '%s'", config.TargetOS)
} }

6
src/exe/pe/DLL.go Normal file
View File

@ -0,0 +1,6 @@
package pe
type DLL struct {
Name string
Functions []string
}

View File

@ -17,37 +17,22 @@ type EXE struct {
Sections []SectionHeader Sections []SectionHeader
} }
type DLL struct {
Name string
Functions []string
}
// Write writes the EXE file to the given writer. // Write writes the EXE file to the given writer.
func Write(writer io.Writer, code []byte, data []byte) { func Write(writer io.Writer, code []byte, data []byte, dlls []DLL) {
NumSections := 2 NumSections := 2
HeaderEnd := DOSHeaderSize + NTHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections HeaderEnd := DOSHeaderSize + NTHeaderSize + OptionalHeader64Size + SectionHeaderSize*NumSections
codeStart, codePadding := exe.Align(HeaderEnd, config.Align) codeStart, codePadding := exe.Align(HeaderEnd, config.Align)
dataStart, dataPadding := exe.Align(codeStart+len(code), config.Align) dataStart, dataPadding := exe.Align(codeStart+len(code), config.Align)
dlls := []DLL{
{
Name: "kernel32.dll",
Functions: []string{
"ExitProcess",
"GetStdHandle",
"WriteFile",
},
},
}
dllAddresses := []uint64{}
dllImports := []DLLImport{} dllImports := []DLLImport{}
dllName := len(data) for _, dll := range dlls {
data = append(data, dlls[0].Name...) dllAddresses := []uint64{}
dllNamePos := len(data)
data = append(data, dll.Name...)
data = append(data, 0x00) data = append(data, 0x00)
for _, f := range dlls[0].Functions { for _, f := range dll.Functions {
pos := len(data) pos := len(data)
data = append(data, 0x00, 0x00) data = append(data, 0x00, 0x00)
data = append(data, f...) data = append(data, f...)
@ -64,33 +49,25 @@ func Write(writer io.Writer, code []byte, data []byte) {
// Add the address table to the data section // Add the address table to the data section
functionAddressesStart := dataStart + len(data) functionAddressesStart := dataStart + len(data)
functionAddressesSize := 8 * len(dllAddresses) data, _ = binary.Append(data, binary.LittleEndian, &dllAddresses)
data, err := binary.Append(data, binary.LittleEndian, &dllAddresses)
if err != nil {
panic(err)
}
dllImports = append(dllImports, DLLImport{ dllImports = append(dllImports, DLLImport{
RvaFunctionNameList: uint32(functionAddressesStart), RvaFunctionNameList: uint32(functionAddressesStart),
TimeDateStamp: 0, TimeDateStamp: 0,
ForwarderChain: 0, ForwarderChain: 0,
RvaModuleName: uint32(dataStart + dllName), RvaModuleName: uint32(dataStart + dllNamePos),
RvaFunctionAddressList: uint32(functionAddressesStart), RvaFunctionAddressList: uint32(functionAddressesStart),
}) })
}
dllImports = append(dllImports, DLLImport{}) // a zeroed structure marks the end of the list dllImports = append(dllImports, DLLImport{}) // a zeroed structure marks the end of the list
// Add imports to the data section // Add imports to the data section
importsStart := dataStart + len(data) importsStart := dataStart + len(data)
importsSize := DLLImportSize * len(dllImports) importsSize := DLLImportSize * len(dllImports)
data, err = binary.Append(data, binary.LittleEndian, &dllImports) data, _ = binary.Append(data, binary.LittleEndian, &dllImports)
if err != nil { imageSize := dataStart + len(data)
panic(err)
}
imageSize := functionAddressesStart + functionAddressesSize
imageSize, _ = exe.Align(imageSize, config.Align) imageSize, _ = exe.Align(imageSize, config.Align)
pe := &EXE{ pe := &EXE{
@ -151,7 +128,7 @@ func Write(writer io.Writer, code []byte, data []byte) {
{VirtualAddress: 0, Size: 0}, {VirtualAddress: 0, Size: 0},
{VirtualAddress: 0, Size: 0}, {VirtualAddress: 0, Size: 0},
{VirtualAddress: 0, Size: 0}, {VirtualAddress: 0, Size: 0},
{VirtualAddress: uint32(functionAddressesStart), Size: uint32(functionAddressesSize)}, // RVA of the import address table {VirtualAddress: 0, Size: 0},
{VirtualAddress: 0, Size: 0}, {VirtualAddress: 0, Size: 0},
{VirtualAddress: 0, Size: 0}, {VirtualAddress: 0, Size: 0},
{VirtualAddress: 0, Size: 0}, {VirtualAddress: 0, Size: 0},

View File

@ -8,5 +8,5 @@ import (
) )
func TestWrite(t *testing.T) { func TestWrite(t *testing.T) {
pe.Write(io.Discard, nil, nil) pe.Write(io.Discard, nil, nil, nil)
} }