@author: dlive

IAT Hook时如果要钩取的API不在IAT中(LoadLibrary后调用),则无法使用该技术。而Inline Hook不存在这个限制。

0x01 Inline Hook原理

原理比较简单,将API代码的前5个字节修改为JMP xxxxxx 指令来钩取API。调用执行被钩取的API时,JMP XXXXXX指令被执行,转而跳转至Hook函数。

0x02 相关API

用户模式下检测进程的相关API通常分为如下两类:

  1. CreateToolhelp32Snapshot() 和 EnumProcess()

    这两个API均在其内部调用了ntdll.ZwQuerySystemInformation

  2. ZwQuerySystemInformation()

    该API可获得运行中的所有进程信息(结构体),形成一个链表,操作该链表从链表中删除相关进程即可达到隐藏的目的。

0x03 隐藏进程时可能遇到的问题

  1. 要钩取进程的个数。要想把某个进程隐藏起来,需要钩取系统中运行的所有进程
  2. 需要对新启动的进程也做同样的钩取操作

以上就是全局钩取的概念

注意:鉴于系统安全性考虑,系统进程禁止进行注入操作

0x04 代码分析

1. HideProc.cpp

InjectAllProcess

向所有进程注入/卸载DLL

BOOL InjectAllProcess(int nMode, LPCTSTR szDllPath)
{DWORD                   dwPID = 0;HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;PROCESSENTRY32          pe;// Get the snapshot of the systempe.dwSize = sizeof( PROCESSENTRY32 );hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );// find processProcess32First(hSnapShot, &pe);do{dwPID = pe.th32ProcessID;//鉴于系统安全性考虑,对于PID小于100的系统进程,不执行DLL诸如操作if( dwPID < 100 )continue;if( nMode == INJECTION_MODE )InjectDll(dwPID, szDllPath);elseEjectDll(dwPID, szDllPath);}while( Process32Next(hSnapShot, &pe) );CloseHandle(hSnapShot);return TRUE;
}

2. stealth.cpp

实际API的钩取由stealth.dll负责

2.1 SetProcName

// global variable (in sharing memory)
#pragma comment(linker, "/SECTION:.SHARE,RWS")
#pragma data_seg(".SHARE")TCHAR g_szProcName[MAX_PATH] = {0,};
#pragma data_seg()

#pragma data_seg(".SHARE")一般用于DLL中,在DLL中定义一个共享的,有名字的节区。最关键的是:这个节区中的全局变量可以被多个进程共享。 这里将建立的节区命名为.SHARE。您可以将这段命名为任何一个您喜欢的名字。在这里的#pragma叙述之后的所有初始化了的变量都放在.SHARE节区中。

#pragma data_seg()叙述标示段的结束。对变量进行专门的初始化是很重要的,否则编译器将把它们放在普通的未初始化数据段(.bss)中而不是放在shared中。

连结器必须知道有一个「shared」共享节区: #pragma comment(linker,"/SECTION:shared,RWS") 字母RWS表示节区具有读、写和共享属性。

// ------------------------------   我是一个题外话  --------------------------------------
//说个题外话,通过共享节区变量可以做到防多开(腾讯游戏安全竞赛的时候曾经用过这个方法)
//DLL加载时count++, 卸载时count--
//demo代码如下,只是demo
#pragma data_seg("flag_data")
int count=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:flag_data,RWS") if(count>1)
{
MessageBox("已经启动了一个应用程序","Warning",MB_OK);
return FLASE;
}
count++;
// ------------------------------   我是一个题外话  --------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void SetProcName(LPCTSTR szProcName)
{//将steach.dll字符串存放在内存共享节区_tcscpy_s(g_szProcName, szProcName);
}
#ifdef __cplusplus
}
#endif

2.2 DllMain

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{char            szCurProc[MAX_PATH] = {0,};char            *p = NULL;// #1. 判断进程名称,不向HideProc.exe注入dllGetModuleFileNameA(NULL, szCurProc, MAX_PATH);p = strrchr(szCurProc, '\\');if( (p != NULL) && !_stricmp(p+1, "HideProc.exe") )return TRUE;switch( fdwReason ){// #2. API Hookingcase DLL_PROCESS_ATTACH : hook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, (PROC)NewZwQuerySystemInformation, g_pOrgBytes);break;// #3. API Unhooking case DLL_PROCESS_DETACH :unhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, g_pOrgBytes);break;}return TRUE;
}

