能力值:
( LV4,RANK:50 )
2 楼
楼主的意思大概是,LoadLibrary会调用 ZwMapViewOfSection,于是在这个函数的结尾处插入一个断点,SEH中捕获断点的时候,作些处理。
好像你的那个代码有点问题。应该是
WaitForSingleObject( hThread ,INFINITE),
而不是
WaitForSingleObject( hevent2 ,INFINITE),
吧。你没有地方设置hevent2。
你说断点位置比较特殊,不知道特殊在哪,还有,你的线程好像也没做什么事,为什么要创建呢?
能力值:
( LV15,RANK:440 )
3 楼
这里我故意没有设置hevent2,目的是让发生异常的线程停在那里。然后设置其它线程等待的事件,让其它线程进行处理。可是,那个myThread没有进行调度,不知为何。
能力值:
( LV15,RANK:440 )
4 楼
为什么没人帮忙呢?自己再顶一次吧。
能力值:
( LV2,RANK:10 )
5 楼
也许你的hEvent的值在代码执行过程中被改变了也不一定了,你可以调试看看。
MSDN上对WaitForSignleObject的描述
Remarks
The WaitForSingleObject function checks the current state of the specified object. If the object's state is nonsignaled, the calling thread enters the wait state. It uses no processor time while waiting for the object state to become signaled or the time-out interval to elapse.
The function modifies the state of some types of synchronization objects. Modification occurs only for the object whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one.
能力值:
( LV15,RANK:440 )
6 楼
我感觉不是这个原因,上边msdn的这个描述我是看过的。hevent是事件内核对象句柄,调试过程显示它的值并没有发生变化。只要异常处理一结束。那个线程就可以结束等待状态,这个事实说明我们设置的确实是hevent事件。
能力值:
( LV4,RANK:50 )
7 楼
给你改了改:
1, 选择ZwMapViewOfSection不合适, LdrLoadDll开始就有SEH, 你的__except block得不到执行,被内部的
SEH filter给吃掉了。
2, 处理int3的重新执行要调节EIP。
#include "stdafx.h"
#include<stdio.h>
#include <conio.h>
#include<windows.h>
#include<tchar.h>
HANDLE hevent,hevent2;
HMODULE DllHandle;
PUCHAR Address;
DWORD myThread( PVOID context )
{
WaitForSingleObjectEx(hevent,INFINITE,TRUE);
printf("myThread is signaled! \n");
printf("singal main thread to run ... \n");
SetEvent(hevent2);
return 0;
} LONG WINAPI ExceptionFilter(
__in struct _EXCEPTION_POINTERS* ExceptionInfo
)
{
//
// don't care about other exception conditions.
//
printf("Enter ExceptionFilter \n");
if (*Address == (UCHAR)0x8b) {
return EXCEPTION_CONTINUE_SEARCH;
}
if (*Address != (UCHAR)0xcc) {
return EXCEPTION_CONTINUE_SEARCH;
}
//
// recover old opcode
//
*Address = 0x8b,
//
// adjust EIP to old value to re-execute
//
ExceptionInfo->ContextRecord->Eip = (DWORD)(Address - 1);
SetEvent(hevent);
WaitForSingleObject(hevent2, INFINITE);
printf("Exit ExceptionFilter \n");
return EXCEPTION_CONTINUE_EXECUTION;
} int main(int argc, TCHAR *argv)
{
HANDLE hThread;
ULONG OldProtect;
hevent = CreateEvent( NULL,FALSE,FALSE,NULL );
hevent2 = CreateEvent( NULL,FALSE,FALSE,NULL );
hThread = CreateThread( NULL,0,(LPTHREAD_START_ROUTINE)myThread,0,0,NULL);
DllHandle = LoadLibrary(_T("kernel32.dll"));
Address = (PUCHAR)GetProcAddress(DllHandle, "LoadLibraryW");
printf("LoadLibrary address: 0x%08x \n", Address);
VirtualProtect(Address, 1, PAGE_EXECUTE_READWRITE, &OldProtect);
*(PUCHAR)Address = (UCHAR)0xcc;
putch(getch());
printf("\n");
__try{
DllHandle = LoadLibrary(_T("mshtml.dll"));
printf("LoadLibrary is called : 0x%08x \n", DllHandle);
}
__except(ExceptionFilter(GetExceptionInformation())) {
}
getch();
return 0;
}
能力值:
( LV15,RANK:440 )
8 楼
看了看你的分析,不过还是有些问题。
1,一般而言,更低层的异常处理器如果不能处理异常,其会返回EXCEPTION_CONTINUE_SEARCH,使高层的异常处理器得到处理机会,我的那个问题就是这样的。我在我的异常处理器中放了个Beep函数,结果有声音产生。说明我们得到了异常处理控制,而不是你所说的被吃掉了。
2,系统在一轮分发异常给调试器 时,对于陷阱类异常,结构中的ExceptionAddress和对应线程上下文中eip的值是不同的,eip = ExceptionAddress + 1.不过,系统在将异常控制传给我们的异常处理代码之前把这个调整了,eip = ExceptionAddress。我们无需自己将eip值减1.(当时我也郁闷这个问题,看有人写调试循环,明明自己设了cc,eip确不调整,直接continue execution了)
不过还是谢谢你的热心人帮助。麻烦了。还得继续寻找原因……
能力值:
( LV15,RANK:440 )
9 楼
求高人指教!!!!