用户态下HOOK API隐藏文件

突然想写个RING3下隐藏文件的程序,于是花了一天的时间,把我以前写的一个HOOK send的程序改了。
要实现Ring3下隐藏文件,最简单的方法就是HOOK掉Explorer进程里的FindFirstFile和FindNextFile函数,考虑到A和W两个版本,我们应该要HOOK四个函数,但是事实上,我们只要HOOK掉W版本的两个函数就可以了,因为用Dependency看下就能发现Explorer.exe并没有使用FindFirstFileA和FindNextFileA。HOOK API的方法有好多种,我这里用的是HOOK IAT法,也就是遍历Exeplorer进程中的所有模块,凡是模块的导入表中用到FindFirstFileW和FindNextFileW的,就修改FirstThunk数组中对应项的Function地址为MYFindFirstFileW和MYFindNextFileW的地址,再在MYFindFirstFileW函数中调用真实的FindFirstFileW地址,MYFindNextFileW函数类似。以下直接给出源程序,程序中为了安全也可以HOOK掉A版本的函数,只要把//#define HookProA行的注释符号去掉就行。
 
 
// Hook FindFile.cpp : 定义 DLL 应用程序的入口点。
//
#include "stdafx.h"
#include "stdlib.h"
#include<windows.h>
#include <Dbghelp.h>
#include <tlhelp32.h>
#include "mydebug.h"
#pragma comment(lib, "imagehlp.lib")
 
//不要以\结尾 要隐藏的文件路径
#define HIDEFILE "E:\\abc\\abc.txt"
//#define HookProA
 
typedef HANDLE (WINAPI *PFNFindFirstFile)(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData );
typedef BOOL (WINAPI *PFNFindNextFile)(HANDLE hFindFile,LPWIN32_FIND_DATA lpFindFileData );
 
DWORD *MyFindFirstFileWAddr,*FindFirstFileWAddr;
DWORD *MyFindNextFileWAddr,*FindNextFileWAddr;
#ifdef HookProA
DWORD *MyFindFirstFileAAddr,*FindFirstFileAAddr;
DWORD *MyFindNextFileAAddr,*FindNextFileAAddr;
#endif
bool bPathMatch=false;
 
HANDLE WINAPI MyFindFirstFileW(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData )
{
     HANDLE hFind;
     static WCHAR HidePath[MAX_PATH+1]={0};
     int i;
/*
     file_str("---------------------------------------","F:\\temp2.txt");
     i=WideCharToMultiByte(CP_ACP,0,(WCHAR *)lpFileName,wcslen((WCHAR *)lpFileName),path,MAX_PATH,0,0);
     path[i]='\0';
     file_str(path,"F:\\temp2.txt");
*/
 
     if(wcslen(HidePath)==0)
     {
         i=MultiByteToWideChar(CP_ACP,0,HIDEFILE,strlen(HIDEFILE),HidePath,MAX_PATH);
         while(HidePath[i]!='\\' && i>0)
              i--;
         HidePath[i]='\0';
         //file_str2(HidePath,"F:\\temp1.txt");
     }
 
     hFind=((PFNFindFirstFile)FindFirstFileWAddr)(lpFileName,lpFindFileData);
 
     if(wcsnicmp((WCHAR *)lpFileName,HidePath,wcslen(HidePath))==0)
     {
         bPathMatch=true;
         //file_str("路径匹配","F:\\temp1.txt");
     }
     else
     {
         bPathMatch=false;
         //file_str("路径不匹配","F:\\temp1.txt");
     }
 
    
 
/*
     i=WideCharToMultiByte(CP_ACP,0,(WCHAR *)lpFindFileData->cFileName,wcslen((WCHAR *)lpFindFileData->cFileName),path,MAX_PATH,0,0);
     path[i]='\0';
     file_str(path,"F:\\temp2.txt");
*/
     return hFind;
}
BOOL WINAPI MyFindNextFileW(HANDLE hFindFile,LPWIN32_FIND_DATA lpFindFileData)
{
     BOOL bReturn;
     static WCHAR HideName[MAX_PATH+1]={0};
     int i,j;
 
     bReturn=((PFNFindNextFile)FindNextFileWAddr)(hFindFile,lpFindFileData);
 
     if(bPathMatch)
     {   
         if(wcslen(HideName)==0)
         {
              i=MultiByteToWideChar(CP_ACP,0,HIDEFILE,strlen(HIDEFILE),HideName,MAX_PATH);
              HideName[i]='\0';
              while(HideName[i]!='\\' && i>0)
                   i--;
              i++;
              j=0;
              while(HideName[i]!='\0' && i<MAX_PATH)
              {
                   HideName[j]=HideName[i];
                   i++;j++;
              }
              HideName[j]='\0';
              //file_str2(HideName,"F:\\temp1.txt");
         }
 
         while(wcsnicmp((WCHAR *)lpFindFileData->cFileName,HideName,wcslen(HideName))==0)
         {
              bReturn=((PFNFindNextFile)FindNextFileWAddr)(hFindFile,lpFindFileData);
              //file_str("需要隐藏","F:\\temp1.txt");
              if(bReturn==false)
                   break;
         }
 
 
     }
 
     //i=WideCharToMultiByte(CP_ACP,0,(WCHAR *)lpFindFileData->cFileName,wcslen((WCHAR *)lpFindFileData->cFileName),name,MAX_PATH,0,0);
     //name[i]='\0';
     //file_str(name,"F:\\temp2.txt");
     return bReturn;
}
//----------------------------------------------------
#ifdef HookProA
HANDLE WINAPI MyFindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData )
{
     HANDLE hFind;
     static char HidePath[MAX_PATH+1]={0};
     int i;
/*
     file_str("---------------------------------------","F:\\temp2.txt");
     i=WideCharToMultiByte(CP_ACP,0,(WCHAR *)lpFileName,wcslen((WCHAR *)lpFileName),path,MAX_PATH,0,0);
     path[i]='\0';
     file_str(path,"F:\\temp2.txt");
*/
 
     if(strlen(HidePath)==0)
     {
         strcpy(HidePath,HIDEFILE);
         i=strlen(HidePath);
         while(HidePath[i]!='\\' && i>0)
              i--;
         HidePath[i]='\0';
         //file_str2(HidePath,"F:\\temp1.txt");
     }
 
     hFind=((PFNFindFirstFile)FindFirstFileAAddr)(lpFileName,lpFindFileData);
 
     if(stricmp(lpFileName,HidePath)==0)
     {
         bPathMatch=true;
         //file_str("路径匹配","F:\\temp1.txt");
     }
     else
     {
         bPathMatch=false;
         //file_str("路径不匹配","F:\\temp1.txt");
     }
 
    
 
/*
     i=WideCharToMultiByte(CP_ACP,0,(WCHAR *)lpFindFileData->cFileName,wcslen((WCHAR *)lpFindFileData->cFileName),path,MAX_PATH,0,0);
     path[i]='\0';
     file_str(path,"F:\\temp2.txt");
*/
     return hFind;
}
BOOL WINAPI MyFindNextFileA(HANDLE hFindFile,LPWIN32_FIND_DATA lpFindFileData)
{
     BOOL bReturn;
     static char HideName[MAX_PATH+1]={0};
     int i,j;
 
     bReturn=((PFNFindNextFile)FindNextFileWAddr)(hFindFile,lpFindFileData);
 
     if(bPathMatch)
     {   
         if(strlen(HideName)==0)
         {
              strcpy(HideName,HIDEFILE);
              i=strlen(HideName);
              while(HideName[i]!='\\' && i>0)
                   i--;
              i++;
              j=0;
              while(HideName[i]!='\0' && i<MAX_PATH)
              {
                   HideName[j]=HideName[i];
                   i++;j++;
              }
              HideName[j]='\0';
              //file_str2(HideName,"F:\\temp1.txt");
         }
 
         while(stricmp(lpFindFileData->cFileName,HideName)==0)
         {
              bReturn=((PFNFindNextFile)FindNextFileAAddr)(hFindFile,lpFindFileData);
              //file_str("需要隐藏","F:\\temp1.txt");
              if(bReturn==false)
                   break;
         }
 
 
     }
 
     //i=WideCharToMultiByte(CP_ACP,0,(WCHAR *)lpFindFileData->cFileName,wcslen((WCHAR *)lpFindFileData->cFileName),name,MAX_PATH,0,0);
     //name[i]='\0';
     //file_str(name,"F:\\temp2.txt");
     return bReturn;
}
#endif
//////----------------------------------------------------------
void IATFind(DWORD *FromAddr,DWORD *ToAddr,const char *module)
{
     PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
     PIMAGE_THUNK_DATA         pThunkData;
     ULONG uSize ;
     DWORD *Addr2;
     DWORD dwOLD;
     MEMORY_BASIC_INFORMATION mbi;
 
     HMODULE hMod=GetModuleHandle(module);
     pImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hMod,true,IMAGE_DIRECTORY_ENTRY_IMPORT,&uSize);
     if(!pImportDescriptor)
         return;
 
     while(pImportDescriptor->Name)
     {
         char *szModName = (char *)((PBYTE)hMod+pImportDescriptor->Name) ;
         if(stricmp(szModName,"kernel32.dll")==0)
         {
              //file_str("找到kernel32.dll","F:\\temp.txt");
              pThunkData = (PIMAGE_THUNK_DATA32)((PBYTE)hMod+pImportDescriptor->FirstThunk) ;
              while(pThunkData->u1.Function)
              {
                   //file_str("pThunkData循环","F:\\temp.txt");
                   Addr2 = (DWORD *)pThunkData->u1.Function ;
                   //file_num((DWORD)Addr2,"F:\\temp.txt");
                   if((DWORD)Addr2==(DWORD)FromAddr)
                   {
                       //file_str("找到导入","F:\\temp.txt");
                       VirtualQuery(&(pThunkData->u1.Function),&mbi,sizeof(mbi));
                       VirtualProtect(&(pThunkData->u1.Function),sizeof(DWORD),PAGE_READWRITE,&dwOLD);
                       WriteProcessMemory(GetCurrentProcess(),&(pThunkData->u1.Function),&ToAddr, sizeof(DWORD), NULL);
                       VirtualProtect(&(pThunkData->u1.Function),sizeof(DWORD),dwOLD,0);
                       break ;
                   }
 
                   pThunkData++ ;
              }
 
         }
         pImportDescriptor++ ;
     }
 
 
}
//---------------------------------------------
void DLLFind()
{
     HANDLE hSnapshot= NULL;
     MODULEENTRY32 moudle;
 
        
     hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
     moudle.dwSize = sizeof(MODULEENTRY32);
     Module32First(hSnapshot,&moudle);
     do
     {
         //file_str(moudle.szModule,"F:\\temp.txt");
         IATFind(FindFirstFileWAddr,MyFindFirstFileWAddr,moudle.szModule);
         IATFind(FindNextFileWAddr,MyFindNextFileWAddr,moudle.szModule);
#ifdef HookProA
         IATFind(FindFirstFileAAddr,MyFindFirstFileAAddr,moudle.szModule);
         IATFind(FindNextFileAAddr,MyFindNextFileAAddr,moudle.szModule);
#endif
     }
     while(Module32Next(hSnapshot,&moudle) );
     CloseHandle(hSnapshot);
}
 
 
DWORD WINAPI APIHook(LPVOID lpParameter)
{
     HMODULE h;
 
     h=GetModuleHandle("kernel32.dll");
 
     MyFindFirstFileWAddr=(DWORD *)MyFindFirstFileW;
     FindFirstFileWAddr=(DWORD *)GetProcAddress(h,"FindFirstFileW");
 
     MyFindNextFileWAddr=(DWORD *)MyFindNextFileW;
     FindNextFileWAddr=(DWORD *)GetProcAddress(h,"FindNextFileW");
#ifdef HookProA
     MyFindFirstFileAAddr=(DWORD *)MyFindFirstFileA;
     FindFirstFileAAddr=(DWORD *)GetProcAddress(h,"FindFirstFileA");
 
     MyFindNextFileAAddr=(DWORD *)MyFindNextFileA;
     FindNextFileAAddr=(DWORD *)GetProcAddress(h,"FindNextFileA");
#endif
 
     CloseHandle(h);
    
     while(1)
     {
         DLLFind();
         Sleep(100000);
     }
     return 0;
}
 
 
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
     if(ul_reason_for_call==DLL_PROCESS_ATTACH)
         CreateThread(0,0,APIHook,0,0,0);
    return TRUE;
}
 
 
完整源程序:HookFindFile.rar

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

Copyright langouster. Some Rights Reserved.   苏ICP备06046736号   

本站点由 Z-Blog 2.0 bate Build 构建,基于 Glued Ideas Subtle 主题,由 zx.asd 移植并创新.