66 lines
3.5 KiB
C++
66 lines
3.5 KiB
C++
// Standalone attribution probe. No clipboard, registry or user input mutations.
|
|
#include <windows.h>
|
|
#include <shlobj.h>
|
|
#include <propkey.h>
|
|
#include <propvarutil.h>
|
|
#include <uiautomation.h>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
|
|
static void check(HRESULT hr) {
|
|
if (FAILED(hr)) { fprintf(stderr,"HRESULT=%08lx\n",(unsigned long)hr); exit(2); }
|
|
}
|
|
static void phase(const char *name) {
|
|
printf("%s\n",name); fflush(stdout);
|
|
if (getchar()==EOF) exit(3);
|
|
}
|
|
int main(int argc,char **argv) {
|
|
const char *mode=argc>1?argv[1]:"baseline";
|
|
const bool baseline=!strcmp(mode,"baseline");
|
|
const bool shell=!strcmp(mode,"shell") || !strcmp(mode,"combined");
|
|
const bool uia=!strcmp(mode,"uia") || !strcmp(mode,"focused") || !strcmp(mode,"combined");
|
|
phase("baseline");
|
|
if(!baseline) check(CoInitializeEx(nullptr,!strcmp(mode,"sta") || shell ? COINIT_APARTMENTTHREADED : COINIT_MULTITHREADED));
|
|
phase("com");
|
|
IShellLinkW *link{}; IPropertyStore *store{}; IPersistFile *file{};
|
|
IUIAutomation2 *automation{}; IUIAutomationElement *element{}; IUIAutomationTextPattern *pattern{};
|
|
wchar_t temporary[MAX_PATH]{},shortcut[MAX_PATH]{},exe[MAX_PATH]{};
|
|
if(shell) {
|
|
check(CoCreateInstance(CLSID_ShellLink,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&link)));
|
|
GetModuleFileNameW(nullptr,exe,MAX_PATH);
|
|
check(link->SetPath(exe)); check(link->SetIconLocation(exe,0));
|
|
check(link->QueryInterface(IID_PPV_ARGS(&store)));
|
|
PROPVARIANT value{}; check(InitPropVariantFromString(L"KSwitcher.MemoryProbe",&value));
|
|
check(store->SetValue(PKEY_AppUserModel_ID,value)); PropVariantClear(&value);
|
|
GUID id{0xe3f78047,0xf0ad,0x49b6,{0x90,0x74,0x41,0x19,0x31,0x70,0x61,0x67}};
|
|
value.vt=VT_CLSID; value.puuid=&id;
|
|
check(store->SetValue(PKEY_AppUserModel_ToastActivatorCLSID,value)); check(store->Commit());
|
|
PWSTR programs{}; check(SHGetKnownFolderPath(FOLDERID_Programs,0,nullptr,&programs)); CoTaskMemFree(programs);
|
|
GetTempPathW(MAX_PATH,temporary); if(!GetTempFileNameW(temporary,L"ksm",0,shortcut)) return 4;
|
|
check(link->QueryInterface(IID_PPV_ARGS(&file))); check(file->Save(shortcut,TRUE));
|
|
}
|
|
if(uia) {
|
|
check(CoCreateInstance(CLSID_CUIAutomation8,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&automation)));
|
|
check(automation->put_ConnectionTimeout(200)); check(automation->put_TransactionTimeout(200));
|
|
if(strcmp(mode,"uia")) {
|
|
HRESULT focused=automation->GetFocusedElement(&element);
|
|
fprintf(stderr,"focus=%08lx\n",(unsigned long)focused);
|
|
if(SUCCEEDED(focused) && element) {
|
|
BOOL password=TRUE,enabled=FALSE; CONTROLTYPEID type{};
|
|
element->get_CurrentIsPassword(&password); element->get_CurrentIsEnabled(&enabled); element->get_CurrentControlType(&type);
|
|
fprintf(stderr,"type=%d enabled=%d protected=%d\n",type,enabled,password);
|
|
if(!password) fprintf(stderr,"pattern=%08lx\n",(unsigned long)element->GetCurrentPatternAs(UIA_TextPatternId,IID_PPV_ARGS(&pattern)));
|
|
}
|
|
}
|
|
}
|
|
phase("active");
|
|
if(pattern) pattern->Release(); if(element) element->Release(); if(automation) automation->Release();
|
|
if(file) file->Release(); if(store) store->Release(); if(link) link->Release();
|
|
if(shortcut[0]) DeleteFileW(shortcut);
|
|
phase("released");
|
|
if(!baseline) { CoFreeUnusedLibrariesEx(0,0); CoUninitialize(); }
|
|
phase("uninitialized");
|
|
return 0;
|
|
}
|