System‑Wide Process Intelligence
A comprehensive guide to monitoring, inspecting, and understanding running processes on Linux and Windows.
The /proc Filesystem (Linux)
Under Linux, the virtual /proc directory acts as a central repository for runtime process information. Every active process has its own subdirectory named after its PID. For example, a process with PID 1337 can be examined by looking inside /proc/1337/. Access is restricted to processes owned by the user, unless you have superuser privileges.
The most informative files within each PID directory include:
cmdline – the full command line that started the process, including arguments.
cwd – a symbolic link pointing to the process’s current working directory.
environ – the environment variables in effect for that process.
exe – a link to the actual executable file on disk.
fd – a directory listing all open file descriptors.
maps – extremely valuable: a detailed memory map showing which regions of the address space are used by the process, including shared libraries, heap, stack, and memory‑mapped files. This information can be fed directly into a debugger like gdb to investigate specific memory regions.
Process Explorer (Sysinternals)
For Windows, the Sysinternals suite offers Process Explorer, a graphical tool that parallels the functionality of /proc—and in some ways surpasses it. It displays:
- DLL mapping information, including the exact addresses where exported functions reside.
- Detailed process properties, such as environment variables, security tokens, open handles (files, registry keys, named pipes, etc.), and object types.
- Interactive controls to close handles, adjust security permissions, attach a debugger, or change scheduling priority—capabilities not directly available through
/proc.
Gathering Linking Information
Before diving into a binary’s internals, it is wise to identify which external libraries it depends on. This initial step often reveals the program’s general nature and hints at its behaviour.
ldd (Linux/UNIX)
The ldd command lists all shared libraries required by an executable, along with their load addresses. It also indicates whether the binary is statically linked. These addresses become useful later when correlating disassembled code with library functions.
Dependency Walker (depends.exe)
This tool ships with the Microsoft SDK and Visual Studio. It goes far beyond simple library listing: it shows which functions are imported from each DLL, how they are imported (by name or ordinal), and recursively analyses all dependent DLLs. The interface is dense but powerful:
- When you select a DLL, the upper‑right pane displays the functions that its parent module imports from it.
- The exports of the selected DLL are shown alongside; functions that match an import are highlighted in light blue with a dot, those that are used somewhere in the dependency chain are blue, and unused exports appear grey.
- Many imports are resolved by name or ordinal; some are “bound” – the linker pre‑fills an assumed address. However, bindings can become stale, and modifying them in the binary does not always produce the expected result (a point we revisit in later chapters on code modification).
Extracting Function Symbols
Distinguishing functional blocks within a binary is a core reverse‑engineering task, but without debug symbols it can be tricky.
nm (Linux/UNIX)
The nm tool lists all symbols (functions, global variables, etc.) along with their addresses, provided the binary has not been stripped with the strip command. It works on object files and executables.
dumpbin.exe (Windows)
Windows lacks a direct equivalent to nm, but dumpbin.exe can show imported functions (/imports) and exported functions (/exports) from PE files. However, a function is only visible in the export table if it has been explicitly marked with __declspec(dllexport) (or equivalent). In practice, Dependency Walker often provides more than enough detail, and the Cygwin port of objdump (covered later) also serves as a capable alternative.
Monitoring Filesystem Activity
lsof (Linux/UNIX)
lsof stands for “list open files” and reports every file, directory, socket, pipe, and memory‑mapped region currently open by any process. It is not installed by default on all distributions, but it is widely available. The output includes the command name, PID, user, file descriptor type, device numbers, size, inode, and path. Common descriptor types shown are:
cwd – current working directory
rtd – root directory
txt – program code and data
mem – memory‑mapped file
CHR – character special device
DIR – directory
FIFO – named pipe
unix – UNIX domain socket
sock – socket of unknown domain
A related command is fuser, which accepts a file or socket name as an argument and returns the PIDs of any processes accessing that resource.
Filemon (Sysinternals)
For Windows, Filemon provides a real‑time view of file system activity, including reads, writes, queries, and other operations. It supports filtering by process name and operation type, making it a valuable companion.
Regmon (Sysinternals)
The Windows Registry often holds configuration secrets, credentials, or other interesting data. Regmon allows live monitoring of registry accesses, showing which keys are being read, written, or queried. This is indispensable when exploring how a Windows application stores its settings or protects its state.
Inspecting Network Connections
netstat
This classic utility exists on both Linux and Windows with nearly identical syntax and output. It displays active network connections, listening ports, routing tables, and interface statistics. Two sections are typically shown:
- Internet connections – TCP/UDP endpoints with local and remote addresses, port numbers, and connection states (e.g.,
ESTABLISHED, LISTEN, SYN_SENT, TIME_WAIT).
- UNIX domain sockets – inter‑process communication channels (only on Linux/UNIX).
On many systems, the -p flag (requires root privileges on Linux) reveals the PID and process name associated with each connection. Combining -a (show all, including listening sockets) and -n (numeric addresses, no hostname resolution) gives a comprehensive, unfiltered view. For instance, a typical output might show that a mozilla-bin process has an established connection to a remote web server on port 80.
Capturing Network Traffic
Network sniffing involves placing the network interface into promiscuous mode (on hubs or non‑switched segments) to capture all packets that pass by. On switched networks, techniques like ARP poisoning are used to redirect traffic; these are discussed elsewhere.
Popular sniffing tools include:
- Ethereal / Wireshark – a feature‑rich graphical protocol analyser that decodes headers, flags, and payloads for hundreds of protocols. It offers powerful filtering and capture‑save capabilities. It requires the
libpcap (Linux) or WinPcap (Windows) library.
- tcpdump – a classic command‑line sniffer that prints packet summaries. It comes pre‑installed on most Linux distributions; a Windows port (WinDump) is also available.
- ettercap – a console‑based tool with a curses interface; it specialises in ARP poisoning and man‑in‑the‑middle attacks, and supports plugins that can modify traffic on the fly. While its sniffing engine is not as robust as Ethereal’s, it complements other tools well.
Using a filter such as tcp.port == 110 in Ethereal, you can isolate POP3 traffic to study how a mail client authenticates and retrieves messages. Ethereal’s dissection pane breaks down each packet’s headers (IP, TCP, application layer) and highlights checksums, flags, and payload structure, making protocol reverse‑engineering more accessible.
Tracing System Calls and Library Calls
System‑Call Tracing (UNIX)
Tools like strace (Linux) or truss (Solaris) intercept every system call made by a process, showing arguments and return values. Useful flags:
-f – follow child processes (forks)
-ff – output to separate files per child (with .pid suffix)
-i – print the instruction pointer at each call
-o – redirect output to a file
Library‑Call Tracing
A step deeper lies ltrace, which tracks calls to dynamic libraries (including standard C library functions, GTK, etc.). It can also show system calls with -S. Options include:
-f – follow forks
-o – output file
-C – demangle C++ names
-n 2 – indent nested calls by 2 spaces
-i – show caller’s instruction pointer
-p pid – attach to an already‑running process
API Monitor (Windows)
This powerful tool monitors Windows API calls in real time, supporting filtering by DLL, category, and other criteria. It is the closest Windows equivalent to ltrace and can reveal how an application interacts with the operating system, registry, file system, and networking stack.
💡 Summary: By combining these system‑wide information sources—from /proc and lsof to netstat, sniffers, and call tracers—you can build a comprehensive picture of a target program’s behaviour without ever looking at its source code. Each tool contributes a distinct piece of the puzzle, and together they form the foundation of any systematic reverse‑engineering effort.
📘 Note: The original document contained placeholders (FIXME) for some tool outputs, diagrams, and advanced topics such as ARP poisoning. Those have been omitted or summarised here to maintain focus on the core concepts.
This HTML rendering is based on the system‑wide process intelligence document. All content is for educational purposes.