【第53节】Windows编程必学之使用C++写exe压缩加密壳

article/2025/8/16 16:08:26

目录

一、实现背景

1.1 前言

1.2 前置知识

1.3 达到目标

二、壳的实现要点

2.1 写壳怎么做

2.2 写壳的困难点

2.3 如何写壳代码

2.4 API函数的调用问题

2.5 重定位问题

2.6 信息交互问题

2.7 调试问题

2.8 关于目标程序的随机基址

2.9 关于目标程序的导入表

2.10 关于动态加解密

2.11 关于TLS的处理

三、实现一个壳的步骤

四、Windows PE 文件壳的实现例子

4.1 实现功能

4.2 附加功能

4.3 加壳后的程序执行流程

4.4 加壳大概流程

4.5 压缩流程

4.6 重定位原理

4.7 整体加壳流程伪代码

4.8 程序运行截图

4.9 后续优化工作

4.10 收获


一、实现背景

1.1 前言

        壳是软件保护领域里的高端技术,自打出现,就一直处在安全对抗的最前线。这些年不断发展,加密壳的类型越来越多,可不管怎么变,它的核心思路始终是对PE文件做些变形处理,让软件不那么容易被分析和破解。

        在我的信息安全专栏中,我们试过一步步脱掉一些常见的壳,相信大家对壳已经有了比较清楚的认识。不熟悉的同学请自行关注学习我的前面的文章和信息安全专栏的文章。而在这个项目里,我们要打造一个加壳软件的框架。等有了这个框架,你就能把自己熟悉的反调试手段加进去,进而拥有一款完全属于自己的壳,想想都让人觉得激动,同时本文末尾将提供完整的代码参考学习。

1.2 前置知识

        要实现这个壳框架,得先掌握下面这些知识:

(1)PE文件相关知识:这部分内容在《windows编程原理》的PE文件板块能找到,具体包含:
    - PE头
    - 导入表
    - 导出表
    - 重定位表

(2)PEB中LDR模块链相关知识:想了解这方面内容,可以参考学习windows的调试与异常以及内核编程基础。

        编程环境:win10或以上,vs2015或以上

1.3 达到目标

(1)弄明白壳是怎么实现的,掌握其基本的实现方法。
(2)学会构建一个用C++编写的壳的实现框架。
(3)给壳增加一些反调试的方法,让壳更难被破解,提升它的保护能力 。

二、壳的实现要点

(1)弄明白壳是怎么实现的,掌握其基本的实现方法。 

(2)学会构建一个用C++编写的壳的实现框架。 

(3)给壳增加一些反调试的方法,让壳更难被破解,提升它的保护能力 。

2.1 写壳怎么做

        壳的原理很简单,就是对目标PE文件动手脚,在里面添加一段壳代码。当目标PE文件开始执行时,会先运行壳代码这部分,等壳代码执行完,才会回到原本程序的入口,继续执行原始程序。加壳前和加壳后的样子,看下面这张图就清楚了。

        从这里我们能想到,把EXE文件变成加壳状态的那段代码,和被添加到目标程序里的壳代码,其实是两个不同的程序。所以,编写壳需要完成下面这两项工作:

(1)加壳程序:对PE文件进行加工,然后把解壳代码添加到目标可执行文件上。
(2)解壳代码:附着在目标可执行文件上,保证目标文件可以正常运行起来。

2.2 写壳的困难点

        搞清楚编写壳都要做些什么之后,咱就来聊聊编写壳会遇到哪些难题。大概有下面这几个方面:

1. 壳代码具体该怎么写。
2. API函数调用过程中会碰到的麻烦。
3. 重定位相关的问题。
4. 信息交互方面的难题。
5. 调试时可能出现的状况。
6. 目标程序存在随机基址的情况。
7. 目标程序导入表带来的问题。
8. 动态加解密的实现问题。
9. TLS的处理问题。

        下面我们会一个一个讨论这些问题,大家思考的时候,别忘了多看看之前那张加壳前后的图。

