首页 > VMP > VMP-异常处理SEH4的Handle和Filter反汇编查找
2016四月18

VMP-异常处理SEH4的Handle和Filter反汇编查找

[隐藏]

1.EH4的IDA解析

http://www.hexblog.com/?p=106

http://www.hexblog.com/?p=19

示例1:

void SEHTest()
{
	DWORD dwTemp = 100;
	__try //0层
	{
		__try  //1层
		{
			__try //2层
			{ 
			}
			__except(2) //filter里的值是随便写的 
			{
				dwTemp = 20;
			}
		}
		__except(1)
		{
			dwTemp = 10;
		}
	} 
	__except(0)
	{
		dwTemp = 0;
	}
}

IDA可以解析了它的所有filter和hander:

1.png

  

2.EH4的结构

EH4的完整解析可以参看http://www.mouseos.com/windows/SEH8.html

其结构如下:

1.png

所以关键是找到ScopeTable,这里有一篇翻译:http://www.cnblogs.com/awpatp/archive/2010/06/15/1758763.html

  

3.EH4反汇编手工解析

3.1.步骤1 

我们来看看关键点:

exception handler链表的头是存储在FS:[0]当中的. 所以, 如果你步入debugger的汇编语言语句的话, 你会看到如下的指令:

MOV DWORD PTR FS:[00000000],ESP

或者

 MOV DWORD PTR FS:[00000000],ECX

你可以确定, 这就是在配置和拆除一个_try/_except 块了.

以上面的示例1为参考,我们可以写这样的代码来判断这个函数是否存在EH4:

 if (dwLen == 7 && memcmp(pDecode, "\x64\x89\x25\x00\x00\x00\x00", 7) == 0
|| dwLen == 7 && memcmp(pDecode, "\x64\x89\x0D\x00\x00\x00\x00", 7) == 0)//EH4 增加ecx判断
{
                //64:8925 00000000          mov     dword ptr fs:[0], esp
		//64:890D 00000000	    mov     dword ptr fs:[0], ecx

或者:

if (memcmp(pbyTemp1, "\x64\x89\x25", 3) == 0
            || memcmp(pbyTemp1, "\x64\xA3", 2) == 0)
        {
            //64:8925 00000000          mov     dword ptr fs:[0], esp

3.2.步骤2 

最大搜索控制在一个段内,从函数起始,到步骤1之间的汇编,判断是否依次有以下关键汇编:

1."\x6A\xFE",指令长为2

00230000 6afe            push    0FFFFFFFEh // tryleavel的初始值,一般在push ebp后就会使用

2."\x68\x00\x00\x00\x00",指令长为5,后四字节随意,比如:按EH4结构,这里可能会push ScopeTable

push    offset stru_416A68

3."\x68\x00\x00\x00\x00",指令长为5,后四字节随意,比如:按EH4结构,这里可能会push ExceptionHandler

push    offset SEH_4113B0

  

3.3.步骤3

如果存在步骤2这三条依次指令,就做下一步判断:

同样是搜索从函数起始从函数起始,到步骤1之间的汇编,是否依次有以下关键汇编:

1."\x64\xA1\x00\x00\x00\x00",6字节,这个是必须的,因为EH4是放在fs:[0]处

 64a100000000    mov     eax,dword ptr fs:[00000000h]

2."\x50",1字节,压入eax,即上表的prev_structure,把前一个压栈

50              push    eax

3."\x64\xA3\x00\x00\x00\x00",6字节,把新构建的EH4压回到fs:[0]

mov     large fs:0, eax

  

3.4.步骤4

在前面两步之后,我们猜它就是except_handler4,怎么确认呢?

1.试着从步骤2的第3步偏移取得后四字节,它可能是ExceptionHandler,即__except_handler4

1.1.它的前两字节是不是FF25(jmp),如果是,就判断它的跳转是不是_except_handler4,这个可以通过PE的导入表来查找

1.2.它的前1字节是不是E9或EB,如果是,就判断它的跳转是不是__except_handler4,这个可以通过MAP来确认

1.3.如果都不是跳转,那就判断它的字节序列是不是__except_handler4

 

2.如果第一步证明了它就是__except_handler4,那么从步骤2的第2步偏移我们可以取得ScopeTable

因为我们的目标是要得到Handle和Filter,所以,跳过前面16个字节,到达EnclosingLevel

然后循环遍历,直到找到的VA不在代码内或为0

           for(int i=0; ; i++)
            {
                DWORD dwFilterVa = pScopeTable[i].lpfnFilter;
                DWORD dwHandlerVa = pScopeTable[i].lpfnHandler;
                DWORD dwNewItemCount = 0;

                if(dwFilterVa != 0 && m_pPEFile->IsInCode(dwFilterVa))
                {
                    stExceptionInfo.vecBreakIn.push_back(dwFilterVa);
                    dwNewItemCount++;
                }

                if(dwHandlerVa != 0 && m_pPEFile->IsInCode(dwHandlerVa))
                {
                    stExceptionInfo.vecBreakIn.push_back(dwHandlerVa);
                    dwNewItemCount++;
                }

                //这里不能用pScopeTable[i].preTryLevel == -2来判断
                if(dwNewItemCount == 0)
                {
                    break;
                }
            }

自测最终结果如下:

1.png

可以看到,结果和IDA解析一样

文章作者:hgy413
本文地址:https://hgy413.com/3269.html
版权所有 © 转载时必须以链接形式注明作者和原始出处!

本文目前尚无任何评论.

发表评论