random loader name

This commit is contained in:
KingKDot
2026-08-19 18:16:28 -05:00
parent c0560b0598
commit a489c4368b
5 changed files with 97 additions and 28 deletions
@@ -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
}