钩取API之代码修改方法【一】
IAT方式就不去花精力了,加了壳的程序用这方法压根用不上。
就熟悉一下代码修改方法。书上用的是隐藏进程的实例
第一种办法
一,枚举进程,给所有进程加载DLL【用远程线程注入】
二,传入需要隐藏的进程名
三,判断有没有修改过需要钩取的函数,如果还没有修改过就改掉,跳向自己的函数,同时保存好原来的值
四,在自己的替代函数里将原来的值修改回去,并再执行一次,执行完做相关处理
五,在自己的替代函数最后再钩取函数,修改跳转到替代函数
基本逻辑就是这样,像是移花接木啊。。。
DLL代码:
#define STATUS_SUCCESS (0x00000000L)
typedef LONG NTSTATUS;
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
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;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
BYTE Reserved1[48];
PVOID Reserved2[3];
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;
//+0x3c 进程名
//+0x44 进程ID
typedef NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION)
(SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength);
#define DEF_NTDLL ("ntdll.dll")
#define DEF_ZWQUERYSYSTEMINFORMATION ("ZwQuerySystemInformation")
// global variable (in sharing memory)
#pragma comment(linker, "/SECTION:.SHARE,RWS")
#pragma data_seg(".SHARE")
TCHAR g_szProcName[MAX_PATH] = {L""};
#pragma data_seg()
// 全局变量,用于存放钩取函数的前五个字节
BYTE g_pOrgBytes[5] = {0,};
BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
{
FARPROC pfnOrg;
DWORD dwOldProtect, dwAddress;
BYTE pBuf[5] = {0xE9, 0, };
PBYTE pByte;
// 这儿取钩取函数
pfnOrg = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
pByte = (PBYTE)pfnOrg;
// 判断勾取函数是否已经修改
if( pByte[0] == 0xE9 )
return FALSE;
// 修改保护属性
VirtualProtect((LPVOID)pfnOrg, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// 保存原函数的前5个字节
memcpy(pOrgBytes, pfnOrg, 5);
// 计算跳转地址的差值
// => XXXX = pfnNew - pfnOrg - 5
dwAddress = (DWORD)pfnNew - (DWORD)pfnOrg - 5;
memcpy(&pBuf[1], &dwAddress, 4);
// 将跳转代码复制到原函数
memcpy(pfnOrg, pBuf, 5);
// 把页面保护属性修改回来
VirtualProtect((LPVOID)pfnOrg, 5, dwOldProtect, &dwOldProtect);
return TRUE;
}
//恢复
BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
{
FARPROC pFunc;
DWORD dwOldProtect;
PBYTE pByte;
//
pFunc = GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
pByte = (PBYTE)pFunc;
//
if( pByte[0] != 0xE9 )
return FALSE;
VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// Unhook
memcpy(pFunc, pOrgBytes, 5);
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/69581.html
- 上一篇:c#比较两个List相等
- 下一篇:DSAPI之摄像头追踪指定颜色物体