Skip to content

Commit 0b1fe04

Browse files
committed
Fix-up .dynamic section
1 parent d8d15c1 commit 0b1fe04

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

cmd/create-fself/main.go

+3
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ func main() {
105105
err = orbisElf.RewriteProgramHeaders()
106106
check(err)
107107

108+
// Overwrite .dynamic section header to point to the new dynamic table
109+
err = orbisElf.RewriteDynamicSectionHeader()
110+
108111
// Commit
109112
err = orbisElf.FinalFile.Close()
110113
check(err)

pkg/oelf/OELFGenProgramHeaders.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ func (orbisElf *OrbisElf) GenerateProgramHeaders() error {
2525
procParamSection = orbisElf.ElfToConvert.Section(".data.sce_module_param")
2626
}
2727

28+
// Get GNU_RELRO header pre-emptively (we'll need to check it to eliminate duplicate PT_LOAD headers)
29+
gnuRelroSegment := orbisElf.getProgramHeader(elf.PT_GNU_RELRO, elf.PF_R)
30+
2831
// First pass: drop program headers that we don't need and copy all others
2932
for _, progHeader := range orbisElf.ElfToConvert.Progs {
3033
// PT_LOAD read-only should be consolidated into PT_LOAD for .text
@@ -33,12 +36,18 @@ func (orbisElf *OrbisElf) GenerateProgramHeaders() error {
3336
}
3437

3538
// PT_LOAD for relro will be handled by SCE_RELRO, we can get rid of it
36-
if relroSection != nil {
37-
if progHeader.Type == elf.PT_LOAD && progHeader.Off == relroSection.Offset {
39+
if gnuRelroSegment != nil {
40+
if progHeader.Type == elf.PT_LOAD && progHeader.Off == gnuRelroSegment.Off {
3841
continue
3942
}
4043
}
4144

45+
// GNU_RELRO will sometimes get generated even if no .data.rel.ro is present. This is bad for PS4 because the
46+
// header will be unaligned and it's not necessary. Get rid of it if there's no relro section.
47+
if progHeader.Type == elf.PT_GNU_RELRO && relroSection == nil {
48+
continue
49+
}
50+
4251
// GNU_STACK can be dropped, PS4 doesn't need it
4352
if progHeader.Type == elf.PT_GNU_STACK {
4453
continue

pkg/oelf/OELFRewriteData.go

+62
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,65 @@ func (orbisElf *OrbisElf) RewriteInterpreter(interpreter string) error {
122122
_, err = orbisElf.FinalFile.WriteAt(interpreterBuff, rewriteOffset)
123123
return err
124124
}
125+
126+
// RewriteDynamicSectionHeader will overwrite the address of the .dynamic section with the given address. Returns
127+
// an error if the write failed, nil otherwise.
128+
func (orbisElf *OrbisElf) RewriteDynamicSectionHeader() error {
129+
var (
130+
inputFile *os.File
131+
err error
132+
)
133+
134+
// Get the section header offset info from the original file
135+
inputHdr := new(elf.Header64)
136+
137+
if inputFile, err = os.Open(orbisElf.ElfToConvertName); err != nil {
138+
return err
139+
}
140+
141+
if _, err = inputFile.Seek(0, io.SeekStart); err != nil {
142+
return err
143+
}
144+
145+
if err = binary.Read(inputFile, orbisElf.ElfToConvert.ByteOrder, inputHdr); err != nil {
146+
return err
147+
}
148+
149+
sectionHeadersOffset := inputHdr.Shoff
150+
151+
// Find the dynamic header
152+
for i := uint16(0); i < inputHdr.Shnum; i++ {
153+
sectionHdr := new(elf.Section64)
154+
sectionHeaderOffset := int64(sectionHeadersOffset + uint64(i*inputHdr.Shentsize))
155+
156+
if _, err = inputFile.Seek(sectionHeaderOffset, io.SeekStart); err != nil {
157+
return err
158+
}
159+
160+
if err = binary.Read(inputFile, orbisElf.ElfToConvert.ByteOrder, sectionHdr); err != nil {
161+
return err
162+
}
163+
164+
if sectionHdr.Type == uint32(elf.SHT_DYNAMIC) {
165+
sectionHeaderBuff := new(bytes.Buffer)
166+
167+
// Rewrite the address
168+
sectionHdr.Off = _offsetOfDynamic
169+
sectionHdr.Addr = _offsetOfDynamic
170+
sectionHdr.Size = _sizeOfDynamic
171+
172+
// Commit the write
173+
if err := binary.Write(sectionHeaderBuff, binary.LittleEndian, sectionHdr); err != nil {
174+
return err
175+
}
176+
177+
if _, err := orbisElf.FinalFile.WriteAt(sectionHeaderBuff.Bytes(), sectionHeaderOffset); err != nil {
178+
return err
179+
}
180+
181+
break
182+
}
183+
}
184+
185+
return nil
186+
}

0 commit comments

Comments
 (0)