2个版本
0.1.1 | 2023年6月13日 |
---|---|
0.1.0 | 2023年5月31日 |
#52 in Windows APIs
8,374 monthly downloads
用于 7 个crate(3个直接)
82KB
1K SLoC
nt-string
由 Colin Finck <[email protected]>
为各种Windows字符串类型提供惯用的Rust实现
NtUnicodeString
(包括NtUnicodeStr
和NtUnicodeStrMut
):用于与Windows内核字符串类型UNICODE_STRING
进行接口U16StrLe
:用于处理UTF-16(小端)字符串的字节切片
其他有用的UTF-16字符串类型已由优秀的 widestring
crate 提供。这个crate试图尽可能地与它们集成。
使用示例
在WinDbg中调试Rust应用程序并使用 dS
命令来显示在Rust中创建的 UNICODE_STRING
。如您所见,这个crate的 NtUnicodeString
和原始的 UNICODE_STRING
完全兼容。
详细信息
UNICODE_STRING
类型是为C编程语言设计的,该语言只知道NUL终止的字符缓冲区。为了确定缓冲区的长度,需要遍历所有字符直到找到NUL。这还不够糟吗?更糟的是,如果一个缓冲区没有NUL,但算法仍然尝试找到它,则会发生经典的缓冲区溢出。
为了克服这些性能和安全风险,UNICODE_STRING
由一个缓冲区、一个缓冲区容量(“最大长度”)以及一个表示实际使用长度的字段组成。现在确定长度和容量就像查询相应的字段一样简单。长度和容量是16位值,以字节为单位表示。
UNICODE_STRING
已被Windows内核团队广泛使用,并扩展到一些用户模式API。这个crate使UNICODE_STRING
成为Rust的第一类公民。通过以下措施实现安全性
UNICODE_STRING
被拆分为3个Rust类型,分别用于处理引用、可变引用和所有者字符串。你永远不需要调用一个unsafe
方法。- 所有方法都是可失败的(除了分配和像
Add
这样的特性,因为Rust目前没有提供可失败的选择)。 - 内部缓冲区在可能的情况下总是以NUL结尾。虽然根据规范不是必需的,但这种防御性的方法可以防止外部应用程序错误地将内部缓冲区作为NUL结尾的字符串处理。
此外,此crate还提供了U16StrLe
类型。由于UTF-16是Windows上无处不在的字符编码,许多磁盘上的字符串都是以UTF-16小端存储的。U16StrLe
允许在不将它们转换为其他字符串类型之前对这种字符串的字节切片执行基本操作。ntfs crate是它的一个用户。
示例
你可以像处理其他Rust字符串类型一样处理这些字符串类型
let mut string = NtUnicodeString::try_from("Hello! ").unwrap();
string.try_push_str("Moin!").unwrap();
println!("{string}");
也支持从原始的u16
字符串缓冲区以及widestring
crate中的U16CStr
和U16Str
类型转换
let abc = NtUnicodeString::try_from_u16(&[b'A' as u16, b'B' as u16, b'C' as u16]).unwrap();
let de = NtUnicodeString::try_from_u16_until_nul(&[b'D' as u16, b'E' as u16, 0]).unwrap();
let fgh = NtUnicodeString::try_from(u16cstr!("FGH")).unwrap();
let ijk = NtUnicodeString::try_from(u16str!("IJK")).unwrap();
就像一个String
在传递给适当的函数时自动解引用到一个&str
一样,你可以用NtUnicodeString
做到同样的效果,它将解引用到&NtUnicodeStr
let string = NtUnicodeString::try_from("My String").unwrap();
subfunction(&string);
fn subfunction(str_ref: &NtUnicodeStr) {
println!("Hello from subfunction with \"{str_ref}\".");
}
可以在编译时创建常量UNICODE_STRING
。这提供了具有'static
生命周期的字符串,并在运行时节省了UTF-16转换
const MY_CONSTANT_STRING: NtUnicodeStr<'static> = nt_unicode_str!("My Constant String");
最后,你很可能想将你的NtUnicodeStr
、NtUnicodeStrMut
或NtUnicodeString
传递给一个期望一个指向UNICODE_STRING
指针的FFI函数。使用as_ptr
或as_mut_ptr
方法来获取不可变或可变指针。
no_std
支持
此crate与no_std
兼容,因此可以在所有上下文中使用。
但是,堆分配的NtUnicodeString
结构仅在alloc
功能(默认启用)下可用。如果你想在没有堆分配的纯no_std
环境中使用此crate,请使用default-features = false
来禁用默认的alloc
功能。
许可证
此crate的许可证为以下之一
您可选择。
除非您明确声明,否则您根据Apache-2.0许可证定义的任何有意提交以包含在作品中的贡献,将如上双许可,没有任何附加条款或条件。
依赖项
~0.8–1.2MB
~24K SLoC