2.3 如何写壳代码

        当把壳代码复制到目标程序里面的时候,这个壳代码得是已经编译好了的二进制代码才行。这种代码本来是既可以用汇编语言来编写的,不过因为我们要做的是一个C++壳,所以就用C++语言来编写。

        我们把编写好的C++代码生成一个dll文件,然后只把这个dll文件的代码段复制到目标程序中。因为我们写的代码肯定会用到全局变量,所以把代码段和数据段合并起来就很重要,这样一来我们只需要复制一个区段就行。下面这些代码能够把区段合并起来,还能让这个区段具备可读、可写、可执行的属性:

#pragma comment(linker,"/merge:.data=.text")
#pragma comment(linker,"/merge:.rdata=.text")
#pragma comment(linker,"/section:.text,RWE")

2.4 API函数的调用问题

        在原始的PE文件里,差不多99%的时候都会去调用Windows系统的API函数,而我们写的壳代码一般也得用到API函数。不过,那些直接调用API的代码,通常在编译之后就变成了call导入表的形式。所以呢,当我们把壳代码复制到目标程序里的时候,再去调用API就会出错。针对这个问题,有两种解决办法:

(1)动态获取API函数

         - 要是想拿到API函数的地址,而且包含这个API的模块还没被加载,那就可以用LoadLibrary和GetProcAddress这两个API函数。先用LoadLibrary把模块加载进来,这样就能得到模块句柄,然后再用GetProcAddress去获取这个模块里所有能导出的函数地址。但要注意,LoadLibrary和GetProcAddress本身也是API函数,不能直接用,得先想办法拿到它们的地址才行。
        - 好在LoadLibrary和GetProcAddress都在kernel32.dll这个模块里,而且每个进程启动的时候都会加载kernel32.dll模块。所以,关键就在于找到kernel32.dll的加载基址,找到了之后,再去分析这个模块的导出表,就能得到我们想要的函数地址了。比如说,我们可以模块链表方法来找到kernel32.dll的基址。

下面这段代码就能实现:

int GetKernel32Base() {int nAddress = 0;__asm {push eax;mov eax, fs:[0x30];mov eax, [eax + 0xC];mov eax, [eax + 0xC];mov eax, [eax];mov eax, [eax];mov eax, dword ptr ds:[eax + 0x18];mov nAddress, eax;pop eax;}return nAddress;
}

        - 得到Kernel32.dll的基址后,即可获取kernel32.dll模块中的GetProcAddress和LoadLibrary的地址:

GETPROCADDRESS g_GetProcAddress = 0;
LOADLIBRARYW g_LoadLibraryW = 0;
void MyGetProceAddress() {char *Kernel32Buf = (char *)GetKernel32Base();//1获取Ker32的PE基本信息。PIMAGE_DOS_HEADER m_pDos = (PIMAGE_DOS_HEADER)Kernel32Buf;PIMAGE_NT_HEADERS m_pNt = (PIMAGE_NT_HEADERS)(m_pDos->e_lfanew + Kernel32Buf);PIMAGE_OPTIONAL_HEADER m_pOptionalHeader = &m_pNt->OptionalHeader;//2我们要找Kernel32中的导出函数的地址,我们需要去导出表中寻找PIMAGE_DATA_DIRECTORY pExportDir = m_pOptionalHeader->DataDirectory + 0;//3导出表有三张表PIMAGE_EXPORT_DIRECTOR pExport =(PIMAGE_EXPORT_DIRECTORY)(pExportDir->VirtualAddress + Kernel32Buf);PDWORD pEat = (PDWORD)(pExport->AddressOfFunctions + Kernel32Buf);PWORD pId = (PWORD)(pExport->AddressOfNameOrdinals + Kernel32Buf);PDWORD pNameRva = (PDWORD)(pExport->AddressOfNames + Kernel32Buf);DWORD dwNameCount = pExport->NumberOfNames;for (int i = 0; i < dwNameCount; i++) {char* pName = (pNameRva[i] + Kernel32Buf);if (strcmp(pName, "GetProcAddress") == 0) {DWORD dwId = pId[i];g_GetProcAddress =(GETPROCADDRESS)(pEat[dwId] + (DWORD)Kernel32Buf);g_LoadLibraryW =(LOADLIBRARYW)g_GetProcAddress((HMODULE)Kernel32Buf, "LoadLibraryW");return;}}
}

        一旦成功动态获取到这两个函数的地址,后续就能轻松实现动态获取任意模块的API,并且能够顺利调用这些API执行各类操作,像进行内存申请、创建窗口以及创建DialogBox 等操作都不在话下。 

