第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测试效果。


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

图片​​

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


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

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

相关文章

三层交换机与路由器连通上网实验

三层交换机是一种网络交换机&#xff0c;可以实现基于IP地址的高效数据转发和路由功能&#xff0c;通常用于大型企业、数据中心和校园网络等场景。此外&#xff0c;三层交换机还支持多种路由协议&#xff08;如OSPF、BGP等&#xff09;&#xff0c;以实现更为复杂的网络拓扑结构…

2024年第九届“数维杯”大学生数学建模挑战赛B题

第一个问题为&#xff1a;正己烷不溶物对热解产率是否产生显著影响&#xff1f; 第一个问题&#xff1a;正己烷不溶物(INS)对热解产率是否产生显著影响&#xff1f; 解析&#xff1a;正己烷不溶物(INS)主要是由生物质和煤中的非挥发性物质组成&#xff0c;它们在共热解过程中会…

通信指挥类装备(多链路聚合设备)-应急通信指挥解决方案

现场通信指挥系统是一种功能全面的便携式音视频融合指挥通信平台&#xff0c;可实现现场应急救援指挥、多种通信手段融合、现场通信组网等功能&#xff0c;是现场指挥系统的延伸。 多链路聚合设备&#xff0c;是一款通信指挥类装备&#xff0c;具有 4G/5G&#xff0c;专网&…

Cloudera的简介及安装部署

简介 Cloudera是一家位于美国的软件公司&#xff0c;成立于2008年&#xff0c;专注于为企业客户提供基于Apache Hadoop的软件、支持、服务以及培训。Cloudera的开源Apache Hadoop发行版&#xff0c;即Cloudera Distribution including Apache Hadoop&#xff08;CDH&am…

AI赋能未来教育:中国教学科研新蓝图

设“人啊 前言 回顾过去&#xff0c;传统的教育模式以知识灌输和应试为主&#xff0c;虽培养出大量人才&#xff0c;但也存在着学生创新能力不足、实践经验缺乏等问题。随着时代的进步和科技的发展&#xff0c;传统教育模式已难以满足当今社会对人才的需求。然而&#xff0c;当…

阿里云和AWS负载均衡服务对比分析

在云计算时代,负载均衡作为一种关键的网络基础设施,承担着在多个服务器之间分发网络流量的重要任务。作为全球两大主要的云服务提供商,阿里云和Amazon Web Services(AWS)都提供了强大的负载均衡解决方案。本文将从性能、功能、可用性和成本等方面对两者进行对比分析。我们九河云…

Html + Express 实现大文件分片上传、断点续传、秒传

在日常的网页开发中&#xff0c;文件上传是一项常见操作。通过文件上传技术&#xff0c;用户可以将本地文件方便地传输到Web服务器上。这种功能在许多场景下都是必不可少的&#xff0c;比如上传文件到网盘或上传用户头像等。 然而&#xff0c;当需要上传大型文件时&#xff0c;…

不容错过的秘籍:JavaScript数组的创建和使用详解

在编程的世界里&#xff0c;数据是构建一切的基础。而在JavaScript中&#xff0c;有一种特殊且强大的数据结构&#xff0c;它就是——数组。 今天&#xff0c;我们就来一起探索数组的奥秘&#xff0c;从创建到使用&#xff0c;一步步掌握这个重要的工具。 一、什么是数组 数…

pycharm滚轮放大字体

进入settings&#xff0c;然后按从左到右的箭头顺序依次点击即可

Win10鼠标右键新增软件快速打开项

1、cmd 运行 regedit 2、找到该位置的shell文件夹 3、在shell文件夹下创建需要添加的软件名的文件夹&#xff0c;并修改相关信息 4、新建子文件夹command&#xff0c;并修改相关信息 5、效果

斯坦福李飞飞最新对话:AI不会对人类造成“灭绝性危机” | 最新快讯

美国斯坦福大学教授、美国国家工程院院士李飞飞&#xff08;来源&#xff1a;斯坦福大学账号&#xff09; 北京时间 5 月 10 日凌晨举行的 Bloomberg Tech 活动上&#xff0c;著名华人计算机科学家、美国斯坦福大学教授李飞飞&#xff08;Fei-Fei Li&#xff09;与彭博社 Emily…

【NodeMCU实时天气时钟温湿度项目 4】通过NTPClient库获取实时网络时间并显示在TFT屏幕上

今天是【实时天气时钟温湿度项目】第四专题&#xff0c;主要内容是&#xff1a;学习导入NTPClient库&#xff0c;通过这个库获取实时网络时间&#xff0c;显示在1.3寸TFT液晶屏幕上。此前三个专题&#xff0c;请选择查看以下链接。 第一专题内容&#xff0c;请参考 【N…

C语言神奇的经典程序

因为C语言语法格式的特殊性&#xff0c;还诞生了一个C语言乱码大赛&#xff0c;从1984年开始&#xff0c;一直办到现在。在它官网上能看到历年所有的参赛获奖的作品。 官网链接&#xff1a; https://www.ioccc.orghttps://github.com/ioccc-src/temp-test-ioccc 这个比赛的目…

美国政府发布新的国际网络空间和数字政策战略(上)

文章目录 前言一、战略内容介绍二、数字团结的含义三、如何建立数字团结前言 美国务院5月6日正式发布《美国国际网络空间和数字政策战略:迈向创新、安全和尊重权利的数字未来》,旨在指导国际社会参与技术外交并推动《美国国家安全战略》和《美国国家网络安全战略》。 美国务…

界面组件DevExpress Reporting中文教程 - 标记(可访问)PDF导出增强

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 可访问性支持在DevExpress这里仍然是一个高优先…

深入理解卷积函数torch.nn.Conv2d的各个参数以及计算公式(看完写模型就很简单了)

代码解释帮助理解&#xff1a; torch.randn(10, 3, 32, 32)&#xff0c;初始数据&#xff1a;(10, 3, 32, 32)代表有10张图片&#xff0c;每张图片的像素点用三个数表示&#xff0c;每张图片大小为32x32。&#xff08;重点理解这个下面就好理解了&#xff09; nn.Conv2d(3, 64…

独家丨美团直播积极寻求MCN公司合作,却意外成商家刷单圣地?

图片&#xff5c;《扫黑决战》截图 ©自象限原创 作者丨薛黎 编辑丨程心 2023年4月18日&#xff0c;美团直播在“神券节”中正式上线。整整一年之后&#xff0c;美团直播又在持续加码。 据「自象限」独家获悉&#xff0c;在去年12月美团上线达人直播后&#xff0c;近期…

Verilog_学习路线(小白)

#前言&#xff1a; 自从专心学习专业课后&#xff0c;发现知识点得用&#xff0c;越用越熟练&#xff0c;工具也一样&#xff0c;高级工具的学习可帮助我们在工作中极大地提高效率&#xff0c;但这里要记住一点&#xff0c;任何工具都是为解决实际问题出现的&#xff0c;即落脚…

Spring Cloud Gateway 全局过滤器

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 全局过滤器作用于所…

可以直接用的搭建训练一个气象深度学习模型全流程代码--part1 以预报预测为例

本期内容分享一套全流程搭建训练气象深度学习模型的代码&#xff0c;并考虑在基础的预报预测领域的应用。 本期内容的目标是&#xff1a;尽量让看过本文的读者&#xff0c;可以直接在本地一键跑通如SmaAtUNet、UNet等卷积网络&#xff0c;ConvLSTM、TrajGRU、PhyDNet、STPhy等…