Add ProcFdPlugin for Linux process FD analysis#1628
Open
Torres773 wants to merge 6 commits intofox-it:mainfrom
Open
Add ProcFdPlugin for Linux process FD analysis#1628Torres773 wants to merge 6 commits intofox-it:mainfrom
Torres773 wants to merge 6 commits intofox-it:mainfrom
Conversation
Horofic
requested changes
Mar 18, 2026
| def test_fd(target_linux_users: Target, fs_linux_proc: VirtualFilesystem) -> None: | ||
| target_linux_users.add_plugin(ProcPlugin) | ||
| results = list(target_linux_users.fd()) | ||
| assert len(results) == 4 No newline at end of file |
Member
There was a problem hiding this comment.
Missing newline at end of file.
Suggested change
| assert len(results) == 4 | |
| assert len(results) == 4 | |
| """Return information about open file descriptors for all processes. | ||
|
|
||
| This plugin identifies files, sockets, pipes, and other artifacts | ||
| currently in use by processes by parsing /proc/[pid]/fd and fdinfo. |
Member
There was a problem hiding this comment.
Suggested change
| currently in use by processes by parsing /proc/[pid]/fd and fdinfo. | |
| currently in use by processes by parsing ``/proc/[pid]/fd`` and ``/proc/[pid]/fdinfo`` entries. |
Comment on lines
+54
to
+57
| try: | ||
| ts = fd_obj.path.stat().st_mtime | ||
| except Exception: | ||
| ts = None |
Member
There was a problem hiding this comment.
Please make the exception a bit more specific here.
Suggested change
| try: | |
| ts = fd_obj.path.stat().st_mtime | |
| except Exception: | |
| ts = None | |
| try: | |
| ts = fd_obj.path.stat().st_mtime | |
| except Exception: | |
| ts = None | |
| pid (varint): The process id (pid) of the process. | ||
| name (string): The name associated to the pid. | ||
| fd (varint): The file descriptor number. | ||
| path (string): The resolved path or resource link. |
Member
There was a problem hiding this comment.
Suggested change
| path (string): The resolved path or resource link. | |
| link (string): The resolved path or file-type and inode. |
| name (string): The name associated to the pid. | ||
| fd (varint): The file descriptor number. | ||
| path (string): The resolved path or resource link. | ||
| pos (uint64): The current file offset from fdinfo. |
Member
There was a problem hiding this comment.
Suggested change
| pos (uint64): The current file offset from fdinfo. | |
| pos (varint): The current file offset from fdinfo. |
Comment on lines
+33
to
+34
| @export(record=FileDescriptorRecord) | ||
| def fd(self) -> Iterator[FileDescriptorRecord]: |
Member
There was a problem hiding this comment.
So you can access the plugin using filedescriptor as well. Requires the necessary imports.
Suggested change
| @export(record=FileDescriptorRecord) | |
| def fd(self) -> Iterator[FileDescriptorRecord]: | |
| @alias("filedescriptor") | |
| def fd(self) -> Iterator[FileDescriptorRecord]: |
|
|
||
| from dissect.target.exceptions import UnsupportedPluginError | ||
| from dissect.target.helpers.record import TargetRecordDescriptor | ||
| from dissect.target.plugin import Plugin, export |
Member
There was a problem hiding this comment.
Import for the alias suggestion.
Suggested change
| from dissect.target.plugin import Plugin, export | |
| from dissect.target.plugin import Plugin, alias, export |
Comment on lines
+58
to
+67
| yield FileDescriptorRecord( | ||
| ts=ts, | ||
| pid=process.pid, | ||
| name=process.name, | ||
| fd=fd_obj.number, | ||
| link=fd_obj.link, | ||
| pos=int(fd_obj.info.get("pos", 0)), | ||
| flags=fd_obj.info.get("flags", "0"), | ||
| _target=self.target, | ||
| ) |
Member
There was a problem hiding this comment.
I think passing None is a bit more 'correct' when the values are not present. This code might need a little change when you go the FdInfo route mentioned in PR #1609
Suggested change
| yield FileDescriptorRecord( | |
| ts=ts, | |
| pid=process.pid, | |
| name=process.name, | |
| fd=fd_obj.number, | |
| link=fd_obj.link, | |
| pos=int(fd_obj.info.get("pos", 0)), | |
| flags=fd_obj.info.get("flags", "0"), | |
| _target=self.target, | |
| ) | |
| yield FileDescriptorRecord( | |
| ts=ts, | |
| pid=process.pid, | |
| name=process.name, | |
| fd=fd_obj.number, | |
| link=fd_obj.link, | |
| pos=fd_obj.info.get("pos", None), | |
| flags=fd_obj.info.get("flags", None), | |
| _target=self.target, | |
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #1609
Add ProcFdPlugin for Linux process FD analysis
Implement a new plugin to analyze open file descriptors by parsing
/proc/[pid]/fd and fdinfo. This provides forensic visibility into
files, sockets, and pipes used by running processes.
The plugin yields FileDescriptorRecord which includes file offsets
and access flags. This builds upon the recent FileDescriptor
iterator addition in the proc parser.