当前位置: 首页 > news >正文

第12节 第二种shellcode编写实战(1)

我最近在做一个关于shellcode入门和开发的专题课👩🏻‍💻,主要面向对网络安全技术感兴趣的小伙伴。这是视频版内容对应的文字版材料,内容里面的每一个环境我都亲自测试实操过的记录,有需要的小伙伴可以参考🫡

我的个人主页:https://imbyter.com

一、C语言方式编写shellcode​

1. 新建0.createshellcode.cpp文件:用于生成整个项目的shellcode文件,便于其他项目加载执行shellcode。

#include "a.start.h"
#include "z.end.h"
#include "shellcode.h"#pragma optimize("", off ) 
#pragma comment(linker,"/entry:EntryMain")int EntryMain()
{// 获取shellcode片段大小DWORD dwShellcodeSize = (DWORD)ShellCodeEnd - (DWORD)ShellCodeStart;DWORD   dwWriten = 0;HANDLE  hFile = NULL;// 创建文件,用于保存最后的shellcodehFile = CreateFileA("shellcode.bin", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);if (hFile == INVALID_HANDLE_VALUE){return -1;}// 将shellcode写入到文件if (WriteFile(hFile, ShellCodeStart, dwShellcodeSize, &dwWriten, NULL) == FALSE){CloseHandle(hFile);return -1;}CloseHandle(hFile);return 0;
}

2. 新建a.start.h、z.end.h,以及对应的a.start.cpp、z.end.cpp,分别用于标记shellcode的开始和结束。

a.start.h:

#pragma once// 用于标记shellcode开始
void ShellCodeStart();

a.start.cpp:

#include "a.start.h"
#include "shellcode.h"// 用于标记shellcode开始
void ShellCodeStart()
{// shellcode执行的主要功能ShellcodeMain();
}

z.end.h:

#pragma once// 用于标记shellcode结束
void ShellCodeEnd();

z.end.cpp:

// 次函数仅用来标记shellcode结尾
void ShellCodeEnd()
{}

3. 新建shellcode.h,以及对应的shellcode.cpp,用于编写shellcode执行的主要功能代码。

shellcode.h:

#pragma once#include <windows.h>
#include <Winternl.h>HMODULE GetKernel32BaseAddress();
FARPROC _GetPorcAddress();int ShellcodeMain();// 创建文件
int DoCreateFile();
// 弹框提示
int DoMessageBox();

shellcode.cpp:

#include "shellcode.h"// shellcode主要执行的功能
int ShellcodeMain()
{// 创建文件DoCreateFile();// 弹框提示DoMessageBox();// 其他功能...return 0;
}// 功能:创建文件 D:\1.txt
int DoCreateFile()
{// 获取GetPorcAddress函数地址typedef FARPROC(WINAPI* FN_GetProcAddress)(__in HMODULE hModule, __in LPCSTR lpProcName);FN_GetProcAddress fn_GetProcAddress = (FN_GetProcAddress)_GetPorcAddress();if (fn_GetProcAddress){// 获取LoadLibraryA函数地址char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };typedef HMODULE(WINAPI* FN_LoadLibraryA)(__in LPCSTR lpLibFileName);FN_LoadLibraryA fn_LoadLibraryA = (FN_LoadLibraryA)fn_GetProcAddress(GetKernel32BaseAddress(), szLoadLibraryA);if (fn_LoadLibraryA){// 获取CreateFileA函数地址char szCreateFileA[] = { 'C','r','e','a','t','e','F','i','l','e','A',0 };typedef HANDLE(WINAPI* FN_CreateFileA)(_In_ LPCSTR lpFileName,_In_ DWORD dwDesiredAccess,_In_ DWORD dwShareMode,_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,_In_ DWORD dwCreationDisposition,_In_ DWORD dwFlagsAndAttributes,_In_opt_ HANDLE hTemplateFile);FN_CreateFileA fn_CreateFileA = (FN_CreateFileA)fn_GetProcAddress(GetKernel32BaseAddress(), szCreateFileA);// 执行CreateFileAchar szFilePath[] = { 'D',':','\\','1','.','t','x','t',0 };fn_CreateFileA(szFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);}}return 0;
}// 功能:弹框提示
int DoMessageBox()
{// 获取GetPorcAddress函数地址typedef FARPROC(WINAPI* FN_GetProcAddress)(__in HMODULE hModule, __in LPCSTR lpProcName);FN_GetProcAddress fn_GetProcAddress = (FN_GetProcAddress)_GetPorcAddress();if (fn_GetProcAddress){// 获取LoadLibraryA函数地址char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };typedef HMODULE(WINAPI* FN_LoadLibraryA)(__in LPCSTR lpLibFileName);FN_LoadLibraryA fn_LoadLibraryA = (FN_LoadLibraryA)fn_GetProcAddress(GetKernel32BaseAddress(), szLoadLibraryA);if (fn_LoadLibraryA){// 获取MessageBoxA函数地址char szUser32[] = { 'U','s','e','r','3','2','.','d','l','l',0 };char szMessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A',0 };typedef int (WINAPI* FN_MessageBoxA)(__in_opt HWND hWnd, __in_opt LPCSTR lpText, __in_opt LPCSTR lpCaption, __in UINT uType);FN_MessageBoxA fn_MessageBoxA = (FN_MessageBoxA)fn_GetProcAddress(fn_LoadLibraryA(szUser32), szMessageBoxA);// 执行MessageBoxAchar szCaption[] = { 't','i','t','l','e',0 };char szText[] = { 'H','e','l','l','o',' ','W','o','r','l','d', 0 };fn_MessageBoxA(0, szText, szCaption, MB_OK | MB_ICONINFORMATION);}}return 0;
}// 获取kernel32基址
HMODULE GetKernel32BaseAddress()
{HMODULE hKernel32 = NULL;// 用户保存模块名WCHAR wszModuleName[MAX_PATH];#ifdef _WIN64    // 64位PEB偏移为0x60PPEB lpPeb = (PPEB)__readgsqword(0x60);
#else            // 32位PEB偏移为0x30PPEB lpPeb = (PPEB)__readfsdword(0x30);
#endifPLIST_ENTRY pListHead = &lpPeb->Ldr->InMemoryOrderModuleList;PLIST_ENTRY pListData = pListHead->Flink;// 遍历所有模块while (pListData != pListHead){PLDR_DATA_TABLE_ENTRY pLDRData = CONTAINING_RECORD(pListData, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);DWORD dwLen = pLDRData->FullDllName.Length / 2;if (dwLen > 12)    // 12 是"kernel32.dll"的长度,获取到的完整路径肯定要比模块名长{// 从获取到的模块完整路径中提取模块名for (size_t i = 0; i < 12; i++){wszModuleName[11 - i] = pLDRData->FullDllName.Buffer[dwLen - 1 - i];}// 最终要获取的目标模块名("kernel32.dll"),逐个字节比较,包含大小写。if ((wszModuleName[0] == 'k' || wszModuleName[0] == 'K') &&(wszModuleName[1] == 'e' || wszModuleName[1] == 'E') &&(wszModuleName[2] == 'r' || wszModuleName[2] == 'R') &&(wszModuleName[3] == 'n' || wszModuleName[3] == 'N') &&(wszModuleName[4] == 'e' || wszModuleName[4] == 'E') &&(wszModuleName[5] == 'l' || wszModuleName[5] == 'L') &&(wszModuleName[6] == '3') &&(wszModuleName[7] == '2') &&(wszModuleName[8] == '.') &&(wszModuleName[9] == 'd' || wszModuleName[9] == 'D') &&(wszModuleName[10] == 'l' || wszModuleName[10] == 'L') &&(wszModuleName[11] == 'l' || wszModuleName[11] == 'L')){hKernel32 = (HMODULE)pLDRData->DllBase;break;}}pListData = pListData->Flink;}return hKernel32;
}// 获取GetPorcAddress函数地址
FARPROC _GetPorcAddress()
{// 保存最终结果FARPROC pGetPorcAddress = NULL;// kernel32基址HMODULE hKernel32 = GetKernel32BaseAddress();if (!hKernel32){return NULL;}PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hKernel32;PIMAGE_NT_HEADERS lpNTHeader = (PIMAGE_NT_HEADERS)((unsigned char*)hKernel32 + lpDosHeader->e_lfanew);// 模块有效性验证if (!lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size){return NULL;}if (!lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){return NULL;}// 通过导出表中的导出函数名,定位"GetProcAddress"的位置PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((unsigned char*)hKernel32 + lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);PDWORD lpdwFunName = (PDWORD)((unsigned char*)hKernel32 + lpExports->AddressOfNames);PWORD lpdwOrd = (PWORD)((unsigned char*)hKernel32 + lpExports->AddressOfNameOrdinals);PDWORD lpdwFunAddr = (PDWORD)((unsigned char*)hKernel32 + lpExports->AddressOfFunctions);for (DWORD dwLoop = 0; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++){char* pFunName = (char*)(lpdwFunName[dwLoop] + (unsigned char*)hKernel32);// 比较函数名if (pFunName[0] == 'G' &&pFunName[1] == 'e' &&pFunName[2] == 't' &&pFunName[3] == 'P' &&pFunName[4] == 'r' &&pFunName[5] == 'o' &&pFunName[6] == 'c' &&pFunName[7] == 'A' &&pFunName[8] == 'd' &&pFunName[9] == 'd' &&pFunName[10] == 'r' &&pFunName[11] == 'e' &&pFunName[12] == 's' &&pFunName[13] == 's'){pGetPorcAddress = (FARPROC)(lpdwFunAddr[lpdwOrd[dwLoop]] + (unsigned char*)hKernel32);break;}}return pGetPorcAddress;
}

最后的框架结构如下图:

后续开发所有功能都可以在遵循shellcode编写原则的基础上,以新的.h头文件.cpp源文件进行扩展。


二、C++类方式编写shellcode​

也可以使用C++类的方式进行编写,比如将shellcode.cpp改为CDoShellcode类的方式实现:

shellcode.h:

#pragma once#include <windows.h>
#include <Winternl.h>class CDoShellcode
{
private:HMODULE GetKernel32BaseAddress();FARPROC _GetPorcAddress();public:// 创建文件int DoCreateFile();// 弹框提示int DoMessageBox();
};

shellcode.cpp:

#include "shellcode.h"// 功能:创建文件 D:\1.txt
int CDoShellcode::DoCreateFile()
{// 获取GetPorcAddress函数地址typedef FARPROC(WINAPI* FN_GetProcAddress)(__in HMODULE hModule, __in LPCSTR lpProcName);FN_GetProcAddress fn_GetProcAddress = (FN_GetProcAddress)_GetPorcAddress();if (fn_GetProcAddress){// 获取LoadLibraryA函数地址char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };typedef HMODULE(WINAPI* FN_LoadLibraryA)(__in LPCSTR lpLibFileName);FN_LoadLibraryA fn_LoadLibraryA = (FN_LoadLibraryA)fn_GetProcAddress(GetKernel32BaseAddress(), szLoadLibraryA);if (fn_LoadLibraryA){// 获取CreateFileA函数地址char szCreateFileA[] = { 'C','r','e','a','t','e','F','i','l','e','A',0 };typedef HANDLE(WINAPI* FN_CreateFileA)(_In_ LPCSTR lpFileName,_In_ DWORD dwDesiredAccess,_In_ DWORD dwShareMode,_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,_In_ DWORD dwCreationDisposition,_In_ DWORD dwFlagsAndAttributes,_In_opt_ HANDLE hTemplateFile);FN_CreateFileA fn_CreateFileA = (FN_CreateFileA)fn_GetProcAddress(GetKernel32BaseAddress(), szCreateFileA);// 执行CreateFileAchar szFilePath[] = { 'D',':','\\','1','.','t','x','t',0 };fn_CreateFileA(szFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);}}return 0;
}// 功能:弹框提示
int CDoShellcode::DoMessageBox()
{// 获取GetPorcAddress函数地址typedef FARPROC(WINAPI* FN_GetProcAddress)(__in HMODULE hModule, __in LPCSTR lpProcName);FN_GetProcAddress fn_GetProcAddress = (FN_GetProcAddress)_GetPorcAddress();if (fn_GetProcAddress){// 获取LoadLibraryA函数地址char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };typedef HMODULE(WINAPI* FN_LoadLibraryA)(__in LPCSTR lpLibFileName);FN_LoadLibraryA fn_LoadLibraryA = (FN_LoadLibraryA)fn_GetProcAddress(GetKernel32BaseAddress(), szLoadLibraryA);if (fn_LoadLibraryA){// 获取MessageBoxA函数地址char szUser32[] = { 'U','s','e','r','3','2','.','d','l','l',0 };char szMessageBoxA[] = { 'M','e','s','s','a','g','e','B','o','x','A',0 };typedef int (WINAPI* FN_MessageBoxA)(__in_opt HWND hWnd, __in_opt LPCSTR lpText, __in_opt LPCSTR lpCaption, __in UINT uType);FN_MessageBoxA fn_MessageBoxA = (FN_MessageBoxA)fn_GetProcAddress(fn_LoadLibraryA(szUser32), szMessageBoxA);// 执行MessageBoxAchar szCaption[] = { 't','i','t','l','e',0 };char szText[] = { 'H','e','l','l','o',' ','W','o','r','l','d', 0 };fn_MessageBoxA(0, szText, szCaption, MB_OK | MB_ICONINFORMATION);}}return 0;
}// 获取kernel32基址
HMODULE CDoShellcode::GetKernel32BaseAddress()
{HMODULE hKernel32 = NULL;// 用户保存模块名WCHAR wszModuleName[MAX_PATH];#ifdef _WIN64    // 64位PEB偏移为0x60PPEB lpPeb = (PPEB)__readgsqword(0x60);
#else            // 32位PEB偏移为0x30PPEB lpPeb = (PPEB)__readfsdword(0x30);
#endifPLIST_ENTRY pListHead = &lpPeb->Ldr->InMemoryOrderModuleList;PLIST_ENTRY pListData = pListHead->Flink;// 遍历所有模块while (pListData != pListHead){PLDR_DATA_TABLE_ENTRY pLDRData = CONTAINING_RECORD(pListData, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);DWORD dwLen = pLDRData->FullDllName.Length / 2;if (dwLen > 12)    // 12 是"kernel32.dll"的长度,获取到的完整路径肯定要比模块名长{// 从获取到的模块完整路径中提取模块名for (size_t i = 0; i < 12; i++){wszModuleName[11 - i] = pLDRData->FullDllName.Buffer[dwLen - 1 - i];}// 最终要获取的目标模块名("kernel32.dll"),逐个字节比较,包含大小写。if ((wszModuleName[0] == 'k' || wszModuleName[0] == 'K') &&(wszModuleName[1] == 'e' || wszModuleName[1] == 'E') &&(wszModuleName[2] == 'r' || wszModuleName[2] == 'R') &&(wszModuleName[3] == 'n' || wszModuleName[3] == 'N') &&(wszModuleName[4] == 'e' || wszModuleName[4] == 'E') &&(wszModuleName[5] == 'l' || wszModuleName[5] == 'L') &&(wszModuleName[6] == '3') &&(wszModuleName[7] == '2') &&(wszModuleName[8] == '.') &&(wszModuleName[9] == 'd' || wszModuleName[9] == 'D') &&(wszModuleName[10] == 'l' || wszModuleName[10] == 'L') &&(wszModuleName[11] == 'l' || wszModuleName[11] == 'L')){hKernel32 = (HMODULE)pLDRData->DllBase;break;}}pListData = pListData->Flink;}return hKernel32;
}// 获取GetPorcAddress函数地址
FARPROC CDoShellcode::_GetPorcAddress()
{// 保存最终结果FARPROC pGetPorcAddress = NULL;// kernel32基址HMODULE hKernel32 = GetKernel32BaseAddress();if (!hKernel32){return NULL;}PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hKernel32;PIMAGE_NT_HEADERS lpNTHeader = (PIMAGE_NT_HEADERS)((unsigned char*)hKernel32 + lpDosHeader->e_lfanew);// 模块有效性验证if (!lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size){return NULL;}if (!lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress){return NULL;}// 通过导出表中的导出函数名,定位"GetProcAddress"的位置PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((unsigned char*)hKernel32 + lpNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);PDWORD lpdwFunName = (PDWORD)((unsigned char*)hKernel32 + lpExports->AddressOfNames);PWORD lpdwOrd = (PWORD)((unsigned char*)hKernel32 + lpExports->AddressOfNameOrdinals);PDWORD lpdwFunAddr = (PDWORD)((unsigned char*)hKernel32 + lpExports->AddressOfFunctions);for (DWORD dwLoop = 0; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++){char* pFunName = (char*)(lpdwFunName[dwLoop] + (unsigned char*)hKernel32);// 比较函数名if (pFunName[0] == 'G' &&pFunName[1] == 'e' &&pFunName[2] == 't' &&pFunName[3] == 'P' &&pFunName[4] == 'r' &&pFunName[5] == 'o' &&pFunName[6] == 'c' &&pFunName[7] == 'A' &&pFunName[8] == 'd' &&pFunName[9] == 'd' &&pFunName[10] == 'r' &&pFunName[11] == 'e' &&pFunName[12] == 's' &&pFunName[13] == 's'){pGetPorcAddress = (FARPROC)(lpdwFunAddr[lpdwOrd[dwLoop]] + (unsigned char*)hKernel32);break;}}return pGetPorcAddress;
}

然后将a.start.cpp中的ShellCodeStart函数改为:

void ShellCodeStart()
{CDoShellcode shellcode;// 创建文件shellcode.DoCreateFile();// 弹框提示shellcode.DoMessageBox();// 其他功能...
}

这样即可实现类的方式执行shellcode功能。

测试:运行以上代码对应生成的exe文件,会在当前路径下生成shellcode.bin文件,该文件就是我们最后得到的shellcode文件。使用编写shellcode加载器加载执行shellcode.bin测试效果。


如果有任何问题,可以在我们的知识社群中提问和沟通交流:

图片​​

一个人走得再快,不如一群人走得更远!🤜🤛


相关文章:

第12节 第二种shellcode编写实战(1)

我最近在做一个关于shellcode入门和开发的专题课&#x1f469;&#x1f3fb;‍&#x1f4bb;&#xff0c;主要面向对网络安全技术感兴趣的小伙伴。这是视频版内容对应的文字版材料&#xff0c;内容里面的每一个环境我都亲自测试实操过的记录&#xff0c;有需要的小伙伴可以参考…...

在Ubuntu上安装Anaconda并配置远程访问Jupyter

安装 下载Anaconda的.sh文件后&#xff0c;上传到服务器&#xff0c;然后进行安装&#xff1a; chmod x anaconda.sh ./anaconda.sh创建虚拟环境 可以指定Python版本创建虚拟环境&#xff1a; conda create --name langchain python3.11.7 conda activate langchain conda …...

格雷希尔GripSeal:E10系列低压信号电测试连接器,应用于新能源汽车的DCR测试和EOL测试

新能源车的电驱动、电池包等都有一些信号接口&#xff0c;从几针到几十针不等&#xff0c;而且每种接口都有独特的电性能要求&#xff0c;这些接口在电池包进DCR测试或是EOL测试时&#xff0c;为了满足这些信号接口的需求&#xff0c;我们设计了E10系列信号针快速接头&#xff…...

飞跨电容型的三电平(FC-NPC)逆变器simulink仿真模型

本人搭建了飞跨电容型的三电平逆变器simulink仿真模型&#xff0c;相较于二极管钳位型三电平逆变器而言&#xff0c;钳位二极管变为飞跨的电容。采用SPWM调制和均流均压控制&#xff0c;通过搭建仿真模型得到三电平波形。 三电平拓扑中的飞跨电容是指在电路的输出端使用电容来实…...

前端Sass使用详解,看这篇就够了

Sass&#xff08;Syntactically Awesome Style Sheets&#xff09;是一种CSS预处理器&#xff0c;它被设计为改善CSS的可读性和实用性。Sass使用类似于CSS的语法&#xff0c;但增加了变量、嵌套、混合&#xff08;mixins&#xff09;、函数等功能&#xff0c;使得编写CSS更加高…...

用js操作dom节点的一些方法

一、获取节点 document.getElementById(id); 返回拥有指定 id 的第一个节点 document.getElementsByName(name); 返回带有指定名称的节点集合 document.getElementsByTagName(tagname); 返回带有指定标签名的节点集合 document.getElementsByClassName(classname); 返回带有…...

electron 中拦截内嵌页面 beforeunload 的弹窗提示

window 的 beforeunload 事件提示在electron 不兼容&#xff0c;弹窗提示不出来&#xff0c;还会导致莫名其妙的假死问题&#xff0c;下面记录一下解决方法。 1. 如果仅需要拦截弹窗&#xff1a; win.webContents.on(will-prevent-unload, (event) > {event.preventDefault(…...

hcip-datacom英文词汇积累简述3

序号 词汇 中文 1 port link-type access 端口链路类型为接入 2 batch 批量 3 vlan batch 2 3 虚拟局域网批量2和3 4 Default 默认 5 port default vlan 2 端口默认虚拟局域网2 6 trunk 主干 7 port link-type trunk 端口链路类型为主干 8 allow-pass 全部过关 9 port trunk al…...

什么是新能源汽车热管理?

