Skip to content

Instantly share code, notes, and snippets.

@CuB3y0nd
Created February 6, 2026 13:09
Show Gist options
  • Select an option

  • Save CuB3y0nd/09f6e4c3db728b9d2f4714da1cac3ca0 to your computer and use it in GitHub Desktop.

Select an option

Save CuB3y0nd/09f6e4c3db728b9d2f4714da1cac3ca0 to your computer and use it in GitHub Desktop.
Modify segment permissions.
#!/usr/bin/env python3
# Use `readelf -l <file>` to check segment no
import sys
import struct
def main():
if len(sys.argv) != 4:
print(f"Usage: {sys.argv[0]} <file> <segment no> <permissions (rwx)>")
sys.exit(1)
filename = sys.argv[1]
try:
seg_no = int(sys.argv[2])
except ValueError:
print("Error: segment no must be an integer")
sys.exit(1)
perms_str = sys.argv[3].lower()
perms = 0
if "r" in perms_str:
perms |= 4
if "w" in perms_str:
perms |= 2
if "x" in perms_str:
perms |= 1
with open(filename, "rb+") as f:
ident = f.read(16)
if ident[:4] != b"\x7fELF":
print("Error: Not an ELF file")
sys.exit(1)
elf_class = ident[4] # 1 for 32-bit, 2 for 64-bit
is_64 = elf_class == 2
f.seek(0x1C if not is_64 else 0x20)
phoff = struct.unpack(
"<I" if not is_64 else "<Q", f.read(4 if not is_64 else 8)
)[0]
f.seek(0x2A if not is_64 else 0x36)
phentsize = struct.unpack("<H", f.read(2))[0]
phnum = struct.unpack("<H", f.read(2))[0]
if seg_no >= phnum:
print(f"Error: Segment index {seg_no} out of range (0-{phnum - 1})")
sys.exit(1)
seg_offset = phoff + (seg_no * phentsize)
if is_64:
# Elf64_Phdr: type(4), flags(4), offset(8), vaddr(8), ...
# p_flags is at offset 4 within the phdr
f.seek(seg_offset + 4)
else:
# Elf32_Phdr: type(4), offset(4), vaddr(4), paddr(4), filesz(4), memsz(4), flags(4), align(4)
# p_flags is at offset 24 within the phdr
f.seek(seg_offset + 24)
f.write(struct.pack("<I", perms))
print(
f"Successfully changed segment {seg_no} permissions to {perms_str} ({perms})"
)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment