Last active
June 11, 2023 08:54
-
-
Save timsonner/1f7ee60b3ebfe010a154c2e397ea0f7d to your computer and use it in GitHub Desktop.
GoLang. Messing with PE injection.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "encoding/binary" | |
| "log" | |
| "os" | |
| "reflect" | |
| "unsafe" | |
| ) | |
| func main() { | |
| // Open the original PE file | |
| originalFile, err := os.Open("original.exe") | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| defer originalFile.Close() | |
| // Get the size of the file | |
| fileInfo, err := originalFile.Stat() | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| fileSize := fileInfo.Size() | |
| // Create a buffer to hold the file contents | |
| buffer := make([]byte, fileSize) | |
| // Read the file into the buffer | |
| _, err = originalFile.Read(buffer) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| // Create a deep copy of the buffer using unsafe | |
| copyBuffer := make([]byte, len(buffer)) | |
| copy(copyBuffer, buffer) | |
| // Convert the byte slices to unsafe pointers | |
| originalPointer := (*reflect.SliceHeader)(unsafe.Pointer(&buffer)).Data | |
| copyPointer := (*reflect.SliceHeader)(unsafe.Pointer(©Buffer)).Data | |
| // Calculate the size of the memory block to copy | |
| copySize := uintptr(len(buffer)) | |
| // Allocate a new memory block for the copied data | |
| copyMemory := unsafe.Pointer(uintptr(copyPointer)) | |
| // Copy the data from the original memory block to the new memory block | |
| unsafe.Copy(copyMemory, unsafe.Pointer(uintptr(originalPointer))) | |
| // Use the deep copied buffer as needed | |
| // Access PE headers | |
| dosHeader := (*IMAGE_DOS_HEADER)(unsafe.Pointer(copyPointer)) | |
| ntHeader := (*IMAGE_NT_HEADERS)(unsafe.Pointer(copyPointer + uintptr(dosHeader.E_lfanew))) | |
| fileHeader := (*IMAGE_FILE_HEADER)(unsafe.Pointer(&ntHeader.FileHeader)) | |
| optionalHeader := (*IMAGE_OPTIONAL_HEADER)(unsafe.Pointer(&ntHeader.OptionalHeader)) | |
| // Access entry point | |
| entryPoint := optionalHeader.AddressOfEntryPoint | |
| // Access PE sections | |
| sectionTable := (*[1 << 16]IMAGE_SECTION_HEADER)(unsafe.Pointer(copyPointer + uintptr(dosHeader.E_lfanew) + unsafe.Sizeof(*ntHeader)))[0:fileHeader.NumberOfSections] | |
| // Access relocation tables | |
| baseRelocation := (*IMAGE_BASE_RELOCATION)(unsafe.Pointer(copyPointer + uintptr(sectionTable[0].PointerToRelocations))) | |
| numEntries := (baseRelocation.SizeOfBlock - uint32(unsafe.Sizeof(*baseRelocation))) / uint32(unsafe.Sizeof(IMAGE_RELOCATION_ENTRY{})) | |
| relocationEntries := (*[1 << 16]IMAGE_RELOCATION_ENTRY)(unsafe.Pointer(uintptr(unsafe.Pointer(baseRelocation)) + unsafe.Sizeof(*baseRelocation)))[0:numEntries] | |
| // Iterate over the relocation entries | |
| for i := 0; i < int(numEntries); i++ { | |
| entry := relocationEntries[i] | |
| // Process each relocation entry as needed | |
| } | |
| // Access import tables | |
| importDescriptor := (*IMAGE_IMPORT_DESCRIPTOR)(unsafe.Pointer(copyPointer + uintptr(sectionTable[0].PointerToImports))) | |
| for importDescriptor.Name != 0 { | |
| importModuleName := (*string)(unsafe.Pointer(copyPointer + uintptr(importDescriptor.Name))) | |
| // Access other import details if needed | |
| importDescriptor++ | |
| } | |
| // Access export table | |
| exportDirectory := (*IMAGE_EXPORT_DIRECTORY)(unsafe.Pointer(copyPointer + uintptr(sectionTable[0].PointerToExports))) | |
| exportNames := (*[1 << 16]uint32)(unsafe.Pointer(copyPointer + uintptr(exportDirectory.AddressOfNames))) | |
| for i := uint32(0); i < exportDirectory.NumberOfNames; i++ { | |
| exportName := (*string)(unsafe.Pointer(copyPointer + uintptr(exportNames[i]))) | |
| // Access other export details if needed | |
| } | |
| // Clean up the deep copied buffer | |
| copyBuffer = nil | |
| } | |
| // Structures representing the PE file format | |
| type IMAGE_DOS_HEADER struct { | |
| E_magic uint16 | |
| E _lfanew int32 | |
| } | |
| type IMAGE_NT_HEADERS struct { | |
| Signature uint32 | |
| FileHeader IMAGE_FILE_HEADER | |
| OptionalHeader IMAGE_OPTIONAL_HEADER | |
| } | |
| type IMAGE_FILE_HEADER struct { | |
| Machine uint16 | |
| NumberOfSections uint16 | |
| TimeDateStamp uint32 | |
| PointerToSymbolTable uint32 | |
| NumberOfSymbols uint32 | |
| SizeOfOptionalHeader uint16 | |
| Characteristics uint16 | |
| } | |
| type IMAGE_OPTIONAL_HEADER struct { | |
| Magic uint16 | |
| MajorLinkerVersion byte | |
| MinorLinkerVersion byte | |
| SizeOfCode uint32 | |
| SizeOfInitializedData uint32 | |
| SizeOfUninitializedData uint32 | |
| AddressOfEntryPoint uint32 | |
| BaseOfCode uint32 | |
| BaseOfData uint32 | |
| ImageBase uint32 | |
| SectionAlignment uint32 | |
| FileAlignment uint32 | |
| MajorOperatingSystemVersion uint16 | |
| MinorOperatingSystemVersion uint16 | |
| MajorImageVersion uint16 | |
| MinorImageVersion uint16 | |
| MajorSubsystemVersion uint16 | |
| MinorSubsystemVersion uint16 | |
| Win32VersionValue uint32 | |
| SizeOfImage uint32 | |
| SizeOfHeaders uint32 | |
| CheckSum uint32 | |
| Subsystem uint16 | |
| DllCharacteristics uint16 | |
| SizeOfStackReserve uint32 | |
| SizeOfStackCommit uint32 | |
| SizeOfHeapReserve uint32 | |
| SizeOfHeapCommit uint32 | |
| LoaderFlags uint32 | |
| NumberOfRvaAndSizes uint32 | |
| DataDirectory [16]IMAGE_DATA_DIRECTORY | |
| } | |
| type IMAGE_DATA_DIRECTORY struct { | |
| VirtualAddress uint32 | |
| Size uint32 | |
| } | |
| type IMAGE_SECTION_HEADER struct { | |
| Name [8]byte | |
| VirtualSize uint32 | |
| VirtualAddress uint32 | |
| SizeOfRawData uint32 | |
| PointerToRawData uint32 | |
| PointerToRelocations uint32 | |
| PointerToLineNumbers uint32 | |
| NumberOfRelocations uint16 | |
| NumberOfLineNumbers uint16 | |
| Characteristics uint32 | |
| } | |
| type IMAGE_BASE_RELOCATION struct { | |
| VirtualAddress uint32 | |
| SizeOfBlock uint32 | |
| // Additional relocation entries follow the struct | |
| } | |
| type IMAGE_RELOCATION_ENTRY struct { | |
| Data uint16 | |
| } | |
| type IMAGE_IMPORT_DESCRIPTOR struct { | |
| OriginalFirstThunk uint32 | |
| TimeDateStamp uint32 | |
| ForwarderChain uint32 | |
| Name uint32 | |
| FirstThunk uint32 | |
| } | |
| type IMAGE_EXPORT_DIRECTORY struct { | |
| Characteristics uint32 | |
| TimeDateStamp uint32 | |
| MajorVersion uint16 | |
| MinorVersion uint16 | |
| Name uint32 | |
| Base uint32 | |
| NumberOfFunctions uint32 | |
| NumberOfNames uint32 | |
| AddressOfFunctions uint32 | |
| AddressOfNames uint32 | |
| AddressOfNameOrdinals uint32 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment