首页
论坛
课程
招聘
[转帖]HOOK其他进程API和全局HOOK-API
2006-3-9 16:56 7089

[转帖]HOOK其他进程API和全局HOOK-API

2006-3-9 16:56
7089
HOOK是一种WINDOWS下存在很久的技术了。
HOOK一般分两种1。HOOK MESSAGE  2。HOOK API 本问讨论的是HOOK API。(如果你是HOOK高手就不要看了)
在最初学HOOK-API的时候通常都是通过覆盖地址和修改IAT的方法。
通过这两种技术,我们基本都可以实现对本进程的API函数进行HOOK了。但是在高兴之余会有点遗憾,
怎么才能HOOK其他进程的API函数呢?怎么才能对一个API函数进行全局的HOOK呢?
下面是我的一个简单的“HOOK其他进程API函数”的实现。(对另一进程的MessageBoxA这个函数进行HOOK)

其实里面的应用了两个技术
1。远程线程注入
2。修改IAT,HOOK-API

好了贴出代码如下:
一共是3个文件
install.c  注入程序
fundll.cpp  DLL程序
test.cpp  测试程序  

CODE:

//-------------------------install.c--------------------------
//
//install.c

#include "windows.h"
#include "tlhelp32.h"

#pragma comment(lib,"th32.lib")

const char *pkill="fundll.dll";                //DLL文件的路径

//这个路径很有意思,这个路径是相对于目标进程的,而不是自身进程。
//所以要嘛写成绝对路径,要嘛写成相对于目标进程的相对路径。
//如果写成相对于自身的路径就要麻烦了,本程序就找不到DLL文件了。

char *prosess="test.exe";   //要注入的进程名(目标进程名)

int main()
{
        HANDLE hSnap;
        HANDLE hkernel32;        //被注入进程的句柄
        PROCESSENTRY32 pe;
        BOOL bNext;
        HANDLE hToken;
        TOKEN_PRIVILEGES tp;
        LUID Luid;
        LPVOID p;
        FARPROC pfn;

        if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
        {
                return 1;
        }

        if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&Luid))
        {
                return 1;
        }

        tp.PrivilegeCount = 1;
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        tp.Privileges[0].Luid = Luid;

        if (!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
        {
                return 1;
        }

        pe.dwSize = sizeof(pe);
        hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        bNext=Process32First(hSnap, &pe);
        while(bNext)
        {
                if(!stricmp(pe.szExeFile,prosess))                //--->>
                {
                        hkernel32=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,pe.th32ProcessID);
                        break;
                }
                bNext=Process32Next(hSnap, &pe);
        }

        CloseHandle(hSnap);

        p=VirtualAllocEx(hkernel32,NULL,strlen(pkill),MEM_COMMIT,PAGE_READWRITE);
        WriteProcessMemory(hkernel32,p,pkill,strlen(pkill),NULL);
        pfn=GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA");
        CreateRemoteThread(hkernel32,NULL,0,pfn,p,NULL,0);

        return 0;
}

//----------------------fundll.cpp-----------------------------
//
//fundll.cpp

#include "windows.h"
#include "process.h"
#include "tlhelp32.h"
#include "stdio.h"

#pragma comment(lib,"th32.lib")

PIMAGE_DOS_HEADER  pDosHeader;
PIMAGE_NT_HEADERS  pNTHeaders;
PIMAGE_OPTIONAL_HEADER   pOptHeader;
PIMAGE_IMPORT_DESCRIPTOR  pImportDescriptor;
PIMAGE_THUNK_DATA         pThunkData;
PIMAGE_IMPORT_BY_NAME     pImportByName;
HMODULE hMod;

// 定义MessageBoxA函数原型
typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);

int * addr = (int *)MessageBoxA;        //保存函数的入口地址
int * myaddr = (int *)MessageBoxProxy;

void ThreadProc(void *param);//线程函数

//-------------------------------------------------------主函数开始

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
        if(fdwReason==DLL_PROCESS_ATTACH)        
                _beginthread(ThreadProc,0,NULL);        

        return TRUE;
}

//结束进程的函数

