Usando a API e Revelando Senhas Ocultas por Asteriscos por Victory Fernandes (Verdadeiro Autor)
Aprenda como montar o seu próprio aplicativo em Delphi para revelar senha ocultas!
Recentemente me senti desafiado por programas não gratuitos que encontrei na internet cuja única finalidade é revelar senhas contidas em caixas de diálogos que estejam ocultas por asteriscos ou outro caracter.
Apesar destes aplicativos serem largamente difundidos e conhecidos na internet, as rotinas e códigos fontes dos mesmos não o são, sendo assim, decidi que tinha que implementar meu próprio aplicativo com a mesma finalidade.
Após um pouco de pesquisa e algumas horas de programação, cheguei finalmente a uma solução, que utilizando a API do Windows, gera um programa pequeno e fácil de se transportar, tal qual os vendidos por aí!
Implementando o Programa
A implementação do programa em si é realmente muito simples, e o único problema real é saber qual função da API do windows utilizar para executar a nossa tarefa.
De forma geral espera-se que o aplicativo final funcione da seguinte maneira:
Ao mover o cursor, o componente Ttimer deve detectar que o mouse está sobre uma caixa de diálogo contendo uma senha oculta, extrair a mesma e enviar para o componente Tedit, que torna a senha desejada visível ao usuário.
Comece adicionando a um novo projeto do Delphi, um componente Ttimer e um Tedit.
Altere a propriedade Interval do componente Ttimer para o valor 1, indicando que o evento OnTimer será disparado a cada 1 milisegundo, e a propriedade Enabled para False.
No evento OnShow do formulário principal, adicione:
Procedure Tform1.Form1OnShow(Sender: Tobject);
Begin
Timer1.enabled:=true;
End;
No evento OnTimer do Ttimer adicione o seguinte código:
//------ Código responsável por identificar e mostrar a senha oculta ------
procedure TForm1.Timer1Timer(Sender: TObject);
var
//Variável que irá receber a posição do cursor do mouse
Pos: TPoint;
//Variável que irá receber a senha oculta
Paswd: array[0..63] of Char;
begin
//Pega a posição do cursor na tela
GetCursorPos(Pos);
//Pega o Handle da Janela sobre a qual o cursor está localizado
HWin := WindowFromPoint(Pos);
//Verifica se há senha oculta
if SendMessage(HWin, EM_GETPASSWORDCHAR, 0, 0) <> 0 then
begin
//Descobre a senha oculta
SendMessage(HWin, WM_GETTEXT, 64, Longint(@Paswd));
//Mostra a senha no Editbox
edit1.Text:=Paswd;
end;
end;
end;
Pronto está feito! Rode o programa e verifique sua funcionalidade em caixas de senha como por exemplo a senha da sua conexão com a internet.
Do ponto de vista de programação isto é tudo que precisa ser feito para que seja possível revelar senhas ocultas. Vamos agora a algumas explicações sobre o código.
A Função GetCursorPos
Retorna em uma variável do tipo Tpoint a posição atual do mouse nas coordenadas da tela.
A Função WindowFromPoint
Unindo a posição do mouse retornada pela função GetCursorPos a esta função, obtemos um Handle para a janela sobre a qual o mouse se localiza.
A Função SendMessage
Esta é uma função bastante genérica, que é capaz de enviar para a janela ou janelas especificadas uma determinada mensagem, aguardando o fim do processamento da mensagem e sua resposta.
Abaixo vemos a função e seus parâmetros de entrada:
SendMessage(
HWND hWnd, //Handle para a Janela Destino
UINT Msg, //Mensagem a ser enviada
WPARAM wParam, //Primeiro parâmetro da mensagem
LPARAM lParam //Primeiro parâmetro da mensagem
);
A Mensagem EM_GETPASSWORDCHAR
Esta mensagem retorna o “password character”, ou seja, o caracter que está ocultando a senha que desejamos revelar.
Caso o retorno a esta mensagem seja 0, significa que o texto da caixa de texto sobre a qual o mouse está posicionado não está sendo ocultado, e logo não precisa ser tratado, caso contrário, o programa deve seguir em frente e tentar obter o texto oculto.
O primeiro e segundo parâmetros para esta mensagem não devem ser preenchidos.
A Mensagem WM_GETTEXT
Esta é a mensagem que faz todo o trabalho pesado!
Ela captura e retorna texto oculto para dentro de uma variável fornecida, restando apenas ao nosso aplicativo mostrar o valor obtido ao usuário.
Os parâmetro desta função devem ser preenchidos da seguinte forma:
wParam = (WPARAM) cchTextMax; //Número de caracteres a copiar
lParam = (LPARAM) lpszText; //Endereço do buffer para armazenar o texto
É importante ressaltar que esta função irá retornar resultados diferentes de acordo com o componente em que está o texto que se deseja revelar.
Para um controle do tipo TEdit o texto retornado é o “Caption” do mesmo, para controles do tipo TcomboBox o texto retornado será o texto que está sendo mostrado no mesmo, para Tbuttons o valor de retorno é a propriedade Name e para os demais componentes o título da janela é retornado.
Para retornar o texto do item de um ListBox, o aplicativo deve utilizar a mensagem LB_GETTEXT, e para componentes como TrichEdit, caso o texto copiado exceda 64K deve-se utilizar a mensagem EM_STREAMOUT ou EM_GETSELTEXT.
Reduzindo o Tamanho do Aplicativo
Quanto ao meu desafio, ainda não estava completo, restava um último ponto a ser abordado, a capacidade de transportar meu aplicativo!
A maioria dos aplicativos disponíveis na internet eram muito menores em tamanho que os 367 Kb gerados pelo programa descrito acima, o ponto final a ser superado então era como reduzir drasticamente o tamanho do aplicativo final mantendo a funcionalidade? Afinal, um programa como esse deve ser pequeno o suficiente para que o usuário seja capaz de transporta-lo de uma máquina para outra com a maior facilidade possível, caso não queira ser notado.
A reposta estava na criação do aplicativo utilizando apenas chamadas a API do windows, reduzindo drasticamente o tamanho do aplicativo final para mínimos 40 Kb.
A técnica descrita aqui pode ser usada para criação dos mais diversos aplicativos, e de uma forma geral, é na minha opinião, a melhor maneira de se conseguir aplicativos de tamanho reduzido utilizando-se a plataforma RAD do Delphi, apesar do extenso código.
A partir daqui, devo ressaltar que o artigo em questão requer do leitor maior conhecimento da plataforma Delphi, bem como da API do Windows em si.
Implementando o Aplicativo Usando a API
Em um novo projeto no Delphi adicione o sequinte código ao .dpr:
//--- Procedure chamada a cada 1 milisegundo para revelar o password oculto ---
procedure Timer;
var
Pos: TPoint;
HWin: THandle;
Paswd: array[0..63] of Char;
R: TRect;
begin
GetCursorPos(Pos);
HWin := WindowFromPoint(Pos);
if SendMessage(HWin, EM_GETPASSWORDCHAR, 0, 0) <> 0 then
begin
SendMessage(HWin, WM_GETTEXT, 64, Longint(@Paswd));
SetWindowText(wName,Paswd); //Coloca o Texto capturado no Edit
end
end;
//--- Sair do programa ---
procedure Sair;
begin
DeleteObject(Fonte); //Libera recursos do sistema
UnRegisterClass('Revelar', Instancia); //Remove Classes da memória
ExitProcess(Instancia); //Termina o Processo
end;
//--- Definição dos parâmetros do messagebox ---
procedure MostrarAbout;
var
Parametros : TMsgBoxParams;
begin
with Parametros do
begin
cbSize := SizeOf(Parametros);
hwndOwner := handle;
hInstance := Instancia;
lpszText := 'Revelador de Senhas Ocultas :: por TKS Software - Victory Fernandes' + #13 +
'Programado em Delphi 6 usando somente a API do Windows' + #13+
'Programado como Demo para o Guia do Delphi :: www.guiadodelphi.com.br' + #13+
'Para informações acesse:'+ #13 +
'www.victory.hpg.com.br'+ #13 +
'www.enge.cjb.net'+ #13 +
'hereim@gmx.net';
lpszCaption := 'Sobre o Revelador de Senhas Ocultas';
dwStyle := MB_OK or MB_USERICON;
lpszIcon := 'MAINICON';
dwContextHelpId := 0;
lpfnMsgBoxCallback := nil;
dwLanguageId := LANG_NEUTRAL;
end;
MessageBoxIndirect(Parametros); //Mostramos o messagebox
end;
//--- WindowProc, processamos todas as mensagens do windows enviadas ---
function WindowProc(hWnd, uMsg, wParam, lParam: Integer): Integer; stdcall;
begin
//Garante que todas as mensagens que nos enviam são processadas
Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
//Processando mensagens específicas
case uMsg of
WM_Destroy: Sair; //Chamamos a procedure para sair
WM_TIMER: Timer; //Se recebemos a mensagem de timer
WM_COMMAND:
if lparam = Sobre then //Mostramos o AboutBox
MostrarAbout;
end;
end;
begin
Instancia := hInstance; //Instancia do programa
//--- Criamos a Fonte do aplicativo ---
//Para maiores detalhes consulte o Win32Programmer's Reference
Fonte := CreateFont(
-12,
0,
0,
0,
400,
0,
0,
0,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH +
FF_DONTCARE,
'MS Sans Serif');
//--- Definimos a janela para depois registra-la ---
with Classe do
begin
Style := CS_CLASSDC or CS_PARENTDC; //estilo
lpfnWndProc := @WindowProc; //Aponta para função q processa as msgs
hInstance := Instancia; //instância da aplicação
hIcon := LoadIcon(hInstance, 'MAINICON'); //ícone
hbrBackGround := COLOR_BACKGROUND; //cor
lpszClassName := 'Revelar'; //Nome
hCursor := LoadCursor(0, IDC_ARROW); //Cursor
end;
RegisterClass(Classe); //Registramos a janela
//Iniciamos a criação da Janela e os outros componentes
//--- Criamos a janela principal ---
Handle := CreateWindowEx( //Handle := Handle para a janela principal
WS_EX_WINDOWEDGE + WS_EX_TOPMOST,
'Revelar', //Nome da Classe
'Senhas Ocultas', //titulo da janela
WS_SYSMENU or //Estilo da janela
WS_VISIBLE or //Visivel ou não
WS_MINIMIZEBOX, //Se pode minimizar
0,0, //Coordenadas Top e Left
179,100, //Dimensões da janela
0,0, //Consulte Win32 Programmer's reference
Instancia, // Instância do Aplicativo
Nil);
//--- Criando o Botão ---
Sobre := CreateWindow(
'Button', //Nome da Classe
'Sobre', //Caption do Botão
WS_VISIBLE or WS_CHILD,
3,44, // Coordenadas Left e Top
167,26, //Dimensões do Botão
handle, //Handle do Aplicativo
0,
Instancia, //Intância da aplicação
nil);
//--- Criamos um timer com intervalo de 1 milisegundo ---
SetTimer(handle, 0, 1, nil);
//--- Loop que recebe e processa as mensagens que chegam ao programa ---
while (GetMessage(Mensagem, Handle, 0, 0)) do
begin
TranslateMessage(Mensagem);
DispatchMessage(Mensagem);
end;
end.
O Resultado final das janela criadas usando API pode ser visto nas figuras:
Figura 02. Exemplo Finalizado – Revelando Senhas Ocultas usando somente chamadas a API do windows
Figura 03. “AboutBox” criado usando a API
Conclusões
Por fim, não só criamos um aplicativo capaz de revelar senhas ocultas, como também demonstramos a criação de programas em Delphi utilizando somente da API do Windows, reduzindo assim o tamanho do aplicativo final.
Para maiores informações sobre utilização da API para criação de controles e aplicativos consulte o Win32 Programmer's Reference que acompanha o Delphi.
Victory Fernandes é desenvolvedor da TKS Software - Soluções de Automação Comercial e Softwares Dedicados. Pode ser contactado em victory81@uol.com.br, ou através dos sites www.victory.hpg.com.br - www.enge.cjb.net – www.igara.com.br.
Publicidade
Vote no artigo
Quantidade de votos: 0 votos Aceitação:0%
Detalhes do artigo
Categoria: Windows Adicionado dia: 26/04/05 Por: Miguel Machado Visualizado: 26007 vezes