MCPcopy Create free account
hub / github.com/Binject/universal / LoadLibraryImpl

Function LoadLibraryImpl

loader_darwin.go:45–158  ·  view source on GitHub ↗

LoadLibraryImpl - loads a single library to memory, without trying to check or load required imports

(name string, image *[]byte)

Source from the content-addressed store, hash-verified

43
44// LoadLibraryImpl - loads a single library to memory, without trying to check or load required imports
45func LoadLibraryImpl(name string, image *[]byte) (*Library, error) {
46 // On MacOS Sierra and up, NSLinkModule is just a wrapper around
47 // dlopen, pwrite and unlink. There's no "in-memory" only method using
48 // dyld4 APIs, so there's no point in using NSCreateObjectFileImageFromMemory and NSLinkModule anymore.
49 // We can just write our own version that:
50 // - writes the binary image to a temporary file
51 // - calls dlopen on the temporary file
52 // - unlinks the temporary file
53 // - uses dlsym to resolve all the symbols
54 // See https://github.com/apple-oss-distributions/dyld/blob/main/dyld/DyldAPIs.cpp#L2785-L2847 for more details.
55 if isSierra() {
56 return LoadLibraryDlopen(name, image)
57 }
58 // force input image to be a bundle
59 // this is not the most efficient method, but it does create the abililty to do more fixups down the road,
60 // like if we added universal file support
61 machoFile, err := macho.NewFile(bytes.NewReader(*image))
62 if err != nil {
63 return nil, err
64 }
65 machoFile.FileHeader.Type = macho.TypeBundle
66 newImage, err := machoFile.Bytes()
67 if err != nil {
68 return nil, err
69 }
70 image = &newImage
71
72 // Find dyld, loop through all the Mach-O images in memory until we find
73 // one that exports NSCreateObjectFileImageFromMemory and NSLinkModule
74 var execBase uintptr = uintptr(0x0000000001000000)
75 ptr := execBase
76 var createObjectAddr, linkModuleAddr uint64
77
78 for i := 0; i < 10; i++ { // quit after the first ten images
79 ptr, err = findMacho(ptr, 0x1000)
80 if err != nil {
81 return nil, err
82 }
83 fmt.Printf("Found image at 0x%08x\n", ptr)
84 rawr := rawreader.New(ptr, MaxInt)
85 machoFile, err := macho.NewFileFromMemory(rawr)
86 if err != nil {
87 return nil, err
88 }
89 exports := machoFile.Exports()
90
91 foundCreateObj := false
92 foundLinkModule := false
93 for _, export := range exports {
94 if export.Name == "_NSCreateObjectFileImageFromMemory" {
95 fmt.Println("found NSCreateObjectFileImageFromMemory")
96 createObjectAddr = export.VirtualAddress
97 foundCreateObj = true
98 }
99 if export.Name == "_NSLinkModule" {
100 fmt.Println("found NSLinkModule")
101 linkModuleAddr = export.VirtualAddress
102 foundLinkModule = true

Callers

nothing calls this directly

Calls 5

isSierraFunction · 0.85
LoadLibraryDlopenFunction · 0.85
findMachoFunction · 0.85
findMachoPtrFunction · 0.85
CallMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…