前言 新能源汽车热管理是指针对电动汽车等新型动力系统所涉及的热量控制和调节技术&#xff0c;其包括散热、冷却、加热、温度控制等方面。在新能源汽车中&#xff0c;电池、电动机、控制器等部件都会产生一定的热量&#xff0c;如果不进行有效的热管理&#xff0c;将会影响汽…...

iOS plist文件增删改查

一. plist简介 plist文件&#xff0c;即属性列表文件&#xff0c;全名是Property List&#xff0c;这种文件的扩展名为.plist&#xff0c;因此&#xff0c;通常被叫做plist文件。它是一种用来存储串行化后的对象的文件&#xff0c;在iOS开发中通常用来存储用户设置&#xff0c…...

docker安装与重装

docker安装与重装 docker安装 https://blog.csdn.net/lyqhf153/article/details/79585976 参考上面的方式 cat /etc/issueuname -r uname -acat /proc/versiondf -hyum list docker-ce --showduplicates | sort -r 查看docker-ce的版本列表sudo yum install -y docker 没有…...

武汉星起航引领跨境新浪潮,一站式解决方案助力卖家驰骋亚马逊

在全球化浪潮下&#xff0c;跨境电商已成为外贸发展的新引擎&#xff0c;为无数创业者提供了全新的商业机遇。而在这场跨境电商的浪潮中&#xff0c;武汉星起航电子商务有限公司以其专业的一站式解决方案&#xff0c;成为众多创业者和卖家的得力助手&#xff0c;引领着他们成功…...

在做题中学习(56):二维前缀和模板

【模板】二维前缀和_牛客题霸_牛客网 (nowcoder.com) 理解题意&#xff1a; 要求的是(x1,y1) - (x2,y2)这段区间的和。 解法&#xff1a;二维前缀和 1. 和一维前缀和一样&#xff0c;需要有一个同等规模的dp数组&#xff0c;用来保存一段连续区域的和。 在二维dp中&#xff0…...

驾驭多云环境,加速AI创新丨Animbus Cloud 8.3.0 算力调度平台升级发布

大模型开启全球新一轮AI浪潮&#xff0c;伴随算力规模的爆发增长以及计算技术的多元创新&#xff0c;需要更稳定、高效、敏捷的异构计算基础设施&#xff0c;才能充分发挥对算力能力的重要支撑。 作为开放智能云边架构引领者&#xff0c;九州未来凭借多年的技术积累、实践沉淀…...

JavaScript异步编程——02-Ajax入门和发送http请求

同步和异步回顾 同步和异步的简单理解 同步&#xff1a;必须等待前面的任务完成&#xff0c;才能继续后面的任务。 异步&#xff1a;不受当前任务的影响。 拿排队举例&#xff1a; 同步&#xff1a;在银行排队时&#xff0c;只有等到你了&#xff0c;才能够去处理业务。 异…...

湖仓一体 - Apache Arrow的那些事

湖仓一体 - Apache Arrow的那些事 Arrow是高性能列式内存格式标准。它的优势&#xff1a;高效计算&#xff1a;所有列存的通用优势&#xff0c;CPU缓存友好、SIMD向量化计算友好等&#xff1b;零序列化/反序列化&#xff1a;arrow的任何数据结构都是一段连续的内存&#xff0c;…...

常用的启发式算法:探索问题解决的智慧之道

启发式算法是一种通过启发式信息来引导搜索的算法&#xff0c;常用于解决那些在合理时间内难以找到最优解的问题。本文将介绍几种常用的启发式算法&#xff0c;包括贪心算法、遗传算法和模拟退火算法&#xff0c;并提供Java代码实现及测试&#xff0c;帮助读者深入理解这些算法…...

docker Harbor私有仓库部署管理

搭建本地私有仓库&#xff0c;但是本地私有仓库的管理和使用比较麻烦&#xff0c;这个原生的私有仓库并不好用&#xff0c;所以我们采用harbor私有仓库&#xff0c;也叫私服&#xff0c;更加人性化。 一、什么是Harbor Harbor是VWware 公司开源的企业级Docker Registry项…...

序列化的不同格式:JSON、XML、TOML、CSON、YAML

前言 这篇文章参考于知乎&#xff0c;进行了一些总结。 正文 首先什么是序列化&#xff0c;数据序列化是从一个系统获取一些信息&#xff0c;将其转换为其它系统可以读取的格式&#xff0c;然后将其传递给其它系统的过程。也就是可以让不同系统“通信”。 序列化需要满足两…...

