Skip to content

file.list works for directories, shows timestamp information as epoch for create,access,modified,changed#2376

Open
AmeliaYeah wants to merge 5 commits into
spellshift:mainfrom
AmeliaYeah:main
Open

file.list works for directories, shows timestamp information as epoch for create,access,modified,changed#2376
AmeliaYeah wants to merge 5 commits into
spellshift:mainfrom
AmeliaYeah:main

Conversation

@AmeliaYeah

Copy link
Copy Markdown

What type of PR is this?

Feature
Eldritch-Function

What this PR does / why we need it:

While this does somewhat exist in the file.list API call (in regards to obtaining the stringified version of modified time), this is a bit of a hacky approach, and also doesn't work with directories. This API call is designed to be an easier way to obtain the time metadata of a file (aswell as beyond just the mtime).

My specific personal motivation was in regard to timestomping a file to it's metadata BEFORE writing to such file, but I'm sure there are multitudes of other use cases for this API call.

@AmeliaYeah AmeliaYeah changed the title get_times Added get_times() to get timestamp information of files Jun 28, 2026

@hulto hulto left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @AmeliaYeah and sorry for the delay.
We're all on a short break post CCDC so may be slow to respond.

This looks like a great feature!
Instead of adding a new function though would moving this capability to the existing file list function make sense for your use case?
I like the idea of update file list to work on dirs, and also switching to epoch.

@AmeliaYeah

AmeliaYeah commented Jul 8, 2026

Copy link
Copy Markdown
Author

Thanks for the PR @AmeliaYeah and sorry for the delay. We're all on a short break post CCDC so may be slow to respond.

This looks like a great feature! Instead of adding a new function though would moving this capability to the existing file list function make sense for your use case? I like the idea of update file list to work on dirs, and also switching to epoch.

Yeah the more I think of it the more I feel this might be better, I'll update file list to show the directory and also show timestamp information as epoch

@AmeliaYeah AmeliaYeah changed the title Added get_times() to get timestamp information of files file.list works for directories, shows timestamp information as epoch for create,access,modified,changed Jul 9, 2026
@jabbate19

Copy link
Copy Markdown
Collaborator

Reviewing a9f110ac..27f9d1f8file.list now returns dir self + epoch timestamps.

Summary: Good forensic enhancement, keeps legacy modified UTC string for back-compat while adding times dict. Main risk is breaking change on len() semantics.

Detailed file:line comments posted below as inline review comments + this summary.

@jabbate19 jabbate19 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File:line review for timestamp + dir-self changes – see inline comments for exact locations.

// If I implement `handle_list` roughly:
// show information for the file
// if it's a directory, show information of the directory being listed from
final_res.push(create_dict_from_file(&path_buf)?);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change – dir self now included (55-68) at list_impl.rs:55-68:

Old:

if path_buf.is_dir() { push children } else { push self }

New always pushes self then children if dir. Callers checking len() == child_count or files[0] as first child break – adds +1 per dir.

  • Document breaking change in PR description / changelog, or gate with include_self param (default false for v1 compat).
  • read_dir order is FS-dependent; doc example shows deterministic order. Consider sorting by absolute_path or documenting as unordered.
  • Glob edge: file.list("/tmp/*") where matches are dirs now returns each matched dir (self) + its children – one-level recursive for wildcards. Confirm intentional.

File: implants/lib/eldritch/stdlib/eldritch-libfile/src/std/list_impl.rs:55-68

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i added dir_self as a flag, false by default, to show the directory itself. i also added sorting by absolute_path

#[cfg(unix)] {
use std::os::unix::fs::MetadataExt;
times.insert(Value::String("changed".to_string()), Value::Int(metadata.ctime()));
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_times_dict mixes epoch sources + silent omission (76-107) at list_impl.rs:77-106:

  • changed via MetadataExt::ctime() already epoch i64 (can be negative pre-1970). Others via SystemTime::duration_since(UNIX_EPOCH) errors pre-1970 and gets silently dropped. A pre-1970 file could expose only changed. Normalize or document omission.
  • cast_signed() on u64 truncates >i64::MAX; i64::try_from more explicit.
  • Style: return Value::Dictionary(...) + stray ; after } line 103 non-idiomatic – use tail expr Value::Dictionary(Arc::new(RwLock::new(times))).
  • Duplicate syscall: create_dict_from_file:177-182 calls modified() for legacy string then get_times_dict calls it again. Cache once.
  • Typo compatability line 177 → compatibility.

File: implants/lib/eldritch/stdlib/eldritch-libfile/src/std/list_impl.rs:77-106

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixes applied, negative epochs supported for mtime/atime/crtime

Comment thread implants/lib/eldritch/stdlib/eldritch-libfile/src/std/list_impl.rs
Comment thread docs/_docs/user-guide/eldritch.md Outdated
"absolute_path": "/some_directory",
"file_name": "some_directory",
"group": "root",
"modified": "2026-07-09 18:24:44 UTC", // modification time represented as a UTC string

@jabbate19 jabbate19 Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs file.list example – style (735-791) at eldritch.md:747:

  • Caps: CHANGED TIME IS ONLY SUPPORTED IN UNIX SYSTEMS!changed is Unix-only (ctime).

  • "type": "dir" / "file" lower-case matches code (good) but previous docs said Directory/File – call out normalization.

  • Epoch values 1783621485 ≈ mid-2026 future – consider realistic 1700... or note illustrative.

  • Missing disclosure: times.created absent on Linux ext4 (no birthtime), times fields may be missing pre-1970 when duration_since fails.

  • Grammar: along with it's output line 735 → its output.

  • Document that file.list("/some_directory") now returns directory itself as first entry – new vs upstream.

File: docs/_docs/user-guide/eldritch.md:735-791

@AmeliaYeah AmeliaYeah Jul 12, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied, lowercase dir and file are accurate, and all fields are accurate to the current version of file.list (including this PR)

@AmeliaYeah

AmeliaYeah commented Jul 12, 2026

Copy link
Copy Markdown
Author

didnt want to make a separate issue for this but during testing i noticed file.timestomp doesn't seem to support negative epochs (with ref_file and specifying them in fields like mtime) and just defaults them to 0. i might make a fix to this in the future but just wanted to note it.

`file.list(path: str, dir_self: Optional<bool> = False) -> List<Dict>`

The **file.list** method returns a list of files at the specified path. The path is relative to your current working directory and can be traversed with `../`.
If `path` is a directory, `dir_self` denotes whether to show the information of `path` itself in the `List<Dict>`. This field has no impact if `path` is not a directory.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does dir_self only show the local dir or optionally include it?
If only itself - can you name it only_dir_self to be more clear.
If optionally include the local dir - i think we should include that by default similar to ls

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay seems like it optionally includes the local dir. I think we should always include this.

@hulto

hulto commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Thanks @AmeliaYeah !
And feel free to ping us on Discord if you need re-review or workflow run approval.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants