简单分析,小弟能力有限如果有什么错误的话,欢迎各位牛牛指正,共同进步嘛
第一处清零代码
mov edi, edi
push ebp
mov ebp, esp
push ecx
push esi
mov [ebp+var_1], 0
call ds:KeGetCurrentIrql
cmp al, 2 //判断中断级
mov esi, offset SpinLock
mov ecx, esi
jb short loc_1002660
call ds:KefAcquireSpinLockAtDpcLevel
mov [ebp+var_1], 1
jmp short loc_1002669
loc_1002660:
call ds:KfAcquireSpinLock
mov [ebp+NewIrql], al
loc_1002669: mov ecx, dword_100D1C0 //这里比较关键啦。 dword_100D1C0 这个全局变量很重要
mov edx, offset dword_100D1C0
cmp ecx, edx
jz short loc_10026BA// 这个是个关键比较啦
push ebx
push edi
loc_100267A:
mov edi, dword_100CEDC //这里存放着EPROCESS的下标
mov edi, [edi+4] //CEDC+4的位置正是BC
add edi, [ecx-34h] //[D1C0-34]的位置存放着EPROCESS结构的地址
xor eax, eax
xchg eax, [edi] //清零
mov eax, dword_100CEDC
mov ebx, [ecx-2Ch] //存放着EPROCESS+70位置的内容
mov eax, [eax+18h] //CEDC+18位置存放70下标
mov edi, [ecx-34h]//EPROCESS结构的地址
mov [eax+edi], ebx //写回去防止修改位置
mov ebx, [ecx-28h] //74的内容
mov [eax+edi+4], ebx//写回去
mov edi, dword_100CEDC
mov edi, [edi+1Ch] //取78位置
add edi, [ecx-34h]
xor eax, eax //写回去
stosd
stosd
上面这一段把EPROCESS+70,74,78的位置全部封杀了
防止把BC的位置修改为70,74,78,所以曾经某种方法改位置变得无效了
第2段清零位代码,这里有个检测
mov edi, edi
push ebp
mov ebp, esp
push ecx
push ecx
push ebx
xor ebx, ebx
push esi
mov ecx, offset SpinLock
mov byte ptr [ebp-1], 1
mov [ebp-8], ebx
call ds:KfAcquireSpinLock
mov esi, dword_100D1C0 //这里同1的注释 这个变量很重要
cmp esi, offset dword_100D1C0//这里同1的注释一样
mov [ebp-2], al
jz loc_1004FE9 //关键跳
mov [ebp-1], bl
push edi
loc_1004F62:
mov eax, dword_100CEDC //这里存放着EPROCESS的下标
mov eax, [eax+4] //CEDC+4的位置正是BC
lea edi, [esi-34h] //[D1C0-34]的位置存放着EPROCESS结构的地址 注意这里是取地址
add eax, [edi] //指到BC处
xor ebx, ebx
xchg ebx, [eax] //清零
xor eax, eax
cmp [ebp-8], eax
jnz short loc_1004F83
cmp ebx, eax
jz short loc_1004F83
mov ecx, [edi]
mov [ebp-8], ecx
loc_1004F83:
mov ecx, 1505h
movsx edx, byte ptr [edi+eax] //这段算法主要是检测有没有被修改如果有的话就重启机器
imul ecx, 21h //edi存放着EPROCESS的地址,有兴趣的朋友可以逆下
add ecx, edx
inc eax
cmp eax, 18h
jb short loc_1004F88
cmp ecx, [edi+1Ch] //1CH处存放着检验值 1CH+4位置存放着进程名
jz short loc_1004FA1
call sub_100163C //重启机器
其实这里注意dword_100D1C0 变量这里很重要。
这2个都好搞定,关键是有个监控
mov edi, edi
push ebp
mov ebp, esp
sub esp, 10h
mov eax, dword_100CA6C //CA6C=CF;
push ebx
push esi
push edi
mov edi, offset unk_100CA68
sub edi, 0CA68h //EDI=模块载入地址
lea ecx, [eax+eax*2]//EAX=CF;
shl ecx, 2 //这步计算我估计应该是得出了100B268总大小
push 0
mov [ebp+var_10], edi
mov [ebp+var_4], ecx
pop edx
jz short loc_100422B
loc_100420C:
movzx esi, byte_100B268[edx]/*
100B268这个变量指向一个结构 这个结构类似 struct{ULONG PY(偏移),INT LEN,ULONG HASH}
CRC检验,估计是黑白名单之类的,我的猜测,如果有错那位朋友知道的话帮我纠正一下
*/
mov ebx, [ebp+var_4]
shr ebx, 1Bh
xor esi, ebx
mov ebx, [ebp+var_4]
shl ebx, 5
xor esi, ebx
inc edx
cmp edx, ecx
mov [ebp+var_4], esi
jb short loc_100420C
loc_100422B:
cmp [ebp+var_4], 17606A55h //上面一系列的计算和(17606A55计算后的总大小)比较,如果被修改了就重启
jz short loc_100423E
call sub_100163C //重启
mov eax, dword_100CA6C
loc_100423E:
and [ebp+var_C], 0
test eax, eax
jbe short loc_100429F //这个跳可以修改
mov esi, offset unk_100B26C
loc_100424B:
mov ecx, [esi-4] //ECX==STRUCT结构的PY偏移
mov edx, [esi]
and [ebp+var_8], 0
add ecx, edi //加上模块载入地址址
test edx, edx
mov [ebp+var_4], edx
jbe short loc_1004282
loc_100425D:
mov edi, [ebp+var_8]
movzx edi, byte ptr [ecx+edi] //取出PY下面的值来计算HASH
mov ebx, [ebp+var_4]
shr ebx, 1Bh
xor edi, ebx
mov ebx, [ebp+var_4]
shl ebx, 5
xor edi, ebx
inc [ebp+var_8]
cmp [ebp+var_8], edx //edx == STRUCT结构中的LEN
mov [ebp+var_4], edi
jb short loc_100425D
mov edi, [ebp+var_10]
mov ecx, [ebp+var_4]
cmp ecx, [esi+4] //经过一系列运算比较是不是STRUCT中的HASH
jz short loc_1004294 //相同就跳
call sub_100163C //不同就重启
mov eax, dword_100CA6C
loc_1004294:
inc [ebp+var_C]
add esi, 0Ch
cmp [ebp+var_C], eax
jb short loc_100424B
pop edi
pop esi
pop ebx
leave
retn
重启代码
in al, 64h
mov bl, al
test bl, 1
jz short loc_1001660
in al, 60h
test bl, 2
jnz short loc_1001655
mov al, 0FEh
out 64h, al
popa
retn
解决方法很多,我说几种
第一种是我以前用的一种比较挫的,其实最重要的是解决监控哪里,
分2步 1。在监控哪里 跳走或者直接返回
2.注意我标的清零的2段代码
mov ecx, dword_100D1C0 //这里比较关键啦。
mov edx, offset dword_100D1C0
cmp ecx, edx
jz short loc_10026BA// 这个是个关键比较啦
在函数开头钩钩一下跳到我们的函数
处理一下先查找到模块加载地址(Modulebase)。
伪代码
ULONG D1C0=Modulebase+0XD1C0;
_asm{
mov edi,edi
push ebp
mov ebp,esp
mov eax,D1C0
mov [eax],eax
mov eax,Ret(返回地址)
add eax,5
jmp eax
}
jz short loc_10026BA相等就跳啦
第二种方法 前天看到的,好像更加简便 查看
http://bbs.pediy.com/showthread.php?t=126802
感谢这位朋友的共享精神;
第三种没尝试
直接修改 jz short loc_10026BA
jz loc_1004FE9
jbe short loc_100429F
第三种没实践过只是大概估计,有兴趣的朋友可以尝试一下。多实践总不会错
至于那些SSDT HOOK呀inline-hook要我相信大部分人都能解决的。
本人能力有限。此文章如果有什么不正确的地方,希望大家指正一下,共同学习,共同进步嘛。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: