当初的激情以随着无限的重复劳动而消失,留下的只有无尽的失落.
微点算是最强的国产杀毒软件了,有着很多先进且产品级的技术.最强大的莫过于MP的判断逻辑,Hook大家都会,但是怎么判断却是无法复制的..
所以,有时间的时候总是想学习一下.现在要离职了,也终于有时间慢慢的搞些自己想要去做的东西了.
前段时间学习文件系统的时候,大致的看了MP的文件过滤,网络过滤驱动.
今天看见大米同学的微点IDB
驱动的HOOK基本上已经放出来了
闲着没事,所以就看看R3上面有什么好东西没有,学习之后再结合自己分析病毒的经验看看能不能做个山寨的"MP"....
Just For Fun.
今天只看了MP Hook的CreateProcessA, 其原来代码如下:
push 0 ; int
push dword ptr [ebp+2Ch] ; int
push dword ptr [ebp+28h] ; Src
push dword ptr [ebp+24h] ; int
push dword ptr [ebp+20h] ; int
push dword ptr [ebp+1Ch] ; int
..
call CreateProcessInternalA
调试时栈里比较重要的信息:
0012F8E8 700016AB /CALL 到 CreateProcessA 来自 700016A5
0012F8EC 00000000 |ModuleFileName = NULL
0012F8F0 0012F988 |CommandLine = "C:\WINDOWS\system32\mset.exe"
Hook之后的CreateProcessA:
7C80236C 6A 00 push 0
7C80236E FF75 2C push dword ptr [ebp+2C]
7C802371 FF75 28 push dword ptr [ebp+28]
7C802374 EB 01 jmp short 7C802377
7C802376 E8 E8499519 call 96156D63
7C80237B 0090 FF7518FF add byte ptr [eax+FF1875FF], dl
7C802381 75 14 jnz short 7C802397
整理一下:
7C80236C 6A 00 push 0
7C80236E FF75 2C push dword ptr [ebp+2C]
7C802371 FF75 28 push dword ptr [ebp+28]
7C802374 EB 01 jmp short 7C802377
7C802376 90 nop //本来是个EB 花指令?
7C802377 E8 49951900 call ntdll.7C99B8C5 //应该是ntdll中的空隙 ntdll.7C920000 大小=0007B000 区段=.text
7C80237C 90 nop
7C80237D FF75 18 push dword ptr [ebp+18]
跳板,保存REG和esp(模拟windows的方法):
7C99B8C5 FF3424 push dword ptr [esp] //堆栈的主要信息: 0012F8D4 7C80237C 返回到 kernel32.7C80237C
7C99B8C8 9C pushfd
7C99B8C9 50 push eax
7C99B8CA 68 10000000 push 10
7C99B8CF E8 2CFFFFFF call 7C99B800 //代码在下边
7C99B8D4 58 pop eax
7C99B8D5 9D popfd //对应上面的pushfd
7C99B8D6 67:64:8F06 F00F pop dword ptr fs:[FF0] //这个TEB没有啊 返回到 kernel32.CreateProcessA+15
就是7C80237C 90 nop(MP inline的call之后)
7C99B8DC 67:64:8F06 F00F pop dword ptr fs:[FF0]
7C99B8E2 FF75 24 push dword ptr [ebp+24] //CreateProcessA未完成的参数入栈,之后回到CreateProcessInternalA
7C99B8E5 FF75 20 push dword ptr [ebp+20]
7C99B8E8 FF75 1C push dword ptr [ebp+1C]
7C99B8EB 90 nop
7C99B8EC 90 nop
7C99B8ED 90 nop
7C99B8EE 90 nop
7C99B8EF 90 nop
7C99B8F0 90 nop
7C99B8F1 90 nop
7C99B8F2 90 nop
7C99B8F3 90 nop
7C99B8F4 90 nop
7C99B8F5 67:64:FF36 F00F push dword ptr fs:[FF0]
7C99B8FB C3 retn
这个是处理函数,处理后打开MP110013驱动来进行通信
7C99B800 EB 0D jmp short 7C99B80F
7C99B802 FF3424 push dword ptr [esp]
7C99B805 64:8F05 F00F000>pop dword ptr fs:[FF0]
7C99B80C C2 0400 retn 4
7C99B80F 51 push ecx
7C99B810 53 push ebx
7C99B811 52 push edx
7C99B812 57 push edi
7C99B813 81EC 00100000 sub esp, 1000 //很大的局部空间啊
7C99B819 E8 00000000 call 7C99B81E //重定位
7C99B81E 58 pop eax //很节约REG,因为eax不用保存啊...
7C99B81F 8BF8 mov edi, eax
7C99B821 B8 3A210015 mov eax, 1500213A //应该是编译器生成的,编程的时候一个事个变量什么的
7C99B826 2D C0200015 sub eax, 150020C0
7C99B82B 03F8 add edi, eax //eax=7A //以前在壳的源码里好像见过,壳用这样的方式来获取自己存在内存中的一些信息.
(汇编里关键的一个技巧),不知道哪位大牛给解释下吧
7C99B82D 57 push edi //这样就得到了 7C99B898 ASCII "C:\Program Files\Micropoint\mp110031.dll"
7C99B82E B8 A1B6807C mov eax, kernel32.GetModuleHandleA
7C99B833 FFD0 call eax
7C99B835 8BD8 mov ebx, eax
7C99B837 83F8 00 cmp eax, 0
7C99B83A 75 0F jnz short 7C99B84B
7C99B83C 57 push edi
7C99B83D B8 771D807C mov eax, kernel32.LoadLibraryA //加载mp110031.dll .加载之后的行为在mp110031.idb中分析DllMain中
7C99B842 FFD0 call eax
7C99B844 8BD8 mov ebx, eax
7C99B846 83F8 00 cmp eax, 0
7C99B849 74 35 je short 7C99B880
7C99B84B 81C3 D0130000 add ebx, 13D0 //mp110031.dll加载地址加上13D0 即mp110031_03函数的地址
7C99B851 B9 00100000 mov ecx, 1000
7C99B856 8B440C 28 mov eax, dword ptr [esp+ecx+28] //还记得开始分配的局部空间大小是1000h
这个是取以前的参数了(有兴趣的可以往上推,看是哪个参数)
7C99B85A 2BC4 sub eax, esp
7C99B85C 83E8 18 sub eax, 18
7C99B85F 50 push eax //eax=0000105C
7C99B860 B9 00100000 mov ecx, 1000
7C99B865 8B440C 14 mov eax, dword ptr [esp+ecx+14] //堆栈 ss:[0012F8C0]=7C8842E4 (kernel32.7C8842E4) eax=0000105C
7C99B869 83E8 13 sub eax, 13
7C99B86C FF30 push dword ptr [eax] //ds:[7C8842D1]=31010001
7C99B86E B9 00100000 mov ecx, 1000
7C99B873 8D440C 30 lea eax, dword ptr [esp+ecx+30]
7C99B877 0340 EC add eax, dword ptr [eax-14] //堆栈 ds:[0012F8C4]=00000010 eax=0012F8D8
7C99B87A 50 push eax //eax=0012F8E8
7C99B87B FFD3 call ebx // call mp110031_03 继续IDA
7C99B87D 83C4 0C add esp, 0C
7C99B880 64:8B0D 1800000>mov ecx, dword ptr fs:[18] //fs:[18]指向TEB
7C99B887 8B49 34 mov ecx, dword ptr [ecx+34] //TEB.LastErrorValue
7C99B88A B9 00100000 mov ecx, 1000 //释放局部空间
7C99B88F 03E1 add esp, ecx
7C99B891 5F pop edi
7C99B892 5A pop edx
7C99B893 5B pop ebx
7C99B894 59 pop ecx
7C99B895 C2 0400 retn 4
总结:
MP在R3的hook一个不只这一个,可能主要的一些函数都被Hook,而且在mp110031_03中会有分支,通过判断Shell_NotifyIcon,Outlook.Application InternetExplorer.Application,MAPILogon
这些应该是程序窗口的类名,来发生相应的IoCode,做相应的记录,以区别不同种类的程序,走不同的批判逻辑!
mp110031.dll在被加载起来的时候,会检查一下当前进程,不是MP的就创建一个线程.并等待MPUNHOOK(有超时设置),调用ZwQueryInformationThread的ThreadAmILastThread判断是否为最后一个线程,如果是且没有什么情况就FreeLibraryAndExitThread.
微点的一些全局同步Event : MpApiNotify ,MpApiEvent 可以按照这些支线来慢慢的理清判断逻辑
今天就先学习到这里,有时间看看驱动.看看那些IoCode到底是干什么的..
有几个不明白的地方,哪位大牛给解释一下?
mov eax, ecx ; ecx==31010001 这个是传进来的一个参数
and eax, 0F0000h ; eax=00010000, (UNICODE "ALLUSERSPROFILE=C:\Documents and Settings\All Users")
cmp eax, 20000h ; 不知道eax=10000 代表的意义? ALLUSERSPROFILE是什么?为什么下面还有F0000,50000
如上,eax=00010000,OD显示ALLUSERSPROFILE,0x10000地址里面是环境变量,那么F0000,50000,60000..代表什么呢?
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)