(2)在目标程序里建个导入表

        我们可以参照之前学过的导入表格式,在目标程序中创建一个导入表,之后让系统来填充这个导入表的内容。 

2.5 重定位问题

        壳代码肯定会用到全局变量,在汇编里是通过绝对地址(VA)来访问全局变量数据的。要是直接把壳代码贴到目标程序上,程序就会报错。我们之前学PE文件的时候知道,可以通过重定位表找到这些会出错的位置,然后把它们修正成正确的位置。

        正确位置的算法是:正确位置 = 原始位置 - 区段的VA + 目标程序ImageBase + 壳代码rva 。具体的数字可以看相关的图。

2.6 信息交互问题

        壳代码运行的时候,可能得用到一些在写壳代码时还不清楚的数据。像目标程序原本的入口点(OEP)、被加密区域的大小、加密的起始位置,要是加壳后得输入账号密码才能运行,那账号密码也算。

        这些数据得在加壳程序运行的时候才能拿到,得用合适的办法把它们放到壳代码里。有个办法是,让壳部分导出一个全局的结构体变量,加壳的时候通过符号找到这个变量,再把需要的数据写进去。具体怎么做可以看看代码。

2.7 调试问题

        把壳编写好并加到程序里之后,可能会碰到下面这些不太好解决的问题:
(1)加壳程序能用VS来调试,可壳代码是在可执行文件里运行的,要是运行出错了,就只能用OD来调试。
(2)如果程序没办法运行,可以按下面的方法来处理:
    - 检查加壳程序的代码,看看有没有错误,不过很难直接看出出错的原因。
    - 用PE工具打开PE文件,检查所有修改过的地方以及相关的字段,看看数据合不合理。

2.8 关于目标程序的随机基址

        要是目标程序采用随机基址,事情就会变复杂:

(1)目标程序的代码段经过加密或者压缩等变形处理后,让系统自动修复重定位会出错。
(2)壳代码通常只把需要重定位的地方调整到适应目标程序固定基址的位置。但当目标程序是随机基址时,壳代码里的虚拟地址(VA)就会出问题,因为目标程序的重定位表中没有壳代码需要重定位的位置信息。

        针对这些问题,大致有两种处理办法:
(1)去掉目标程序的随机基址功能。只需把目标程序扩展头中的DllCharacteristics属性里的IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE去掉就行,代码是`DllCharacteristics &= ~IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;` 。基址固定后,就不用修复重定位了。
(2)在目标程序里创建一个重定位表,让系统能够修复壳代码的重定位,保证壳代码能正常运行。等壳代码把目标程序解密完,再去修复目标程序的重定位。这种方法比较麻烦,但可以保留目标程序的随机基址功能。

2.9 关于目标程序的导入表

        要是加密或者压缩操作把目标程序的导入表弄坏了,加壳后的程序运行时,系统就没办法填充导入地址表(关于系统为什么要填充导入地址表,可以参考《windows编程原理》里PE文件的部分)。

        这种情况下,在把程序控制权交给目标程序之前,得先填充好它的导入表。填充的方法不难,原始的导入地址表(IAT)里存的是函数名,之前我们讲过怎么根据函数名来获取函数地址,把获取到的函数地址填到对应的位置就可以了。

2.10 关于动态加解密

        动态加解密是一种保护强度比较高的壳技术,它能在目标程序运行的时候,对代码段进行动态的加解密操作。程序先运行一部分代码,接着把后面一部分代码解密,同时把已经运行过的部分加密。等运行完解密后的代码,再去解密更后面的代码,并且把前面的代码又加密起来。这样一来,调试的人就只能看到正在运行的代码附近的几条指令。

        这有点像Hook技术,我们可以在目标程序里设置多个Hook点,让程序在运行过程中能通过这些Hook点回到壳代码那里,进行动态加解密。我们可以试着通过修改指令、设置异常处理等办法来实现这个功能。

2.11 关于TLS的处理

        TLS指的是线程局部存储。有些加壳程序对很多程序区段做了变形处理,这就使得系统找不到目标程序的TLS段,也就没办法调用TLS段里的回调函数。这样一来,那些依赖TLS回调函数才能运行的程序就跑不起来了。

        处理TLS的办法挺简单,在程序执行到入口点之前,挨个调用TLS表中的函数就行。要找TLS表的话,可以参考windows编程原理的PE文件那部分内容。

三、实现一个壳的步骤

实现一个壳,大概要按下面这些步骤来做:
(1)先拿到目标文件的PE信息。
(2)再获取Stub文件的PE信息,把必要的信息设置到Stub里。
(3)往被加壳的程序里添加Stub代码段,具体操作如下:
    - 读取Stub代码段。
    - 修复Stub段里的代码。
    - 把被加壳程序的原始入口点(OEP)改一下,让它指向Stub。
(4)从简单到复杂一步步实现功能:
    - 在目标程序里添加新的区段,要考虑这些参数:
        - 区段的名字
        - 区段的大小
        - 区段里面装什么内容
        - 区段的属性
    - 让目标程序先执行壳代码,执行完什么都不做就跳回,而且程序不能报错。关键步骤有:
        - 修复壳代码的重定位问题。
        - 算出新的入口点(OEP)并设置好。
        - 把原始的入口点(OEP)存到壳代码里,这样壳代码运行的时候就能找到原程序的入口。
    - 对目标程序的代码段进行简单加密,在解壳的时候能把代码解密,让程序正常运行。
    - 对目标程序进行压缩,壳代码负责解压缩,让目标程序没办法被静态分析,但还能正常运行且不报错。具体要注意:
        - 选个合适的压缩库。
        - 因为壳代码会用到API函数,所以得动态获取API。
        - 注意目标程序的代码段默认是不可写的,解压缩或者解密的时候要把它设置成可读、可写、可执行。

四、Windows PE 文件壳的实现例子

        在软件保护领域,Windows PE 文件壳技术发挥着关键作用。它能够对目标程序进行保护,增加程序被破解的难度。下面例子包含PE 文件壳的实现功能、附加功能、加壳流程、压缩流程、重定位原理、导入表处理等。

该代码例子实现主要特点:

(1)加密保护:
        使用异或加密算法对代码段进行加密
        使用随机密钥增加破解难度
(2)压缩保护:
        使用aP压缩算法对代码段进行压缩
        减小文件体积并增加逆向难度
(3)反调试保护:
        检测调试器存在
        检测硬件断点
        使用VEH异常处理
(4)重定位处理:
        处理PE文件的重定位信息
        确保加壳后的程序能正确加载
(5)导入表处理:
        保存原始导入表信息
        在运行时重建导入表

        这个加壳程序采用了多层保护机制,包括加密、压缩、反调试等,能有效防止程序被逆向分析。同时,它通过stub代码在运行时进行解密和解压缩,确保程序能正常运行。

4.1 实现功能

(1)向目标程序添加代码
        该功能使得我们能够在目标程序中融入自定义的代码逻辑,为程序增添额外的功能或实现特定的保护机制。
(2)加密压缩代码段
        对代码段进行加密压缩,不仅能减小程序体积,还能增强程序的安全性,让破解者难以直接分析代码。
(3)程序可运行
        加壳后的程序要确保能够正常运行,保证原有功能不受影响。
(4)密码弹框
        设置密码弹框,只有输入正确密码,程序才能正常执行,为程序增加了一层访问控制。

4.2 附加功能

(1)修复重定位
        由于程序加载基址可能发生变化,修复重定位能保证涉及地址的代码在新的加载基址下正常运行。
(2)加密压缩
        进一步增强对代码和数据的保护,提高破解难度。
(3)花指令与混淆
        通过插入花指令和进行代码混淆,扰乱破解者的分析思路,增加逆向工程的难度。
