Onde no código ele encontra nossa chave?
Usando o Process Monitor, pesquisar no evento ETL lendo esse rastreamento de pilha de valores nos fornece:
"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"
Podemos ver que OSKSettingsManager::GetOskSetting
lê o valor.
Então, como é essa parte? Podemos depurar?
Examinando essa função com o WinDBG, ele acessa a chave do registro logo antes 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]
...
Agora, o problema aqui é que, quando tento interromper nesse local, não consigo mais digitar nada, porque se osk.exe
adiciona aos drivers de entrada. Isso pode ser facilmente visto pressionando uma tecla modificadora, como Altno teclado, isso acende osk.exe
.
Olhando através do código para adições ou subtrações, só vejo algo acontecer com 40
hexadecimal, que é 64
decimal. Então, isso também não está relacionado ao número.
Pode estar em uma das quatro cmp
instruções (comparar), mas isso exigiria informações de depuração. Ou isso poderia acontecer em uma função superior, o que exigiria mais investigação. Mas sem a capacidade de depurá-lo sem perder os recursos de entrada, isso é algo muito difícil de fazer ...
Parece que encontrar o local correto exigirá um cabo de depuração, pois o computador no qual você depura perde seus recursos de entrada ou é muito lento devido à sobrecarga da depuração. Como atualmente não tenho um laptop com uma porta de 1943, não consigo fazer isso depurando sozinho. Seria capaz de fazer isso e, sim, literalmente congelaria seu sistema operacional. Depurar um SO em vez de um aplicativo é divertido ... ^^
Espere, temos acesso aos símbolos! Podemos encontrar o código incorreto?
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)
Olhando mais de perto, você notará a função ofensiva:
OSKSettingsManager::_KeepSettingValueInBounds(ulong,ulong *,int)
Se percorrermos essa função, veremos primeiro:
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, isso compara algo e depois pula para outro local. O que há?
pop ebp
retn 8
Portanto, se a condição decidir que deve pular, ela deixará a função e não mudará nada.
Então, como fazemos com que ela sempre saia da função?
Mude a jz
instrução para uma jmp
instrução que sempre salte; você pode encontrá-la em deslocamento relativo 41BC10
. Caso seu programa calcule deslocamentos diferentes, você precisa saber que ele usa 401000
como base, para subtrair nos fornece o deslocamento absoluto 1AC10
.
Observe que alterar 74
( JZ
) no editor hexadecimal para E9
( JMP
) não funcionará. Você não pode fazer isso em um editor hexadecimal, precisará de algo que desmonte e remonte o código, mas isso não é necessariamente fácil de encontrar (por exemplo, o IDA Professional pelo qual as pessoas realmente pagam, não podem produzir o código c ou um executável adequado. O OllyDBG, comumente usado na comunidade de patches, nem consegue abrir o executável.). E mesmo assim, a Microsoft pode estar protegendo seu executável contra adulteração, porque isso pode ser considerado contra o EULA; então boa sorte!
Meh! Isso é difícil, eu só quero digitar rápido usando o mouse / olhos / ...
Você deve definitivamente conferir o Dasher, que é muito mais rápido que um teclado na tela. Simplesmente funciona movendo o mouse em direção a letras; o movimento horizontal determina a velocidade e o movimento vertical seleciona as letras. Com um dicionário incorporado, ele pode até dimensionar as letras mais prováveis de serem maiores, mas também tenta aprender com o seu movimento, de modo que a velocidade e as letras estejam realmente acostumadas ao seu uso.
Uma imagem fala mais que mil palavras ...
É claro que isso é pequeno e não é muito rápido, como exemplo, mas você pode redimensioná-lo para ficar no lado direito da tela, de modo que não interfira na tela. Isso permite que você digite o mais rápido possível ...
Aqui está um bom exemplo de como as previsões permitem que você digite qualquer idioma mais rapidamente:
Observe também que as letras à direita são classificadas em uma ordem específica, de modo que a direção principal (para cima, para cima ou para baixo) escolha entre os diferentes tipos (minúsculas, maiúsculas, números e pontuação); e, nessa direção principal, sua direção menor escolherá entre AZ, az, 0-9 e assim por diante. Eu usei isso no passado e fiquei realmente impressionado com o quão fluente isso é comparado a outros concorrentes ...
Observe também que o Dasher possui alguma configuração; portanto, você pode ajustar algo que não gosta.