Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 使用windows CryptoUnprotectData使FFI生锈_Winapi_Rust_Ffi - Fatal编程技术网

Winapi 使用windows CryptoUnprotectData使FFI生锈

Winapi 使用windows CryptoUnprotectData使FFI生锈,winapi,rust,ffi,Winapi,Rust,Ffi,我试图从一些简单的东西开始学习FFI(并且有实际用途),但这似乎不起作用: mod绑定{ ::windows::包括_绑定!(); } 使用std::{convert::TryFrom,ptr}; 使用绑定::{ windows::win32::security::CryptUnprotectData, windows::win32::security::CRYPTOAPI\u BLOB }; //用于生成令牌的Powershell代码 //$pw=读取主机“输入令牌”-AsSecureStri

我试图从一些简单的东西开始学习FFI(并且有实际用途),但这似乎不起作用:

mod绑定{
::windows::包括_绑定!();
}
使用std::{convert::TryFrom,ptr};
使用绑定::{
windows::win32::security::CryptUnprotectData,
windows::win32::security::CRYPTOAPI\u BLOB
};
//用于生成令牌的Powershell代码
//$pw=读取主机“输入令牌”-AsSecureString
//从SecureString$pw转换
fn main()->windows::Result{
//加密字符串为“foobar”
让加密的\u令牌="01000000D08C9DDF0115D1118C7A00C04FC297EB01000000C336DCA1C99B7D40AE3F797C2B5D2951000000000001066000000010000200000007A87D6AC2FC8037EF45E3DBCB0B652432A22A9B48FC5FA3E4FCFD9AF92294900000000E800000002000020000200000EEAA76A44B6CD5DA837F4B070DE795ED846ABE27F27D2365D00CF8CF8C10000CF802ABE7F27F2365D8AD780CF80808AF802f1e7b8a54c6ad89ff57f0ee3d8c51ecd8c5b48e99b58d0e738c9fae9fc41b4280938865a047f2724106d34313c88a0f3852d5ba9d75abfd”;
让mut et_bytes=hex::decode(加密的_令牌).unwrap();
让size=u32::try_from(et_bytes.len()).unwrap();
让mut decrypted=vec![0u8;et_bytes.len();
让dt_字节=&mut解密;
让mut p_data_in=CRYPTOAPI_BLOB{
cb_数据:大小,
pb_数据:et_字节。as_mut_ptr(),
};
让mut p_data_out=CRYPTOAPI_BLOB{
cb_数据:大小,
pb_数据:dt_字节。as_mut_ptr(),
};
设pin=&mut p_data_in;
let pout=&mut p_data_out;
不安全{
let result=CryptUnprotectData(
别针,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
0,
噘嘴
);
println!(“{:?},{:?}”,dt_字节,结果);
}
好(())
}
基本上,它返回全零数组,但CryptUnprotectData的结果返回1,根据文档,这意味着成功:

我已通过尝试破坏十六进制字符串来验证这一点,从而破坏加密数据,导致其返回0。我不确定它是否写入了错误的位置或其他内容,但成功条件可能意味着它写入了某个位置。

API为您分配了输出缓冲区。它不会写入您提供的缓冲区。这就是为什么不管API调用的结果如何,都会不断获取原始数据

相反,您需要传入一个(默认初始化的)
CRYPTOAPI\u BLOB
结构,并观察API传回的值,如下所示:

fn main()->windows::Result{
//加密字符串为“foobar”
让加密的_令牌=”01000000D08C9DDF0115D1118C7A00C04FC297EB01000000C336DCA1C99B7D40AE3F797C2B5D2951000000000001066000000010000200000007A87D6AC2FC8037EF45E3DBCB0B652432A22A9B48FC5FA3E4FCFD9AF92294900000000E800000002000020000200000EEAA76A44B6CD5DA837F4B070DE795ED846ABE27F27D2365D00CF8CF8C10000CF802ABE7F27F2365D8AD780CF80808AF802f1e7b8a54c6ad89ff57f0ee3d8c51ecd8c5b48e99b58d0e738c9fae9fc41b4280938865a047f2724106d34313c88a0f3852d5ba9d75abfd”;
让mut et_bytes=hex::decode(加密的_令牌).unwrap();
让size=u32::try_from(et_bytes.len()).unwrap();
让mut p_data_in=CRYPTOAPI_BLOB{
cb_数据:大小,
pb_数据:et_字节。as_mut_ptr(),
};
//默认初始化;不分配任何内存
让mut p_data_out=CRYPTOAPI_BLOB::default();
设pin=&mut p_data_in;
let pout=&mut p_data_out;
不安全{
let result=CryptUnprotectData(
别针,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
0,
噘嘴
);
//也许可以忽略结果`
if!p_data_out.pb_data.is_null(){
//从返回的数据构造一个切片
让输出=来自原始零件(p_数据_out.pb_数据,p_数据_out.cb_数据为u);
println!(“{:?}”,输出);
//清理
LocalFree(p_data_out.pb_data as_);
}
好(())
}
为我生成以下输出:

这是
foobar
的UTF-16LE编码



请注意,您需要生成并导入
windows::win32::system\u services::LocalFree
以执行清理。

我认为最后一个参数应该是
DATA\u BLOB
变量的地址,该变量在成功返回时接收解密的数据。提示出现在参数描述中,其中指出您需要o使用
LocalFree
释放存储。该库可以在两个方面得到改进:错误报告和灵活性。调用
到\u string\u lossy()
实际上应该被调用
到\u string()代替
,并传播错误信息。否则,
解密
将报告成功,即使输入不符合预期,也会在以后导致错误,不再指向根本原因。库的接口应基于
和[u8]
slices。CryptoAPI是以字节为单位运行的,而这个库只支持某些字节序列,这不适当地限制了它的实用性。请不要编辑您的问题来添加答案。相反,您可以回答自己的问题,甚至可以接受您最喜欢的答案。起初我试图回答自己的问题,但stackexchange说我可以没有足够的分数来回答我自己的问题或类似的问题。在看到你的问题之前,我碰巧意外地发现了一个我自己的解决方案,尽管我仍然不清楚我的解决方案是如何与我的相同的,只是更详细、更昂贵,并且内存泄漏。如果你需要作为
字符串的结果,你可以打开将de>&[u8]
转换为
&[u16]
,并将其从UTF-16转换为UTF-8。无论您做什么,都需要清理内存
[102, 0, 111, 0, 111, 0, 98, 0, 97, 0, 114, 0]