Last active
May 13, 2024 12:58
-
-
Save The-King-of-Toasters/675d7512d5c03a083e34a7dc0d3f89d0 to your computer and use it in GitHub Desktop.
NT Object Name Mismatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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