网站 维护方案,如何做天猫网站,三亚网站建设方案,WordPress阿柳云API HOOK 顾名思义是挂钩API函数#xff0c;拦截#xff0c;控制某些API函数的调用#xff0c;用于改变API执行结果的技术。 大致流程#xff1a;
进入进程-获取相关权限-将我们写的dll写入进程内存-加载kernel32中的LoadLibrary()以调用我们写的dll。 http:/…API HOOK 顾名思义是挂钩API函数拦截控制某些API函数的调用用于改变API执行结果的技术。 大致流程
进入进程-获取相关权限-将我们写的dll写入进程内存-加载kernel32中的LoadLibrary()以调用我们写的dll。 http://blog.csdn.net/junbopengpeng/article/details/28142669一文中有更加详细的讲解以下代码源自http://blog.chinaunix.net/uid-660282-id-2414901.html对其做了修正同时添加了详细注释实现劫持源程序的MessageBox函数改变其标题和内容欢迎质询一起学习。 源程序我们劫持的程序 #include#includeint main(){
printf(hello world!\n);
while(1){
getchar();
MessageBoxA(NULL, 原函数, yuan, 0);
}
return 0;
} 我们编写的dll #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函数原型
// MessageBox函数原型int WINAPI MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
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(fdwReasonDLL_PROCESS_ATTACH)
//进程映射
//每个进程的第一次映射用DLL_PROCESS_ATTACH调用DLL的DllMain函数。
_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);
//定位Dos头NT头可选头
pImportDescriptor (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod pOptHeader-DataDirectory[1].VirtualAddress);
//导入表ID
while(pImportDescriptor-FirstThunk){
//IAT的RVA
char * dllname (char *)((BYTE *)hMod pImportDescriptor-Name);
//被导入的DLL 名称
pThunkData (PIMAGE_THUNK_DATA)((BYTE *)hMod pImportDescriptor-OriginalFirstThunk);
//IMAGE_THUNK_DATA的RVA
int no 1;
while(pThunkData-u1.Function){
//被输入的函数的内存地址
char * funname (char *)((BYTE *)hMod (DWORD)pThunkData-u1.AddressOfData 2);
//AddressOfData指向IMAGE_IMPORT_BY_NAME导入函数名称
//hMod2后到导入的DLL(user32.dll)函数导出表中获取导入函数的地址
PDWORD lpAddr (DWORD *)((BYTE *)hMod (DWORD)pImportDescriptor-FirstThunk) (no-1);
//为了下方VirtualQuery穷举每一块内存信息no
//修改内存的部分---------------------------------
if((*lpAddr) (int)addr){
//修改内存页的属性
DWORD dwOLD;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(lpAddr,mbi,sizeof(mbi));
//获取内存信息
VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,dwOLD);
//在呼叫处理程序的虚拟位址空间里变更认可页面区域上的保护
//请求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, HOOK成功,success,0);
//这个地方可以写出对这个API函数的处理代码
}
此处想补充一下dll文件的生成方式在vc中新建工程Win32 Dynamic-Link Library再在该工程中新建文件C Source File代码完成后compile-build即可我们写的dll存放于该工程目录下的Debug文件夹中。 开始HOOK #include windows.h
#include tlhelp32.h
#include#pragma comment(lib,th32.lib)
const char *pkilldll3.dll;//DLL文件的路径
//这个路径很有意思这个路径是相对于目标进程的而不是自身进程。
//所以要嘛写成绝对路径要嘛写成相对于目标进程的相对路径。
//如果写成相对于自身的路径就要麻烦了本程序就找不到DLL文件了。
char *prosessyuan.exe;//要注入的进程名(目标进程名)
int main(){
HANDLE hSnap;//获取进程信息
HANDLE hkernel32;//被注入进程的句柄
PROCESSENTRY32 pe;//存放进程信息和调用成员输出进程信息的结构体
BOOL bNext;//是否还有下一个进程
HANDLE hToken;
TOKEN_PRIVILEGES tp;//包括LUID和特权的属性的结构体
LUID Luid;//locally unique identifier保证局部唯一
LPVOID p;
FARPROC pfn;
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,hToken)){
//打开与进程相关联的访问令牌
return 1;
}
if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,Luid)){
//查看系统权限的特权值SE_DEBUG_NAME存在Luid中
return 1;
}
tp.PrivilegeCount 1;
//指定特权数组的个数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);
//结构体大小
hSnapCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
//通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照
bNextProcess32First(hSnap, pe);
//获得第一个进程的句柄
while(bNext) {
if(!stricmp(pe.szExeFile,prosess)){
//该进程的可执行文件名称是否是我们需要的 process
hkernel32OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION,1,pe.th32ProcessID);
//如果两者一样打开该进程
break;
}
bNextProcess32Next(hSnap, pe);
//不一样则寻找下一个
}
CloseHandle(hSnap);
pVirtualAllocEx(hkernel32,NULL,strlen(pkill),MEM_COMMIT,PAGE_READWRITE);
//在指定进程的虚拟空间保留或提交内存区域
WriteProcessMemory(hkernel32,p,pkill,strlen(pkill),NULL);
//将我们的dll写入该进程内存
pfnGetProcAddress(GetModuleHandle(kernel32.dll),LoadLibraryA);
//获取 kernel32.dll中的 LoadLibraryA用以加载我们的dll
CreateRemoteThread(hkernel32,NULL,0,(LPTHREAD_START_ROUTINE)pfn,p,NULL,0);
//pfn在CreateRemoteThread类型为LPTHREAD_START_ROUTINE
return 0;
}
效果截图 需要注意的是在hook过程中原函数不要关闭噢否则就没有该进程了。