wazuh-modules-sca-scan
sca模块主函数wm_sca_main -> wm_sca_start
检查policy文件中的每一个项目wm_sca_check_policy
static int wm_sca_check_policy(const cJSON * const policy, const cJSON * const checks, OSHash *global_check_list)
{if(!policy) {return 1;}const cJSON * const id = cJSON_GetObjectItem(policy, "id");if(!id) {mwarn("Field 'id' not found in policy header.");return 1;}if(!id->valuestring){mwarn("Invalid format for field 'id'");return 1;}char *coincident_policy_file;if((coincident_policy_file = OSHash_Get(global_check_list,id->valuestring)), coincident_policy_file) {mwarn("Found duplicated policy ID: %s. File '%s' contains the same ID.", id->valuestring, coincident_policy_file);return 1;}const cJSON * const name = cJSON_GetObjectItem(policy, "name");if(!name) {mwarn("Field 'name' not found in policy header.");return 1;}if(!name->valuestring){mwarn("Invalid format for field 'name'");return 1;}const cJSON * const file = cJSON_GetObjectItem(policy, "file");if(!file) {mwarn("Field 'file' not found in policy header.");return 1;}if(!file->valuestring){mwarn("Invalid format for field 'file'");return 1;}const cJSON * const description = cJSON_GetObjectItem(policy, "description");if(!description) {mwarn("Field 'description' not found in policy header.");return 1;}const cJSON * const regex_type = cJSON_GetObjectItem(policy, "regex_type");if(!regex_type) {mdebug1("Field 'regex_type' not found in policy header. The OS_REGEX engine shall be used.");}if(!description->valuestring) {mwarn("Invalid format for field 'description'");return 1;}// Check for policy rules with duplicated IDs */if (!checks) {mwarn("Section 'checks' not found.");return 1;}int *read_id;os_calloc(1, sizeof(int), read_id);read_id[0] = 0;const cJSON *check;cJSON_ArrayForEach(check, checks) {const cJSON * const check_id = cJSON_GetObjectItem(check, "id");if (check_id == NULL) {mwarn("Check ID not found.");free(read_id);return 1;}if (check_id->valueint <= 0) {// Invalid IDmwarn("Invalid check ID: %d", check_id->valueint);free(read_id);return 1;}char *coincident_policy;char *key_id;size_t key_length = snprintf(NULL, 0, "%d", check_id->valueint);os_malloc(key_length + 1, key_id);snprintf(key_id, key_length + 1, "%d", check_id->valueint);if((coincident_policy = (char *)OSHash_Get(global_check_list, key_id)), coincident_policy){// Invalid IDmwarn("Found duplicated check ID: %d. First appearance at policy '%s'", check_id->valueint, coincident_policy);os_free(key_id);os_free(read_id);return 1;}os_free(key_id);int i;for (i = 0; read_id[i] != 0; i++) {if (check_id->valueint == read_id[i]) {// Duplicated IDmwarn("Found duplicated check ID: %d", check_id->valueint);free(read_id);return 1;}}os_realloc(read_id, sizeof(int) * (i + 2), read_id);read_id[i] = check_id->valueint;read_id[i + 1] = 0;const cJSON * const rules = cJSON_GetObjectItem(check, "rules");if (rules == NULL) {mwarn("Invalid check %d: no rules found.", check_id->valueint);free(read_id);return 1;}int rules_n = 0;const cJSON *rule;cJSON_ArrayForEach(rule, rules) {if (!rule->valuestring) {mwarn("Invalid check %d: Empty rule.", check_id->valueint);free(read_id);return 1;}char *valuestring_ref = rule->valuestring;valuestring_ref += 4 * (!strncmp(valuestring_ref, "NOT ", 4) || !strncmp(valuestring_ref, "not ", 4));switch (*valuestring_ref) {
#ifdef WIN32case 'r':
#endifcase 'f':case 'd':case 'p':case 'c':break;case '\0':mwarn("Invalid check %d: Empty rule.", check_id->valueint);free(read_id);return 1;default:mwarn("Invalid check %d: Invalid rule format.", check_id->valueint);free(read_id);return 1;}rules_n++;if (rules_n > 255) {free(read_id);mwarn("Invalid check %d: Maximum number of rules is 255.", check_id->valueint);return 1;}}if (rules_n == 0) {mwarn("Invalid check %d: no rules found.", check_id->valueint);free(read_id);return 1;}}char *policy_file = NULL;os_strdup(file->valuestring, policy_file);const int id_add_retval = OSHash_Add(global_check_list, id->valuestring, policy_file);if (id_add_retval == 0){os_free(policy_file);os_free(read_id);merror_exit("(1102): Could not acquire memory");}if (id_add_retval == 1){merror("Error validating duplicated ID. Policy %s in file %s is duplicated", id->valuestring, policy_file);os_free(policy_file);os_free(read_id);return 1;}int i;for (i = 0; read_id[i] != 0; ++i) {char *policy_id = NULL;os_strdup(id->valuestring, policy_id);const int check_add_retval = OSHash_Numeric_Add_ex(global_check_list, read_id[i], policy_id);if (check_add_retval == 0){os_free(policy_id);os_free(read_id);merror_exit("(1102): Could not acquire memory");}if (check_add_retval == 1){merror("Error validating duplicated ID. Check %s in policy %s is duplicated", id->valuestring, policy_id);os_free(policy_id);os_free(read_id);return 1;}}os_free(read_id);return 0;
}
policy文件中的具体rules项目,其中规则之一:
# 1.1.1.3 udf: filesystem- id: 6002title: "Ensure mounting of udf filesystems is disabled"description: "The udf filesystem type is the universal disk format used to implement ISO/IEC 13346 and ECMA-167 specifications. This is an open vendor filesystem type for data storage on a broad range of media. This filesystem type is necessary to support writing DVDs and newer optical disc formats."rationale: "Removing support for unneeded filesystem types reduces the local attack surface of the system. If this filesystem type is not needed, disable it."remediation: "Edit or create the file /etc/modprobe.d/CIS.conf and add the following line: install udf /bin/true. Run the following command to unload the udf module: rmmod udf"compliance:- cis: ["1.1.1.3"]- cis_csc: ["5.1"]- pci_dss: ["2.2.5"]- tsc: ["CC6.3"]references:- AJ Lewis, "LVM HOWTO", https://tldp.org/HOWTO/LVM-HOWTO/condition: allrules:- 'c:modprobe -n -v udf -> r:install /bin/true|Module udf not found'- 'not c:lsmod -> r:udf'
rules中的每一项是r (读取), f,d,p,c,not,NOT开头 "->"表示前一个动作之后的接着的下一个动作,或者条件
sca扫描核心函数
/*
Rules that match always return 1, and the other way arround.Rule aggregators logic:##########################################################ALL:r_1 -f -> r:123...r_n -f -> r:234For an ALL to succeed, every rule shall return 1, in other words,| = n -> ALL = RETURN_FOUND
SUM(r_i, 0, n) || != n -> ALL = RETURN_NOT_FOUND##########################################################ANY:r_1 -f -> r:123...r_n -f -> r:234For an ANY to succeed, a rule shall return 1, in other words,| > 0 -> ANY = RETURN_FOUND
SUM(r_i, 0, n) || = 0 -> ANY = RETURN_NOT_FOUND##########################################################NONE:r_1 -f -> r:123...r_n -f -> r:234For a NONE to succeed, all rules shall return RETURN_NOT_FOUND, in other words,| > 0 -> NONE = RETURN_NOT_FOUND
SUM(r_i, 0, n) || = 0 -> NONE = RETURN_FOUND##########################################################ANY and NONE aggregators are complementary.*/static int wm_sca_do_scan(cJSON * checks,OSStore * vars,wm_sca_t * data,int id,cJSON * policy,int requirements_scan,int cis_db_index,unsigned int remote_policy,int first_scan,int * checks_number,char ** sorted_variables,char * policy_engine)
{int type = 0;char buf[OS_SIZE_1024 + 2];char final_file[2048 + 1];char *reason = NULL;int ret_val = 0;OSList *p_list = NULL;/* Initialize variables */memset(buf, '\0', sizeof(buf));memset(final_file, '\0', sizeof(final_file));int check_count = 0;cJSON *check = NULL;cJSON_ArrayForEach(check, checks) {char _check_id_str[50];if (requirements_scan) {snprintf(_check_id_str, sizeof(_check_id_str), "Requirements check");} else {const cJSON * const c_id = cJSON_GetObjectItem(check, "id");if (!c_id || !c_id->valueint) {merror("Skipping check. Check ID is invalid. Offending check number: %d", check_count);ret_val = 1;continue;}snprintf(_check_id_str, sizeof(_check_id_str), "id: %d", c_id->valueint);}const cJSON * const c_title = cJSON_GetObjectItem(check, "title");if (!c_title || !c_title->valuestring) {merror("Skipping check with %s: Check name is invalid.", _check_id_str);if (requirements_scan) {ret_val = 1;goto clean_return;}continue;}const cJSON * const c_condition = cJSON_GetObjectItem(check, "condition");if (!c_condition || !c_condition->valuestring) {merror("Skipping check '%s: %s': Check condition not found.", _check_id_str, c_title->valuestring);if (requirements_scan) {ret_val = 1;goto clean_return;}continue;}int condition = 0;wm_sca_set_condition(c_condition->valuestring, &condition);if (condition == WM_SCA_COND_INV) {merror("Skipping check '%s: %s': Check condition (%s) is invalid.",_check_id_str, c_title->valuestring, c_condition->valuestring);if (requirements_scan) {ret_val = 1;goto clean_return;}continue;}int g_found = RETURN_NOT_FOUND;if ((condition & WM_SCA_COND_ANY) || (condition & WM_SCA_COND_NON)) {/* aggregators ANY and NONE break by matching, so they shall return NOT_FOUND if they never break */g_found = RETURN_NOT_FOUND;} else if (condition & WM_SCA_COND_ALL) {/* aggregator ALL breaks the moment a rule does not match. If it doesn't break, all rules have matched */g_found = RETURN_FOUND;}mdebug1("Beginning evaluation of check %s '%s'", _check_id_str, c_title->valuestring);mdebug1("Rule aggregation strategy for this check is '%s'", c_condition->valuestring);mdebug2("Initial rule-aggregator value por this type of rule is '%d'", g_found);mdebug1("Beginning rules evaluation.");const cJSON *const rules = cJSON_GetObjectItem(check, "rules");if (!rules) {merror("Skipping check %s '%s': No rules found.", _check_id_str, c_title->valuestring);if (requirements_scan) {ret_val = 1;goto clean_return;}continue;}w_expression_t * regex_engine = NULL;cJSON * engine = cJSON_GetObjectItem(check, "regex_type");if (engine) {if (strcmp(PCRE2_STR, cJSON_GetStringValue(engine)) == 0) {w_calloc_expression_t(®ex_engine, EXP_TYPE_PCRE2);} else {w_calloc_expression_t(®ex_engine, EXP_TYPE_OSREGEX);}} else {if(strcmp(PCRE2_STR, policy_engine) == 0) {w_calloc_expression_t(®ex_engine, EXP_TYPE_PCRE2);} else {w_calloc_expression_t(®ex_engine, EXP_TYPE_OSREGEX);}}mdebug1("SCA will use '%s' engine to check the rules.", w_expression_get_regex_type(regex_engine));char *rule_cp = NULL;const cJSON *rule_ref;cJSON_ArrayForEach(rule_ref, rules) {/* this free is responsible of freeing the copy of the previous rule ifthe loop 'continues', i.e, does not reach the end of its block. */os_free(rule_cp);if(!rule_ref->valuestring) {mdebug1("Field 'rule' must be a string.");ret_val = 1;os_free(regex_engine);goto clean_return;}mdebug1("Considering rule: '%s'", rule_ref->valuestring);os_strdup(rule_ref->valuestring, rule_cp);char *rule_cp_ref = NULL;#ifdef WIN32char expanded_rule[2048] = {0};ExpandEnvironmentStrings(rule_cp, expanded_rule, 2048);rule_cp_ref = expanded_rule;mdebug2("Rule after variable expansion: '%s'", rule_cp_ref);#elserule_cp_ref = rule_cp;#endifint rule_is_negated = 0;if (rule_cp_ref &&(strncmp(rule_cp_ref, "NOT ", 4) == 0 ||strncmp(rule_cp_ref, "not ", 4) == 0)){mdebug2("Rule is negated.");rule_is_negated = 1;rule_cp_ref += 4;}/* Get value to look for. char *value is a referenceto rule_cp memory. Do not release value! */char *value = wm_sca_get_value(rule_cp_ref, &type);if (value == NULL) {merror("Invalid rule: '%s'. Skipping policy.", rule_ref->valuestring);os_free(rule_cp);ret_val = 1;os_free(regex_engine);goto clean_return;}int found = RETURN_NOT_FOUND;if (type == WM_SCA_TYPE_FILE) {/* Check files */char *pattern = wm_sca_get_pattern(value);char *rule_location = NULL;char *aux = NULL;os_strdup(value, rule_location);/* If any, replace the variables by their respective values */if (sorted_variables) {int i = 0;for (i = 0; sorted_variables[i]; i++) {if (strstr(rule_location, sorted_variables[i])) {mdebug2("Variable '%s' found at rule '%s'. Replacing it.", sorted_variables[i], rule_location);aux = wstr_replace(rule_location, sorted_variables[i], OSStore_Get(vars, sorted_variables[i]));os_free(rule_location);rule_location = aux;if (!rule_location) {merror("Invalid variable replacement: '%s'. Skipping check.", sorted_variables[i]);break;}mdebug2("Variable replaced: '%s'", rule_location);}}}if (!rule_location) {continue;}const int result = wm_sca_check_file_list(rule_location, pattern, &reason, regex_engine);if (result == RETURN_FOUND || result == RETURN_INVALID) {found = result;}char _b_msg[OS_SIZE_1024 + 1];_b_msg[OS_SIZE_1024] = '\0';snprintf(_b_msg, OS_SIZE_1024, " File: %s", rule_location);append_msg_to_vm_scat(data, _b_msg);os_free(rule_location);} else if (type == WM_SCA_TYPE_COMMAND) {/* Check command output */char *pattern = wm_sca_get_pattern(value);char *rule_location = NULL;char *aux = NULL;os_strdup(value, rule_location);if (!data->remote_commands && remote_policy) {mwarn("Ignoring check for policy '%s'. The internal option 'sca.remote_commands' is disabled.", cJSON_GetObjectItem(policy, "name")->valuestring);if (reason == NULL) {os_malloc(snprintf(NULL, 0, "Ignoring check for running command '%s'. The internal option 'sca.remote_commands' is disabled", rule_location) + 1, reason);sprintf(reason, "Ignoring check for running command '%s'. The internal option 'sca.remote_commands' is disabled", rule_location);}found = RETURN_INVALID;} else {/* If any, replace the variables by their respective values */if (sorted_variables) {int i = 0;for (i = 0; sorted_variables[i]; i++) {if (strstr(rule_location, sorted_variables[i])) {mdebug2("Variable '%s' found at rule '%s'. Replacing it.", sorted_variables[i], rule_location);aux = wstr_replace(rule_location, sorted_variables[i], OSStore_Get(vars, sorted_variables[i]));os_free(rule_location);rule_location = aux;if (!rule_location) {merror("Invalid variable: '%s'. Skipping check.", sorted_variables[i]);break;}mdebug2("Variable replaced: '%s'", rule_location);}}}if (!rule_location) {continue;}mdebug2("Running command: '%s'", rule_location);const int val = wm_sca_read_command(rule_location, pattern, data, &reason, regex_engine);if (val == RETURN_FOUND) {mdebug2("Command output matched.");found = RETURN_FOUND;} else if (val == RETURN_INVALID){mdebug2("Command output did not match.");found = RETURN_INVALID;}}char _b_msg[OS_SIZE_1024 + 1];_b_msg[OS_SIZE_1024] = '\0';snprintf(_b_msg, OS_SIZE_1024, " Command: %s", rule_location);append_msg_to_vm_scat(data, _b_msg);os_free(rule_location);} else if (type == WM_SCA_TYPE_DIR) {/* Check directory */mdebug2("Processing directory rule '%s'", value);char * const file = wm_sca_get_pattern(value);char *rule_location = NULL;char *aux = NULL;os_strdup(value, rule_location);/* If any, replace the variables by their respective values */if (sorted_variables) {int i = 0;for (i = 0; sorted_variables[i]; i++) {if (strstr(rule_location, sorted_variables[i])) {mdebug2("Variable '%s' found at rule '%s'. Replacing it.", sorted_variables[i], rule_location);aux = wstr_replace(rule_location, sorted_variables[i], OSStore_Get(vars, sorted_variables[i]));os_free(rule_location);rule_location = aux;if (!rule_location) {merror("Invalid variable: '%s'. Skipping check.", sorted_variables[i]);break;}mdebug2("Variable replaced: '%s'", rule_location);}}}if (!rule_location) {continue;}char * const pattern = wm_sca_get_pattern(file);found = wm_sca_check_dir_list(data, rule_location, file, pattern, &reason, regex_engine);mdebug2("Check directory rule result: %d", found);os_free(rule_location);} else if (type == WM_SCA_TYPE_PROCESS) {/* Check process existence */if (!p_list) {/* Lazy evaluation */p_list = w_os_get_process_list();}mdebug2("Checking process: '%s'", value);if (wm_sca_check_process_is_running(p_list, value, &reason, regex_engine)) {mdebug2("Process found.");found = RETURN_FOUND;} else {mdebug2("Process not found.");}char _b_msg[OS_SIZE_1024 + 1];_b_msg[OS_SIZE_1024] = '\0';snprintf(_b_msg, OS_SIZE_1024, " Process: %s", value);append_msg_to_vm_scat(data, _b_msg);}#ifdef WIN32else if (type == WM_SCA_TYPE_REGISTRY) {/* Check windows registry */char * const entry = wm_sca_get_pattern(value);char * const pattern = wm_sca_get_pattern(entry);found = wm_sca_is_registry(value, entry, pattern, &reason, regex_engine);char _b_msg[OS_SIZE_1024 + 1];_b_msg[OS_SIZE_1024] = '\0';snprintf(_b_msg, OS_SIZE_1024, " Registry: %s", value);append_msg_to_vm_scat(data, _b_msg);}#endif/* Rule result processing */if (found != RETURN_INVALID) {found = rule_is_negated ^ found;}mdebug1("Result for rule '%s': %d", rule_ref->valuestring, found);if (((condition & WM_SCA_COND_ALL) && found == RETURN_NOT_FOUND) ||((condition & WM_SCA_COND_ANY) && found == RETURN_FOUND) ||((condition & WM_SCA_COND_NON) && found == RETURN_FOUND)){g_found = found;mdebug1("Breaking from rule aggregator '%s' with found = %d", c_condition->valuestring, g_found);break;}if (found == RETURN_INVALID) {/* Rules that agreggate by ANY are the only that can success after an INVALIDOn the other hand ALL and NONE agregators can fail after an INVALID. */g_found = found;mdebug1("Rule evaluation returned INVALID. Continuing.");}}if ((condition & WM_SCA_COND_NON) && g_found != RETURN_INVALID) {g_found = !g_found;}mdebug1("Result for check %s '%s' -> %d", _check_id_str, c_title->valuestring, g_found);if (g_found != RETURN_INVALID) {os_free(reason);}/* if the loop breaks, rule_cp shall be released.Also frees the the memory reserved on the last iteration */os_free(rule_cp);/* Determine if requirements are satisfied */if (requirements_scan) {/* return value for requirement scans is the inverse of the result,unless the result is INVALID */ret_val = g_found == RETURN_INVALID ? 1 : !g_found;int i;for (i=0; data->alert_msg[i]; i++){free(data->alert_msg[i]);data->alert_msg[i] = NULL;}w_free_expression_t(®ex_engine);goto clean_return;}/* Event construction */const char failed[] = "failed";const char passed[] = "passed";const char invalid[] = ""; //NOT AN ERROR!const char *message_ref = NULL;if (g_found == RETURN_NOT_FOUND) {wm_sca_summary_increment_failed();message_ref = failed;} else if (g_found == RETURN_FOUND) {wm_sca_summary_increment_passed();message_ref = passed;} else {wm_sca_summary_increment_invalid();message_ref = invalid;if (reason == NULL) {os_malloc(snprintf(NULL, 0, "Unknown reason") + 1, reason);sprintf(reason, "Unknown reason");mdebug1("A check returned INVALID for an unknown reason.");}}cJSON *event = wm_sca_build_event(check, policy, data->alert_msg, id, message_ref, reason);if (event) {/* Alert if necessary */if(!cis_db_for_hash[cis_db_index].elem[check_count]) {os_realloc(cis_db_for_hash[cis_db_index].elem, sizeof(cis_db_info_t *) * (check_count + 2), cis_db_for_hash[cis_db_index].elem);cis_db_for_hash[cis_db_index].elem[check_count] = NULL;cis_db_for_hash[cis_db_index].elem[check_count + 1] = NULL;}if (wm_sca_check_hash(cis_db[cis_db_index], message_ref, check, event, check_count, cis_db_index) && !first_scan) {wm_sca_send_event_check(data,event);}check_count++;cJSON_Delete(event);} else {merror("Error constructing event for check: %s. Set debug mode for more information.", c_title->valuestring);ret_val = 1;}int i;for (i=0; data->alert_msg[i]; i++){free(data->alert_msg[i]);data->alert_msg[i] = NULL;}os_free(reason);w_free_expression_t(®ex_engine);}*checks_number = check_count;/* Clean up memory */
clean_return:os_free(reason);w_del_plist(p_list);return ret_val;
}
迭代每一个检查项cJSON_ArrayForEach(check, checks)
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
相关文章:
wazuh-modules-sca-scan
sca模块主函数wm_sca_main -> wm_sca_start 检查policy文件中的每一个项目wm_sca_check_policy static int wm_sca_check_policy(const cJSON * const policy, const cJSON * const checks, OSHash *global_check_list) {if(!policy) {return 1;}const cJSON * const id c…...
力扣-图论-15【算法学习day.65】
前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非…...
JS萤石云录像回放拖动进度条无法正常播放
问题描述: 本项目版本:vue2.6.12,webpack3.6.0,ezuikit-js0.7.2 在使用萤石云的JavaScript SDK做监控的直播、录像回放时,遇到部分设备的录像回放,无法根据控制面板的拖动进度条查看某时间段的录像。 官方…...
Spring Boot 启动时间优化全攻略
引言 随着 Spring Boot 的广泛应用,开发者享受到了快速开发和自动化配置的便利。然而,随着项目复杂度的增加,Spring Boot 项目启动时间也变得越来越长,这在开发、调试和部署阶段可能会成为效率瓶颈。如何优化 Spring Boot 的启动…...
ubuntu服务器木马类挖矿程序排查、及安全管理总结
版本 24.04 由于GPU多卡服务器多人使用,需要链接隧道ssh等,容易中招挖矿脚本。 总的思路是,顺着进程的PID回溯最终的程序运行起点,这里可以先看一下日志: journalctl -u PID 通过 PID 精确定位进程的信息,…...
redis 使用Lettuce 当redis挂掉重启之后 网络是怎么重新连接
Lettuce是一个高性能的Java Redis客户端,支持同步、异步和反应式编程模式 Lettuce的核心功能包括: 高性能:通过使用Netty作为底层网络通信框架,实现了非阻塞IO,提高了性能。丰富的API:提供了丰富…...
【PyTorch】实现在训练过程中自定义动态调整学习率
问题描述: 在使用 PyTorch 训练自定义神经网络时,我们希望能够动态地调整学习率,以便在训练过程中逐渐优化模型,避免过拟合并加速收敛。那么,如何在 PyTorch 中实现这一功能呢? 解决方案: 在训…...
【Flink-scala】DataStream编程模型总结
系列文章目录 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器 4.【Flink-scala】DataStream编程模型之水位线 5.【…...
语音芯片赋能可穿戴设备:开启个性化音频新体验
在科技日新月异的今天,语音芯片与可穿戴设备的携手合作,正引领我们步入一个前所未有的个性化音频时代。这一创新融合,用户可以享受到更加个性化、沉浸式的音频体验。下面将详细介绍语音芯片与可穿戴设备合作的优点和具体应用。 1. 定制化音效…...
JavaFX使用jfoenix的UI控件
jfoenix还是一个不错的样式,推荐使用,而且也可以支持scene builder中的拖拖拽拽 需要注意的是过高的javafx版本可能会使得某些样式或控件无法使用 比如alert控件,亲测javaFX 19版本可以正常使用 1.在pom.xml中引入依赖 GitHub地址https://gi…...
SpringBoot集成ENC对配置文件进行加密
在线MD5生成工具 配置文件加密,集成ENC 引入POM依赖 <!-- ENC配置文件加密 --><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.2</ver…...
基于AI对话生成剧情AVG游戏
游戏开发这个领域,一直有较高的学习门槛。作为一个非专业的游戏爱好者,如果想要开发游戏,往往受制于游戏引擎的专业程度,难以完成复杂的游戏项目。 AI IDE的诞生,提供了另外的一种思路,即通过AI 生成项目及…...
MAVEN--Maven的生命周期,pom.xml详解,Maven的高级特性(模块化、聚合、依赖管理)
目录 (一)Maven的生命周期 1.Maven的三套生命周期 2.Maven常用命令 (二)pom.xml详解 (三)Maven的高级特性(模块化、聚合、依赖管理) 1.Maven的依赖范围 2.版本维护 3.依赖传…...
SpringBoot的事务钩子函数
如果需要在A方法执行完成之后做一个不影响主方法运行的动作B,我们需要判断这个A方法是否存在事务,并且使用异步执行动作B; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transa…...
uniapp滚动消息列表
两个相同的循环列表,循环滚动 <view class"winners_list uni-flex uni-column" :animation"animationData"><view v-for"(item, index) in winnersList" :key"index" class"li uni-flex uni-column"&g…...
基于python对pdf文件进行加密等操作
利用python对pdf文件进行操作 读取pdf-源码 import PyPDF2 # 读取pdf格式的文件 reader PyPDF2.PdfFileReader(示例文件/aaa.pdf) print(reader)# 读取指定页面的文件 page reader.getPage(0) # 输出当前页面的文本数据 print(page.extractText())读取pdf-源码解析 这段代…...
Three.js材质纹理扩散过渡
Three.js材质纹理扩散过渡 import * as THREE from "three"; import { ThreeHelper } from "/src/ThreeHelper"; import { LoadGLTF, MethodBaseSceneSet } from "/src/ThreeHelper/decorators"; import { MainScreen } from "/src/compone…...
【Leetcode 每日一题 - 扩展】45. 跳跃游戏 II
问题背景 给定一个长度为 n n n 的 0 0 0 索引 整数数组 n u m s nums nums。初始位置为 n u m s [ 0 ] nums[0] nums[0]。 每个元素 n u m s [ i ] nums[i] nums[i] 表示从索引 i i i 向前跳转的最大长度。换句话说,如果你在 n u m s [ i ] nums[i] nums[i…...
被裁20240927 --- YOLO 算法
背景 在云端部署ViSP,ViSP实现视觉伺服、yolo实现视觉跟踪。 开源的2d视觉跟踪算法有哪些? 开源的2D视觉跟踪算法有很多呢,这里给你推荐一些比较知名和常用的吧。 ByteTrackV2:这是一个通用2D跟踪算法,提出了分层的…...
AI技术架构:从基础设施到应用
人工智能(AI)的发展,正以前所未有的速度重塑我们的世界。了解AI技术架构,不仅能帮助我们看懂 AI 的底层逻辑,还能掌握其对各行业变革的潜力与方向。 一、基础设施层:AI 技术的坚实地基 基础设施层是 AI 技…...
植物大战僵尸辅助【控制台版本】
前面介绍了使用CE和OD的简单使用:CE和OD介绍和使用CE查找阳光的教学:阳光基地址和偏移地址,下面先使用最简单的控制台程序来实现修改阳光的功能。 项目地址 1.分析程序 我们的控制台程序想要修改植物大战僵尸游戏内的数据,它们…...
css中样式前加 css样式前面加个圆点
创建CSS样式,样式名称的前面需要加什么 1、我们只知道符号代表的意思是at,其翻译是 在... 例如media就是 在媒介上。没人规定本身具有什么意义,或者说就算规定了我们也改变不了,只需要知道其规定属性的用法即可。 2、px;}然后根据你自己索要…...
算法刷题Day18: BM41 输出二叉树的右视图
题目链接 描述 思路: 递归构造二叉树在Day15有讲到。复习一下,就是使用递归构建左右子树。将中序和前序一分为二。 接下来是找出每一层的最右边的节点,可以利用队列层次遍历。 利用队列长度记录当前层有多少个节点,每次从队列里…...
如何实现规范化LabVIEW编程
规范编写LabVIEW程序的目的是提高代码的可读性、可维护性、可扩展性,并确保团队成员能够高效地理解和修改代码。以下是一些关键建议,帮助您编写更专业的LabVIEW代码,并确保它易于后续的升级和维护: 1. 合理的项目结构 目录结构…...
TQ15EG开发板教程:使用SSH登录petalinux
本例程在上一章“创建运行petalinux2019.1”基础上进行,本例程将实现使用SSH登录petalinux。 将上一章生成的BOOT.BIN与imag.ub文件放入到SD卡中启动。给开发板插入电源与串口,注意串口插入后会识别出两个串口号,都需要打开,查看串…...
Springboot+vue实现大文件上传
背景:为了实现大文件上传的功能 1新建数据表sql file_chunk CREATE TABLE file_chunk (id bigint UNSIGNED NOT NULL AUTO_INCREMENT,file_name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NULL DEFAULT NULL COMMENT 文件名,chunk_nu…...
Linux笔记
常用的基本命令 查询某个安装包有没有安装某个软件 使用的命令是rpm -qa |grep 软件名字 卸载软件 rpm -e --nodeps 软件名称 查看已经启动的服务 netstat -tunlp 一般我们在Linux系统中上传文件一般上传到 /usr/local/src的目录下 查看防火墙的命令 firewall-cmd --sta…...
相机(Camera)成像原理详解
简介:个人学习分享,如有错误,欢迎批评指正。 成像流程 1、光学相机的定义 顾名思义,光学相机就是利用光学原理进行成像的相机,而且市面上的相机几乎都是光学相机,只不过随着时代的发展,胶卷式…...
计算机网络知识点全梳理(一.TCP/IP网络模型)
目录 TCP/IP网络模型概述 应用层 什么是应用层 应用层功能 应用层协议 传输层 什么是传输层 传输层功能 传输层协议 网络层 什么是网络层 网络层功能 网络层协议 数据链路层 什么是数据链路层 数据链路层功能 物理层 物理层的概念和功能 写在前面 本系列文…...
后端接受前端传递数组进行批量删除
问题描述:当我们需要做批量删除功能的时候,我们循环单次删除的接口也能进行批量删除,但要删除100条数据就要调用100次接口,或者执行100次sql,这样系统开销是比较大的,那么我们直接采用接收的数组格式数据sq…...
理解数据结构 hashtable的简易理解思路
结构图 为了方便演示,下图中分区算法为下标取模 private int hashFun(int id) {//使用 hash并取模return id % size;}Hashtable的结构如图所示:是一个数组(元素为各个链表的表头) 多个链表组成,也就是说 hashtable 结…...
大数据面试题--企业面试真题
大数据面试题--企业面试真题 PlanHub 点击访问获取: 大数据面试体系专栏_酷兜科技www.kudoumh.top/hlwai/85.html 点击访问获取: 大数据面试体系专栏_酷兜科技www.kudoumh.top/hlwai/85.html 大数据面试题汇总 HDFS 1、 HDFS 读写流程。 2、HDF…...
数据结构(C语言版)-6.查找
1. 查找的基本概念 2. 静态查找 2.1 顺序查找 typedef int KeyType; typedef int InfoType; typedef struct {KeyType key;InfoType otherdata; }SeqList; // 顺序表类型 // 顺序查找int SeqSearch(SeqList R[], int n, int k) {int i n;R[0].key k; // R[0].key为查找不成…...
RabbitMQ消息队列的笔记
Rabbit与Java相结合 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> 在配置文件中编写关于rabbitmq的配置 rabbitmq:host: 192.168.190.132 /…...
linux不同发行版中的主要差异
一、初始化系统 Linux不同发行版中的系统初始化系统(如 System V init、Upstart 或 systemd) System V init: 历史:System V init 是最传统的 Linux 系统初始化系统,起源于 Unix System V 操作系统。运行级别ÿ…...
Elasticsearch+Kibana分布式存储引擎
1.ElaticSearch介绍 ElaticSearch ,简称为 ES , ES 是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检 索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别的数据。 ES 也使用 …...
spark 分布式 原理
Apache Spark 是一个快速且通用的大数据处理引擎,它支持分布式计算。Spark 的设计旨在通过高效的内存内计算和对多种数据源的支持来简化大规模数据集的处理。以下是关于 Spark 分布式原理的详细介绍: 1. 架构概述 Driver Program(驱动程序&…...
Hadoop学习笔记(包括hadoop3.4.0集群安装)(黑马)
Hadoop学习笔记 0-前置章节-环境准备 0.1 环境介绍 配置环境:hadoop-3.4.0,jdk-8u171-linux-x64 0.2 VMware准备Linux虚拟机 0.2.1主机名、IP、SSH免密登录 1.配置固定IP地址(root权限) 开启master,修改主机名为…...
thinkphp:try-catch捕获异常
使用简单的例子,实现了一个简单的try-catch捕获异常的实例 //开始事务Db::startTrans(); try{ //有异常抛出异常 if(存在错误){ throw new \Exception("异常信息"); } // 提交事务 Db::commit(); // 返回成功信息 ... } catch (\…...
如何使用 uni-app 构建直播应用程序?
使用uni-app构建直播应用程序涉及前端和后端的开发,以及音视频处理技术的选择。下面我将概述一个典型的直播应用架构,并详细说明如何在uni-app中实现关键功能。 直播应用架构 前端(uni-app):负责用户界面展示、互动逻…...
正则表达式入门教程
正则表达式入门教程 1. 引言 正则表达式(Regular Expression,简称Regex)是一种用于处理字符串的强大工具,它允许用户通过特定的模式(pattern)来搜索、匹配、查找和替换文本中的数据。正则表达式在文本处理、数据验证、数据提取等领域有着广泛的应用。本教程将带你了解正…...
uniapp 常用的指令语句
uniapp 是一个使用 Vue.js 开发的跨平台应用框架,因此,它继承了 Vue.js 的大部分指令。以下是一些在 uniapp 中常用的 Vue 指令语句及其用途: v-if / v-else-if / v-else 条件渲染。v-if 有条件地渲染元素,v-else-if 和 v-else 用…...
【Figma_01】Figma软件初始与使用
Figma初识与学习准备 背景介绍软件使用1.1 切换主题1.2 官方社区 设计界面2.1 创建一个项目2.2 修改文件名2.3 四种模式2.4 新增界面2.5 图层2.6 工具栏2.7 属性栏section透明度和圆角改变多边形的边数渐变效果描边设置阴影等特效拖拽相同的图形 背景介绍 Ul设计:User Interfa…...
AI工具如何深刻改变我们的工作与生活
在当今这个科技日新月异的时代,人工智能(AI)已经从科幻小说中的概念变成了我们日常生活中不可或缺的一部分。从智能家居到自动驾驶汽车,从医疗诊断到金融服务,AI正以惊人的速度重塑着我们的世界。 一、工作方式的革新…...
信息安全实训室网络攻防靶场实战核心平台解决方案
一、引言 网络安全靶场,作为一种融合了虚拟与现实环境的综合性平台,专为基础设施、应用程序及物理系统等目标设计,旨在向系统用户提供全方位的安全服务,涵盖教学、研究、训练及测试等多个维度。随着网络空间对抗态势的日益复杂化…...
平方根无迹卡尔曼滤波(SR-UKF)的MATLAB例程,使用三维非线性的系统
本MATLAB 代码实现了平方根无迹卡尔曼滤波(SR-UKF)算法,用于处理三维非线性状态估计问题 文章目录 运行结果代码概述代码 运行结果 三轴状态曲线对比: 三轴误差曲线对比: 误差统计特性输出(命令行截图&…...
【从零开始入门unity游戏开发之——C#篇04】栈(Stack)和堆(Heap),值类型和引用类型,以及特殊的引用类型string,垃圾回收( GC)
文章目录 知识回顾一、栈(Stack)和堆(Heap)1、什么是栈和堆2、为什么要分栈和堆3、栈和堆的区别栈堆 4、总结 二、值类型和引用类型1、那么值类型和引用类型到底有什么区别呢?值类型引用类型 2、总结 三、特殊的引用类…...
人员离岗监测摄像机智能人员睡岗、逃岗监测 Python 语言结合 OpenCV
在安全生产领域,人员的在岗状态直接关系到生产流程的顺利进行和工作环境的安全稳定。人员离岗监测摄像机的出现,为智能人员睡岗、逃岗监测提供了高效精准的解决方案,而其中的核心技术如AI识别睡岗脱岗以及相关的算法盒子和常见的安全生产AI算…...
Linux-ubuntu点LED灯C语言版
一,C语言点灯 1.寄存器配置 设置为SVC模式,复用寄存器设置GPIO1-IO003,设置电气属性,设置为输出模式。 2.软件 汇编语言对模式设置,并且将堆栈指针指向主程序: .global _start_start: /*设置为svr模式 */mrs …...
第P3周:Pytorch实现天气识别
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目标 读取天气图片,按文件夹分类搭建CNN网络,保存网络模型并加载模型使用保存的模型预测真实天气 具体实现 (一…...