2.3 hook_by_code

BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
{FARPROC pfnOrg;DWORD dwOldProtect, dwAddress;BYTE pBuf[5] = {0xE9, 0, };PBYTE pByte;// 获取要钩取的API地址pfnOrg = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pfnOrg;// 若已经被钩取,则返回Falseif( pByte[0] == 0xE9 )return FALSE;// 修改内存属性VirtualProtect((LPVOID)pfnOrg, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);// 备份原有的5字节memcpy(pOrgBytes, pfnOrg, 5);// JMP  (E9 XXXX)// => XXXX = pfnNew - pfnOrg - 5dwAddress = (DWORD)pfnNew - (DWORD)pfnOrg - 5;memcpy(&pBuf[1], &dwAddress, 4);// Hook - 5 byte (JMP XXXX)memcpy(pfnOrg, pBuf, 5);// 恢复内存属性VirtualProtect((LPVOID)pfnOrg, 5, dwOldProtect, &dwOldProtect);return TRUE;
}

JMP目的地址的计算,xxxxxxxx为相对地址

长跳转
E9 xxxxxxxx
xxxxxxxx = 要跳转的绝对地址 - 当前指令绝对地址 - 当前指令长度(5)

还有另外的一些跳转指令

短跳转 short jmp
EB xx (指令长度为两字节, xx为相对地址)跳转到绝对地址
push xxxxxxxx; ret
68 xxxxxxxx c3跳转到绝对地址
move eax, xxxxxxxx
jmp eax
B8 xxxxxxxx
FFE0

2.4 unhook_by_code

BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
{FARPROC pFunc;DWORD dwOldProtect;PBYTE pByte;// 获取API地址pFunc = GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;// 判断API 代码是否被修改过if( pByte[0] != 0xE9 )return FALSE;// 将API开始5Byte内存属性修改为RWXVirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);// Unhook,将原始的5Byte数据修改回来memcpy(pFunc, pOrgBytes, 5);// 恢复内存属性VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);return TRUE;
}

2.5 NewZwQuerySystemInformation

Zw开头的函数和Nt开头的函数的区别:

在RING3下,应用程序调用NT或者ZW效果是一样的, 在dll中执行的是同一段代码。
在RING0下,调用NT函数跟ZW函数就不一样了,ZW开头的函数是通过eax中系统服务号去SSDT中查找相应的系统服务,然后调用之。
若在驱动中直接调用NT开头的函数是不会经过SSDT的 也不会被SSDT HOOK拦截的。
即:在R0下通过调用NT系列函数可以绕过SSDT HOOK 。微软推荐使用Zw开头的函数

ZwQuerySystemInformation微软官方手册(对各个字段解释不完整)

https://msdn.microsoft.com/en-us/library/windows/desktop/ms725506(v=vs.85).aspx