void ThreadProc(void *param)
{
        //------------hook api----------------
        hMod = GetModuleHandle(NULL);

        pDosHeader = (PIMAGE_DOS_HEADER)hMod;
        pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);
        pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader);

        pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress);

        while(pImportDescriptor->FirstThunk)
        {
                char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name);

                pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk);

                int no = 1;
                while(pThunkData->u1.Function)
                {
                        char * funname = (char *)((BYTE *)hMod + (DWORD)pThunkData->u1.AddressOfData + 2);
                        PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) +(no-1);
               
                        //修改内存的部分
                        if((*lpAddr) == (int)addr)
                        {
                                //修改内存页的属性
                                DWORD dwOLD;
                                MEMORY_BASIC_INFORMATION  mbi;
                                VirtualQuery(lpAddr,&mbi,sizeof(mbi));
                                VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
                                
                                WriteProcessMemory(GetCurrentProcess(),
                                                lpAddr, &myaddr, sizeof(DWORD), NULL);
                                //恢复内存页的属性
                                VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);
                        }
            //---------
                        no++;
                        pThunkData++;
                }

                pImportDescriptor++;
        }
        //-------------------HOOK END-----------------
}

//new messagebox function
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
        return         ((PFNMESSAGEBOX)addr)(NULL, "gxter_test", "gxter_title", 0);
        //这个地方可以写出对这个API函数的处理代码
}

//----------------------------test.cpp------------------------------------
//test.cpp

#include "stdio.h"
#include "windows.h"

int main()
{
        printf("test---\n");
        while(1)
        {
                getchar();
                MessageBoxA(NULL, "原函数", "09HookDemo", 0);
        }
        return 0;
}

测试过程:先运行TEST不要关闭(建立目标),再运行install(进行注入)。但要注意FUNDLL和TEST文件位置。

上面的代码进本上就实现了对其他进程的API进行HOOK了。
但还有一个问题就是对“API函数进行全局的HOOK”。我的想法就是注入所有进程就可以实现了。
只要简单的改一下上面的代码就可以实现了。 这好象有点像SetWindowsHookEx这个函数的的实现过程。
以上就是我想法了,如果在什么地方有错误还请纠正。

参考资料:
《WINDOWS 程序设计》
《WINDOWS 核心编程》

[培训] 优秀毕业生寄语:恭喜id咸鱼炒白菜拿到远超3W月薪的offer,《安卓高级研修班》火热招生!!!

收藏
点赞0
打赏
分享
最新回复 (8)
雪    币: 113
活跃值: 活跃值 (11)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
WAKU 活跃值 7 2006-3-9 17:25
2
0
能把附件上传吗?这样方便学习
雪    币: 1613
活跃值: 活跃值 (33)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
北极星2003 活跃值 25 2006-3-9 18:14
3
0
这些转贴都是 不错的东东!!!
现在论坛里面已经有不少关于HOOK的帖子了,不过有些散乱
如果有谁能把这些收集、整理下做成CHM,那就好了
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ffff 活跃值 2006-3-10 12:05
4
0
好文章,好好学习
雪    币: 206
活跃值: 活跃值 (27)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
云重 活跃值 1 2006-3-11 18:03
5
0
整天转这些没营养的东西,建议干脆转MSDN吧,什么都有
雪    币: 158
活跃值: 活跃值 (131)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
Lenus 活跃值 3 2006-3-19 16:18
6
0
“我的想法就是注入所有进程就可以实现了。”所有的进程都能注入吗?
雪    币: 454
活跃值: 活跃值 (16)
能力值: ( LV12,RANK:660 )
在线值:
发帖
回帖
粉丝
prince 活跃值 16 2006-3-24 09:48
7
0
说实话这种HOOK方法不值得推荐...
雪    币: 203
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
beast 活跃值 2006-3-25 15:35
8
0
mark   good
雪    币: 234
活跃值: 活跃值 (12)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
ah007 活跃值 2 2006-3-25 20:32
9
0
最初由 Lenus 发布
“我的想法就是注入所有进程就可以实现了。”所有的进程都能注入吗?


游客
登录 | 注册 方可回帖
返回