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

objmgr cleanup and improvements #2294

Open
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

DartVanya
Copy link
Contributor

@DartVanya DartVanya commented Nov 23, 2024

Object Manager

  • objmgr cleanup and fixes

    • KphObjectAttributesInformation -> KphObjectExtendedInformation, retrieve object address, type index and flags.
    • Public hndlmenu.h APIs. ID_HANDLE_OBJECTPROPERTIES[1/2] menu support for Device/File, Key, Section handles. Add Security menu item.
    • Add Name and Original name columns for Device/File, Key, ALPC Port and for any type object from \ObjectTypes.
  • objmgr cleanup and improvements

    • Handles tab Refresh (F5) button added. Handles and refs counts on main page will also be updated.
    • EtTreeViewFindItem add reverse scan for more reliable result.
    • [Resolver] Extract Section information for more kernel objects using driver.
  • Add menu - Copy Object Address (Ctrl+Shift+C). Add Ctrl+Alt+C shortcut for Copy Full Name.

  • Show more correct Reference count in object properties (subtracting RefCnt of PH's opened handle). This is light version of windbg !trueref. For permanent objects with no handles it show exact RealPointerCount.

  • Add "Object address" column (showed only when driver on)  But copying address from the menu always works.

  • Menu "Handles" added (quick open of Handles tab)

  • One object - one properties window. Flash already open window to user.

  • Improve navigation to complex symlinks

  • fix Show "??" entry in Object Manager #2074


General

  • Handle list - new column "Handle pointer count". Show nt!_HANDLE_TABLE_ENTRY RefCnt.

    [Alex Ionescu] Each time an existing handle to an object is used, the reference count goes down by 1.

    Allows to see how processes uses handles in realtime. Minimal code changes, use Reserved filed in KPH_PROCESS_HANDLE and SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX. Works only then driver on, column will be empty in any other scenarios.

  • Handle properties - Add "Handle pointer count" field. Dynamically updates on GeneralCallbackProcessProviderUpdatedEvent.

  • Fix handle list "File share access"

  • Handle attributes search support. ColorPartiallySuspended for both Protected and Inherit handles.


  • memsrcht show memory editor on double click, F5 - refresh.
    @jxy-s new memory strings dialog is amazing 🚀
  • Improve PhUiCloseHandles for protected handles.
  • Fix options saving if dialog closes, when any non-general page active.

Preview:

s23_11-20_7BF2w.mp4

@DartVanya DartVanya force-pushed the master-objmgr branch 3 times, most recently from 0c756f3 to 5d57d22 Compare November 23, 2024 21:47
- Handle attributes search support. ColorPartiallySuspended for both Protected and Inherit handles.
- Fix options saving from Advanced page.
@DartVanya DartVanya force-pushed the master-objmgr branch 2 times, most recently from e9bf993 to cdad3e1 Compare November 23, 2024 22:49
@DartVanya
Copy link
Contributor Author

I think this PR is ready to review. 😊

plugins/ExtendedTools/objmgr.c Outdated Show resolved Hide resolved
KSystemInformer/object.c Outdated Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Outdated Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Show resolved Hide resolved
KSystemInformer/object.c Outdated Show resolved Hide resolved
{
if (handles->Handles[i].Handle == OwnHandle)
{
*PointerCount = *PointerCount - handles->Handles[i].HandleRefCnt - 1;
Copy link
Member

Choose a reason for hiding this comment

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

Let's please remove this and other areas you have #if 0 pending driver changes. What you have here isn't correct. An eventual implementation is probably best optimized by letting the driver calculate the real pointer count itself. In order to calculate the real pointer count you need to enumerate all handle tables across the system, not just the current process. The reason you should probably let the driver do this is it can stop enumeration once it has retrieved the HandleCount number of handle table entries.

Additionally... I'm not sure if it's even reasonable to be able to calculate the true reference in all cases. The reason being that the real pointer count is a function of the object header pointer count minus the "inverted" ref counts for each active handle. This includes the handles in the CID table (the processes/threads PID/TID table). The CID table is not something immediately available (problem I'm trying to solve in my private branch).

Some background. When the kernel creates a handle it increments the _OBJECT_HEADER.PointerCount by 0x8000 and initializes the _HANDLE_TABLE_ENTRY.RefCnt. Then when that handle is "used" (e.g. ObLookupObjectByHandle) rather than incrementing the _OBJECT_HEADER.PointerCount the system simply needs to decrement the _HANDLE_TABLE_ENTRY.RefCnt. It then allows the kernel to decrement the PointerCount when it has finished with the object. This is "fine" because the PointerCount was originally incremented by 0x8000. When the handle is then closed - the kernel just subtracts the remaining RefCnt from the PointerCount.

In order to calculate the real pointer count accurately you must enumerate all handle tables on system... the performance of that could be prohibitive of an eventual implementation.

Copy link
Contributor Author

@DartVanya DartVanya Nov 25, 2024

Choose a reason for hiding this comment

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

Thanks for great info. I thought the same that for precision we need to enumerate all handles in system for every process. I didn't mean to try to implement an accurate method for counting real pointers. Just looking at how long windbg performs !trueref, I understood that not worth.
But in this case current method will show correct true reference count, since there is only one handle for this object opened by objmgr itself:

            if (real_count == 0)
            {
                count = PH_AUTO(PhGetListViewItemText(context->ListViewHandle, PH_PLUGIN_HANDLE_GENERAL_INDEX_REFERENCES, 1));
                if (!PhIsNullOrEmptyString(count) && PhStringToUInt64(&count->sr, 0, &real_count))
                {
                    ULONG trueref_count = (ULONG)real_count;
                    if (NT_SUCCESS(EtObjectManagerTrueRef(context->HandleItem->Handle, &trueref_count)))
                    {
                        PhPrintUInt32(string, trueref_count);
                        PhSetListViewSubItem(context->ListViewHandle, PH_PLUGIN_HANDLE_GENERAL_INDEX_REFERENCES, 1, string);
                    }
                }
            }

We can use EtObjectManagerTrueRef for objects with HandleCoun = 0 and keep original value in other cases.

Copy link
Member

Choose a reason for hiding this comment

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

Let me think about this a bit more. We can't guarantee we have an exclusive handle to something. And in many cases there will be multiple handles open to the same thing on a system. Then the cases where you could get the true reference wouldn't be many... Sorry to continue to press this, but let's please remove the code that doesn't have a clear accurate path forward for the time being. Showing inaccurate or partial information can be confusing or misleading (current case with the displayed pointer count).

Copy link
Contributor Author

@DartVanya DartVanya Nov 27, 2024

Choose a reason for hiding this comment

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

3fe93a1
I decide to hide reference count row from object properties window because this value does not currently contain useful and accurate information.
PhRemoveListViewItem(context->ListViewHandle, PH_PLUGIN_HANDLE_GENERAL_INDEX_REFERENCES);

phlib/native.c Outdated Show resolved Hide resolved
SystemInformer/findobj.c Outdated Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Outdated Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Outdated Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Outdated Show resolved Hide resolved
plugins/ExtendedTools/objmgr.c Outdated Show resolved Hide resolved
- memsrcht show memory editor on double click, F5 - refresh.
@DartVanya DartVanya force-pushed the master-objmgr branch 3 times, most recently from 34f8b7d to b80d038 Compare November 26, 2024 07:37
- Better organize of menu with separators
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.

Show "??" entry in Object Manager
2 participants