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

泉州做网站优化哪家好市场调研的内容

泉州做网站优化哪家好,市场调研的内容,做机械的老板都看什么网站,中山网站建设 760前言 在之前几篇文章已经学习了解了几种钩取的方法 浅谈调试模式钩取浅谈热补丁浅谈内联钩取原理与实现导入地址表钩取技术 这篇文章就利用钩取方式完成进程隐藏的效果。 进程遍历方法 在实现进程隐藏时,首先需要明确遍历进程的方法。 CreateToolhelp32Snapsh…

前言

在之前几篇文章已经学习了解了几种钩取的方法

  • 浅谈调试模式钩取
  • 浅谈热补丁
  • 浅谈内联钩取原理与实现
  • 导入地址表钩取技术

这篇文章就利用钩取方式完成进程隐藏的效果。

进程遍历方法

在实现进程隐藏时,首先需要明确遍历进程的方法。

CreateToolhelp32Snapshot

CreateToolhelp32Snapshot函数用于创建进程的镜像,当第二个参数为0时则是创建所有进程的镜像,那么就可以达到遍历所有进程的效果。

#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>int main()
{//设置编码,便于后面能够输出中文setlocale(LC_ALL, "zh_CN.UTF-8");//创建进程镜像,参数0代表创建所有进程的镜像HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hSnapshot == INVALID_HANDLE_VALUE){std::cout << "Create Error" << std::endl;exit(-1);}/** typedef struct tagPROCESSENTRY32 { * DWORD dwSize;               进程信息结构体大小,首次调用之前必须初始化* DWORD cntUsage;              引用进程的次数,引用次数为0时,则进程结束* DWORD th32ProcessID;           进程的ID* ULONG_PTR th32DefaultHeapID;       进程默认堆的标识符,除工具使用对我们没用* DWORD th32ModuleID;                  进程模块的标识符* DWORD cntThreads;             进程启动的执行线程数* DWORD th32ParentProcessID;           父进程ID* LONG  pcPriClassBase;          进程线程的基本优先级* DWORD dwFlags;              保留* TCHAR szExeFile[MAX_PATH];          进程的路径* } PROCESSENTRY32; * typedef PROCESSENTRY32 *PPROCESSENTRY32; */PROCESSENTRY32 pi;pi.dwSize = sizeof(PROCESSENTRY32);//取出第一个进程BOOL bRet = Process32First(hSnapshot, &pi);while (bRet){wprintf(L"进程路径:%s\t进程号:%d\n", pi.szExeFile, pi.th32ProcessID);//取出下一个进程bRet = Process32Next(hSnapshot, &pi);}
}

EnumProcesses

EnumProcesses用于将所有进程号的收集。

#include <iostream>
#include <Windows.h>
#include <Psapi.h>int main()
{setlocale(LC_ALL, "zh_CN.UTF-8");DWORD processes[1024], dwResult, size;unsigned int i;//收集所有进程的进程号if (!EnumProcesses(processes, sizeof(processes), &dwResult)){std::cout << "Enum Error" << std::endl;}//进程数量size = dwResult / sizeof(DWORD);for (i = 0; i < size; i++){//判断进程号是否为0if (processes[i] != 0){//用于存储进程路径TCHAR szProcessName[MAX_PATH] = { 0 };//使用查询权限打开进程HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,FALSE,processes[i]);if (hProcess != NULL){HMODULE hMod;DWORD dwNeeded;//收集该进程的所有模块句柄,第一个句柄则为文件路径if (EnumProcessModules(hProcess, &hMod, sizeof(hMod),&dwNeeded)){//根据句柄获取文件路径GetModuleBaseName(hProcess, hMod, szProcessName,sizeof(szProcessName) / sizeof(TCHAR));}wprintf(L"进程路径:%s\t进程号:%d\n", szProcessName, processes[i]);}}   }
}

ZwQuerySystemInfomation

ZwQuerySystemInfomation函数是CreateToolhelp32Snapshot函数与EnumProcesses函数底层调用的函数,也用于遍历进程信息。代码参考https://cloud.tencent.com/developer/article/1454933

