API拦截-实现Ring3全局HOOK.docVIP

  • 5
  • 0
  • 约8.76千字
  • 约 20页
  • 2017-08-20 发布于北京
  • 举报
API拦截-实现Ring3全局HOOK

API拦截——实现Ring3全局HOOK 首先来解释一下这次的目标。由于windows的copy-on-write机制(Ring0下可以用CR0寄存器关掉它),Ring3下的HOOK只对当前进程有效,其他进程的API还是正常的。这就是说我们必须枚举进程,然后对每个Ring3进程执行一遍HOOK操作。 但是,系统中总有新进程产生,对于这些新进程我们怎么处理呢?最容易想到的就是设置一个TIMER,每隔一段时间就枚举一遍进程然后把新的挂钩。但仔细一想就知道不行,TEMER过快严重影响系统效率,慢了又起不到作用,况且windows不是一个实时操作系统,没人能保证到时间TEMER就被激活。如果我们能监控进程创建,并在他们真正运行之前就执行挂钩操作,就可以完美的解决问题。 但是如何做到这一点呢?我们知道Ring3的进程都有一个“父进程”也就是说新进程都是由老进程创建的(驱动很少创建进程)。知道这一点就好办了,我们要做的只是截获进程创建。你肯定会说“这么简单,HOOK NtCreateProcess就可以了!”但是这不是最简单的做法。为什么这么说呢,首先在NtCreateProcess函数被调用时进程并没有真正被创建,我们无法执行HOOK操作,而当NtCreateProcess返回时,进程又已经开始运行,HOOK时存在线程同步的问题(我用OD在NtCreateProcess设下INT3断点,却拦不到,不只是为什么?)。 所以我选的函数是NtResumeThread。我们知道,当新进程被创建时,OS会为其创建一个住线程,而在这之后会调用NtResumeThread时期开始运行,这时初始化完毕,DLL都已经被载入,但进程却没有开始运行这时我们最好的机会(HAHA,天助我也HAHAHA…)。 NTSTATUS NtResumeThread( IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL ); 思路是这样但是怎么实现呢?来看一下函数的定义: 我们关心的是第一个参数,它存储的是新进程主线程的句柄,我们可以通过调用ThreadInformationClass=0,ThreadInformationLength=28的NtQueryInformationThread函数来获得该县城所属进程的PID,然后只要HOOK它就可以了。 话虽如此,可是如果把HOOK的代码都放到远程去未免太麻烦了。开始我想的是用远程进程调用CreateRemoteThread来回调HOOK进程。但仔细想想就会发现,我们在本地HOOK时有足够的权限,可是如果远程进程是GUEST权限的呢?回调时由于权限不够就会出错。翻了翻《windows核心编程》后恍然大悟:可以使用windows的事件对象来实现。用到的API有:OpenEvent,CreateEvent,SetEvent,ResetEvent。在HOOK每一个进程的时候,用CreateEvent创建一个不可继承、自动重置的Event对象,然后创建一个线程用WaitForSingleObject函数等待改Event。当拦截到新进程创建时,远程线程调用SetEvent来激活Event,然后同样调用WaitForSingleObject函数等待。这时本地的WaitForSingleObject会返回, 然后再进行相关的处理,然后调用SetEvent来让远程hook函数继续运行。这样有个问题就是本题怎样知道新进程PID?我的解决办法是远程调用SetEvent前先把PID写在HOOK函数开头的特定偏移位置,然后本地用ReadProcessMemory来读取。限于篇幅讲得不太具体,如果不懂最好去看一看《windows核心编程》。 好了,理论就讲道这里,来看看代码,GO!(虽然是在去年的5期文章的基础上改的,不过改动较大,所以关键代码已提上来了。) 首先是hook函数,主要功能是对指定进程的指定API进行hook操作: int HookNamedApi( PDLLINFO pDllInfo, char *ApiName, DWORD HookProc, HANDLE ObjectProcessHandle) { DWORD dw, NamedApiAddress,NewFunc;//变量初始化 MEMORY_BASIC_INFORMATION mbi; static EventInfo myEventInfo; static Num=0x676e696b; NamedApiAddress = (DWORD)GetProcAddress(pDllInfo-hModule, ApiName);//目标api地址 ,每个进程的api地址都是一样的,只要找本

文档评论(0)

1亿VIP精品文档

相关文档