Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save The-King-of-Toasters/675d7512d5c03a083e34a7dc0d3f89d0 to your computer and use it in GitHub Desktop.
Save The-King-of-Toasters/675d7512d5c03a083e34a7dc0d3f89d0 to your computer and use it in GitHub Desktop.
NT Object Name Mismatch
const std = @import("std");
const windows = std.os.windows;
const ntdll = windows.ntdll;
const L = std.unicode.utf8ToUtf16LeStringLiteral;
const name_buf_size = @sizeOf(windows.OBJECT_NAME_INFORMATION) + windows.PATH_MAX_WIDE * @sizeOf(u16);
var name_buf: [name_buf_size]u16 align(@alignOf(windows.OBJECT_NAME_INFORMATION)) = undefined;
var type_buf: [1024]u16 align(@alignOf(OBJECT_TYPE_INFORMATION)) = undefined;
const GENERIC_MAPPING = extern struct {
GenericRead: windows.ACCESS_MASK,
GenericWrite: windows.ACCESS_MASK,
GenericExecute: windows.ACCESS_MASK,
GenericAll: windows.ACCESS_MASK,
};
const OBJECT_TYPE_INFORMATION = extern struct {
TypeName: windows.UNICODE_STRING,
TotalNumberOfObjects: windows.ULONG,
TotalNumberOfHandles: windows.ULONG,
TotalPagedPoolUsage: windows.ULONG,
TotalNonPagedPoolUsage: windows.ULONG,
TotalNamePoolUsage: windows.ULONG,
TotalHandleTableUsage: windows.ULONG,
HighWaterNumberOfObjects: windows.ULONG,
HighWaterNumberOfHandles: windows.ULONG,
HighWaterPagedPoolUsage: windows.ULONG,
HighWaterNonPagedPoolUsage: windows.ULONG,
HighWaterNamePoolUsage: windows.ULONG,
HighWaterHandleTableUsage: windows.ULONG,
InvalidAttributes: windows.ULONG,
GenericMapping: GENERIC_MAPPING,
ValidAccessMask: windows.ULONG,
SecurityRequired: windows.BOOLEAN,
MaintainHandleCount: windows.BOOLEAN,
PoolType: windows.ULONG,
DefaultPagedPoolCharge: windows.ULONG,
DefaultNonPagedPoolCharge: windows.ULONG,
};
pub const GetObjectNameError = error{Unexpected};
extern "ntdll" fn NtCreateDirectoryObject(
DirectoryHandle: *windows.HANDLE,
DesiredAccess: windows.ACCESS_MASK,
ObjectAttributes: *windows.OBJECT_ATTRIBUTES,
) callconv(windows.WINAPI) windows.NTSTATUS;
extern "kernel32" fn CreateMailslotW(
lpName: windows.LPCWSTR,
nMaxMessageSize: windows.DWORD,
lReadTimeout: windows.DWORD,
lpSecurityAttributes: ?*windows.SECURITY_ATTRIBUTES,
) callconv(windows.WINAPI) windows.HANDLE;
extern "kernel32" fn CreateSemaphoreW(
lpSemaphoreAttributes: ?*windows.SECURITY_ATTRIBUTES,
lInitialCount: windows.LONG,
lMaximumCount: windows.LONG,
lpName: ?windows.LPCWSTR,
) callconv(windows.WINAPI) windows.HANDLE;
extern "user32" fn GetProcessWindowStation() callconv(windows.WINAPI) ?windows.HANDLE;
extern "user32" fn GetThreadDesktop(
dwThreadId: windows.DWORD,
) callconv(windows.WINAPI) ?windows.HANDLE;
extern "user32" fn CreateDesktopW(
lpszDesktop: windows.LPCWSTR,
Device: ?windows.LPCWSTR,
Devmode: ?windows.PVOID,
Flags: windows.DWORD,
DesiredAccess: windows.ACCESS_MASK,
sa: ?*windows.SECURITY_ATTRIBUTES,
) callconv(windows.WINAPI) ?windows.HANDLE;
extern "user32" fn CloseDesktop(
hDesk: windows.HANDLE,
) callconv(windows.WINAPI) windows.BOOL;
extern "kernel32" fn CreateMutexW(
lpMutexAttributes: ?*windows.SECURITY_ATTRIBUTES,
InitialOwner: windows.BOOL,
Name: ?windows.LPCWSTR,
) callconv(windows.WINAPI) ?windows.HANDLE;
fn printTypeAndName(writer: anytype, handle: windows.HANDLE) !void {
var retlen: windows.ULONG = undefined;
switch (ntdll.NtQueryObject(
handle,
.ObjectTypeInformation,
&type_buf,
1024,
&retlen,
)) {
.SUCCESS => {},
.BUFFER_TOO_SMALL => unreachable,
.INFO_LENGTH_MISMATCH => unreachable,
else => |e| return windows.unexpectedStatus(e),
}
const type_info: *OBJECT_TYPE_INFORMATION = @ptrCast(&type_buf);
try writer.print(
"{}\t",
.{std.unicode.fmtUtf16Le(type_info.TypeName.Buffer.?[0 .. type_info.TypeName.Length / @sizeOf(u16)])},
);
switch (ntdll.NtQueryObject(
handle,
.ObjectNameInformation,
&name_buf,
name_buf.len,
&retlen,
)) {
.SUCCESS => {},
.BUFFER_TOO_SMALL => unreachable,
.INFO_LENGTH_MISMATCH => unreachable,
.OBJECT_PATH_INVALID => try writer.writeAll("<error>\n"),
else => |e| return windows.unexpectedStatus(e),
}
const name_info: *windows.OBJECT_NAME_INFORMATION = @ptrCast(&name_buf);
if (name_info.Name.Length > 0) {
const str = name_info.Name.Buffer.?[0 .. name_info.Name.Length / @sizeOf(u16)];
try writer.print(
"{}\n",
.{std.unicode.fmtUtf16Le(str)},
);
name_info.Name.Length = 0;
} else {
try writer.writeAll("<empty>\n");
}
}
pub fn main() !void {
const stdout = std.io.getStdOut();
var buf_writer = std.io.bufferedWriter(stdout.writer());
const writer = buf_writer.writer();
try writer.writeAll("Type\tName\n");
var sattr = windows.SECURITY_ATTRIBUTES{
.nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
.bInheritHandle = 1,
.lpSecurityDescriptor = null,
};
// File
{
var dir = std.testing.tmpDir(.{});
defer dir.cleanup();
const f = try dir.dir.createFile("file", .{});
defer f.close();
try printTypeAndName(writer, dir.dir.fd);
try printTypeAndName(writer, f.handle);
}
// Directory
{
const name = blk: {
const str = L("\\BaseNamedObjects\\test-dir");
const len: u16 = @intCast(str.len * @sizeOf(u16));
break :blk windows.UNICODE_STRING{
.Buffer = @constCast(str),
.Length = len,
.MaximumLength = len,
};
};
var handle: windows.HANDLE = undefined;
var attrs = windows.OBJECT_ATTRIBUTES{
.Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
.RootDirectory = null,
.Attributes = 0,
.ObjectName = @constCast(&name),
.SecurityDescriptor = null,
.SecurityQualityOfService = null,
};
switch (NtCreateDirectoryObject(
&handle,
windows.STANDARD_RIGHTS_REQUIRED | 0xf,
&attrs,
)) {
.SUCCESS => {},
else => |e| return windows.unexpectedStatus(e),
}
defer windows.CloseHandle(handle);
try printTypeAndName(writer, handle);
}
// Named Pipe
{
const handle = windows.kernel32.CreateNamedPipeW(
L("\\\\.\\pipe\\test-pipe"),
windows.PIPE_ACCESS_INBOUND | windows.FILE_FLAG_OVERLAPPED,
windows.PIPE_TYPE_BYTE,
1,
4096,
4096,
0,
&sattr,
);
if (handle == windows.INVALID_HANDLE_VALUE)
return windows.unexpectedError(windows.kernel32.GetLastError());
defer windows.CloseHandle(handle);
try printTypeAndName(writer, handle);
}
// Mailslot
{
const handle = CreateMailslotW(
L("\\\\.\\mailslot\\test-slot"),
0,
std.math.maxInt(windows.DWORD),
&sattr,
);
if (handle == windows.INVALID_HANDLE_VALUE)
return windows.unexpectedError(windows.kernel32.GetLastError());
defer windows.CloseHandle(handle);
try printTypeAndName(writer, handle);
}
// Semaphore
{
const handle = CreateSemaphoreW(
&sattr,
1,
2,
L("test-sema"),
);
if (handle == windows.INVALID_HANDLE_VALUE)
return windows.unexpectedError(windows.kernel32.GetLastError());
defer windows.CloseHandle(handle);
try printTypeAndName(writer, handle);
}
// WindowStation
{
const handle = GetProcessWindowStation();
if (handle == null)
return windows.unexpectedError(windows.kernel32.GetLastError());
try printTypeAndName(writer, handle.?);
}
// Desktop
{
const handle = GetThreadDesktop(windows.GetCurrentThreadId());
if (handle == null)
return windows.unexpectedError(windows.kernel32.GetLastError());
try printTypeAndName(writer, handle.?);
}
{
const handle = CreateDesktopW(
L("test-desktop"),
null,
null,
0,
2,
&sattr,
);
if (handle == null)
return windows.unexpectedError(windows.kernel32.GetLastError());
defer _ = CloseDesktop(handle.?);
try printTypeAndName(writer, handle.?);
}
// Mutant
{
const handle = CreateMutexW(null, 1, L("test-mutant"));
if (handle == null)
return windows.unexpectedError(windows.kernel32.GetLastError());
defer windows.CloseHandle(handle.?);
try printTypeAndName(writer, handle.?);
}
try buf_writer.flush();
}
Type Name
File \Device\HarddiskVolume9\gits\objectnames\zig-cache\tmp\M7HLirYDZKkk0lm1
File \Device\HarddiskVolume9\gits\objectnames\zig-cache\tmp\M7HLirYDZKkk0lm1\file
Directory \BaseNamedObjects\test-dir
File \Device\NamedPipe\test-pipe
File \Device\Mailslot\test-slot
Semaphore \Sessions\1\BaseNamedObjects\test-sema
WindowStation \Sessions\1\Windows\WindowStations\WinSta0
Desktop \Default
Desktop \test-desktop
Mutant \Sessions\1\BaseNamedObjects\test-mutant
Type Name
File \??\Z:\tmp\foo\zig-cache\tmp\0c01xDGgKmGDNVjp
File \??\Z:\tmp\foo\zig-cache\tmp\0c01xDGgKmGDNVjp\file
Directory \BaseNamedObjects\test-dir
File \Device\NamedPipe\test-pipe
File \Device\MailSlot\test-slot
Semaphore \Sessions\1\BaseNamedObjects\test-sema
WindowStation \Sessions\1\Windows\WindowStations\WinSta0
Desktop \Default
Desktop \test-desktop
Mutant \Sessions\1\BaseNamedObjects\test-mutant
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment