En ocasiones nos vemos en la necesidad de matar una aplicación desde código. Ya existen en el foro ejemplos de como hacerlo, bien por su nombre su id de proceso o el puerto que usa una App en red. En esta ocasión me vi en la necesidad de matar un proceso especial, se trataba de un virus de pendrive cuyo nombre variaba y no así el archivo. La solución fue usar el Hash md5 para localizarlo.
La filosofía es recorrer los procesos en ejecución, encontrar la ruta del archivo ejecutable y calcular su hash md5 para compararlo con el que buscamos y matar dicho proceso. Eventualmente, también podemos borrar el archivo ejecutable y desinstalarlo del registro de Windows.
La desinstalación del registro se realiza buscando el proceso en la clave:
Dejo una aplicación de consola que realiza la tarea. Usa como parámetro la cadena MD5 del archivo buscado. En ella está la función para calcular el hash md5 con la API de Windows, la función para encontrar y terminar el proceso y la función para recorrer el registro. Dicho código no encierra grandes complicaciones y puede ser útil para fines como el que me llevó a escribirlo.
El código original lo escribí en C/C++ y en realidad es algo mas complejo del que presento pues incluía un Hook a la API CreateProcessInternalW para, además, evitar la ejecución del proceso viral (o el que se tercie). En este aspecto quisiera recordar el hilo que abrió enecumene Prevenir que aplicación se ejecute
Espero que este ejemplo sea de utilidad.
Saludos.
La filosofía es recorrer los procesos en ejecución, encontrar la ruta del archivo ejecutable y calcular su hash md5 para compararlo con el que buscamos y matar dicho proceso. Eventualmente, también podemos borrar el archivo ejecutable y desinstalarlo del registro de Windows.
La desinstalación del registro se realiza buscando el proceso en la clave:
Código: [Seleccionar]
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\run\en el ejemplo se muestra como recorrer el registro y puede variarse para buscar en HKEY_LOCAL_MACHINE u otras. En mi caso bastó con lo expuesto.Dejo una aplicación de consola que realiza la tarea. Usa como parámetro la cadena MD5 del archivo buscado. En ella está la función para calcular el hash md5 con la API de Windows, la función para encontrar y terminar el proceso y la función para recorrer el registro. Dicho código no encierra grandes complicaciones y puede ser útil para fines como el que me llevó a escribirlo.
El código original lo escribí en C/C++ y en realidad es algo mas complejo del que presento pues incluía un Hook a la API CreateProcessInternalW para, además, evitar la ejecución del proceso viral (o el que se tercie). En este aspecto quisiera recordar el hilo que abrió enecumene Prevenir que aplicación se ejecute
Código CPP
- #include <windows.h>
- #include <Shlwapi.h>
- #include <Tlhelp32.h>
- #include <stdio.h>
- #include <conio.h>
- #pragma hdrstop
- //---------------------------------------------------------------------------
- #define MD5LEN 16
- #define BUFSIZE 1024
- typedef CHAR TMD5[33];
- void GetMD5FromFile(CHAR* FileName, CHAR *MD5)
- {
- HANDLE hFile = 0;
- HCRYPTPROV hProv = 0;
- HCRYPTHASH hHash = 0;
- BYTE Hash[MD5LEN];
- DWORD bHash = 0;
- DWORD bRead = 0;
- BYTE* Buffer = (BYTE*)VirtualAlloc(0, BUFSIZE, MEM_COMMIT, PAGE_READWRITE);
- hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if(hFile != INVALID_HANDLE_VALUE){
- if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)){
- if(CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)){
- while (1) {
- ReadFile(hFile, Buffer, BUFSIZE, &bRead, NULL);
- if(!bRead) break;
- CryptHashData(hHash, Buffer, bRead, 0);
- }
- bHash = MD5LEN;
- if(CryptGetHashParam(hHash, HP_HASHVAL, Hash, &bHash, 0)){
- for(int i=0; i<2*MD5LEN; i++){
- MD5[i] = (0x0F & Hash[i/2] >> 4*((i+1)%2)) + 48;
- if(MD5[i] > '9') MD5[i] += 7;
- }
- MD5[32] = 0;
- }
- }
- CryptDestroyHash(hHash);
- }
- CryptReleaseContext(hProv, 0);
- }
- CloseHandle(hFile);
- VirtualFree(Buffer, 0, MEM_RELEASE);
- }
- //---------------------------------------------------------------------------
- // Desinstala una App de la clave HKEY_CURRENT_USER\...\run
- bool RegDesinstall(CHAR *App)
- {
- CHAR* RunKey = "Software\\Microsoft\\Windows\\CurrentVersion\\run\\";
- HKEY hKey = 0;
- CHAR* Value = 0;
- CHAR ValueName[256];
- DWORD dwValueName = sizeof(ValueName);
- DWORD Type;
- CHAR Data[256];
- DWORD dwData = sizeof(Data);
- int Index;
- bool Result = false;
- // Si es un Path a una sunblave enumeramos los valores
- Index = 0;
- if(RegOpenKeyEx(HKEY_CURRENT_USER, RunKey, 0, KEY_READ | KEY_SET_VALUE, &hKey) == ERROR_SUCCESS){
- int ErrorCode = RegEnumValue(hKey, Index++, ValueName, &dwValueName, NULL, &Type, (PBYTE)Data, &dwData);
- while(ErrorCode != ERROR_NO_MORE_ITEMS){
- if(StrStrI(Data, App)){
- Result = (RegDeleteValue(hKey, ValueName) == ERROR_SUCCESS);
- break;
- }
- DWORD dwValueName = sizeof(ValueName);
- DWORD dwData = sizeof(Data);
- ErrorCode = RegEnumValue(hKey, Index++, ValueName, &dwValueName, NULL, &Type, (PBYTE)Data, &dwData);
- }
- RegCloseKey(hKey);
- }
- return Result;
- }
- //---------------------------------------------------------------------------
- // Termina los procesos conociendo el nombre del exe o su Hash MD5
- void TerminateMD5_Process(TMD5 FileHash, bool Terminate = true, bool DeleteProcess = false)
- {
- TMD5 MD5;
- HANDLE Process = 0;
- PROCESSENTRY32 proc = { sizeof(proc) };
- // Nos Damos privilegios debug
- HANDLE hToken;
- TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}};
- LookupPrivilegeValue(0, SE_DEBUG_NAME, &priv.Privileges[0].Luid);
- OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
- AdjustTokenPrivileges (hToken, FALSE, &priv, sizeof priv, 0, 0);
- HANDLE hSysSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if(hSysSnapshot != INVALID_HANDLE_VALUE && Process32First(hSysSnapshot, &proc)){
- do{
- HANDLE hSnapshot;
- MODULEENTRY32 ModuleEntry = {sizeof(MODULEENTRY32)};
- hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proc.th32ProcessID);
- if(hSnapshot != (HANDLE)-1){
- if(Module32First(hSnapshot, &ModuleEntry)){
- GetMD5FromFile(ModuleEntry.szExePath, MD5);
- if(!stricmp(FileHash, MD5)){
- Process = OpenProcess(PROCESS_TERMINATE, false, proc.th32ProcessID);
- if(Terminate && Process){
- if(TerminateProcess(Process, 0))
- printf(ModuleEntry.szExePath); printf("\n");
- CloseHandle(Process);
- }
- if(DeleteProcess){
- SetFileAttributes(ModuleEntry.szExePath, FILE_ATTRIBUTE_ARCHIVE);
- DeleteFile(ModuleEntry.szExePath);
- RegDesinstall(ModuleEntry.szExePath);
- }
- }
- }
- CloseHandle(hSnapshot);
- }
- }while(Process32Next(hSysSnapshot, &proc));
- }
- CloseHandle(hSysSnapshot);
- // Retirar los privilegios debug
- priv.Privileges[0].Attributes = 0;
- AdjustTokenPrivileges (hToken, FALSE, &priv, sizeof priv, 0, 0);
- CloseHandle (hToken);
- }
- #pragma argsused
- int main(int argc, char* argv[])
- {
- if(argc > 1){
- printf("Terminando procesos...\n");
- TerminateMD5_Process(argv[1], true, false);
- }else
- printf("Se necesita un parámetro MD5 que identifique un archivo.\n");
- printf("Pulse una tecla para terminar.");
- getch();
- return 0;
- }
- //---------------------------------------------------------------------------
Espero que este ejemplo sea de utilidad.
Saludos.








En línea