Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FileLocksmith.Interop] Enhance File Path Resolution with GetFinalPathNameByHandle #31385

Open
PolarGoose opened this issue Feb 11, 2024 · 3 comments
Labels
Help Wanted We encourage anyone to jump in on these and submit a PR. Idea-Enhancement New feature or request on an existing product Product-File Locksmith Refers to the File Locksmith utility

Comments

@PolarGoose
Copy link

Description of the new feature / enhancement

Context

In the current implementation of the FileLocksmith module NtdllExtensions::path_to_kernel_name is utilized to translate NT-style paths to a more conventional, drive-based format.
This translation is necessary after fetching file paths using the NtDll.NtQuerySystemInformation function.

While this manual approach is functional, Windows API offers a more robust and potentially less error-prone method for achieving the same goal: GetFinalPathNameByHandleW. This function, given a file handle, returns the full drive-based path of the file, including handling various path nuances and edge cases automatically.

Proposal

Replace the current manual method implemented in path_to_kernel_name with GetFinalPathNameByHandleW

Scenario when this would be used?

Convert the NT device object path to the path with the drive letter.

Supporting information

Reference implementation in pseudo C#

internal static class WinApi {
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
    [DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
    private static extern int GetFinalPathNameByHandleW(SafeFileHandle hFile, [Out] StringBuilder filePathBuffer, int filePathBufferSize, int flags);

    public static string? GetFinalPathNameByHandle(SafeFileHandle hFile)
    {
        var buf = new StringBuilder();
        var result = GetFinalPathNameByHandleW(hFile, buf, buf.Capacity, 0);
        if(result == 0)
        {
            return null;
        }

        buf.EnsureCapacity(result);
        result = GetFinalPathNameByHandleW(hFile, buf, buf.Capacity, 0);
        if (result == 0)
        {
            return null;
        }

        var str = buf.ToString();
        return str.StartsWith(@"\\?\") ? str.Substring(4) : str;
    }
}

public void Test()
{
    var handles = NtDll.QuerySystemHandleInformation();
    foreach (var h in handles)
    {
        using var openedProcess = WinApi.OpenProcess(...);
        var curProcess = WinApi.GetCurrentProcess();
        var res = WinApi.DuplicateHandle(out var dupHandle);

        // If the handle type is a File, then the driveLetterBasedFileFullName will have a value like "\\?\C:\Windows\System32\en-US\combase.dll.mui"
        var driveLetterBasedFileFullName = WinApi.GetFinalPathNameByHandle(dupHandle)
    }
}
@PolarGoose PolarGoose added the Needs-Triage For issues raised to be triaged and prioritized by internal Microsoft teams label Feb 11, 2024
@davidegiacometti davidegiacometti added Idea-Enhancement New feature or request on an existing product Product-File Locksmith Refers to the File Locksmith utility labels Feb 12, 2024
@joadoumie
Copy link
Contributor

@jaimecbernardo-msft - if you agree with this change I am going to take off the needs-triage label and add the Help-Wanted tag

@jaimecbernardo
Copy link
Collaborator

@jaimecbernardo-msft - if you agree with this change I am going to take off the needs-triage label and add the Help-Wanted tag

Sounds good to me, @joadoumie . Thank you!

@joadoumie joadoumie added Help Wanted We encourage anyone to jump in on these and submit a PR. and removed Needs-Triage For issues raised to be triaged and prioritized by internal Microsoft teams labels Mar 8, 2024
@PolarGoose
Copy link
Author

I also described another improvement here.

In general, the Interop C++ library is not needed. It is possible to write the lock-finding code in C# like I have done in one of my projects here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted We encourage anyone to jump in on these and submit a PR. Idea-Enhancement New feature or request on an existing product Product-File Locksmith Refers to the File Locksmith utility
Projects
Status: ⚠️Needs Walkthrough
Development

No branches or pull requests

4 participants