(4)反调试与动态非对称加密
        反调试功能可检测并阻止调试行为,动态非对称加密则在程序运行过程中动态加密和解密数据,提升安全性。

4.3 加壳后的程序执行流程

(1)保存寄存器环境
        在执行壳代码前,先保存当前寄存器的状态,避免影响后续程序的执行。
(2)初始化壳需要的函数
        为壳代码的运行初始化必要的函数,确保后续操作能够顺利进行。
(3)解压和解密代码和数据
        将之前加密压缩的代码和数据进行解压和解密,恢复其原始状态。
(4)修复 IAT
        导入地址表(IAT)可能在加壳过程中被修改,修复 IAT 以保证程序能够正确调用外部函数。
(5)修复重定位
        根据新的加载基址,对涉及地址的代码进行重定位修复。
(6)恢复寄存器环境
        恢复之前保存的寄存器状态,使程序能够继续正常执行。
(7)跳转到原始 OEP
        跳转到原始程序的入口点,开始执行原始程序的代码。

4.4 加壳大概流程

(1)读取被加壳程序并分析 PE 信息
        深入了解被加壳程序的结构和相关信息,为后续操作提供基础。
(2)拷贝 NT 头到 stub
        将被加壳程序的 NT 头复制到 stub 中,确保 stub 与原程序的兼容性。
(3)加密代码段
        对代码段进行加密处理,增强程序的安全性。


(4)设置 OEP 到新区段的 stub 入口函数
        将被加壳程序的原始入口点(OEP)设置到新区段的 stub 入口函数,使得程序先执行壳代码。同时,去除被加壳程序的重定位属性。
(5)修复 stub 的重定位数据
        在拷贝 stub 之前,对其重定位数据进行修复,确保在新的环境中能够正常运行。
(6)拷贝 stub.dll 的代码段到新区段
        将 stub.dll 的代码段复制到被加壳程序的新区段中,完成壳代码的添加。
(7)压缩
        对加壳后的程序进行压缩,减小程序体积。
(8)保存
        将加壳并压缩后的程序保存到磁盘。

4.5 压缩流程

(1)获取.TEXT 段属性和缓冲区
        通过文件偏移和文件大小定位到.TEXT 段的缓冲区,为后续压缩操作做准备。
(2)计算压缩大小并开辟缓冲区
        利用 aplib 函数计算压缩后的大小,并开辟相应的缓冲区。
(3)进行压缩
        使用 aplib 对缓冲区内容进行压缩。
(4)存储并对齐
        将压缩后的数据存入目标缓冲区,并进行文件对齐操作。
(5)修改文件信息
        修改文件大小、text 区段文件大小以及其他区段的 PointtoRawData。
(6)释放缓冲区
        释放多余的缓冲区,节省系统资源。

4.6 重定位原理

        在程序生成时,很多涉及地址的代码使用的是绝对的虚拟内存地址,这个地址是假设程序加载到 0x400000 时才有效的。当程序加载基址发生变化,新的加载基址与默认加载基址不同,涉及地址的代码就无法正常运行。

        此时,需要对这些代码的操作数进行修改,公式为:新的加载基址 - 默认加载基址 + 指令中的操作数指针字节数。

4.7 整体加壳流程伪代码

