Closed BeneficialCode closed 1 year ago
Can you paste the contents of your ktrace.d file?
#pragma D option quiet
#pragma D option destructive
struct ustr{uint16_t buffer[256];};
inline uintptr_t MmHighestUserAddress = 0x7FFFFFFEFFFF;
int found;
PETHREAD ethread_ptr;
BEGIN
{
found = 0;
ethread_ptr=0;
}
syscall::Nt*:entry
{
if (probefunc == "NtQueryValueKey")
{
temp = ((PUNICODE_STRING)arg1)->Buffer;
len = ((PUNICODE_STRING)arg1)->Length / 2;
printf("%Y: 0x%p value name: %*ws\n", walltimestamp, curthread, len,
((struct ustr*)temp)->buffer);
}
}
What do you mean by "error string on the command"? I see the same output with both %*ws
and %.*ws
std::wstring a(L"\\Device\\HarddiskVolume3\\Windows\\System32\\notepad.exe1111111");
std::cout << a.length() << std::endl;
printf("%*ws\n",52, a.c_str());
printf("%.*ws\n", 52, a.c_str());
You can test the C code. Then you will know the bug. You know the unicode_string might not be null terminated.
@BeneficialCode , perhaps using wstr2str could be an option you can consider
The C code will show the difference between the %ws and %.ws. What do you mean by "using wstr2str"?
@BeneficialCode You are right, that needs to be fixed as the unicode string might not be null terminated. I will fix that in the examples that we provide.
The other option is to use wstr2str. Here is a D-script corresponding to the one you provided which using wstr2str()
and has other improvements as well:
#pragma D option quiet
syscall::NtQueryValueKey:entry
{
this->us = (userland PUNICODE_STRING)args[1];
this->val = wstr2str((wchar_t*)copyin((uintptr_t)this->us->Buffer, this->us->Length), this->us->Length/2);
printf("%Y: 0x%p value name: %s\n", walltimestamp, curthread, this->val);
}
We should use
%*.*ws
or%.*ws
to printf unicode string. If we use %*ws, the format will cause error string on the command.