#define STATUS_SUCCESS                      (0x00000000L) typedef LONG NTSTATUS;//将SYSTEM_INFORMATION_CLASS设置为SystemProcessInformation(5)后调用ZwQuerySystemInformation API
typedef enum _SYSTEM_INFORMATION_CLASS {SystemBasicInformation = 0,SystemPerformanceInformation = 2,SystemTimeOfDayInformation = 3,SystemProcessInformation = 5,SystemProcessorPerformanceInformation = 8,SystemInterruptInformation = 23,SystemExceptionInformation = 33,SystemRegistryQuotaInformation = 37,SystemLookasideInformation = 45
} SYSTEM_INFORMATION_CLASS;//API获得的信息为SYSTEM_PROCESS_INFORMATION结构体组成的单向链表的起始地址,该结构体重存储着运行中所有进程的信息
typedef struct _SYSTEM_PROCESS_INFORMATION {ULONG NextEntryOffset;      //链表中下一个结构体相对于当前结构体的偏移量ULONG NumberOfThreads;      //线程数目;BYTE Reserved1[48];PVOID Reserved2[3];         //Reserved2[1]为进程名称,进程名称为Unicode字符串HANDLE UniqueProcessId;PVOID Reserved3;ULONG HandleCount;BYTE Reserved4[4];PVOID Reserved5[11];SIZE_T PeakPagefileUsage;SIZE_T PrivatePageCount;LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;  typedef NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, //参数单向链表的起始地址ULONG SystemInformationLength, PULONG ReturnLength);#define DEF_NTDLL                       ("ntdll.dll")
#define DEF_ZWQUERYSYSTEMINFORMATION    ("ZwQuerySystemInformation")
//NTSTATUS 是被定义为32位的无符号长整型。在驱动程序开发中,人们习惯用 NTSTATUS 返回状态。
NTSTATUS WINAPI NewZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength)
{NTSTATUS status;FARPROC pFunc;PSYSTEM_PROCESS_INFORMATION pCur, pPrev;char szProcName[MAX_PATH] = {0,};// 首先脱钩unhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, g_pOrgBytes);// 调用原始APIpFunc = GetProcAddress(GetModuleHandleA(DEF_NTDLL), DEF_ZWQUERYSYSTEMINFORMATION);status = ((PFZWQUERYSYSTEMINFORMATION)pFunc)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);if( status != STATUS_SUCCESS )goto __NTQUERYSYSTEMINFORMATION_END;// 判断调用API时是否为要钩取的调用方式(SystemProcessInformation(5))if( SystemInformationClass == SystemProcessInformation ){// pCur 存储单链表的首地址pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;while(TRUE){// 比较进程名称// g_szProcName为要隐藏的进程if(pCur->Reserved2[1] != NULL){if(!_tcsicmp((PWSTR)pCur->Reserved2[1], g_szProcName)){// 删除链表节点if(pCur->NextEntryOffset == 0)pPrev->NextEntryOffset = 0;elsepPrev->NextEntryOffset += pCur->NextEntryOffset;}else        pPrev = pCur;}//遍历结束if(pCur->NextEntryOffset == 0)break;// 相当于p=p->nextpCur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pCur + pCur->NextEntryOffset);}}__NTQUERYSYSTEMINFORMATION_END:// 重新Hook APIhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, (PROC)NewZwQuerySystemInformation, g_pOrgBytes);return status;
}

0x05 全局API钩取

全局API钩取技术针对的进程:

  1. 当前运行的所有进程
  2. 将来要运行的所有进程

前面的示例程序并不是全局API钩取的例子,因为它并不满足全局API钩取定义中的第二个条件

1.相关API

//Kernel32.CreateProcess
BOOL WINAPI CreateProcess(_In_opt_    LPCTSTR               lpApplicationName,_Inout_opt_ LPTSTR                lpCommandLine,_In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,_In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,_In_        BOOL                  bInheritHandles,_In_        DWORD                 dwCreationFlags,_In_opt_    LPVOID                lpEnvironment,_In_opt_    LPCTSTR               lpCurrentDirectory,_In_        LPSTARTUPINFO         lpStartupInfo,_Out_       LPPROCESS_INFORMATION lpProcessInformation
);

该API用于创建新进程,其他启动运行进程的API(WinExec, ShellExecute, system)在其内部调用的都是该函数

WinExec:

https://msdn.microsoft.com/en-us/library/ms687393(v=vs.85).aspx

可以直接钩取父进程(通常是explorer.exe)的CreateProcess API来监控子进程创建,从而达到钩取子进程的目的。

但是这种方法存在一些问题,且不说需要同时钩取CreateProcessA, CreateProcessW,CreateProcessInternalA, CreateProcessInternalW, 还存在在NewCreateProcess(攻击者自定义的Hook函数)调用CreateProcess创建子进程时,极短时间内,子进程可能在未钩取的状态下运行。

//Ntdll.ZwResumeThread
ZwResumeThread(IN HANDLE ThreadHandle,OUT PULONG SuspendCount OPTIONAL
)

该API也是一个未公开API,它是比CreateProcess更低级的API,它在进程创建后,主线程运行前被调用执行。所以只要钩取这个函数即可在不运行子进程代码的情况下钩取API。