// 加壳主流程
BOOL Pack(CString strFilePath) {// 1. 打开目标PE文件PeFileHandling pePacked;if (!pePacked.open(strFilePath)) {return FALSE;}// 2. 打开stub.dll(壳代码)PeFileHandling peStub;if (!peStub.open("stub.dll")) {return FALSE;}// 3. 获取stub的.text段IMAGE_SECTION_HEADER* pStubText = peStub.getSection(".text");// 4. 在目标PE中添加新节IMAGE_SECTION_HEADER* pNewScn = pePacked.addSection("TANGPACK", NULL, pStubText->SizeOfRawData);// 5. 获取stub配置结构体地址DWORD dwRvaStubConf = peStub.getProcAddress("g_stubConf");StubConf* pStubConf = (StubConf*)(peStub.RvaToOffset(dwRvaStubConf) + peStub.getFileBuff());// 6. 保存目标PE的NT头信息到stub配置中pStubConf->ntheader = *pePacked.getNtHdr();// 7. 加密代码段pStubConf->dwTextSectionRva = pePacked.getSection(".text")->VirtualAddress;pStubConf->dwTextSectionSize = pePacked.getSection(".text")->Misc.VirtualSize;pStubConf->key = Uncode1(pePacked.getSection(".text")->PointerToRawData + pePacked.getFileBuff(),pePacked.getSection(".text")->Misc.VirtualSize,rand() % 255);// 8. 设置新的入口点DWORD dwStubOep = peStub.getProcAddress("start");dwStubOep -= pStubText->VirtualAddress;dwStubOep += pNewScn->VirtualAddress;pePacked.setOep(dwStubOep);// 9. 禁用动态基址pePacked.getOptionHdr()->DllCharacteristics &= (~0x40);// 10. 修复stub重定位peStub.fixStubRva(peStub.getOptionHdr()->ImageBase,pePacked.getOptionHdr()->ImageBase,pStubText->VirtualAddress,pNewScn->VirtualAddress);// 11. 将stub代码段复制到新节pePacked.setSectioData(pNewScn,(void*)(pStubText->PointerToRawData + peStub.getFileBuff()),pStubText->SizeOfRawData);// 12. 压缩代码段pePacked.compress();// 13. 保存加壳后的文件pePacked.saveAs((strFilePath + CString("_pack.exe")).GetBuffer());return TRUE;
}// 壳代码执行流程
void start() {// 1. 获取API函数地址GetAPIs();// 2. 反调试检查CheckDebugger();if (isVehHardware()) {MessageBox(0, 0, L"正在被调试", 0);}// 3. 解压缩代码段decompress();// 4. 解密代码段decrypt();// 5. 跳转到原始入口点jmp to original OEP;
}

4.8 程序运行截图

加壳程序运行界面:

选择文件中选择需要加壳的exe文件,点击加壳,运行成功弹出如下消息弹框

运行被加壳后的exe文件会出现如下:

输入正确密码便能正常执行:

4.9 后续优化工作

(1)调试随机基址重定位问题
        确保在随机基址的情况下,程序的重定位功能能够正常工作。
(2)调试 TLS 处理问题
        处理好线程局部存储(TLS)相关问题,保证依赖 TLS 回调函数运行的程序能够正常执行。
(3)加密 IAT 并修复
        对导入地址表(IAT)进行加密处理,同时确保在运行时能够正确修复。
(4)实现边运行边解密和运行完加密
        增强程序的安全性,让破解者难以获取完整的代码信息。
(5)实现全部区段压缩加密
        对程序的所有区段进行压缩加密,进一步提高程序的安全性。

4.10 收获

        通过本次对 Windows PE 文件壳的研究与实现,我们进一步熟悉了 PE 文件的格式和数据结构,掌握了如何对 PE 文件进行操作。同时,深入了解了壳的制作流程和实现技术,为软件保护领域的学习和实践积累了宝贵的经验。输入正确密码后程序能正常执行,这也验证了我们所实现的功能的有效性。

        总之,Windows PE 文件壳技术是一个充满挑战和机遇的领域,后续我们将继续深入研究和优化,为软件安全提供更强大的保障。

完整代码参考:https://download.csdn.net/download/linshantang/90530484


http://www.hkcw.cn/article/xRaKsauwhq.shtml

相关文章

C++离线查询

前言 C算法与数据结构 打开打包代码的方法兼述单元测试 概念及原理 离线算法( offline algorithms)&#xff0c;离线计算就是在计算开始前已知所有输入数据&#xff0c;输入数据不会产生变化&#xff0c;且在解决一个问题后就要立即得出结果的前提下进行的计算。 通俗的说&a…

金价又涨了!金饰克价涨至1018元,一夜涨14元

美东时间5月23日,国际贵金属期货普遍收涨,COMEX黄金期货涨1.90%,报3357.70美元/盎司,本周累计上涨4.75%。5月24日,国内金饰价格跟涨。周生生足金饰品标价1018元/克,较前一日1004元/克的价格上涨14元/克。责任编辑:zx0002

