Gdzie w kodzie znajduje się nasz klucz?
Korzystając z Monitora procesów, zagłębianie się w zdarzenie ETL odczytujące ślad stosu wartości daje nam:
"Frame","Module","Location","Address","Path"
...
"3","ntdll.dll","NtQueryValueKey + 0xa","0x7fbce17344a","C:\Windows\SYSTEM32\ntdll.dll"
"4","KERNELBASE.dll","LocalBaseRegQueryValue + 0x15d","0x7fbcb1a3e1d","C:\Windows\system32\KERNELBASE.dll"
"5","KERNELBASE.dll","RegQueryValueExW + 0xe9","0x7fbcb1a3c19","C:\Windows\system32\KERNELBASE.dll"
"6","ADVAPI32.dll","RegQueryValueExWStub + 0x1e","0x7fbcba412fe","C:\Windows\system32\ADVAPI32.dll"
"7","osk.exe","OSKSettingsManager::GetOskSetting + 0xc7","0x7f72356057f","C:\Windows\System32\osk.exe"
"8","osk.exe","OSKSettingsManager::Initialize + 0x6e","0x7f72355ffe2","C:\Windows\System32\osk.exe"
"9","osk.exe","OSKSettingsManager::GetOSKSettingsManager + 0x64","0x7f72355fee4","C:\Windows\System32\osk.exe"
"10","osk.exe","COskNativeHWNDHost::DetermineOSKWindowSizeAndLimits + 0x5a","0x7f72355d4fa","C:\Windows\System32\osk.exe"
"11","osk.exe","COskNativeHWNDHost::Initialize + 0xaa","0x7f72355d28e","C:\Windows\System32\osk.exe"
"12","osk.exe","PresentOSK + 0x112","0x7f723557882","C:\Windows\System32\osk.exe"
"13","osk.exe","wWinMain + 0x356","0x7f723557f16","C:\Windows\System32\osk.exe"
"14","osk.exe","operator new[] + 0x37a","0x7f723564b12","C:\Windows\System32\osk.exe"
"15","KERNEL32.DLL","BaseThreadInitThunk + 0x1a","0x7fbcd24298e","C:\Windows\system32\KERNEL32.DLL"
"16","ntdll.dll","RtlUserThreadStart + 0x1d","0x7fbce19e229","C:\Windows\SYSTEM32\ntdll.dll"
Widzimy, że OSKSettingsManager::GetOskSetting
odczytuje wartość.
Jak więc wygląda ta część? Czy możemy to debugować?
Patrząc na tę funkcję w WinDBG, uzyskuje dostęp do tego klucza rejestru już wcześniej 000007f7 23560517
.
osk!OSKSettingsManager::GetOskSetting:
...
000007f7`2356050e ff15440bfeff call qword ptr [osk!_imp_RegOpenKeyExW (000007f7`23541058)]
000007f7`23560514 448bd8 mov r11d,eax
000007f7`23560517 85c0 test eax,eax
000007f7`23560519 751f jne osk!OSKSettingsManager::GetOskSetting+0x82 (000007f7`2356053a)
000007f7`2356051b 488b0b mov rcx,qword ptr [rbx]
...
Problem polega na tym, że kiedy próbuję dokonać punktu przerwania w tej lokalizacji, nie mogę już nic pisać, ponieważ osk.exe
dodaje się do sterowników wejściowych. Można to łatwo zauważyć, przytrzymując klawisz modyfikujący Altna klawiaturze, co powoduje jego podświetlenie osk.exe
.
Przeglądając kod dodawania lub odejmowania, widzę tylko, że coś się dzieje z wartością 40
szesnastkową, która jest 64
dziesiętna. To też nie ma nic wspólnego z liczbą.
Może to być jedna z czterech cmp
instrukcji (porównaj), ale wymagałoby to informacji o debugowaniu. Może się to zdarzyć w przypadku funkcji wyższego poziomu, co wymagałoby więcej badań. Ale bez możliwości debugowania bez utraty możliwości wprowadzania danych jest to bardzo trudne ...
Wydaje się, że znalezienie właściwej lokalizacji będzie wymagało kabla debugowania, ponieważ komputer, na którym debugujesz, traci możliwości wprowadzania danych lub jest zbyt wolny z powodu obciążenia związanego z debugowaniem. Ponieważ obecnie nie mam laptopa z portem z 1943 r., Nie jestem w stanie samodzielnie przeprowadzić debugowania. Byłby w stanie to zrobić i tak, dosłownie zawiesiłby twój system operacyjny. Debugowanie systemu operacyjnego zamiast aplikacji jest fajne ... ^^
Czekaj, mamy dostęp do symboli! Czy możemy znaleźć obrażający kod?
OSKSettingsManager::ClearTransferKey(void)
OSKSettingsManager::GetOSKSettingsManager(OSKSettingsManager * *)
OSKSettingsManager::GetOskSetting(ulong,ulong *)
OSKSettingsManager::GetOskSetting(ulong,ulong *,int)
OSKSettingsManager::Initialize(void)
OSKSettingsManager::NotifyListeners(ulong,ulong)
OSKSettingsManager::RegisterListener(void (*)(ulong,ulong))
OSKSettingsManager::SQMStartupSettings(void)
OSKSettingsManager::SetOskSetting(ulong,ulong)
OSKSettingsManager::SetOskSetting(ulong,ulong,int)
OSKSettingsManager::_HandleUpdateAllListeners(void)
OSKSettingsManager::_KeepSettingValueInBounds(ulong,ulong *,int)
OSKSettingsManager::`scalar deleting destructor'(uint)
Przy bliższym przyjrzeniu zauważysz funkcję obrażającą:
OSKSettingsManager::_KeepSettingValueInBounds(ulong,ulong *,int)
Jeśli przejdziemy przez tę funkcję, najpierw zobaczymy:
mov edi, edi
push ebp
mov ebp, esp
mov eax, [ebp+arg_4]
imul eax, 14h
cmp dword_4B7598[eax], 0
jz short loc_41BC36
Ok, to coś porównuje, a następnie przeskakuje w inne miejsce. Co tam jest?
pop ebp
retn 8
Więc jeśli warunek zdecyduje, że musi skoczyć, po prostu opuści funkcję i niczego nie zmieni.
Jak więc sprawić, że zawsze opuszcza funkcję?
Zmień jz
instrukcję na jmp
instrukcję, która zawsze wykonuje skok, można ją znaleźć z względnym przesunięciem 41BC10
. Jeśli Twój program oblicza różne przesunięcia, musisz wiedzieć, że używa ich 401000
jako podstawy, więc odjęcie daje nam absolutne przesunięcie 1AC10
.
Pamiętaj, że zmiana 74
( JZ
) w edytorze szesnastkowym na E9
( JMP
) nie będzie działać. Nie możesz tego zrobić w edytorze szesnastkowym, potrzebujesz czegoś, co deasembluje i ponownie składa kod, ale niekoniecznie jest łatwe do znalezienia (np. IDA Professional, za które ludzie faktycznie płacą, nie może wytworzyć odpowiedniego kodu c lub pliku wykonywalnego. OllyDBG, często używany w społeczności łatek, nie może nawet otworzyć pliku wykonywalnego.). A nawet Microsoft może chronić swój plik wykonywalny przed manipulacją, ponieważ można to rozważyć w kontekście umowy EULA; więc powodzenia!
Meh! To trudne, chcę tylko szybko pisać za pomocą myszy / oczu / ...
Zdecydowanie powinieneś sprawdzić Dasher, który jest znacznie szybszy niż klawiatura ekranowa. Po prostu działa, przesuwając mysz w kierunku liter; ruch poziomy określa prędkość, a ruch pionowy wybierz litery. Dzięki wbudowanemu słownikowi można nawet dopasować wielkość liter, które mogą być większe, stara się także uczyć na podstawie ruchu, tak aby szybkość i litery były naprawdę przyzwyczajone do użycia.
Obraz mówi więcej niż tysiąc słów ...
Oczywiście jest to raczej niewielkie i niezbyt szybkie, ponieważ jest to przykład, ale można zmienić jego rozmiar, aby znajdował się po prawej stronie ekranu, aby nie zakłócał ekranu. Dzięki temu możesz pisać tak szybko, jak to możliwe ...
Oto dobry przykład tego, jak podpowiedzi pozwalają szybciej pisać dowolny język:
Należy również pamiętać, że litery po prawej stronie są sortowane w określonej kolejności, tak że główny kierunek (góra, środek lub dół) wybiera pomiędzy różnymi typami (małe litery, wielkie litery, cyfry i znaki interpunkcyjne); a następnie w tak dużym kierunku, twój mniejszy kierunek wybierze między AZ, az, 0-9 i tak dalej. Korzystałem z tego w przeszłości i byłem naprawdę zaskoczony, jak płynnie jest to porównywane z innymi konkurentami ...
Pamiętaj też, że Dasher ma pewną konfigurację, więc możesz dostosować coś, co ci się nie podoba.