_ _ (_) | | __ ____ __ _ _ _ _ __ ___ _ __ _ __ ___ | |_ \ \ / /\ \/ /| || | | || '_ ` _ \ | '_ \ | '_ \ / _ \| __| \ V / > < | || |_| || | | | | || |_) |_ | | | || __/| |_ \_/ /_/\_\| | \__,_||_| |_| |_|| .__/(_)|_| |_| \___| \__| _/ | | | |__/ |_| /---------------------------------------------------------------------------------------\ |>...................[ AV引擎中壳识别技术的改进 ]...................<| |>......................[ by nEINEI/vxjump.net ]......................<| |>......................[ 08-04-10 ]......................<| \>...................... [ neineit@gmail.com ] ...................... TEAM ECLiPSE sign = B8????????B9????????33D2EB010F56EB010FE803??????EB010FEB010F5EEB01 再比如: PEtite 2.x -> Ian Luck sign = B8????????669C6050 Microsoft Visual C++ Private Version 1 sign = 8B44240883????74 Microsoft Visual C++ 7.0 DLL Method 3 sign = 558BEC538B5D08568B750C 当然特征并非局限于EOP处,也可以程序其它地方,但这样的特征质量并不好,比较耗时。 [0x02].现有壳识别结构 typedef vector VBYTE typedef struct tagShellInfo { bool bEOP; // 说明是否是EOP处特征,否则则全文匹配 VBYTE Index; // 偏移位置 VBYTE Value; // 偏移出对应数据 CString strDescip; // 对壳的描述 }ShellInfo,*pShellInfo; 通过这样一组简单的结构定义,就可对壳进行识别了,不考虑效率因素的话,顺序匹配就可以。否则就要 对数据进行进一步处理,以求高效率的识别过程(我是利用hash+b树的方式来检测。也可以利用自动机方式。 因这块不是本文讨论重点故省略)。 [0x03].产生问题 因MEW加壳后的文件或此类经加壳工具产生的文件(EOP处为跳转语句,之后数据随机,这部分随机的数据 已经不能代表壳的特性了),无法提取出适应现有结构的数据,故需要对现有壳识别机制进行调整。 [0x04].壳识别加入新的改进方式 以规则命令的方式告知识别模块。每一步匹配过程有相应的指示 。 1 定义数据 : BYTE cbRule; 2 表示形式: 0000 | 0000 // 当都为零时表示无特殊要求,按现有规则匹配 3 数据说明: 高4位 -- 规则(说明该做何种操作) 低4位 -- 数据(该操作对应的数据) 4 具体规则说明: 对跳转一类语句 call jmp,jne,ja .. 1 0 0 0 | 0 0 1 0 | | 跳转 正 (数据长度) 1 0 0 1 | 0 0 1 0 | | 跳转 负 (数据长度) 方向位为 0 表示跳向高地址空间,为 1 表示跳向低地址空间。 当跳转位置不固定,需要识别程序自己计算跳转位置时,此情况由第6位指出,此时正负位失效。 0 0 1 0 |0 0 0 0 | 手工/自动 | 1 0 1 0 |0 0 1 0 #define JMPD 0x82 #define JMPU 0x92 #define JMPA 0xa2 5 处理流程: ..... switch(cbRule) { case JMPD: ... break; case JMPU: ... break; case JMPA: ... break; default : break; } [0x05].新壳识别结构 typedef struct tagShellInfo { bool bEOP; // 说明是否是EOP处特征,否则则全文匹配 BYTE cbRule; // 规则 VBYTE Index; // 偏移位置 VBYTE Value; // 偏移出对应数据 CString strDescip; // 对壳的描述 }ShellInfo,*pShellInfo; 当通过规则cbRule,识别出来跳转语句后,处理方式则有了很大的处理空间,理论上任何一种 检测方法都可以加入处理流程中来,但那已经不是我们讨论的范围了。 注:本文所提供的思路有一定的通用性,但并非对所有壳都有效,实践中还需具体问题具体分析。 欢迎大家交流指正。