但由于其为未公开API,随着OS的升级,API可能失效。

2.代码分析

stealth2.cpp中增加了对CreateProcessA和CreateProcessW的Hook操作,并对新创建的进程进行dll注入d

有NewCreateProcessA为例:

BOOL WINAPI NewCreateProcessA(LPCTSTR lpApplicationName,LPTSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCTSTR lpCurrentDirectory,LPSTARTUPINFO lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation
)
{BOOL bRet;FARPROC pFunc;// unhookunhook_by_code("kernel32.dll", "CreateProcessA", g_pOrgCPA);pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessA");bRet = ((PFCREATEPROCESSA)pFunc)(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);// 如果新进程创建成果,将stealth.dll注入到新进程中if( bRet )InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME);// hookhook_by_code("kernel32.dll", "CreateProcessA", (PROC)NewCreateProcessA, g_pOrgCPA);return bRet;
}

0x06 利用热补丁技术钩取API

前面demo程序中通过代码修改技术进行API Hook存在的缺点

  1. 频繁脱钩,挂钩会造成整体性能下降
  2. 多线程环境,当一个线程尝试运行某段代码,而另一进程刚好在对该代码进行写操作,这时就会发生冲突,会引起非法访问异常(Access Violation)。《windows核心编程》指出,利用代码修改技术钩取API会对系统安全造成威胁

1.热补丁(修改7Byte代码)

Windows系统库中的函数,如kernel32.CreateProcessA/W, user32.MessageBoxA,gdi32.TextOutW有一个相似点

  1. API以MOV EDI, EDI指令开始(IA-32 0X8bff)
  2. API上方有5个NOP指令(IA-32 0X90)

微软做此设计的目的就是方便打热补丁。

使用热补丁Hook API的过程如下

  1. 修改API开始的两个字节MOV EDI,EDI为SHORT JMP指令EB F9, 跳转的目标地址是address_of_api - 5,即5个NOP指令的第一条
  2. 修改5个NOP指令为长跳转E9 XXXXXXXX,跳转到用户自定义API
  3. 用户自定义代码调用原始API时,直接以API+2的地址为API地址调用原API,这样就不会引起内存非法访问

2.代码分析

2.1 DllMain

和之前代码一样,在Dll附加进程的时候调用hook方法,在dll卸载时调用unhook方法

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{char            szCurProc[MAX_PATH] = {0,};char            *p = NULL;// 判断进程名称,不向HideProc2.exe注入dllGetModuleFileNameA(NULL, szCurProc, MAX_PATH);p = strrchr(szCurProc, '\\');if( (p != NULL) && !_stricmp(p+1, "HideProc2.exe") )return TRUE;// change privilegeSetPrivilege(SE_DEBUG_NAME, TRUE);switch( fdwReason ){case DLL_PROCESS_ATTACH : // hookhook_by_hotpatch("kernel32.dll", "CreateProcessA", (PROC)NewCreateProcessA);hook_by_hotpatch("kernel32.dll", "CreateProcessW", (PROC)NewCreateProcessW);//可以看到这里没有对ZwQuerySystemInformation使用热补丁Hook,具体原因见"3.热补丁Hook的缺点"hook_by_code("ntdll.dll", "ZwQuerySystemInformation", (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI);break;case DLL_PROCESS_DETACH :// unhookunhook_by_hotpatch("kernel32.dll", "CreateProcessA");unhook_by_hotpatch("kernel32.dll", "CreateProcessW");unhook_by_code("ntdll.dll", "ZwQuerySystemInformation", g_pOrgZwQSI);break;}return TRUE;
}

2.2 hook_by_hotpatch

修改API中无用的7字节数据,跳转到用户自定义Hook函数

