Skip to content

Commit 917ea45

Browse files
K900Mic92
authored andcommitted
feat: add --no-clobber-old-sections switch
Works around #520, may be useful for other cursed self-modifying things.
1 parent afd3cc9 commit 917ea45

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

patchelf.1

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ old_name new_name
131131

132132
Symbol names do not contain version specifier that are also shown in the output of the nm -D command from binutils. So instead of the name write@GLIBC_2.2.5 it is just write.
133133

134+
.IP "--no-clobber-old-sections"
135+
Do not clobber old section values.
136+
137+
patchelf defaults to overwriting replaced header sections with garbage to ensure they are not
138+
used accidentally. This option allows to opt out of that behavior, so that binaries that attempt
139+
to read their own headers from a fixed offset (e.g. Firefox) continue working.
140+
141+
Use sparingly and with caution.
142+
134143
.IP "--output FILE"
135144
Set the output file name. If not specified, the input will be modified in place.
136145

src/patchelf.cc

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
static bool debugMode = false;
5959

6060
static bool forceRPath = false;
61+
static bool clobberOldSections = true;
6162

6263
static std::vector<std::string> fileNames;
6364
static std::string outputFileName;
@@ -664,14 +665,16 @@ template<ElfFileParams>
664665
void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
665666
Elf_Addr startAddr, Elf_Off startOffset)
666667
{
667-
/* Overwrite the old section contents with 'Z's. Do this
668-
*before* writing the new section contents (below) to prevent
669-
clobbering previously written new section contents. */
670-
for (auto & i : replacedSections) {
671-
const std::string & sectionName = i.first;
672-
const Elf_Shdr & shdr = findSectionHeader(sectionName);
673-
if (rdi(shdr.sh_type) != SHT_NOBITS)
674-
memset(fileContents->data() + rdi(shdr.sh_offset), 'Z', rdi(shdr.sh_size));
668+
if (clobberOldSections) {
669+
/* Overwrite the old section contents with 'Z's. Do this
670+
*before* writing the new section contents (below) to prevent
671+
clobbering previously written new section contents. */
672+
for (auto & i : replacedSections) {
673+
const std::string & sectionName = i.first;
674+
const Elf_Shdr & shdr = findSectionHeader(sectionName);
675+
if (rdi(shdr.sh_type) != SHT_NOBITS)
676+
memset(fileContents->data() + rdi(shdr.sh_offset), 'Z', rdi(shdr.sh_size));
677+
}
675678
}
676679

677680
std::set<unsigned int> noted_phdrs = {};
@@ -2505,6 +2508,7 @@ static void showHelp(const std::string & progName)
25052508
[--clear-execstack]\n\
25062509
[--set-execstack]\n\
25072510
[--rename-dynamic-symbols NAME_MAP_FILE]\tRenames dynamic symbols. The map file should contain two symbols (old_name new_name) per line\n\
2511+
[--no-clobber-old-sections]\t\tDo not clobber old section values - only use when the binary expects to find section info at the old location.\n\
25082512
[--output FILE]\n\
25092513
[--debug]\n\
25102514
[--version]\n\
@@ -2661,6 +2665,9 @@ static int mainWrapped(int argc, char * * argv)
26612665
symbolsToRename[*symbolsToRenameKeys.insert(from).first] = to;
26622666
}
26632667
}
2668+
else if (arg == "--no-clobber-old-sections") {
2669+
clobberOldSections = false;
2670+
}
26642671
else if (arg == "--help" || arg == "-h" ) {
26652672
showHelp(argv[0]);
26662673
return 0;

0 commit comments

Comments
 (0)