能力值:
( LV2,RANK:10 )
2 楼
觉得异常没发生?难不成你是用感觉来判断的?
能力值:
( LV2,RANK:10 )
3 楼
我顶!
老大们告诉我异常在哪里发生啊~
能力值:
( LV2,RANK:10 )
4 楼
[dwAddress]也就是后来的edx这个地址被写入了0xcc(int3)
所以这里就发生了异常
能力值:
( LV2,RANK:10 )
5 楼
楼上的意思是说当执行到红色语句的时候
.else ; re-install hook
mov cl, byte ptr [edx] ; byte ptr [edx] = API 原入口地址
mov byte ptr [edx], 0CCh ; 断点异常(INT 3 指令)
mov [bOldByte], cl ; 储存 API 的原入口地址
invoke lstrcat, addr szMsgAbout, addr szMyText ; 改变原对话框的输出文字:
发生异常,因此没有去执行下一条语句 mov [bOldByte], cl 而跳到Error_Handler proc咯?
能力值:
( LV2,RANK:10 )
6 楼
看雪的老大们去哪了?我的 问题写得这么详细都没有人来么?
看雪不要让我失望啊~不然会损失老客户的~
能力值:
( LV9,RANK:490 )
7 楼
并不是在那里出现了异常。
此程序是在 API(MessageBoxIndirectA)的入口放入int3(CC)使程序在调用MessageBoxIndirectA时产生单步异常,从而使程序进入我们设计的SEH里来达到HOOK的目的
个人意见,仅供参考。
能力值:
( LV2,RANK:10 )
8 楼
请问LS,被放入int3的是[dwAddress],但是程序调用的是 invoke MessageBoxIndirect,而不是call dwAddress,那程序如何产生单步异常?
能力值:
( LV9,RANK:490 )
9 楼
invoke GetProcAddress, eax, addr szProcMsgBoxInd mov [dwAddress], eax dwAddress 存放的就是 MessageBoxIndirect 的地址
能力值:
( LV2,RANK:10 )
10 楼
楼主你应该去掌握的处理器的中断技术,了解什么是中断,发生中断时处理器会干什么就明白了。
能力值:
( LV2,RANK:10 )
11 楼
(1)有谁可以告诉我这个程序在选定hook message 是程序的流程是什么吗?
(2)SetHook proc uses ecx
mov eax, [dwAddress]
mov cl, [eax]
mov byte ptr [eax], 0CCh ; 断点异常(INT 3 指令)
mov [bOldByte], cl
jmp [dwRetAddr] ; 跳回经过 Hook 之后的 API 的返回地址(很重要!)
SetHook endp
有人能给我解释一下这段代码的功能吗?
(3)我认为是程序是这样的,首先把MessageBoxIndirectA的代码入口改为INT3,当程序调用MessageBoxIndirectA时发生异常,跳到Error_Handler proc 。
在Error_Handler proc 中,我是这样理解下面代码的。
mov eax, [lpContext] 获得各寄存器的值 mov eax, [eax][CONTEXT.regEsp] 将SP的值赋给EAX,其SP指向Error_Handler proc的返回地址,既代码 .elseif eax == IDC_CHECKBUTTON_HOOK的地址 mov ecx, [eax] SP有赋给ECX mov [eax], offset SetHook 将栈顶的返回地址改为SetHook的地址,当执行到ret时跳到SetHook去执行 mov [dwRetAddr], ecx .elseif eax == IDC_CHECKBUTTON_HOOK的地址保存在dwRetAddr中
所以我的理解的流程是这样的-》执行到MessageBoxIndirectA发生中断-》Error_Handler proc-》SetHook
我的思路到此终止,到了SetHook就不知道它是怎么执行的了
(4)ASM程序不像VC那样可以在源代码中下断点,所以不知道如何调试。有一篇说如何在VC中调试ASM,但是编译时提示 STYLE DS_SETFONT 未定义,不知为何。我包含StdAfx.h文件后不再提示STYLE DS_SETFONT 未定义,但提示unresolved external symbol _mainCRTStartup
能力值:
( LV9,RANK:490 )
12 楼
(1)
; 把内存保护设置成 可读/可写/可执行:
invoke VirtualProtect, [dwAddress], 1, PAGE_EXECUTE_READWRITE, addr dwOldProtect
invoke IsDlgButtonChecked, hWnd, IDC_CHECKBUTTON_HOOK
mov edx, [dwAddress]
test eax, eax
.if zero? ; uninstall hook
mov cl, [bOldByte] ; bOldByte = API 原入口地址
mov byte ptr [edx], cl ; 恢复 API 的原入口地址
invoke lstrcpy, addr szMsgAbout, addr szText ; 恢复原对话框的输出文字:
.else ; re-install hook
mov cl, byte ptr [edx] ; byte ptr [edx] = API 原入口地址
mov byte ptr [edx], 0CCh ; 断点异常(INT 3 指令)
mov [bOldByte], cl ; 储存 API 的原入口地址
invoke lstrcat, addr szMsgAbout, addr szMyText ; 改变原对话框的输出文字:
.endif
上面就是程序的流程
改变API入口地址处的保护属性
IDC_CHECKBUTTON_HOOK Checked?
if not Checked 恢复API入口地址并将显示字符串恢复为存原始字符串
if Checked 将入口首字节改为 CC 并显示字符串改为加入szMyText后的字符串。
(2)&&(3)
这两个问题要放在一起理解:
mov eax, [lpContext]
mov eax, [eax][CONTEXT.regEsp]
mov ecx, [eax]
mov [eax], offset SetHook
mov [dwRetAddr], ecx
上面这段代码在做什么呢?我想你能理解,只是你没有放在汇编码的状态下去理解。这段代码其实是在改变异常发生时ESP的值,这个ESP里放的是什么呢?你已经知道了,就是CALL API时push进的返回地址,上面这段代码把这个地址改写成了 SetHook函数的地址,并对原返回地址进行了保存。这样做起到什么作用呢?
我们此时看下程序流程,假设程序代码如下:
AAA
CALL API
BBB
我们在Call入API时第一条指令发生了异常(此时堆栈顶为BBB处地址),程序进入异常处理程序。异常处理程序中改变了异常发生时的栈顶内容,即把栈顶的BBB处地址改写成了SetHook的地址,然后把CC改写成了原代码。异常处理完毕后,程序继续到异常发生处执行。当API调用完毕准备返回的时候,因为我们改写了返回地址,所以程序将进入SetHook中执行,我们看SetHook的代码:
mov eax, [dwAddress]
mov cl, [eax]
mov byte ptr [eax], 0CCh ; 断点异常(INT 3 指令)
mov [bOldByte], cl
jmp [dwRetAddr] ; 跳回经过 Hook 之后的 API 的返回地址(很重要!)
上面很好理解,程序将API入口第一字节再次改为CC,并将程序引导到BBB处。至此,程序在被我们改变了流程之后又进入了原来的轨道。
好了,现在我们可以站在全局的高度理解下程序流程(我只列出关键部分):
1 初始化时,获取API的地址和第一字节代码进行保存。
2 运行后通过判断CheckButton是还先中来设定CC或清除CC
3 如果已设定CC,点OK CALL API时则进入SEH Handler
3.1 改变返回地址,恢复原代码
3.2 API 执行完后,进入SetHook再次恢复CC,并将程序引入原轨道。
。。。。。。。
为什么要改变返回地址,最后还又引回原地址,当然是为了设置CC,为了程序完美,你可以试想一下不这样做的结果。
(4)
调试ASM程序用OD,我感觉还是不错的
不知道我说明白了没有,仅供参考吧
能力值:
( LV2,RANK:10 )
13 楼
谢谢LS大哥的指点,但是还有那么一点小问题
mov [mbp.lpszIcon], IDI_LC
invoke MessageBoxIndirect, addr mbp
.elseif eax == IDC_CHECKBUTTON_HOOK
这3条语句相当与
AAA
CALL API
BBB 首先执行CALL API进入异常后,会执行
invoke MessageBox, [mbp.hwndOwner], addr szMsgHooked, addr szCaption,\
MB_OK or MB_ICONINFORMATION
弹出一个提示对话框,异常处理完毕后进入SetHook中,SetHook没有弹出任何东西就跳到
.elseif eax == IDC_CHECKBUTTON_HOOK
去执行了,那么我想问第二个弹出的对话框(既带有“哈哈“字样的对话框)是在哪条语句中执行的?
能力值:
( LV9,RANK:490 )
14 楼
异常处理完毕后程序又从异常发生处恢复执行了,即继续invoke DialogBoxParam, hInstance, offset szDlgName, 0, WndProc, 0去了,第二个对话框是他.
SetHook不是在异常处理中执行的
能力值:
( LV2,RANK:10 )
15 楼
第二个弹出的对话框(既带有“哈哈“字样的对话框)是MessageBoxIndirect执行的
能力值:
( LV2,RANK:10 )
16 楼
不对吧?在以前的帖子里你不是说异常处理完了就到sethook中吗?怎么会跑到invoke DialogBoxParam, hInstance, offset szDlgName, 0, WndProc, 0那里呢?
能力值:
( LV2,RANK:10 )
17 楼
我忙了一个下午,终于弄懂了,谢谢ptent大哥!