日本人准备开始吃饲料了?

日本农业水产大臣小泉进次郎十分骄傲地宣布政府将要拿出2021年所产陈米以每5公斤1800日元的价格进行售卖(合人民币差不多1斤大米9块钱)。当地专家吹捧此举将有效缓解日本米荒,并放话越是陈米吃着越香,这下日本人有口福了结果评论区直接翻车了,有网友直接贴出往年饲料米价格…

国际乒联发声明回应选举争议 谴责扰乱行为并重启会议

当地时间29日,国际乒联发布了关于2025年度代表大会期间选举事宜的声明。5月27日,在卡塔尔多哈举行的国际乒联年度股东大会上,因主席选举争议引发混乱,会议最终宣布临时暂停。声明中提到,主席选举结束后,一些既不是会员协会代表也不是执行委员会、理事会、委员会成员或受邀…

胖东来红内裤案宣判:“段某”赔偿40万元 名誉权获法院支持

2025年5月28日,许昌市魏都区人民法院公开审理了许昌市胖东来商贸集团有限公司与段某之间的名誉权纠纷案。法院判决段某在其个人抖音账号“两个小段(小)”发布书面道歉信的视频,并赔偿胖东来公司40万元经济损失。部分人大代表、政协委员、媒体记者、律师代表和企业代表旁听了…

市监总局就毕井泉被查表态 再度引发市场关注

六年多前,毕井泉因长春长生疫苗案从原国家食品药品监督管理总局局长位置引咎辞职的消息震惊了市场;六年多后,他被查的消息再次引发市场的强烈关注。据中央纪委国家监委网站5月29日消息,十四届全国政协常委、经济委员会副主任毕井泉涉嫌严重违纪违法,目前正接受中央纪委国家…

高芙评职业生涯最经典三胜 荣耀时刻回顾

近日,美国网球运动员高芙在法网接受记者采访时,回顾了自己职业生涯中的三场经典胜利。这三场比赛分别是2024年终总决赛争冠战对阵郑钦文、2019年温网第一轮对阵大威廉姆斯以及2023年美网决赛对阵萨巴伦卡。她还特别提到了此前罗马半决赛与郑钦文的那场长达三个半小时的大战,…

女子露营归来脖子惨遭“毁容” 提醒:夏季蚊虫活跃,如遇皮肤瘙痒红肿不能拖

近日,浙江30岁女子小妍露营归来后,颈部便出现刺痛和瘙痒,起初她并未在意。两天后,症状急剧加重——皮肤红肿成片,冒出红色丘疹和水疱,还伴随灼热疼痛。无独有偶,小学生骏骏在户外骑车后,小腿处的皮肤上也出现了个大包。两人来浙江省皮肤病医院就医后,均被确诊为“虫咬…

男子乘火车旅行刷新吉尼斯纪录:24小时内乘火车旅行5887.76公里

近日,吉尼斯世界纪录官网公布了一项纪录——中国男子王冬成功以24小时内5887.76公里的火车旅行距离,刷新了“24小时内乘坐火车旅行最远距离”的吉尼斯世界纪录。▲王冬刷新吉尼斯世界纪录今年39岁的王冬是四川德阳人,12年前在上海求学时的他,就曾因换乘8趟列车回家而走红网…

从外卖APP到网络协议:深入解析UDP及应用层协议

目录 1. 应用层和传输层1.1 开发中常见的自定义协议格式 2. UDP2.1 源端口号及目的端口号2.2 UDP报文长度2.3 UDP校验和(checksum) 3. 基于UDP的应用层协议 关注我&#xff0c;学习更多企业开发和面试内容~ 1. 应用层和传输层 应用层和程序员接触最密切&#xff0c;应用程序&a…

【JavaWeb】基本概念、web服务器、Tomcat、HTTP协议

