Sample Header Ad - 728x90

Writable and executable memory regions

0 votes
1 answer
100 views
I wrote a simple Python script to scan /proc/{pid}/maps for regions that are writable and executable on my computer. It came up with a few hits surprisingly, all private anonymous. Wondering why a program would ever need writable executable region these days? What are these being used for?
/proc/1286/maps
	 ['/usr/lib/xorg/Xorg\x00:0\x00-seat\x00seat0\x00-auth\x00/var/run/lightdm/root/:0\x00-nolisten\x00tcp\x00vt7\x00-novtswitch\x00']
	 7f5860c03000-7f5860c04000 rwxp 00000000 00:00 0
/proc/2659/maps
	 ['xfwm4\x00--display\x00:0.0\x00--sm-client-id\x002c1781f72-47a5-494a-a3e7-32424563\x00']
	 7ffb7d804000-7ffb7d805000 rwxp 00000000 00:00 0
/proc/404436/maps
	 ['xfce4-terminal\x00--geometry=180x56-0-0\x00']
	 7f44aa15a000-7f44aa18a000 rwxp 00000000 00:00 0
/proc/404436/maps
	 ['xfce4-terminal\x00--geometry=180x56-0-0\x00']
	 7f44aa19b000-7f44aa1fb000 rwxp 00000000 00:00 0
/proc/404436/maps
	 ['xfce4-terminal\x00--geometry=180x56-0-0\x00']
	 7f44aaa5c000-7f44aaa7c000 rwxp 00000000 00:00 0
/proc/404436/maps
	 ['xfce4-terminal\x00--geometry=180x56-0-0\x00']
	 7f44aabba000-7f44aabca000 rwxp 00000000 00:00 0
/proc/404436/maps
	 ['xfce4-terminal\x00--geometry=180x56-0-0\x00']
	 7f44ac736000-7f44ac766000 rwxp 00000000 00:00 0
/proc/407109/maps
	 ['/usr/lib/firefox-esr/firefox-esr\x00-contentproc\x00-childID\x001\x00-isForBrowser\x00-prefsLen\x0037585\x00-prefMapSize\x00265304...']
	 10737c04c000-10737c05c000 rwxp 00000000 00:00 0
Script:
#!/usr/bin/env python3
import sys
import os
import re
import glob
from os.path import dirname, join

def main():
    map_files = list(filter(lambda f: re.match(r'^\d+$', f.split('/')), glob.glob('/proc/*/maps')))
    for map_file in map_files:
        with open(map_file, 'r') as map_f:
            for line in map_f.readlines():  # for each mapped region
                [start, end, perms, offset, dev, inode, pathname] = parse_maps_line(line)
                if 'x' in perms and 'w' in perms:
                    print(map_file)
                    with open(join(dirname(map_file), 'cmdline'), 'r') as cmd_f:
                        print('\t', cmd_f.readlines())
                    print('\t', line.strip())



def parse_maps_line(line):
    ''' The format of the file is:
    address           perms offset  dev   inode       pathname
    00400000-00452000 r-xp 00000000 08:02 173521      /usr/bin/dbus-daemon
    '''
    [address, perms, offset, dev, inode, pathname] = re.split(r'\s+', line, 5)
    [start, end] = address.split('-')
    return [int(start, 16), int(end, 16), perms, int(offset, 16), dev, inode, pathname]


if __name__ == "__main__":
    main()
**UPDATE:** ChatGPT gave a pretty good answer: While generally avoided and discouraged, a region may be writable and executable to support: 1. JIT. 2. Self modifying code. 3. Dynamically loaded code. I'm still interested in understanding specifically why all these processes - Xorg, xfwm4, xfce4-terminal and firefox-esr would need executable regions.
Asked by spinkus (500 rep)
Jan 16, 2025, 01:37 PM
Last activity: Mar 29, 2025, 10:05 PM