'转'test和cmp一个很菜很基础的话题! @ pediy.com

本文详细解释了在计算机体系结构中test和cmp指令的工作原理及其使用场景。test指令执行逻辑与运算并根据结果设置标志寄存器,常用于位检测和寄存器清零测试;cmp指令执行算术减法,仅修改标志位而不保存结果,主要用于比较两个值。通过具体实例展示了这两种指令如何影响程序流程。

看过破解教程,都知道test,cmp是比较关键,可是我一直不清楚它们究竟是怎么比较的,最后下决心找了很多资料,和大家一起把它们弄清楚.

首先看看:状态寄存器(即标志寄存器)

PSW(Program Flag)程序状态字(即标志)寄存器,是一个16位寄存器,由条件码标志(flag)和控制标志构成,
如下所示:

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
        OF DF IF TF SF ZF   AF   PF   CF

条件码:
①OF(Overflow Flag)溢出标志,溢出时为1,否则置0.标明一个溢出了的计算,如:结构和目标不匹配.
②SF(Sign Flag)符号标志,结果为负时置1,否则置0.
③ZF(Zero Flag)零标志,运算结果为0时置1,否则置0.
④CF(Carry Flag)进位标志,进位时置1,否则置0.注意:Carry标志中存放计算后最右的位.
⑤AF(Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。
有进位时1,否则置0.
⑥PF(Parity Flag)奇偶标志.结果操作数中1的个数为偶数时置1,否则置0.

控制标志位:
⑦DF(Direction Flag)方向标志,在串处理指令中控制信息的方向。
⑧IF(Interrupt Flag)中断标志。
⑨TF(Trap Flag)陷井标志。


为举例方便说一下jnz和jz
测试条件
JZ ZF=1
JNZ ZF=0
即Jz=jump if zero (结果为0则设置ZF零标志为1,跳转)
Jnz=jump if not zero

好,接着来看test和cmp

*******************************************************************************
test属于逻辑运算指令

功能: 执行BIT与BIT之间的逻辑运算
测试(两操作数作与运算,仅修改标志位,不回送结果).
Test对两个参数(目标,源)执行AND逻辑操作,并根据结果设置标志寄存器,结果本身不会保存。EST AX,BX 与 AND AX,BX 命令有相同效果

语法: TEST r/m,r/m/data
影响标志: C,O,P,Z,S(其中C与O两个标志会被设为0)

运用举例:
1.Test用来测试一个位,例如寄存器:

test eax, 100b; b后缀意为二进制
jnz ******; 如果eax右数第三个位为1,jnz将会跳转

我是这样想的,jnz跳转的条件是ZF=0,ZF=0意味着ZF(零标志)没被置位,即逻辑与结果为1.

2.Test的一个非常普遍的用法是用来测试一方寄存器是否为空:

test ecx, ecx
jz somewhere

如果ecx为零,设置ZF零标志为1,Jz跳转

*******************************************************************************
CMP属于算术运算指令

功能: 比较两个值(寄存器,内存,直接数值)
语法: CMP r/m,r/m/data
标志位: C,P,A,Z,O

CMP比较.(两操作数作减法,仅修改标志位,不回送结果).
cmp实际上是只设置标志不保存结构的减法,并设置Z-flag(零标志).
零标志很像carry,也是内部标志寄存器的一位.

例如:
Cmp eax, 2; 如果eax-2=0即eax=2就设置零标志为1
Jz ****; 如果设置了零标志就跳转


*******************************************************************************
我得出的结论
test逻辑与运算结果为零,就把ZF(零标志)置1;
cmp 算术减法运算结果为零,就把ZF(零标志)置1.

结论很简单嘛,之前我怎么就分不清呢,真是笨哪!

/*----------------------------------------------------------------------- 第13章 Hook技术 《加密与解密(第四版)》 (c) 看雪学院 www.kanxue.com 2000-2018 -----------------------------------------------------------------------*/ // VEHHook.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> BOOL SetBreakPoint(PVOID pFuncAddr); BOOL ClearBreakPoint(PVOID pFuncAddr); BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler); VOID UnInstallVEHHook(); typedef int (WINAPI *PFN_MessageBox)( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); LONG WINAPI VectoredHandler1(struct _EXCEPTION_POINTERS *ExceptionInfo); LONG WINAPI VectoredHandler2(struct _EXCEPTION_POINTERS *ExceptionInfo); LONG WINAPI VectoredHandler3(struct _EXCEPTION_POINTERS *ExceptionInfo); VOID ShowMsgBox(LPCTSTR lpMsg); ULONG_PTR InitTrampolineFun(); PFN_MessageBox g_OriginalMessageBoxA; PVOID g_AddrofMessageBoxA = 0 ; PVOID g_hVector; BYTE g_OldCode[16]={0}; int main(int argc, char* argv[]) { HMODULE hUser32 = LoadLibrary("user32.dll"); g_AddrofMessageBoxA = (PVOID)GetProcAddress(hUser32,"MessageBoxA"); printf("Address of MessageBoxA = 0x%p\n",g_AddrofMessageBoxA); g_OriginalMessageBoxA = (PFN_MessageBox)InitTrampolineFun(); //跳过开头的Hook printf("Addr of VectoredHandler1 = 0x%p\n",VectoredHandler1); printf("Addr of VectoredHandler2 = 0x%p\n",VectoredHandler2); printf("Addr of VectoredHandler3 = 0x%p\n",VectoredHandler3); //选择安装一个进行测试 InstallVEHHook(VectoredHandler1); //设置断点 SetBreakPoint(g_AddrofMessageBoxA); //call ShowMsgBox("VEH Hook Test."); printf("All Finished!\n"); ClearBreakPoint(g_AddrofMessageBoxA); UnInstallVEHHook(); ShowMsgBox("Hook Cleared"); return 0; } VOID ShowMsgBox(LPCTSTR lpMsg) { MessageBoxA(NULL,lpMsg,"Test",MB_OK); } ULONG_PTR InitTrampolineFun() { ULONG_PTR uResult = 0 ; PBYTE pFun = NULL; #ifdef _WIN64 //x64需要申请shellcode /* USER32!MessageBoxA: 00000000`779412b8 4883ec38 sub rsp,38h 00000000`779412bc 4533db xor r11d,r11d 00000000`779412bf 44391d760e0200 cmp dword ptr [USER32!gapfnScSendMessage+0x927c (00000000`7796213c)],r11d */ pFun = (PBYTE)VirtualAlloc(NULL,128,MEM_COMMIT,PAGE_EXECUTE_READWRITE); uResult = (ULONG_PTR)pFun; memset(pFun,0,128); memcpy(pFun,(PVOID)g_AddrofMessageBoxA,4); //拷贝第一条指令,4字节,推荐使用反汇编引擎来实际计算 pFun += 4 ; //下一条指令构造为jmp [xxxxxx] pFun[0] = 0xFF; pFun[1] = 0x25; *(ULONG_PTR*)(pFun + 6) = (ULONG_PTR)g_AddrofMessageBoxA + 4 ; //跳回到原函数加4的地方 #else //x86,第一条指令是mov edi,edi,直接跳过即可 uResult = (ULONG_PTR)g_AddrofMessageBoxA + 2; #endif return uResult; } //处理方式,修改参数并返回原函数继续执行 LONG WINAPI VectoredHandler1( struct _EXCEPTION_POINTERS *ExceptionInfo ) { char *szNewMsg = "[VectoredHandler1] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH ; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0 ; pExceptionRecord = ExceptionInfo->ExceptionRecord ; pContextRecord = ExceptionInfo->ContextRecord ; ULONG_PTR* uESP = 0 ; printf("Exception Address = %p\n",pExceptionRecord->ExceptionAddress); if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 //修改第二个参数,即LpMsg printf("lpText = 0x%p %s\n",pContextRecord->Rdx,(char*)pContextRecord->Rdx); pContextRecord->Rdx = (ULONG_PTR)szNewMsg; pContextRecord->Rip = (ULONG_PTR)g_OriginalMessageBoxA ; //跳到Trampoline继续执行 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n",pContextRecord->Esp) ; uESP = (ULONG_PTR*)pContextRecord->Esp ; //取中断时的ESP uESP[2] = (ULONG_PTR)szNewMsg; //修改栈中的参数 pContextRecord->Eip = (ULONG_PTR)g_OriginalMessageBoxA ; //跳过函数开头 #endif lResult = EXCEPTION_CONTINUE_EXECUTION ; } return lResult; } //处理方式:直接调用原函数并替原函数返回 LONG WINAPI VectoredHandler2( struct _EXCEPTION_POINTERS *ExceptionInfo ) { char *szNewMsg = "[VectoredHandler2] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH ; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0 ; pExceptionRecord = ExceptionInfo->ExceptionRecord ; pContextRecord = ExceptionInfo->ContextRecord ; ULONG_PTR* uESP = 0 ; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 printf("RSP = 0x%p\n",pContextRecord->Rsp) ; uESP = (ULONG_PTR*)pContextRecord->Rsp ; printf("Return Address = 0x%p\n",uESP[0]); ret = g_OriginalMessageBoxA((HWND)pContextRecord->Rcx,szNewMsg,(LPCTSTR)pContextRecord->R8,(int)pContextRecord->R9); printf("ret = %d\n",ret); //修正RSP pContextRecord->Rsp += sizeof(ULONG_PTR);//参数在寄存器中,栈中无参数,仅需跳过返回地址 //直接返回到调用者处 pContextRecord->Rip = uESP[0] ;//设置EIP为返回地址 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n",pContextRecord->Esp) ; uESP = (ULONG_PTR*)pContextRecord->Esp ; ret = g_OriginalMessageBoxA((HWND)uESP[1],szNewMsg,(LPCTSTR)uESP[3],(int)uESP[4]); printf("ret = %d\n",ret); //直接返回到调用者处 pContextRecord->Eip = uESP[0] ;//设置EIP为返回地址 pContextRecord->Esp += (4 + 1)*sizeof(ULONG_PTR); //4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION ; } return lResult; } //处理方式:直接返回,相当于过滤掉 LONG WINAPI VectoredHandler3( struct _EXCEPTION_POINTERS *ExceptionInfo ) { LONG lResult = EXCEPTION_CONTINUE_SEARCH ; PEXCEPTION_RECORD pExceptionRecord = ExceptionInfo->ExceptionRecord ; PCONTEXT pContextRecord = ExceptionInfo->ContextRecord ; ULONG_PTR* uESP = 0 ; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ //直接返回到调用者处 #ifdef _WIN64 printf("RSP = 0x%p\n",pContextRecord->Rsp) ; uESP = (ULONG_PTR*)pContextRecord->Rsp ; pContextRecord->Rip = uESP[0] ;//设置EIP为返回地址 pContextRecord->Rsp += sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #else printf("ESP = 0x%X\n",pContextRecord->Esp) ; uESP = (ULONG_PTR*)pContextRecord->Esp ; pContextRecord->Eip = uESP[0] ;//设置EIP为返回地址 pContextRecord->Esp += (4 + 1)*sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION ; } return lResult; } BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler) { printf("Current Handler Address = 0x%p\n",Handler); g_hVector = AddVectoredExceptionHandler(1,Handler); return g_hVector != NULL ; } VOID UnInstallVEHHook() { RemoveVectoredExceptionHandler(g_hVector); } /* 0:000> u user32!messageboxA USER32!MessageBoxA: 77d507ea 8bff mov edi,edi 77d507ec 55 push ebp 77d507ed 8bec mov ebp,esp */ BOOL SetBreakPoint(PVOID pFuncAddr) { DWORD dwCnt = 0 ; BYTE *pTarget = (BYTE*)pFuncAddr; g_OldCode[0] = *pTarget; printf("Original Fun Head Code = 0x%02X\n",g_OldCode[0]); //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget,&mbi,sizeof(mbi)); VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dwOLD); //写入int3 *pTarget = 0xCC ; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress,mbi.RegionSize,dwOLD,0); return TRUE; } BOOL ClearBreakPoint(PVOID pFuncAddr) { BYTE *pTarget = (BYTE*)pFuncAddr; //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget,&mbi,sizeof(mbi)); VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dwOLD); *pTarget = g_OldCode[0] ; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress,mbi.RegionSize,dwOLD,0); return TRUE; } int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ) { char newMsg[400]; char newCation[]="标题被我改了!"; int result; if (lpText) { ZeroMemory(newMsg,400); lstrcpy(newMsg,lpText); lstrcat(newMsg,"\n\tMessage Box hacked by pediy.com"); } printf("有人调用MessageBox...\n"); result = g_OriginalMessageBoxA(hWnd,newMsg,newCation,uType); return result; }分析是什么代码?有什么作用?如何执行
07-25
#include <stdio.h> // 添加printf支持 #include <windows.h> BOOL SetBreakPoint(PVOID pFuncAddr); BOOL ClearBreakPoint(PVOID pFuncAddr); BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler); VOID UnInstallVEHHook(); typedef int (WINAPI* PFN_MessageBox)( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ); LONG WINAPI VectoredHandler1(struct _EXCEPTION_POINTERS* ExceptionInfo); LONG WINAPI VectoredHandler2(struct _EXCEPTION_POINTERS* ExceptionInfo); LONG WINAPI VectoredHandler3(struct _EXCEPTION_POINTERS* ExceptionInfo); VOID ShowMsgBox(LPCTSTR lpMsg); ULONG_PTR InitTrampolineFun(); PFN_MessageBox g_OriginalMessageBoxA; PVOID g_AddrofMessageBoxA = 0; PVOID g_hVector; BYTE g_OldCode[16] = { 0 }; int main(int argc, char* argv[]) { HMODULE hUser32 = LoadLibrary("user32.dll"); g_AddrofMessageBoxA = (PVOID)GetProcAddress(hUser32, "MessageBoxA"); printf("Address of MessageBoxA = 0x%p\n", g_AddrofMessageBoxA); g_OriginalMessageBoxA = (PFN_MessageBox)InitTrampolineFun(); //跳过开头的Hook printf("Addr of VectoredHandler1 = 0x%p\n", VectoredHandler1); printf("Addr of VectoredHandler2 = 0x%p\n", VectoredHandler2); printf("Addr of VectoredHandler3 = 0x%p\n", VectoredHandler3); //选择安装一个进行测试 InstallVEHHook(VectoredHandler1); //设置断点 SetBreakPoint(g_AddrofMessageBoxA); //call ShowMsgBox("VEH Hook Test."); printf("All Finished!\n"); ClearBreakPoint(g_AddrofMessageBoxA); UnInstallVEHHook(); ShowMsgBox("Hook Cleared"); return 0; } VOID ShowMsgBox(LPCTSTR lpMsg) { MessageBoxA(NULL, lpMsg, "Test", MB_OK); } ULONG_PTR InitTrampolineFun() { ULONG_PTR uResult = 0; PBYTE pFun = NULL; #ifdef _WIN64 //x64需要申请shellcode /* USER32!MessageBoxA: 00000000`779412b8 4883ec38 sub rsp,38h 00000000`779412bc 4533db xor r11d,r11d 00000000`779412bf 44391d760e0200 cmp dword ptr [USER32!gapfnScSendMessage+0x927c (00000000`7796213c)],r11d */ pFun = (PBYTE)VirtualAlloc(NULL, 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE); uResult = (ULONG_PTR)pFun; memset(pFun, 0, 128); memcpy(pFun, (PVOID)g_AddrofMessageBoxA, 4); //拷贝第一条指令,4字节,推荐使用反汇编引擎来实际计算 pFun += 4; //下一条指令构造为jmp [xxxxxx] pFun[0] = 0xFF; pFun[1] = 0x25; *(ULONG_PTR*)(pFun + 6) = (ULONG_PTR)g_AddrofMessageBoxA + 4; //跳回到原函数加4的地方 #else //x86,第一条指令是mov edi,edi,直接跳过即可 uResult = (ULONG_PTR)g_AddrofMessageBoxA + 2; #endif return uResult; } //处理方式,修改参数并返回原函数继续执行 LONG WINAPI VectoredHandler1( struct _EXCEPTION_POINTERS* ExceptionInfo ) { const char* szNewMsg = "[VectoredHandler1] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0; pExceptionRecord = ExceptionInfo->ExceptionRecord; pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; printf("Exception Address = %p\n", pExceptionRecord->ExceptionAddress); if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 //修改第二个参数,即LpMsg printf("lpText = 0x%p %s\n", pContextRecord->Rdx, (char*)pContextRecord->Rdx); pContextRecord->Rdx = (ULONG_PTR)szNewMsg; pContextRecord->Rip = (ULONG_PTR)g_OriginalMessageBoxA; //跳到Trampoline继续执行 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; //取中断时的ESP uESP[2] = (ULONG_PTR)szNewMsg; //修改栈中的参数 pContextRecord->Eip = (ULONG_PTR)g_OriginalMessageBoxA; //跳过函数开头 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } //处理方式:直接调用原函数并替原函数返回 LONG WINAPI VectoredHandler2( struct _EXCEPTION_POINTERS* ExceptionInfo ) { const char* szNewMsg = "[VectoredHandler2] Hacked by pediy.com"; LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord; PCONTEXT pContextRecord; int ret = 0; pExceptionRecord = ExceptionInfo->ExceptionRecord; pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { #ifdef _WIN64 //x64上前四个参数依次为RCX,RDX,R8,R9 printf("RSP = 0x%p\n", pContextRecord->Rsp); uESP = (ULONG_PTR*)pContextRecord->Rsp; printf("Return Address = 0x%p\n", uESP[0]); ret = g_OriginalMessageBoxA((HWND)pContextRecord->Rcx, szNewMsg, (LPCTSTR)pContextRecord->R8, (int)pContextRecord->R9); printf("ret = %d\n", ret); //修正RSP pContextRecord->Rsp += sizeof(ULONG_PTR);//参数在寄存器中,栈中无参数,仅需跳过返回地址 //直接返回到调用者处 pContextRecord->Rip = uESP[0];//设置EIP为返回地址 #else /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ printf("ESP = 0x%p\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; ret = g_OriginalMessageBoxA((HWND)uESP[1], szNewMsg, (LPCTSTR)uESP[3], (int)uESP[4]); printf("ret = %d\n", ret); //直接返回到调用者处 pContextRecord->Eip = uESP[0];//设置EIP为返回地址 pContextRecord->Esp += (4 + 1) * sizeof(ULONG_PTR); //4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } //处理方式:直接返回,相当于过滤掉 LONG WINAPI VectoredHandler3( struct _EXCEPTION_POINTERS* ExceptionInfo ) { LONG lResult = EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD pExceptionRecord = ExceptionInfo->ExceptionRecord; PCONTEXT pContextRecord = ExceptionInfo->ContextRecord; ULONG_PTR* uESP = 0; if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT && pExceptionRecord->ExceptionAddress == g_AddrofMessageBoxA) { /* 0012FF70 0040105A /CALL 到 MessageBoxA 来自 VEHHook.00401054 0012FF74 00000000 |hOwner = NULL 0012FF78 00407030 |Text = "VEH Hook" 0012FF7C 0040703C |Title = "Test" 0012FF80 00000000 \Style = MB_OK|MB_APPLMODAL 0012FF84 00401225 返回到 VEHHook.<ModuleEntryPoint>+0B4 来自 VEHHook.00401000 */ //直接返回到调用者处 #ifdef _WIN64 printf("RSP = 0x%p\n", pContextRecord->Rsp); uESP = (ULONG_PTR*)pContextRecord->Rsp; pContextRecord->Rip = uESP[0];//设置EIP为返回地址 pContextRecord->Rsp += sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #else printf("ESP = 0x%X\n", pContextRecord->Esp); uESP = (ULONG_PTR*)pContextRecord->Esp; pContextRecord->Eip = uESP[0];//设置EIP为返回地址 pContextRecord->Esp += (4 + 1) * sizeof(ULONG_PTR); //将压入栈内的参数返回地址清理掉,4为参数个数,1为返回地址 #endif lResult = EXCEPTION_CONTINUE_EXECUTION; } return lResult; } BOOL InstallVEHHook(PVECTORED_EXCEPTION_HANDLER Handler) { printf("Current Handler Address = 0x%p\n", Handler); g_hVector = AddVectoredExceptionHandler(1, Handler); return g_hVector != NULL; } VOID UnInstallVEHHook() { RemoveVectoredExceptionHandler(g_hVector); } /* 0:000> u user32!messageboxA USER32!MessageBoxA: 77d507ea 8bff mov edi,edi 77d507ec 55 push ebp 77d507ed 8bec mov ebp,esp */ BOOL SetBreakPoint(PVOID pFuncAddr) { DWORD dwCnt = 0; BYTE* pTarget = (BYTE*)pFuncAddr; g_OldCode[0] = *pTarget; printf("Original Fun Head Code = 0x%02X\n", g_OldCode[0]); //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget, &mbi, sizeof(mbi)); VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwOLD); //写入int3 *pTarget = 0xCC; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress, mbi.RegionSize, dwOLD, 0); return TRUE; } BOOL ClearBreakPoint(PVOID pFuncAddr) { BYTE* pTarget = (BYTE*)pFuncAddr; //修改内存页的属性 DWORD dwOLD; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pTarget, &mbi, sizeof(mbi)); VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwOLD); *pTarget = g_OldCode[0]; //恢复内存页的属性 VirtualProtect(mbi.BaseAddress, mbi.RegionSize, dwOLD, 0); return TRUE; } int WINAPI My_MessageBox( HWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT uType // style of message box ) { char newMsg[400]; char newCation[] = "标题被我改了!"; int result; if (lpText) { ZeroMemory(newMsg, 400); lstrcpy(newMsg, lpText); lstrcat(newMsg, "\n\tMessage Box hacked by pediy.com"); } printf("有人调用MessageBox...\n"); result = g_OriginalMessageBoxA(hWnd, newMsg, newCation, uType); return result; }系统版本是win10 10240
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值