BOOL hook_by_hotpatch(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew)
{FARPROC pFunc;DWORD dwOldProtect, dwAddress;BYTE pBuf[5] = { 0xE9, 0, };BYTE pBuf2[2] = { 0xEB, 0xF9 };PBYTE pByte;pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] == 0xEB )return FALSE;VirtualProtect((LPVOID)((DWORD)pFunc - 5), 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);// 1. NOP (0x90)dwAddress = (DWORD)pfnNew - (DWORD)pFunc;memcpy(&pBuf[1], &dwAddress, 4);memcpy((LPVOID)((DWORD)pFunc - 5), pBuf, 5);// 2. MOV EDI, EDI (0x8BFF)memcpy(pFunc, pBuf2, 2);VirtualProtect((LPVOID)((DWORD)pFunc - 5), 7, dwOldProtect, &dwOldProtect);return TRUE;
}

2.3 unhook_by_hotpatch

将7字节数据修改为原数据

BOOL unhook_by_hotpatch(LPCSTR szDllName, LPCSTR szFuncName)
{FARPROC pFunc;DWORD dwOldProtect;PBYTE pByte;BYTE pBuf[5] = { 0x90, 0x90, 0x90, 0x90, 0x90 };BYTE pBuf2[2] = { 0x8B, 0xFF };pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);pByte = (PBYTE)pFunc;if( pByte[0] != 0xEB )return FALSE;VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);// 1. NOP (0x90)memcpy((LPVOID)((DWORD)pFunc - 5), pBuf, 5);// 2. MOV EDI, EDI (0x8BFF)memcpy(pFunc, pBuf2, 2);VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);return TRUE;
}

2.4 NewCreateProcess

这里需要注意一点,在使用之前的hook方法进行API钩取时,在用户自定义NewCreateProcess函数开头需要调用unhook方法(防止进入钩取的死循环),函数结尾需要调用hook方法进行重新钩取。

但是使用热补丁Hook时不需要这样反复脱钩,挂钩,只需在调用原始API时,使用address of API + 2的地址调用API即可

BOOL WINAPI NewCreateProcessA(LPCTSTR lpApplicationName,LPTSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTES lpThreadAttributes,BOOL bInheritHandles,DWORD dwCreationFlags,LPVOID lpEnvironment,LPCTSTR lpCurrentDirectory,LPSTARTUPINFO lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation
)
{BOOL bRet;FARPROC pFunc;pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessA");//以API地址+2为函数地址调用CreateProcessA函数pFunc = (FARPROC)((DWORD)pFunc + 2);bRet = ((PFCREATEPROCESSA)pFunc)(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);// 注入steach3.dllif( bRet )InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME);return bRet;
}

3.使用热补丁进行Hook的缺点

热补丁钩取技术有个明显的缺点,即不符合钩取条件(7字节无用代码)的API无法使用热补丁钩取

这样的API有,ntdll.dll提供的API 和kernel32.GetStartInfoA() 等

并非所有API都能使用热补丁钩取,所以使用前需要先确认要钩取的API是否支持,若不支持则需使用前面的5字节代码修改技术

0x07 Ntdll.dll API钩取技巧

Ntdll.dll中提供的API代码都较短,钩取这些API时有一种非常好的方法,使用这种方法时先将原API备份到用户内存区域,然后使用5字节代码修改技术修改原API的起始部分。在用户钩取函数内部调用API时,只需调用备份的API即可,这样实现的API钩取既简单又稳定。由于Ntdll.all API代码较短,且代码内部地址无依赖性,所以它们非常适合用该技术钩取

0x08 一些问题

  1. Dll在内存中只会加载一次,那么在Hook时对Dll进行修改后岂不是会影响所有使用该dll的进程?

    主要是Copy-On-Write机制,a.dll在内存中只有一份拷贝,增加的是dll的引用计数,当dll的引用计数为0时,系统会回收对应内存和删除对应的映射。
    如果有一个程序对dll的内存进行了相应的修改,比如说修改内存加载钩子,那么系统会将对应页面复制一份出来给程序,此时,两个程序指向的dll的对应内存就不同了。

    http://bbs.csdn.net/topics/330026043

  2. 使用HideProc注入时注入失败

    Windows 7/Vista中使用了会话隔离技术,可能导致Dll注入失败。出现这个问题时,不要使用kernel32.CreateRemoteThread而使用ntdll.NtCreateThreadEx就可以了。

    此外,尝试向PE32+格式的进程注入PE32格式的DLL时也会失败(反之亦然)。注入时必须保证注入的DLL文件和目标进程PE格式一致。