目录 1. 基本概念1.1 基本概念1.2 web应用程序1.3 静态web1.4 动态web 2. web服务器3. tomcat详解3.1 安装3.2 启动3.3 配置3.3.1 配置启动的端口号3.3.2 配置主机的名称3.3.3 其他常用配置项日志配置数据源配置安全配置 3.4 发布一个网站 4. Http协议4.1 什么是http4.2 http的…

自扶正救生艇,乘风破浪,守护生命

在复杂水域救援中存在显著缺陷。遇巨浪或急流漩涡易倾覆且无法自主复位&#xff0c;使救援人员与被困者陷入二次危险。统计显示&#xff0c;激流救援中近三成五的救援人员伤亡源于船只倾覆后被困。更严重的是&#xff0c;传统救生艇倾覆后常需外部救援力量才能恢复&#xff0c;…

法国7月1日起实施最严户外禁烟令,范围包括这些

法国卫生与家庭部长卡特琳沃特兰表示,法国将在所有儿童可能出入的户外场所禁止吸烟。该禁令将于7月1日生效,范围包括海滩、公园、花园、学校外、公交车站和体育场馆等。责任编辑:zx0002

规定明令禁止自热类食品坐火车既不能带也不能托运

自热米饭发热包因高温爆炸风险被高铁禁止,单独食材包携带需密封完好且车上禁加热。各地规定不一,建议优先选择高铁餐食或非加热速食,出行前确认车站要求。一、发热包为何被禁?安全风险是主因自热米饭的发热包主要成分为镁铝粉、生石灰等,遇水后快速放热,温度可达100℃以上…

贵妇扎堆的“月子中心”IPO 圣贝拉月子中心28天收费13.88万起

核心提示:1.尽管“圣贝拉”定位高端月子服务,28天收费13.88万元起,但一度陷亏损泥潭,2022年经调整净亏损4463万元,高成本结构侵蚀利润,租赁与人力成本合计占销售成本近70%。2.这家“最贵”月子中心的合规风险密集暴露:位于北京的月子中心2021-2022年两次因无证行医被处罚…

(NAT64)IPv6网络用户访问IPv4网络服务器(动态映射方式)

1.实验拓扑 2.配置 [FW1]dis cu 2025-05-29 10:44:44.030 !Software Version V500R005C10SPC300 # sysname FW1 # ipv6 #nat64 prefix 3001:: 96 # interface GigabitEthernet1/0/0undo shutdownip address 1.1.1.1 255.255.255.0 # interface GigabitEthernet1/0/1undo shut…

力扣刷题Day 64:括号生成(22)

1.题目描述 2.思路 回溯&#xff0c;过程当中记录左括号和右括号的数量&#xff0c;以此作为剪枝的依据。 3.代码&#xff08;Python3&#xff09; class Solution:def generateParenthesis(self, n: int) -> List[str]:def backtrack(left_n, right_n, parenthesis):if …

高速收发器

一、高速收发器 1.FPGA高速收发器&#xff1a;GTP,GTX,GTH,GTZ 2.每个Quad有4对高速收发器GT(4个TX和4个RX)和一个COmmon 3.走差分&#xff0c;提高抗干扰性 4.CPLL是每个lane私有的&#xff0c;QPLL是整个Quad的所有通道共享的 5.每个MGT的bank有两对差分参考时钟 6.CPLL的时钟…

社保交满最低缴费年限停止就亏大了

社保交满最低缴费年限后停止缴纳确实会带来损失‌。首先,社保缴费满15年只是满足了领取养老金的一个必要条件,但并不是最优条件。养老金的领取金额与缴费年限和缴费金额密切相关,缴费年限越长、金额越高,退休后领取的养老金也会越多‌。具体来说,养老金的计算遵循“多缴多…

瑞幸咖啡降价 价格战再升级

瑞幸咖啡降价 价格战再升级!5月30日,消费者发现瑞幸咖啡多款饮品价格降至6.9元。此前,瑞幸咖啡的最低价通常是9.9元一杯。这次降价可能与近期外卖平台的价格战有关。本季度,奶茶和咖啡行业的价格竞争尤为激烈,瑞幸的主要竞争对手之一库迪咖啡将单品价格压低至3.9元和4.9元…