我没有成功地让以下代码片段输出“Hello World!”在PS7中
$string = $("Hello World!" | ConvertTo-SecureString -AsPlainText -Force)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($string))
上面的代码是解密不指定长度的安全字符串的示例。
相同的代码可以在 PS6 和 PS5 中工作以完全解密安全字符串,但在 PS7 中不起作用。我发现解决这个问题的唯一方法是使用 PtrToStringBSTR。然后,对于该用例,它可以在所有 PS 版本中按预期工作。
我在 Github 上的 Powershell 存储库中提出了问题,但尚未得到任何回复。老实说,我只是在寻找一些证据来证明这种行为对于其他人来说是一样的。
https://github.com/PowerShell/PowerShell/issues/11953 https://github.com/PowerShell/PowerShell/issues/11953
我认为这样的事情对于移植到 PS7 的大量代码来说将是一个重大改变。
这是我到目前为止发现的:
文档
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.ptrtostringauto?view=netframework-4.8 https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.ptrtostringauto?view=netframework-4.8
根据文档,当指定整数时,PtrToStringAuto:
Allocates a managed String and copies the specified number of characters from a string stored in unmanaged memory into it.
指定 int 11 返回“Hello”,这是因为返回的所有其他字符均为 Null。在这种情况下,您必须指定 int 23 才能返回完整的字符串“Hello World!”使用这种方法。我已将输出存储在变量中来演示这一点。
$String = $("Hello World!" | ConvertTo-SecureString -AsPlainText -Force)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($string), 23)
$String[0] Returns H
$String[1] Returns NULL
$String[2] Returns E
$String[3] Returns NULL
etc....
如果未指定整数,则 PtrToStringAuto:
Allocates a managed String and copies all characters up to the first null character from a string stored in unmanaged memory into it.
我相信这表明要么安全字符串是用 NULL 值存储的,而在 PS6 中不是,要么 PtrToStringAuto 函数的行为已经改变,现在遵循上面文档描述的行为。
这只是 macOS 上的问题;但是,使用 PtrToStringBSTR 代替 PtrToStringAuto 来解密安全字符串可以在 Windows 和 macOS 上按预期工作。
这似乎相关:https://stackoverflow.com/a/11022662/4257163 https://stackoverflow.com/a/11022662/4257163
我也没有看到任何地方发生了变化。