Для современного антивируса обязателен драйвер. В Венде для использования произвольного языка не надо преодолевать формальности в виде пальца Линуса.Нашёл достаточно простой пример драйвера. devrandom driver sample which has been ported to Rust.
https://github.com/pravic/winapi-kmd-rs/blob/master/examples...
Оригинал на Си++ https://github.com/pravic/ontl/blob/master/samples/devrandom...
несколько больше по размеру, за счёт дополнительного функционала. Но интересно не это, а безопасная работа с памятью.
Вариант на небезопасном Си++ использует механизм структурной обработки исключений, если указатель Buffer адресует навалидный адрес, функция завершится корректно со статусом status::data_error.
ntstatus RandomData(void* Buffer, uint32_t Length)
{
int64_t seed;
KeQueryTickCount(seed);
__try{
uint32_t* data = reinterpret_cast<uint32_t*>(Buffer);
for(uint32_t i = 0; i < Length / 4; i++)
data[i] = RtlRandom((uint32_t*)&seed);
if(Length % 4){
uint32_t r = RtlRandom((uint32_t*)&seed);
std::memcpy(&data[Length/4], &r, Length % 4);
}
}__except(efilter(exception_info(), __FUNCTION__)){
return status::data_error;
}
return status::success;
}
Вопрос к знатокам: упадёт ли аналог в синьку, или Rust неявно использует SEH, или как-то иначе гарантируется валидность адреса?
// RtlRandom: Random number generator based on MacLaren and Marsaglia.
// RtlRandomEx is twice as fast and produces better random numbers
// since the period of the random numbers generated is comparatively higher.
fn GenerateRandom(buffer: PVOID, size: usize) -> Result<usize> {
let mut seed = km::time::QueryTickCount() as u32;
let data = buffer as *mut u32;
let dwords = size / 4;
let tail = size % 4;
KdPrint!("[rs] generate random for %d bytes as %d words and %d padding\n", size as u32, dwords as u32, tail as u32);
unsafe {
let mut i = 0;
while i < dwords {
let word = km::rtl::RtlRandomEx(&mut seed);
*data.offset(i as isize) = word;
i += 1;
}
if tail != 0 {
let word = km::rtl::RtlRandomEx(&mut seed);
km::crt::memcpy(data.offset(dwords as isize) as *mut u8, &word as *const u32 as *const u8, tail);
}
}
KdPrint!("[rs] generate complete\n");
return Ok(size);
}