转载于:https://www.cnblogs.com/dliv3/p/6398967.html

Inline Hook相关推荐

  1. C语言playsoundw函数,使用inline hook实现修改PC微信通知铃声-哥哥微信来了

    本帖最后由 bester 于 2020-2-15 01:20 编辑 原贴:https://www.52pojie.cn/thread-1103441-1-1.html 最近频繁刷某音刷到哥哥微信来了的 ...

  2. inline hook __usercall 函数

    usercall 调用约定表示这个函数用寄存器传参,hook 它就没那么方便,需要整一个包装函数.原理是很简单的,下面给个例子,一看就懂: 说明一下我这里用的是 tramp hook 技术,或者叫&q ...

  3. WIN32 Inline HOOK

    Inline hook 和CE里面的代码注入很像(应该是一个东西),这个技术的原理是,修改汇编指令,让某个指令跳转到我们定义的函数,然后在函数内完成被替换的指令,然后再跳转回去.在我们定义的函数内,我 ...

  4. inline hook学习

    vs2013编译 //inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转至我们自己设置的一个函数里,产生hook.#include <windows.h> ...

  5. Windows驱动开发学习笔记(六)—— Inline HOOK

    Windows驱动开发学习笔记(六)-- Inline HOOK SSDT HOOK Inline Hook 挂钩 执行流程 脱钩 实验一:3环 Inline Hook 实验二:0环 Inline H ...

  6. Windows内核实验005 Inline Hook

    文章目录 准备工作 寻找Inline Hook的返回地址 编写代码 动态变化的返回地址 JmpTargetAddr Inline Hook基本框架 示例代码 实战HOOK KiTrap01 无需计算偏 ...

  7. Android inline hook手记

    2019独角兽企业重金招聘Python工程师标准>>> 许久没搞安全方面的东西了.最近有些时间看了看android下面的开发,看去看来总是想往内深入,结果又往Native和内核挖过去 ...

  8. Ring3下Inline Hook API

    用CreateFile为例子,讲解一下Ring3下的Inline Hook API,基本原理很简单 1.获取CreateFile函数的地址 2.读取CreateFile函数的前8个字节 3.将Crea ...

  9. SSDT Hook的妙用-对抗ring0 inline hook

    ******************************************************* *标题:[原创]SSDT Hook的妙用-对抗ring0 inline hook  * ...

最新文章

  1. 漫话:如何给女朋友解释什么是熔断?
  2. alipay html5 app,H5App支付宝开发详解
  3. Maven的scope详解
  4. 如何在JavaScript中区分深层副本和浅层副本
  5. 四则运算 结对项目
  6. 信安教程第二版-第19章操作系统安全保护
  7. Oracle报错:IO Error: Invalid number format for port number
  8. How can I force Python's file.write() to use the same newline format in Windows as in Linux (“\r\n”
  9. R 学习笔记《五》 R语言初学者指南--第二章总结
  10. java 删除文件夹和文件_如何创建无法删除的文件夹?
  11. AEAI Miscdp文件上传功能使用心得
  12. 代码检查工具 Sonar 安装使用
  13. 油田生产数据选取进展22.3.12 观察实验
  14. Go语言——cap函数详解
  15. 各种主流浏览器的调试
  16. 第六章 商品详情进阶 + redis分布式锁 + redis问题解决 + redisson + 布隆过滤器
  17. Swoole实现基于WebSocket的群聊私聊
  18. VS2015未定义标识符gets
  19. 亚马逊开店店铺选品技巧分析
  20. 西安理工大学计算机视觉与应用,关于举办计算机视觉与图像处理应用最新进展报告会的通知...

热门文章

  1. Windows7是什么
  2. 使用component小程序
  3. centos 7 安装docker 并设置阿里云镜像仓库
  4. Linux 编程中的API函数和系统调用的关系【转】
  5. APP专项测试方法有哪些?
  6. jpa tutorials
  7. Linux字符界面操作进阶
  8. Android adb opendir failed ,permission denied
  9. 区块链100问1-20问
  10. Jzoj4458 密钥破解——Pollard-rho