VMPROTECT處理異常4–seh4(2)

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:

EH4的結構

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

其結構如下:

所以關鍵是找到ScopeTable,這裡有一篇翻譯:http://www.cnblogs.com/awpatp/archive/2010/06/15/1758763.html

EH4反彙編手工解析

步驟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, "x64x89x25x00x00x00x00", 7) == 0  || dwLen == 7 && memcmp(pDecode, "x64x89x0Dx00x00x00x00", 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, "x64x89x25", 3) == 0              || memcmp(pbyTemp1, "x64xA3", 2) == 0)          {              //64:8925 00000000          mov     dword ptr fs:[0], esp

步驟2 

最大搜索控制在一個段內,從函數起始,到步驟1之間的彙編,判斷是否依次有以下關鍵彙編:

1."x6AxFE",指令長為2

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

2."x68x00x00x00x00",指令長為5,後四位元組隨意,比如:按EH4結構,這裡可能會push ScopeTable

push    offset stru_416A68

3."x68x00x00x00x00",指令長為5,後四位元組隨意,比如:按EH4結構,這裡可能會push ExceptionHandler

push    offset SEH_4113B0

步驟3

如果存在步驟2這三條依次指令,就做下一步判斷:

同樣是搜索從函數起始從函數起始,到步驟1之間的彙編,是否依次有以下關鍵彙編:

1."x64xA1x00x00x00x00",6位元組,這個是必須的,因為EH4是放在fs:[0]處

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

2."x50",1位元組,壓入eax,即上表的prev_structure,把前一個壓棧

50              push    eax

3."x64xA3x00x00x00x00",6位元組,把新構建的EH4壓回到fs:[0]

mov     large fs:0, eax