#include <iostream>
#include <Windows.h>
#include <ntstatus.h>
#include <winternl.h> 
#pragma comment(lib, "ntdll.lib") //定义函数指针
typedef NTSTATUS(WINAPI* NTQUERYSYSTEMINFORMATION)(IN      SYSTEM_INFORMATION_CLASS SystemInformationClass,IN OUT   PVOID                    SystemInformation,IN      ULONG                    SystemInformationLength,OUT PULONG                   ReturnLength);int main()
{//设置编码setlocale(LC_ALL, "zh_CN.UTF-8");//获取模块地址HINSTANCE ntdll_dll = GetModuleHandle(L"ntdll.dll");if (ntdll_dll == NULL) {std::cout << "Get Module Error" << std::endl;exit(-1);}NTQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;//获取函数地址ZwQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(ntdll_dll, "ZwQuerySystemInformation");if (ZwQuerySystemInformation != NULL){SYSTEM_BASIC_INFORMATION sbi = { 0 };//查询系统基本信息NTSTATUS status = ZwQuerySystemInformation(SystemBasicInformation, (PVOID)&sbi, sizeof(sbi), NULL);if (status == STATUS_SUCCESS){wprintf(L"处理器个数:%d\r\n", sbi.NumberOfProcessors);}else{wprintf(L"ZwQuerySystemInfomation Error\n");}DWORD dwNeedSize = 0;BYTE* pBuffer = NULL;wprintf(L"\t----所有进程信息----\t\n");PSYSTEM_PROCESS_INFORMATION psp = NULL;//查询进程数量status = ZwQuerySystemInformation(SystemProcessInformation, NULL, 0, &dwNeedSize);if (status == STATUS_INFO_LENGTH_MISMATCH){pBuffer = new BYTE[dwNeedSize];//查询进程信息status = ZwQuerySystemInformation(SystemProcessInformation, (PVOID)pBuffer, dwNeedSize, NULL);if (status == STATUS_SUCCESS){psp = (PSYSTEM_PROCESS_INFORMATION)pBuffer;wprintf(L"\tPID\t线程数\t工作集大小\t进程名\n");do {//获取进程号wprintf(L"\t%d", psp->UniqueProcessId);//获取线程数量wprintf(L"\t%d", psp->NumberOfThreads);//获取工作集大小wprintf(L"\t%d", psp->WorkingSetSize / 1024);//获取路径wprintf(L"\t%s\n", psp->ImageName.Buffer);//移动psp = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)psp + psp->NextEntryOffset);} while (psp->NextEntryOffset != 0);delete[]pBuffer;pBuffer = NULL;}else if (status == STATUS_UNSUCCESSFUL) {wprintf(L"\n STATUS_UNSUCCESSFUL");}else if (status == STATUS_NOT_IMPLEMENTED) {wprintf(L"\n STATUS_NOT_IMPLEMENTED");}else if (status == STATUS_INVALID_INFO_CLASS) {wprintf(L"\n STATUS_INVALID_INFO_CLASS");}else if (status == STATUS_INFO_LENGTH_MISMATCH) {wprintf(L"\n STATUS_INFO_LENGTH_MISMATCH");}}}
}

进程隐藏

通过上述分析可以知道遍历进程的方式有三种,分别是利用CreateToolhelp32SnapshotEnumProcesses以及ZwQuerySystemInfomation函数

但是CreateToolhelp32SnapshotEnumProcesses函数底层都是调用了ZwQuerySystemInfomation函数,因此我们只需要钩取该函数即可。

由于测试环境是Win11,因此需要判断在Win11情况下底层是否还是调用了ZwQuerySystemInfomation函数。

可以看到在Win11下还是会调用ZwQuerySystemInfomation函数,在用户态下该函数的名称为NtQuerySystemInformation函数。

这里采用内联钩取的方式对ZwQuerySystemInfomation进行钩取处理,具体怎么钩取在浅谈内联钩取原理与实现已经介绍过了,这里就不详细说明了。这里对自定义的ZwQuerySystemInfomation函数进行说明。

首先第一步需要进行脱钩处理,因为后续需要用到初始的ZwQuerySystemInfomation函数,紧接着获取待钩取函数的地址即可。

...//脱钩UnHook("ntdll.dll", "ZwQuerySystemInformation", g_pOrgBytes);HMODULE hModule = GetModuleHandleA("ntdll.dll");//获取待钩取函数的地址PROC    pfnOld = GetProcAddress(hModule, "ZwQuerySystemInformation");//调用原始的ZwQuerySystemInfomation函数NTSTATUS status = ((NTQUERYSYSTEMINFORMATION)pfnOld)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
...

为了隐藏指定进程,我们需要遍历进程信息,找到目标进程并且删除该进程信息实现隐藏的效果。这里需要知道的是进程信息都存储在SYSTEM_PROCESS_INFORMATION结构体中,该结构体是通过单链表对进程信息进行链接。因此我们通过匹配进程名称找到对应的SYSTEM_PROCESS_INFORMATION结构体,然后进行删除即可,效果如下图。

通过单链表中删除节点的操作,取出目标进程的结构体。代码如下

...pCur = (PSYSTEM_PROCESS_INFORMATION)(SystemInformation);while (true){if (!lstrcmpi(pCur->ImageName.Buffer, L"test.exe")){//需要隐藏的进程是最后一个节点if (pCur->NextEntryOffset == 0)pPrev->NextEntryOffset = 0;//不是最后一个节点,则将该节点取出elsepPrev->NextEntryOffset += pCur->NextEntryOffset;}//不是需要隐藏的节点,则继续遍历elsepPrev = pCur;//链表遍历完毕if (pCur->NextEntryOffset == 0)break;pCur = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)pCur + pCur->NextEntryOffset);}
...

完整代码:https://github.com/h0pe-ay/HookTechnology/blob/main/ProcessHidden/inlineHook.c

但是采用内联钩取的方法去钩取任务管理器就会出现一个问题,这里将断点取消,利用内联钩取的方式去隐藏进程。

首先利用bl命令查看断点

紧着利用 bc [ID]删除断点

在注入之后任务管理器会在拷贝的时候发生异常

在经过一番调试后发现,由于多线程共同执行导致原本需要可写权限的段被修改为只读权限

windbg可以用使用!vprot + address查看指定地址的权限,可以看到由于程序往只读权限的地址进行拷贝处理,所以导致了异常。

但是在执行拷贝阶段是先修改了该地址为可写权限,那么导致该原因的情况就是其他线程执行了权限恢复后切换到该线程中进行写,所以导致了这个问题。

因此内联钩取是存在多线程安全的问题,此时可以使用微软自己构建的钩取库Detours,可以在钩取过程中确保线程安全。

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

Detours

项目地址:https://github.com/microsoft/Detours

环境配置

参考:https://www.cnblogs.com/linxmouse/p/14168712.html

使用vcpkg下载

vcpkg.exe install detours:x86-windows
vcpkg.exe install detours:x64-windows
vcpkg.exe integrate install

实例

挂钩

利用Detours挂钩非常简单,只需要根据下列顺序,并且将自定义函数的地址与被挂钩的地址即可完成挂钩处理。

...//用于确保在 DLL 注入或加载时,恢复被 Detours 修改的进程镜像,保持稳定性DetourRestoreAfterWith();//开始一个新的事务来附加或分离DetourTransactionBegin();//进行线程上下文的更新DetourUpdateThread(GetCurrentThread());//挂钩DetourAttach(&(PVOID&)TrueZwQuerySystemInformation, ZwQuerySystemInformationEx);//提交事务error = DetourTransactionCommit();
...

脱钩

然后根据顺序完成脱钩即可。

...//开始一个新的事务来附加或分离DetourTransactionBegin();//进行线程上下文的更新DetourUpdateThread(GetCurrentThread());//脱钩DetourDetach(&(PVOID&)TrueZwQuerySystemInformation, ZwQuerySystemInformationEx);//提交事务error = DetourTransactionCommit();
...

挂钩的原理

从上述可以看到,Detours是通过事务确保了在DLL加载与卸载时后的原子性,但是如何确保多线程安全呢?后续通过调试去发现。

可以利用x ntdl!ZwQuerySystemInformation查看函数地址,可以看到函数的未被挂钩前的情况如下图。

挂钩之后原始的指令被修改为一个跳转指令把前八个字节覆盖掉,剩余的3字节用垃圾指令填充。

该地址里面又是一个jmp指令,并且完成间接寻址的跳转。

该地址是自定义函数ZwQuerySystemInformationEx,因此该间接跳转是跳转到的自定义函数内部。

跳转到TrueZwQuerySystemInformation内部发现ZwQuerySystemInformation函数内部的八字节指令被移动到该函数内部。紧接着又完成一个跳转。

该跳转到ZwQuerySystemInformation函数内部紧接着完成ZwQuerySystemInformation函数的调用。

综上所述,整体流程如下图。实际上Detours实际上使用的是热补丁的思路,但是Detours并不是直接在原始的函数空间中进行补丁,而是开辟了一段临时空间,将指令存储在里面。因此在挂钩后不需要进行脱钩处理就可以调用原始函数。因此就不存在多线程中挂钩与脱钩的冲突。

完整代码:https://github.com/h0pe-ay/HookTechnology/blob/main/ProcessHidden/detoursHook.c

http://www.dt0577.cn/news/40002.html

相关文章:

  • 怎么做一元购网站百度一下搜索网页
  • 黄页网站推广app软件什么是网络营销策略
  • python 网站开发 普及站长工具麻豆
  • 三门峡 网站开发付费推广
  • 朝阳网站开发公司郑州seo优化外包
  • 网站制作前景怎么样seo资讯网
  • 小红书的网站建设网站搜索引擎优化的基本内容
  • 2017政府网站建设通知今日国际军事新闻头条
  • 成都那家网站做的好营口seo
  • 做网站分流百度如何推广广告
  • 上海电子商城网站制作重庆seo网站推广费用
  • 网站建设后台管理流程网站建设模板
  • 使用java做直播网站国外独立网站如何建站
  • 网站建设提成方案上海关键词排名提升
  • 熊猫网站ppt精准营销系统价值
  • 糗事百科网站模板开网站需要多少钱
  • delphi怎么做网站浙江百度查关键词排名
  • wordpress b2b2c西安网站seo哪家公司好
  • 做网站的大公司有哪些培训机构网站
  • 建设学校网站的需求分析百度推广登录入口电脑
  • 如何建立一个私人网站优化网站seo
  • 柳城企业网站制作哪家好百度推广怎么才能效果好
  • 网站广告条动画 怎么做网络营销策划公司
  • 雄安网站建设优化公司seo效果检测步骤
  • h5网站开发模板交换链接是什么意思
  • 西安互联网网站建设seo上首页
  • 宁波做网站的哪个好seo1视频发布会
  • 公司网页制作好了 怎么发布宁波seo企业网络推广
  • 公司网站维护更新流程性能优化工具
  • 做国珍新时代 网站网络推广都有哪些方式