Implemented loading of multiple DLLs
This commit is contained in:
parent
c3699ac6ac
commit
771b993dd8
@ -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
6
src/exe/pe/DLL.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package pe
|
||||||
|
|
||||||
|
type DLL struct {
|
||||||
|
Name string
|
||||||
|
Functions []string
|
||||||
|
}
|
@ -17,80 +17,57 @@ 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{}
|
||||||
data = append(data, 0x00)
|
dllNamePos := len(data)
|
||||||
|
data = append(data, dll.Name...)
|
||||||
for _, f := range dlls[0].Functions {
|
|
||||||
pos := len(data)
|
|
||||||
data = append(data, 0x00, 0x00)
|
|
||||||
data = append(data, f...)
|
|
||||||
data = append(data, 0x00)
|
data = append(data, 0x00)
|
||||||
|
|
||||||
if len(data)&1 != 0 {
|
for _, f := range dll.Functions {
|
||||||
data = append(data, 0x00) // align the next entry on an even boundary
|
pos := len(data)
|
||||||
|
data = append(data, 0x00, 0x00)
|
||||||
|
data = append(data, f...)
|
||||||
|
data = append(data, 0x00)
|
||||||
|
|
||||||
|
if len(data)&1 != 0 {
|
||||||
|
data = append(data, 0x00) // align the next entry on an even boundary
|
||||||
|
}
|
||||||
|
|
||||||
|
dllAddresses = append(dllAddresses, uint64(dataStart+pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
dllAddresses = append(dllAddresses, uint64(dataStart+pos))
|
dllAddresses = append(dllAddresses, 0)
|
||||||
|
|
||||||
|
// Add the address table to the data section
|
||||||
|
functionAddressesStart := dataStart + len(data)
|
||||||
|
data, _ = binary.Append(data, binary.LittleEndian, &dllAddresses)
|
||||||
|
|
||||||
|
dllImports = append(dllImports, DLLImport{
|
||||||
|
RvaFunctionNameList: uint32(functionAddressesStart),
|
||||||
|
TimeDateStamp: 0,
|
||||||
|
ForwarderChain: 0,
|
||||||
|
RvaModuleName: uint32(dataStart + dllNamePos),
|
||||||
|
RvaFunctionAddressList: uint32(functionAddressesStart),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
dllAddresses = append(dllAddresses, 0)
|
|
||||||
|
|
||||||
// Add the address table to the data section
|
|
||||||
functionAddressesStart := dataStart + len(data)
|
|
||||||
functionAddressesSize := 8 * len(dllAddresses)
|
|
||||||
data, err := binary.Append(data, binary.LittleEndian, &dllAddresses)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dllImports = append(dllImports, DLLImport{
|
|
||||||
RvaFunctionNameList: uint32(functionAddressesStart),
|
|
||||||
TimeDateStamp: 0,
|
|
||||||
ForwarderChain: 0,
|
|
||||||
RvaModuleName: uint32(dataStart + dllName),
|
|
||||||
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},
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user