Como controlar los videos que se ejecuten en la PC?
#1
Escrito 27 junio 2011 - 10:00
Lo que sucede es que en mi empresa el Jefe decidio que prohibiera la ejecución de videos (musicales, peliculas, novelas, etc) en las PC de toda la red local
Esto lo hice bloqueando la ejecución de todos los reproductores de video, pero resultó que hay videos didacticos y educativos que si necesitan verse, pero con la restriccion puesta tampoco se ven estos
Lo que necesito es la forma de que solo se puedan ejecutare este grupo de videos, que estaran en una carpeta compartida en un servidor
La idea que se me ocurre es:
1- Hacer un reproductor en Delphi que solo reproduzca el contenido de la carpeta especificada
2- Monitorear la ruta de lo que va a reproducir el Reproductor de Video y cancelarlo si no es la autorizada (lo veo mas dificil de hacer)
3- Diganme uds otra idea
Probe haciendo un reproductor con el componente que incorpora Delphi pero no pone el video al tamaño de la ventana ni tampoco a pantalla completa, o al menos no supe como hacerlo
Se que hay una forma de hacer que una aplicación se ejecute dentro de la mia, que pudiera probar con eso, pero no recuerdo como es ni donde lo vi (me parece que fue en ClubDelphi)
Diganme que puedo hacer con esto
#2
Escrito 27 junio 2011 - 05:52
Monitorizar la ruta de lo que va a reproducir el Reproductor de Vídeo y cancelarlo también puede intentarse con un Hook global aunque si el S.O. es Win 7 de 64 bits no creo que funcione. El Hook puede ser a nivel Kernel, esto le hará mucho mas efectivo pero tiene un gran inconveniente, es muy dependiente del S.O. y puede molestar al A.V.
Saludos.
#3
Escrito 28 junio 2011 - 10:03
Cualquier otro reproductor estará bloqueado
Probé haciendolo con el tmediaplayer pero no funciona bien con los avi y no reproduce los VOB
Con que otro componente se podria hacer?
Para lo del Hook, no tengo PC con Win7 pero si podria haber problemas con al AV
#4
Escrito 28 junio 2011 - 10:54
He estado jugando un poco, y he tirado por la calle de "en medio". He realizado un prototipo de DLL que se inyecta de forma global y realiza un Hook a las APIs CreateFileW y OpenFile, probablemente ésta última no sea preciso engancharla, pero lo he hecho.
El Hook funciona de la siguiente forma: Cualquier llamada a esas APIs pasa por mi filtro y si tiene la extensión ".avi", comprueba que la ruta comienza por '\', si es así permite abrir el archivo (está en el servidor) de lo contrario devuelve -1.
La DLL la he escrito en C por varias razones, la primera porque para estas tareas me resulta mucho mas cómodo. La segunda porque para realizar con seguridad un Hook a la API con un trampolín, se precisa desensamblar en tiempo de ejecución las primeras instrucciones (Opcodes) y ese código lo tengo escrito en C, siendo tediosa su traducción a delphi.
Pongo el código de las APIs enganchadas:
HANDLE WINAPI HCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { if(wcsstr(lpFileName, L".avi")){ if(*lpFileName != L'\\'){ //Beep(100, 500); return (HANDLE)-1; } } return OriginCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } HFILE WINAPI HOpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle) { if(strstr(lpFileName, ".avi")){ if(*lpFileName != '\\'){ //Beep(100, 500); return -1; } } return OriginOpenFile(lpFileName, lpReOpenBuff, uStyle); }
La Dll exporta dos funciones accesibles desde delphi: Hook y UnHook. Pongo un ejemplo en delphi y lo subo junto con la dll.
procedure Hook; stdcall external 'HookDll'; procedure UnHook; stdcall external 'HookDll'; ........................................................... procedure TForm1.HookButtonClick(Sender: TObject); begin Hook; end; procedure TForm1.UnHookButtonClick(Sender: TObject); begin UnHook; end;
Se trata de una prueba de concepto pero es funcional, sólo falta añadir todas las extensiones posibles para archivos de vídeo... Pero aún así cabe la posibilidad de que un usuario quite la extensión a un archivo de vídeo y lo cargue en el reproductor, así que en ese caso el filtro debería comprobar las cabeceras de los archivos.
Creo que como idea inicial no está mal.
Saludos.
Archivos adjuntos
#5
Escrito 29 junio 2011 - 08:30
Pero tengo una "pequeña" dificultad, no domino mucho el C y tampoco lo tengo
Podrias ayudarme compilandome la dll?
Para el caso de las extenciones de video serian:
avi, wmv, mpg, flv, vob
Con los .dat como se haria?, pues hay otros archivos .dat que son complementos de otras aplicaciones y no de videos
Entonces, lo que tendria que hacer es:
Copiar la dll con mi aplicacion monitor en las PC, y hacer que la aplicaciion se ejecute al inicio?
#6
Escrito 29 junio 2011 - 09:53
Por otro lado, para resolver tu duda acerca de los reproductores, visita este enlace.
Saludos.
#7
Escrito 29 junio 2011 - 10:59
Entonces mi DLL solo tendra la funcion de aplicar el filtro y la tuya la llamaria, es así?
Muchas gracias por la cooperación, veremos como nos sale
#8
Escrito 29 junio 2011 - 11:26
#9
Escrito 29 junio 2011 - 03:45
Esta muy buena la idea
Entonces mi DLL solo tendra la funcion de aplicar el filtro y la tuya la llamaria, es así?
Muchas gracias por la cooperación, veremos como nos sale
Si, esa es la idea. Tu dll realizará el filtro con una función que será consultada por HookDLLl.
Esa función puede tener el prototipo:
function Filter(FileName: String): boolean;
Dado que el APIHook fundamental es a CreateFileW que trabaja en unicode, podemos usar este formato de cadenas o las clásicas, como prefieras.
El método no va a ser infalible al 100% pero si para la mayoría de los usuarios. Sólo me preocupa el detalle de que un usuario renombre un archivo de vídeo con otra extensión. En ese caso no sería bloqueado, a no ser que se analice la cabecera de dicho archivo en el filtro. Eso supone el análisis y conocimiento de dichas cabeceras o tratar de usar DirectX o funciones de alto nivel similares.
En fin, es cuestión de darle vueltas para encontrar el filtro mas adecuado y eficaz.
Saludos.
#10
Escrito 30 junio 2011 - 07:37
Bien, he modificado HookDLL.
Ahora el filtro debe estar en otra dll denominada "FilterDLL.dll"
El prototipo de la función filtro es el siguiente:
function Filter( lpFileName: PCHAR; dwDesiredAccess: DWORD; dwShareMode: DWORD; lpSecurityAttributes: PSECURITY_ATTRIBUTES; dwCreationDisposition: DWORD; dwFlagsAndAttributes: DWORD; hTemplateFile: THANDLE): boolean; stdcall;
Recibe todos los parámetros de CreateFileW con una diferencia. El Nombre del fichero lo recibe como cadena clásica, no como unicode. De esta manera se controla totalmente la API enganchada.
El Hook queda establecido sólo para la API CreateFileW de la siguiente forma:
HANDLE WINAPI HCreateFileW( LPCWSTR lpFileNameW, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { static Hooking = false; if(!Hooking){ Hooking = true; CHAR lpFileName[MAX_PATH + 1]; WideCharToChar(lpFileNameW, lpFileName); if(Filter){ if(!Filter(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)){ Hooking = false; return (HANDLE)-1; } } Hooking = false; } return OriginCreateFileW(lpFileNameW, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); }
Un ejemplo simple del filtro en el contexto de su dll:
library FilterDLL; uses SysUtils, Windows; {$R *.res} type PSECURITY_ATTRIBUTES = ^SECURITY_ATTRIBUTES; function Filter( lpFileName: PCHAR; dwDesiredAccess: DWORD; dwShareMode: DWORD; lpSecurityAttributes: PSECURITY_ATTRIBUTES; dwCreationDisposition: DWORD; dwFlagsAndAttributes: DWORD; hTemplateFile: THANDLE): boolean; stdcall; begin Result:= true; if Pos('.avi', lpFileName)<>0 then begin if lpFileName^ <> '\' then begin Beep(100, 200); Result:= false; end; end; end; exports Filter; begin end.
Lo mejor será que el filtro no analize extensiones sino que trate de abrir el archivo con cadenas MCI o mediante DirectX, si es un archivo multimedia no obtendremos un error y en ese caso no le dejamos pasar (devolvemos false) a no ser que esté en el servidor.
Espero que te sea de utilidad.
Saludos.
#11
Escrito 30 junio 2011 - 09:20
¡Que cabeza la mia!
Se me pasó subir los archivos.
Ahora mismo los subo.
Saludos.
Archivos adjuntos
#12
Escrito 30 junio 2011 - 09:50
Comenzare a trabajar con esto a ver como sale
Pero lo tendre que hacer a partir de la semana que viene pues el lunes tengo que defender mi tesis de Ing en Informatica, y estoy preparandome para eso
#13
Escrito 01 julio 2011 - 09:25
Muchas Gracias
Comenzare a trabajar con esto a ver como sale
Pero lo tendre que hacer a partir de la semana que viene pues el lunes tengo que defender mi tesis de Ing en Informatica, y estoy preparandome para eso
Que tengas mucha suerte con la defensa de tu tesis, ya nos contarás.
Por otro lado he realizado unas pruebas y ha habido cosas que no me han convencido. He hecho algunos cambios. Ahora no es necesario que las dll estén en la carpeta del sistema, pueden estar en cualquier parte, junto con la aplicación inyectora, a no ser que ésta pase la ruta de las dll, en cuyo caso la ubicación puede ser cualquiera.
Subo los nuevos archivos.
Saludos.
#14
Escrito 01 julio 2011 - 09:48
A la defensa de esa Tesis, dales con todo
Salud OS
#15
Escrito 04 julio 2011 - 12:24
Algo ha pasado. Había publicado una actualización de los archivos del sistema VideoLock y el mensaje a desaparecido...
¿Alguien sabe algo?
Tendré que rebuscar los archivos, afortunadamente tengo copia.
Saludos.
#16
Escrito 04 julio 2011 - 04:37
Comentaba que había cosas que no me gustaban de la versión anterior. En la nueva versión se mejoran algunas cosas y no es necesario que las dlls estén en la carpeta del sistema, pueden estar en cualquier ubicación.
El filtro de ejemplo lo asemejo mas a delphi:
function Filter( lpFileName: PCHAR; dwDesiredAccess: DWORD; dwShareMode: DWORD; lpSecurityAttributes: PSECURITY_ATTRIBUTES; dwCreationDisposition: DWORD; dwFlagsAndAttributes: DWORD; hTemplateFile: THANDLE): boolean; stdcall; var FileName: String; begin Result:= true; FileName:= String(lpFileName); if ExtractFileExt(FileName)='.avi' then begin if FileName[1] <> '\' then begin //Beep(100, 50); //OutputDebugString(PCHAR('bloqueado: '+ FileName)); Result:= false; end; end; // if Result then OutputDebugString(PCHAR('NO bloqueado: ' + FileName)); end;
El Código de HookDll.dll es básicamente este:
#include <windows.h> #include "APIHook.h" #include "APIHook.cpp" typedef HFILE (WINAPI *POPENFILE)(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle); typedef HANDLE (WINAPI *PCREATEFILEW)( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); typedef BOOL (WINAPI *PFILTER)( LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); HHOOK hHook; HINSTANCE HInst; HMODULE hFilter; POPENFILE OriginOpenFile = 0; PCREATEFILEW OriginCreateFileW = 0; PFILTER Filter = 0; //------------------------------------------------------------------------------ // Convierte cadenas Unicode y clásicas entre si char* WideCharToChar(const wchar_t* Entrada, char* Salida, unsigned int Size=-1) { int size = Size; if(Size==-1) size = wcslen(Entrada)+1; WideCharToMultiByte(CP_ACP, 0, Entrada, -1, Salida, size, NULL, NULL); return Salida; } // Provocamos el Hook Global. La dll se inyectará en todo el sistema de ventanas LRESULT CALLBACK HookPorc(int nCode,WPARAM wParam,LPARAM lParam) { return CallNextHookEx(hHook, nCode, wParam, lParam); } extern "C" __declspec(dllexport) __stdcall void Hook() { hHook = SetWindowsHookEx(WH_CALLWNDPROC /*WH_CBT*/, (HOOKPROC)HookPorc, HInst, 0); } extern "C" __declspec(dllexport) __stdcall void UnHook() { UnhookWindowsHookEx(hHook); } HANDLE WINAPI HCreateFileW( LPCWSTR lpFileNameW, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { static Hooking = false; if(!Hooking){ Hooking = true; CHAR lpFileName[MAX_PATH + 1]; WideCharToChar(lpFileNameW, lpFileName); bool Filtro = Filter(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); if(!Filtro){ Hooking = false; return (HANDLE)-1; } Hooking = false; } return OriginCreateFileW(lpFileNameW, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } void InstallHook() { char FilterDLL[MAX_PATH+1]; GetModuleFileName(HInst, FilterDLL, sizeof(FilterDLL)); char *F = strrchr(FilterDLL, '\\'); *F = 0; strcat(FilterDLL, "\\FilterDLL.dll"); hFilter = LoadLibrary(FilterDLL); Filter = (PFILTER)GetProcAddress(hFilter, "Filter"); InstallHook(HCreateFileW, (void**)&OriginCreateFileW, "Kernel32.dll", "CreateFileW"); } void UnInstallHook() { UnInstallHook((void**)&OriginCreateFileW, "Kernel32.dll", "CreateFileW"); FreeLibrary(hFilter); } #pragma argsused BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved) { HInst = hinstDLL; switch (fwdreason) { case DLL_PROCESS_ATTACH: InstallHook(); break; case DLL_PROCESS_DETACH: UnInstallHook(); break; } return 1; }
Saludos.
#17
Escrito 05 julio 2011 - 12:22
Ya probe y me sale bien lo que quiero, ahora que tengo un poco mas de tiempo voy a terminar y refinar un poco mas nuestro "guardian de videos"
Pues ya me gradue con la calificación maxima
y tengo mas tiempo disponible
#18
Escrito 05 julio 2011 - 02:45
Muchas gracias escafandra,
Ya probe y me sale bien lo que quiero, ahora que tengo un poco mas de tiempo voy a terminar y refinar un poco mas nuestro "guardian de videos"
Pues ya me gradue con la calificación maxima
y tengo mas tiempo disponible
Me alegran dos cosas, que el proyecto se ajuste a tu necesidad y que consiguieras la máxima calificación.
Saludos.
#19
Escrito 05 julio 2011 - 03:45
Felicitaciones amigo JoAnCa.Pues ya me gradue con la calificación maxima
y tengo mas tiempo disponible
#20
Escrito 05 julio 2011 - 03:49
Felicidades JoAnCa y muchas gracias a escafandra, realmente son éstas las cosas que hacen que valga la pena seguir adelante con una comunidad.
¡¡¡ Vamos DelphiAccess !!! o lo que es lo mismo Go DA !!!
Salud OS