Mapreduce | 案例

根据提供的数据文件【test.log】 数据文件格式&#xff1a;姓名,语文成绩,数学成绩,英语成绩 完成如下2个案例&#xff1a; &#xff08;1&#xff09;求每个学科的平均成绩 &#xff08;2&#xff09;将三门课程中任意一门不及格的学生过滤出来 &#xff08;1&#xff09;求每…...

U盘文件剪切丢失怎么办?揭秘原因并给出恢复方法

在日常生活和工作中&#xff0c;U盘已成为我们不可或缺的数据存储和传输工具。但有时候&#xff0c;我们在对U盘中的文件进行剪切操作时&#xff0c;会遇到文件丢失的情况。这种突如其来的数据消失往往会让人感到惊慌和困惑。那么&#xff0c;为什么U盘剪切时文件会丢失呢&…...

软件设计师考试---访问控制列表、堆,栈和堆栈、防火墙、数据流图、嵌入式操作、绑定方式、uml、模式、传输协议

访问控制列表 访问控制列表&#xff08;Access Control List&#xff0c;ACL&#xff09; 是一种用于控制对资源&#xff08;如文件、目录、网络资源等&#xff09;访问权限的方法。ACL是在计算机安全领域广泛使用的概念&#xff0c;它允许系统管理员定义哪些用户或系统进程有…...

vlock工具:锁定Linux终端的安全智能方法

虚拟控制台是 Linux 非常重要的功能&#xff0c;它们为系统用户提供 shell 提示&#xff0c;以非图形设置方式使用系统&#xff0c;该设置只能在物理机上使用&#xff0c;而不能远程使用。 用户只需从一个虚拟控制台切换到另一个虚拟控制台即可同时使用多个虚拟控制台会话。 …...

【Linux】Docker 安装部署 Nacos

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 【Linux】Docker 安装部署 Nacos docker搜索na…...

纯血鸿蒙APP实战开发——阅读翻页方式案例

介绍 本示例展示手机阅读时左右翻页&#xff0c;上下翻页&#xff0c;覆盖翻页的功能。 效果图预览 使用说明 进入模块即是左右翻页模式。点击屏幕中间区域弹出上下菜单。点击设置按钮&#xff0c;弹出翻页方式切换按钮&#xff0c;点击可切换翻页方式。左右翻页方式可点击翻…...

如何从Mac电脑恢复任何删除的视频

Microsoft Office是包括Mac用户在内的人们在世界各地创建文档时使用的最佳软件之一。该软件允许您创建任何类型的文件&#xff0c;如演示文稿、帐户文件和书面文件。您可以使用 MS Office 来完成。所有Microsoft文档都可以在Mac上使用。大多数情况下&#xff0c;您处理文档&…...

【Halcon 内存泄漏记录 - C#】

Halcon 内存泄漏记录 - C# 1. Bitmap 转 HImage2. new 之后要Dispose()3. 切换配方后&#xff0c;内存会增加4. Parallel.For 嵌套Parallel.For&#xff0c; 会出现问题5. 图像预处理使用需要注意不能直接在原有变量上赋值 1. Bitmap 转 HImage 由于Bitmap 在转化时使用Bitmap…...

MT8370_联发科MTK8370(Genio 510)芯片性能规格参数

MT8370芯片是一款利用超高效的6nm制程工艺打造的边缘AI平台&#xff0c;具有强大的性能和功能。这款芯片集成了六核CPU(2x2.2 GHz Arm Cortex-A78 & 4x2.0 GHz Arm Cortex-A55)、Arm Mali-G57 MC2 GPU、集成的APU(AI处理器)和DSP&#xff0c;以及一个HEVC编码加速引擎&…...

【Qt 学习笔记】Qt常用控件 | 多元素控件 | Table Widget的说明及介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 多元素控件 | Table Widget的说明及介绍 文章编号&#…...

ES全文检索支持拼音和繁简检索

ES全文检索支持拼音和繁简检索 1. 实现目标2. 引入pinyin插件2.1 编译 elasticsearch-analysis-pinyin 插件2.2 安装拼音插件 3. 引入ik分词器插件3.1 已有作者编译后的包文件3.2 只有源代码的版本3.3 安装ik分词插件 4. 建立es索引5.测试检索6. 繁简转换 1. 实现目标 ES检索时…...