summaryrefslogtreecommitdiff
path: root/src/objectscanner_analyze.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/objectscanner_analyze.cpp')
-rw-r--r--src/objectscanner_analyze.cpp275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/objectscanner_analyze.cpp b/src/objectscanner_analyze.cpp
new file mode 100644
index 0000000..dccca63
--- /dev/null
+++ b/src/objectscanner_analyze.cpp
@@ -0,0 +1,275 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <string.h>
+
+#include "librdkafka/rdkafka.h"
+
+#include "avlsdk/engine.h"
+#include "avlsdk/error_code.h"
+#include "avlsdk/AVLSDK_rpt_idx.h"
+#include "avlsdk/AVLSDK_conf_idx.h"
+#include "avlsdk/ID2Name_interface.h"
+
+#include "object_store_client.h"
+
+#include "objectscanner_main.h"
+#include "objectscanner_kafka.h"
+#include "objectscanner_analyze.h"
+
+extern objscan_global_info_t g_objscan_info;
+
+int avl_scan_engine_init(void)
+{
+ long ret, long_last_ret;
+ void *p_engine_handle=NULL, *p_i2n_handle=NULL;
+ void *p_sdk_handle = NULL, *p_name_handle = NULL;
+
+ ret = AVL_SDK_CreateInstance(&p_engine_handle);
+ if(ret != ERR_SUCCESS)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_SDK_CreateInstance error: %ld", ret);
+ return -1;
+ }
+ ret = AVL_SDK_LoadConfigFile(p_engine_handle, (char *)DEFAULT_CONFIG_FILE);
+ if(ret != ERR_SUCCESS)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_SDK_LoadConfigFile error: %ld", ret);
+ return -1;
+ }
+ ret = AVL_SDK_SetConfigInt(p_engine_handle, CFG_INT_APACK_RECURE_LAYER, 5);
+ if(ret != ERR_SUCCESS)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_SDK_SetConfigInt error: %ld", ret);
+ return -1;
+ }
+ ret = AVL_SDK_SetConfigString(p_engine_handle, CFG_STR_LICENSE_PATH, DEFAULT_LICENCE_FILE);
+ if(ret != ERR_SUCCESS)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_SDK_SetConfigString error: %ld", ret);
+ return -1;
+ }
+ ret = AVL_SDK_InitInstance(p_engine_handle, NULL);
+ if(ret != ERR_SUCCESS)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_SDK_InitInstance error: %ld", ret);
+ return -1;
+ }
+
+ ret = AVL_NTranser_Init(DEFAULT_ID2N_DB_PATH, &p_i2n_handle);
+ if(ret != ERR_SUCCESS)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_NTranser_Init error: %ld", ret);
+ return -1;
+ }
+
+ g_objscan_info.p_engine_handle = p_engine_handle;
+ g_objscan_info.p_i2n_handle = p_i2n_handle;
+ return 0;
+}
+
+static long func_long_query_continue_callback(void *p_param)
+{
+ message_meta_item_t *message = (message_meta_item_t *)p_param;
+
+ // This is the code sample, so it returns unconditionally. Users can modify according to the condition.
+ //�кܶ����ļ��������һ�����ļ�ɨ�к��ټ���ɨ��
+ return (message->hitted)?OD_ABORT:OD_CONTINUE;
+}
+
+static long func_long_get_rslt_callback(P_OBJ_PROVIDER p_op, void *p_data, void *p_param)
+{
+ long long_malware_id=0, long_qry_ret=-1;
+ message_meta_item_t *message = (message_meta_item_t *)p_param;
+ unsigned char *puchar_analyser=NULL, auchar_malware_name[128]={0};
+ char *malware_type, *malware_name;
+ char *save_ptr;
+
+ if(p_data == NULL)
+ {
+ return -1;
+ }
+ // Query the Malware ID
+ long_qry_ret = AVL_SDK_QueryReportInt(g_objscan_info.p_engine_handle, p_data, RPT_IDX_MALWARE_ID, &long_malware_id);
+ if (long_qry_ret==ERR_RPT_NOT_EXIST || long_qry_ret<0)
+ {
+ return long_qry_ret;
+ }
+
+ // Query the analyser who detected this malware, users will use it when they need to get the malware name
+ long_qry_ret = AVL_SDK_QueryReportStr(g_objscan_info.p_engine_handle, p_data, RPT_IDX_ANALYSER, &puchar_analyser);
+ if (long_qry_ret != ERR_SUCCESS)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_SDK_QueryReportStr error: %ld", long_qry_ret);
+ return long_qry_ret;
+ }
+
+ // Query the VName
+ long_qry_ret = AVL_NTranser_QueryNameByID(g_objscan_info.p_i2n_handle, (char *)puchar_analyser, long_malware_id, (unsigned char *)auchar_malware_name, sizeof(auchar_malware_name) - 1);
+ if (long_qry_ret < 0)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_NTranser_QueryNameByID error: %ld", long_qry_ret);
+ return long_qry_ret;
+ }
+
+ /* AVL���к�, auchar_malware_name��ʽ�����"Trojan/Win32.SGeneric", ��Ҫ��� */
+ malware_type = strtok_r((char *)auchar_malware_name, "/", &save_ptr);
+ malware_name = strtok_r(NULL, "/", &save_ptr);
+ if(NULL == malware_name)
+ {
+ malware_name = malware_type;
+ }
+ cJSON_AddNumberToObject(message->meta_json, "malware_id", long_malware_id);
+ cJSON_AddStringToObject(message->meta_json, "malware_type", malware_type);
+ cJSON_AddStringToObject(message->meta_json, "malware_name", malware_name);
+ message->hitted = 1;
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_DEBUG, "AVL_SDK_Scan %s hit, type: %s, name: %s", message->object_uri, malware_type, malware_name);
+ atomic_inc(&g_objscan_info.statistic.num[MESSAGE_HITTED]);
+ return long_qry_ret;
+}
+
+static int32_t scan_object_by_avl_engine(message_meta_item_t *message)
+{
+ long long_last_ret = 0;
+ OBJ_PROVIDER op = {0};
+ OBJ_DISPOSER od = {0};
+
+ op.obj_ver = CUR_ENGINE_VER;
+ op.evro_type = ET_DESKTOP;
+ op.buf = (unsigned char *)message->content;
+ op.size = message->current_len;
+ strncpy((char *)op.obj_des, message->object_uri, strlen(message->object_uri));
+
+ od.rpt_callback = func_long_get_rslt_callback;
+ od.p_rpt_param = message;
+ od.query_continue_callback = func_long_query_continue_callback;
+ od.p_qc_param = message;
+
+ long_last_ret = AVL_SDK_Scan(g_objscan_info.p_engine_handle, &op, &od);
+ if (long_last_ret < 0)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_FATAL, "AVL_SDK_Scan error: %ld", long_last_ret);
+ return 0;
+ }
+ return message->hitted;
+}
+
+void* thread_analyze_object(void *arg)
+{
+ message_meta_item_t *message;
+ char *buffer;
+ size_t buflen;
+ long node_size;
+ int ret=0;
+
+ prctl(PR_SET_NAME, "anly_object");
+ while(1)
+ {
+ node_size = sizeof(message_meta_item_t *);
+ if(MESA_lqueue_get_head(g_objscan_info.queue_analyze, (void *)&message, &node_size))
+ {
+ usleep(100000);
+ continue;
+ }
+
+ if(scan_object_by_avl_engine(message))
+ {
+ buffer = cJSON_PrintUnformatted(message->meta_json);
+ buflen = strlen(buffer);
+ ret = rd_kafka_produce(g_objscan_info.produc_topic, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_FREE, buffer, buflen, NULL, 0, NULL);
+ rd_kafka_poll(g_objscan_info.kafka_producer, 0);
+ if(ret!=0)
+ {
+ MESA_HANDLE_RUNTIME_LOGV2(g_objscan_info.log_runtime, RLOG_LV_DEBUG, "rd_kafka_produce error: %d", rd_kafka_last_error());
+ atomic_inc(&g_objscan_info.statistic.num[MESSAGE_OTH_FAIL]);
+ free(buffer);
+ }
+ }
+ else
+ {
+ atomic_inc(&g_objscan_info.statistic.num[MESSAGE_SUCC]);
+ }
+ destroy_parsed_message(message);
+ }
+ return NULL;
+}
+
+void get_future_failed(enum e_future_error err, const char * what, void * user)
+{
+ message_meta_item_t *message = (message_meta_item_t *)user;
+
+ atomic_inc(&(g_objscan_info.statistic.num[MESSAGE_OTH_FAIL]));
+ destroy_parsed_message(message);
+}
+
+void get_future_success(future_result_t* result, void * user)
+{
+ struct tango_cache_result *res = cache_evbase_read_result(result);
+ message_meta_item_t *message = (message_meta_item_t *)user;
+
+ switch(res->type)
+ {
+ case RESULT_TYPE_USERTAG:
+ case RESULT_TYPE_HEADER:
+ if(message->content == NULL)
+ {
+ message->max_len = (res->tlength>=g_objscan_info.anly_max_len)?g_objscan_info.anly_max_len:res->tlength;
+ message->content = (char *)malloc(message->max_len);
+ }
+ break;
+
+ case RESULT_TYPE_BODY:
+ if(message->current_len+res->size <= message->max_len)
+ {
+ memcpy(message->content+message->current_len, res->data_frag, res->size);
+ message->current_len += res->size;
+ }
+ break;
+
+ case RESULT_TYPE_MISS:
+ atomic_inc(&(g_objscan_info.statistic.num[MESSAGE_NOT_EXIST]));
+ destroy_parsed_message(message);
+ break;
+
+ case RESULT_TYPE_END:
+ if(MESA_lqueue_join_tail(g_objscan_info.queue_analyze, (void *)&message, sizeof(message)) < 0)
+ {
+ atomic_inc(&g_objscan_info.statistic.num[MESSAGE_DROP]);
+ destroy_parsed_message(message);
+ }
+ break;
+ default:break;
+ }
+}
+
+void* thread_fetch_object(void *arg)
+{
+ message_meta_item_t *message;
+ long node_size;
+ struct tango_cache_meta_get getmeta;
+
+ prctl(PR_SET_NAME, "fetch_object");
+ memset(&getmeta, 0, sizeof(struct tango_cache_meta_get));
+ while(1)
+ {
+ node_size = sizeof(message_meta_item_t *);
+ if(MESA_lqueue_get_head(g_objscan_info.queue_delay, (void *)&message, &node_size))
+ {
+ usleep(100000);
+ continue;
+ }
+
+ message->future = future_create(get_future_success, get_future_failed, message);
+
+ getmeta.url = message->object_uri;
+ if(object_store_fetch_object(g_objscan_info.instance, message->future, &getmeta, OBJECT_IN_UNKNOWN) < 0)
+ {
+ get_future_failed(FUTURE_ERROR_CANCEL, "", message);
+ }
+ }
+ return NULL;
+}
+