0

MSDN states that on older versions of Windows, NtOpenProcess supports opening a process by name but fails to document that actual syntax of the name string.

In Windows Server 2003, Windows XP, and Windows 2000, the caller has the option of supplying either a client ID or an object name (but not both). If the ObjectName field of the structure pointed to by ObjectAttributes contains a non-NULL pointer to an object name, ClientId must be NULL.

I've tried various versions of %d, %#x and %x, what is the correct syntax for the object name?

HANDLE handle = 0;
WCHAR b[99];
wsprintfW(b, L"Process\\%x", GetCurrentProcessId()); // What is the syntax supposed to be? "Process" is the name of the process object type but I'm not sure if it's required here.
UNICODE_STRING name;
RtlInitUnicodeString(&name, b);
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &name, 0, NULL, NULL);
NTSTATUS status = NtOpenProcess(&handle, SYNCHRONIZE, &oa, NULL);
_tprintf(_T("%X %p\n"), status, handle);

(I realize this question is outdated by about 20 years but I'm just curious)

Anders
  • 97,548
  • 12
  • 110
  • 164
  • 1
    here problem bit another - for open process (any object) by name - object must have name and we must know this name. if process have name - no problem open it by name in `OBJECT_ATTRIBUTES`. but first need create process with name. `CreateProcess[Internal]W` not allow this. but `NtCreateProcess[Ex]` take `OBJECT_ATTRIBUTES` - so let use name. so you need first begin from create process by this api – RbMm Jul 23 '22 at 17:49
  • Have you tried this? Can you use any name? Any why document it at all if there is no documented way to start a named process. – Anders Jul 23 '22 at 17:51
  • if say true - i never try. modern `NtCreateUserProcess` also take `OBJECT_ATTRIBUTES` so posible try of course. but what sense in this ? i never view processes with name in nt object namespace. maybe this will be interesting, but for what ? – RbMm Jul 23 '22 at 17:55
  • No real use, just thought it was fascinating. But if it only works for processes created with a specific name the capability does seem rather pointless. – Anders Jul 23 '22 at 17:57
  • i try create process with name. think name can be any legal nt name. take events object for instance - can we open event by name ? only if this event was created with name. same and for process object - possible open process by name only if process initially created with name – RbMm Jul 23 '22 at 18:01
  • 1
    in first try - i got `STATUS_OBJECT_NAME_INVALID` from `NtCreateUserProcess` need more research, are posible use name. i until use "\\BaseNamedObjects\\Restricted\\[DemoProcess]" – RbMm Jul 23 '22 at 18:12
  • 1
    in win10 inside `OBJECT_TYPE_INITIALIZER.UnnamedObjectsOnly == 1` for `PsProcessType->TypeInfo` so win10 clear not support names. may be old version (xp/2003) yet support this – RbMm Jul 23 '22 at 18:33
  • @RbMm Yes, MSDN might be correct about that. Thanks to your comments I got it to work on XP. – Anders Jul 23 '22 at 18:40
  • yes, i just create process with name on xp – RbMm Jul 23 '22 at 18:45
  • https://i.imgur.com/IqZYPZ9.png – RbMm Jul 23 '22 at 18:47
  • @RbMm Why did you create it in the Restricted subdirectory? – Anders Jul 23 '22 at 18:55
  • simply for easy look - this directory usually empty. so any object created here just visible. only because this. also for win7 (probably on vista too ) this already not work - STATUS_OBJECT_NAME_INVALID i got and this because - https://i.imgur.com/Qqx2q5R.png – RbMm Jul 23 '22 at 19:03
  • Apparently it also works for thread objects as well. Neat. – Luke Jul 23 '22 at 19:46

1 Answers1

1

With help from RbMm in the comments I was able to get it to work but since you are limited to processes named on purpose and the functions to do that are undocumented the whole feature is rather useless.

if (LOBYTE(GetVersion()) != 5) return -1;
UNICODE_STRING name;
OBJECT_ATTRIBUTES oa;
RtlInitUnicodeString(&name, L"\\BaseNamedObjects\\HelloWorld");
NTSTATUS status;
HANDLE handle = 0;
InitializeObjectAttributes(&oa, &name, 0, NULL, NULL);
status = NtCreateProcessEx(&handle, STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x0FFF, &oa, GetCurrentProcess(), 0, NULL, NULL, NULL, 0);
_tprintf(_T("create %X %p pid=%d\n"), status, handle, status ? 0 : GetProcessId(handle));
if (status) return status;
    
status = NtOpenProcess(&handle, SYNCHRONIZE|PROCESS_QUERY_INFORMATION|PROCESS_TERMINATE, &oa, NULL);
_tprintf(_T("open %X %p pid=%d\n"), status, handle, status ? 0 : GetProcessId(handle));
if (status) return status;
Sleep(1000*60);
TerminateProcess(handle, 0); // Kill zombie child

named process on XP

Anders
  • 97,548
  • 12
  • 110
  • 164
  • possible do this and with `CreateProcessW` and create not zombie but full working process. but until 2003 – RbMm Jul 23 '22 at 19:12
  • @RbMm I don't see how you could do this with `CreateProcessW` but I'd be happy to accept your answer if you want to provide a working non-zombie example... – Anders Jul 23 '22 at 20:29
  • 1
    inside call `CreateProcessW` - `NtCreateProcessEx` called anyway on xp (now this is `NtCreateUserProcess` ) - we can hook excution at this point and replace 0 in `POBJECT_ATTRIBUTES` parameter to our pointer to `OBJECT_ATTRIBUTES` with name. the most clean way do this - set break via DR registers on current thread. or possible in debugger set bp and manually fix memory for test. early on xp this was useful for change parent of process. but after `PROC_THREAD_ATTRIBUTE_PARENT_PROCESS` added to vista this way already not actual – RbMm Jul 23 '22 at 20:47
  • 1
    `AddVectoredExceptionHandler` + set thread context with Dr0-3 Dr7 do task. bat this is question about self hook technique already – RbMm Jul 23 '22 at 20:51