{"id":670,"date":"2026-03-26T21:38:45","date_gmt":"2026-03-26T21:38:45","guid":{"rendered":"https:\/\/hackcuba.net\/?p=670"},"modified":"2026-03-26T21:38:46","modified_gmt":"2026-03-26T21:38:46","slug":"webcam","status":"publish","type":"post","link":"https:\/\/hackcuba.net\/?p=670","title":{"rendered":"WebCam"},"content":{"rendered":"\n<p>No han sido pocas las ocaciones en que personas conocidas han acudido a mi a formularme la misma pregunta. \u00bfC\u00f3mo puedo espiar una WebCam? A trav\u00e9s de un ejemplo pienso exponer de la manera m\u00e1s clara posible los pasos a seguir para tomar el control de este dispositivo de captura. Por esta v\u00e9z nada de componentes visuales mediocres que hagan todo el trabajo por nosotros, el c\u00f3digo va dirigido a las personas que de verdad quieren saber como trabajar con los dispositivos de captura en Windows, y la \u00fanica manera de hacerlo es a trav\u00e9s de las API.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p><br>Este conocimiento puede ser utilizado para identificar primitivas geom\u00e9ricas con la imagen obtenida, puedes usarlo para poner un sensor de movimiento en tu cuarto, o puedes usarlo para espiar la WebCam de tu vecina que est\u00e1 muy buena. Con esto quiero decir que el uso que le des depende de ti, puedes hacer cosas muy constructivas o muy retorcidas. Me encantar\u00eda hacer un art\u00edculo m\u00e1s explicativo del tema pero desafortunadamente el tiempo no me alcanza. Espero que basten los comentarios que acompa\u00f1an al c\u00f3digo, cualquier duda pueden consultar el SDK de Windows o hacermela llegar directamente a mi correo.<br>A continuaci\u00f3n el c\u00f3digo. El ejemplo compilado lo puedes bajar de aqu\u00ed.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n\/\/---------------------------------------------------------------------------\n\/*\n** Nombre: WebCamPreview.cpp\n** Autor: h0aX\n** Fecha: 27\/08\/2007\n** Descripci\u00f3n: Ejemplo para utilizaci\u00f3n de dispositivos de captura en Windows.\n*\/\n\/\/---------------------------------------------------------------------------\n#include &lt;windows.h&gt;\n#include &lt;vfw.h&gt; \/*aqu\u00ed encontraremos todo lo necesario para\ndispositivos de captura*\/\n#include &lt;stdio.h&gt;\n\/\/--------------------------VARIABLES GLOBALES-------------------------------\nHWND hWndMain, hWnd_btnPicture, hWnd_btnSequence,\nhWnd_btnStop, hWnd_btnAbout,\nhWnd_cbxNegative,\nhWndCapture; \/\/manejador del dispositivo de captura\nHINSTANCE hInst;\n\/\/-----------------------DECLARACI\u00d3N DE FUNCIONES----------------------------\nLRESULT CALLBACK Frame(HWND w, LPVIDEOHDR h);\nBOOL IniciaWebCam(HANDLE Parent);\nLRESULT CALLBACK WndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );\nWINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);\n\/\/---------------------------------------------------------------------------\n\/* Esta funci\u00f3n ser\u00e1 llamada antes del frame ser mostrado, as\u00ed\n** que podremos usarla para muchas cosas, enviar el frame por la\n** red, detectar movimiento, cambiar algo en el frame, etc.\n** En este caso lo uso para poner la imagen en negativo.\n*\/\nLRESULT CALLBACK Frame(HWND w, LPVIDEOHDR h)\n{\n  typedef struct {BYTE b,g,r;} PIXEL;\n  for (DWORD i=0; i&lt;h-&gt;dwBytesUsed\/3; i++)\n  {\n    PIXEL *pixel = &amp;((PIXEL*)h-&gt;lpData)&#x5B;i];\n    pixel-&gt;r = ~pixel-&gt;r;\n    pixel-&gt;g = ~pixel-&gt;g;\n    pixel-&gt;b = ~pixel-&gt;b;\n    }\n  return TRUE;\n}\n\n\n\/\/---------------------------------------------------------------------------\n\/*\n** Inicializaci\u00f3n de nuestro dispositivo de captura\n*\/\nBOOL IniciaWebCam(HANDLE Parent)\n{\n\/\/creamos la ventana de captura\n  hWndCapture = capCreateCaptureWindow(&quot;hXWebCam&quot;, \/\/nombre\n  WS_CHILD | WS_VISIBLE, \/\/estilo de ventana\n  0, 0, \/\/posici\u00f3n\n  320, 240, \/\/tama\u00f1o\n  Parent, 0); \/\/ventana padre\n\/\/chequea si se cre\u00f3 la ventana de captura\n  if (!hWndCapture)\n  {\n    MessageBoxA(Parent, &quot;Error creando ventana de captura&quot;,\n    &quot;Error&quot;, MB_ICONERROR);\n    return FALSE;\n  }\n\/\/conectamos al dispositivo de captura\n  if (!capDriverConnect(hWndCapture,0))\n  {\n    MessageBoxA(Parent, &quot;Error conectando al dispositivo de captura.\\r\\n&quot;\n    &quot;Es posible que no haya ningun dispositivo de este &quot;\n    &quot;tipo instalado.&quot;,\n    &quot;Error&quot;, MB_ICONERROR);\n    return FALSE;\n  }\n\/\/aqu\u00ed especificamos el formato\n  BITMAPINFO bmFormat;\n  memset(&amp;bmFormat, 0, sizeof(BITMAPINFO));\n  bmFormat.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n  bmFormat.bmiHeader.biWidth = 320;\n  bmFormat.bmiHeader.biHeight = 240;\n  bmFormat.bmiHeader.biBitCount = 24;\n  bmFormat.bmiHeader.biCompression = 0;\n\n\/\/el formato definido aqu\u00ed es 320x240x24\n  capSetVideoFormat(hWndCapture, &amp;bmFormat, sizeof(BITMAPINFO));\n\n\/\/cada 30 milisegundo se refresca la imagen\n  capPreviewRate(hWndCapture,30);\n\n\/\/Preview activado\n  capPreview(hWndCapture,TRUE);\n  return TRUE;\n}\n\/\/---------------------------------------------------------------------------\n\/*\n** Procedimiento de ventana\n*\/\nLRESULT CALLBACK WndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )\n{\n  switch (uMsg)\n  {\n      case WM_COMMAND:\n    {\n\/\/bot\u00f3n foto\n      if (hWnd_btnPicture == (HWND) lParam)\n      {\n\/\/esto es para guardar el frame actual en un Bitmap\n        capFileSaveDIB(hWndCapture, &quot;picture.bmp&quot;);\n        Beep(600,50);\n      }\n      else\n\/\/bot\u00f3n secuencia\n      if (hWnd_btnSequence == (HWND) lParam)\n      {\n        SetWindowTextA(hWndMain, &quot;Grabando Sequencia Audio\/Video&quot;);\n        EnableWindow(hWnd_btnStop, TRUE);\n        EnableWindow(hWnd_btnSequence, FALSE);\n        EnableWindow(hWnd_btnPicture, FALSE);\n        EnableWindow(hWnd_cbxNegative, FALSE);\n\n\/\/especifica el lugar donde guardar\u00e1 la secuencia de video, por\n\/\/defecto es C:\\\\Capture.avi\n        capFileSetCaptureFile(hWndCapture, &quot;video.avi&quot;);\n\n\/\/Inicia captura de video\n        capCaptureSequence(hWndCapture);\n      }\n      else\n\n\/\/bot\u00f3n Detener\n      if (hWnd_btnStop == (HWND) lParam)\n      {\n        SetWindowTextA(hWndMain, &quot;WebCam Preview por h0aX&quot;);\n        EnableWindow(hWnd_btnStop, FALSE);\n        EnableWindow(hWnd_btnSequence, TRUE);\n        EnableWindow(hWnd_btnPicture, TRUE);\n        EnableWindow(hWnd_cbxNegative, TRUE);\n\n\/\/Termina captura de video\n        capCaptureStop(hWndCapture);\n      }\n      else\n\n\/\/bot\u00f3n Acerca de\n      if (hWnd_btnAbout == (HWND) lParam)\n      {\n        MessageBoxA(hWndMain, &quot;WebCam Preview v1.0\\r\\n\\r\\n&quot;\n        &quot;por h0aX &#x5B;hoax_ws@yahoo.es] 27\/08\/2007 9:28 pm\\r\\n&quot;\n        &quot;para la comunidad BlackHat &#x5B;blackhat4all@gmail.com]\\r\\n&quot;,\n        &quot;Acerca de&quot;, MB_ICONINFORMATION);\n      }\n      else\n\n\/\/checkbox Negativo\n      if (hWnd_cbxNegative == (HWND) lParam)\n      {\n        BOOL bChecked;\n        bChecked = SendMessage(hWnd_cbxNegative, BM_GETCHECK, 0, 0);\n        if (!bChecked)\n        {\n          capSetCallbackOnFrame(hWndCapture, (FARPROC) Frame);\n          SendMessage(hWnd_cbxNegative, BM_SETCHECK, 1, 0);\n        }\n        else\n        {\n          capSetCallbackOnFrame(hWndCapture, NULL);\n          SendMessage(hWnd_cbxNegative, BM_SETCHECK, 0, 0);\n        }\n      }\n      return 0;\n    }\n    case WM_DESTROY:\n    {\n\n\/\/desconecta del dispositivo de captura\n      capDriverDisconnect(hWndCapture);\n      PostQuitMessage(0);\n      return 0;\n    }\n  }\n  return DefWindowProcA(hwnd,uMsg,wParam,lParam);\n}\n\n\/\/---------------------------------------------------------------------------\nWINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)\n{\n  MSG msg;\n  WNDCLASS wndclass;\n  char szClassName&#x5B;] = &quot;hXWebCamPreview&quot;;\n  hInst = hInstance;\n  wndclass.style = CS_VREDRAW | CS_HREDRAW;\n  wndclass.lpfnWndProc = WndProc;\n  wndclass.cbClsExtra = 0;\n  wndclass.cbWndExtra = 0;\n  wndclass.hInstance = hInstance;\n  wndclass.hIcon = LoadIconA(NULL, IDI_APPLICATION);\n  wndclass.hCursor = LoadCursorA(NULL, IDC_ARROW);\n  wndclass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);\n  wndclass.lpszMenuName = NULL;\n  wndclass.lpszClassName = szClassName;\n  RegisterClassA(&amp;wndclass);\n\n\/\/Ventana padre\n  hWndMain = CreateWindow(szClassName,&quot;WebCam Preview por h0aX&quot;, WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE,\n  CW_USEDEFAULT, CW_USEDEFAULT, 415, 272,\n  NULL, NULL, hInstance, 0);\n\n\/\/Botones\n  hWnd_btnPicture = CreateWindow(&quot;Button&quot;,&quot;Foto&quot;, WS_VISIBLE | WS_CHILD,\n  325,30, 75,25, hWndMain, 0, hInst, NULL);\n  hWnd_btnSequence = CreateWindow(&quot;Button&quot;,&quot;Secuencia&quot;, WS_VISIBLE | WS_CHILD,\n  325,60, 75,25, hWndMain, 0, hInst, NULL);\n  hWnd_btnStop = CreateWindow(&quot;Button&quot;,&quot;Detener&quot;, WS_VISIBLE | WS_CHILD,\n  325,90, 75,25, hWndMain, 0, hInst, NULL);\n  EnableWindow(hWnd_btnStop, FALSE);\n  hWnd_btnAbout = CreateWindow(&quot;Button&quot;,&quot;Acerca de&quot;, WS_VISIBLE | WS_CHILD,\n  325,120, 75,25, hWndMain, 0, hInst, NULL);\n\n\/\/CheckBox\n  hWnd_cbxNegative = CreateWindow(&quot;Button&quot;,&quot;Negativo&quot;, WS_VISIBLE | WS_CHILD | BS_CHECKBOX,\n  325,150, 78,25, hWndMain, 0, hInst, NULL);\n  ShowWindow(hWndMain, nCmdShow);\n\n\/\/Si no logra iniciar la WebCam cierra.\n  if (!IniciaWebCam(hWndMain))\n  {\n    PostQuitMessage(0);\n  }\n  while (GetMessageA(&amp;msg, NULL,0,0))\n  {\n    TranslateMessage(&amp;msg);\n    DispatchMessageA(&amp;msg);\n  }\n  return msg.wParam;\n}\n\/\/---------------------------------------------------------------------------.\n\n<\/pre><\/div>\n\n\n<p>Escrito por H0ax [hoax_ws@yahoo.es]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No han sido pocas las ocaciones en que personas conocidas han acudido a mi a formularme la misma<\/p>\n","protected":false},"author":2,"featured_media":228,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,14,157],"tags":[88,92,4,38,206],"class_list":["post-670","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigos","category-hacking","category-sistemas-operativos","tag-codigos","tag-hacker","tag-hacking","tag-proyecto-blackhat","tag-webcam"],"_links":{"self":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/670","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=670"}],"version-history":[{"count":1,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/670\/revisions"}],"predecessor-version":[{"id":671,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/670\/revisions\/671"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/media\/228"}],"wp:attachment":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=670"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=670"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=670"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}