Где в коде он находит наш ключ?
Используя Process Monitor, копаясь в для события ETL, считывающего, что трассировка стека значений дает нам:
"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"
Мы можем видеть, что OSKSettingsManager::GetOskSetting
считывает значение.
Итак, как выглядит эта часть? Можем ли мы отладить это?
Рассматривая эту функцию с помощью WinDBG, он получает доступ к этому разделу реестра прямо перед этим 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]
...
Теперь проблема в том, что когда я пытаюсь установить точку останова в этом месте, я больше не могу ничего печатать, потому что osk.exe
добавляется в драйверы ввода. Это легко увидеть, удерживая клавишу-модификатор, как Altна клавиатуре, и она загорается osk.exe
.
Просматривая код для дополнений или вычитаний, я вижу только то, что происходит с 40
шестнадцатеричным, который является 64
десятичным. Так что это тоже ничего не связано с числом.
Это может быть в одной из четырех cmp
(сравнить) инструкций, но для этого потребуется отладочная информация. Или это может произойти в целом с более высокой функцией, что потребует более тщательного изучения. Но без возможности отладки без потери возможностей ввода это очень сложно сделать ...
Похоже, что для поиска правильного места потребуется кабель отладки, поскольку компьютер, на котором вы отлаживаете, теряет свои возможности ввода или слишком медленный из-за накладных расходов на отладку. Поскольку в настоящее время у меня нет ноутбука с портом 1943 года, я не могу выполнить эту отладку самостоятельно. Он мог бы сделать это, и да, он буквально заморозил бы вашу ОС. Отладка ОС вместо приложения - это весело ... ^^
Подождите, у нас есть доступ к символам! Можем ли мы найти нарушающий код?
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)
Присмотревшись, вы заметите оскорбительную функцию:
OSKSettingsManager::_KeepSettingValueInBounds(ulong,ulong *,int)
Если мы пройдемся по этой функции, то сначала увидим:
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
Хорошо, это сравнивает что-то, а затем переходит в другое место. Что там?
pop ebp
retn 8
Таким образом, если условие решит, что оно должно перейти, оно просто выйдет из функции и ничего не изменит.
Итак, как мы можем заставить его всегда выходить из функции?
Измените jz
инструкцию на jmp
инструкцию, которая всегда выполняет переход, вы можете найти ее с относительным смещением 41BC10
. Если ваша программа рассчитывает разные смещения, вам нужно знать, что она использует 401000
в качестве основы, поэтому вычитание дает нам абсолютное смещение1AC10
.
Обратите внимание, что изменение 74
( JZ
) в шестнадцатеричном редакторе на E9
( JMP
) не будет работать. Вы не можете сделать это в шестнадцатеричном редакторе, вам нужно что-то, что разбирает и повторно собирает код, но это не обязательно легко найти (например, IDA Professional, за который люди фактически платят, не может произвести надлежащий код на c или исполняемый файл). OllyDBG, обычно используемая в сообществе патчей, не может даже открыть исполняемый файл.). И даже тогда, Microsoft может защищать свой исполняемый файл от несанкционированного доступа, потому что это может быть рассмотрено против EULA; удачи!
Мех! Это сложно, я просто хочу быстро набрать мышью / глазами / ...
Вы обязательно должны проверить Dasher, который намного быстрее, чем экранная клавиатура. Это просто работает, перемещая вашу мышь к буквам; Горизонтальное движение определяет скорость, а вертикальное движение выбирают буквы. Благодаря встроенному словарю он может даже определять размеры наиболее вероятных букв, он также пытается учиться на ваших движениях, чтобы скорость и буквы действительно привыкли к вашему использованию.
Изображение говорит более тысячи слов ...
Конечно, это довольно мало и не очень быстро, как в примере, но вы можете изменить его размер, чтобы он находился с правой стороны экрана, чтобы он не мешал вашему экрану. Это позволяет печатать так быстро, как вы можете ...
Вот хороший пример того, как прогнозы позволяют быстрее набирать любой язык:
Также обратите внимание, что буквы справа сортируются в определенном порядке, так что основное направление (вверх, в середине или вниз) выбирает между различными типами (строчные, прописные, цифры и знаки пунктуации); и затем в пределах такого основного направления ваше второстепенное направление будет выбирать между AZ, az, 0-9 и так далее. Я использовал это в прошлом и был действительно удивлен тем, насколько свободно это по сравнению с другими конкурентами ...
Также обратите внимание, что Dasher имеет некоторую конфигурацию, так что вы можете настроить то, что вам не нравится.