首页
社区
课程
招聘
[原创]简单对抗某个驱动的反调试
发表于: 2010-4-18 20:02 67847

[原创]简单对抗某个驱动的反调试

2010-4-18 20:02
67847

先声明:
1.  本文纯娱乐,本人并不从事制作非法软件的活动…也请读者不要将本文的技术运用到非法领域,否则一切后果自负。
2.我是菜鸟,都是些基本内容。只是看网上很多人搞,又弄的很麻烦,反正自己前两天玩儿了一小下,索性发出来。在ring0搞反反调试似乎已经被某广告鄙视的不行了~所以说我只是娱乐,没有其他目的。我很挫~欢迎批评指正,欢迎交流:http://hi.baidu.com/andriy_aolala/blog
3.  本文参考了一些文章,在文末 一 并感谢

不同游戏的保护驱动版本不太一样,我看的是cf的版本。先用ark初步扫描一下(如果要用xuetr,要先于tp加载,因为它hook了 tessafe.sys同样hook的指令,后启动xuetr导致直接重启),我用我以前写的一个ark扫描了一下。
他的hook如下:

  IAT   kdcom.dll  KdSendPacket    KdRecivePacket
  Inline NtRead/WriteVirtualMemory KiAttachProcess
  Call hook  NtOpenThread NtOpenProcess 中的ObReferenceObjectByPointer
  此外还有3个Callback,两个系统线程
.text:01001532                 call    ds:KdDisableDebugger
.text:01001538
.text:01001538 loc_1001538:                            ; CODE XREF: .text:01001530j
.text:01001538                 mov     edx, ds:KdDebuggerEnabled
.text:0100153E                 xor     ecx, ecx
.text:01001540                 xor     eax, eax
.text:01001542                 inc     ecx
.text:01001543                 inc     eax
.text:01001544                 lock cmpxchg [edx], ecx
.text:01001548                 test    al, al
.text:0100154A                 jnz     short loc_1001532
.text:0100154C                 retn
.text:01001EBD                 call    ds:IoGetCurrentProcess ;得到调用者的eprocess
.text:01001EC3                 mov     [ebp+pEpro], eax
.text:01001EC6                 push    [ebp+pEpro]     ; pEpro
.text:01001EC9                 call    EprocessChk  ;非常关键的比对函数
.text:01001ECE                 movzx   eax, al
.text:01001ED1                 test    eax, eax
.text:01001ED3                 jz      short loc_1001EDA
.text:01001ED5                 jmp     loc_1001FC7  ;返回1的话 直接放行

.text:01001FC7                 mov     eax, off_100A090
.text:01001FCC                 or      ecx, 0FFFFFFFFh
.text:01001FCF                 lock xadd [eax], ecx
.text:01001FD3                 popf
.text:01001FD4                 popa
.text:01001FD5                 mov     esp, ebp
.text:01001FD7                 pop     ebp
.text:01001FD8                 jmp     OringinObReferenobjByPointer 跳回去

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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (42)
雪    币: 419
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
呵呵 这东西
2010-4-18 20:40
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
尾随膜拜
2010-4-18 21:28
0
雪    币: 695
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼主 你的博客被和谐了?
2010-4-18 21:42
0
雪    币: 269
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
汗啊。。Link已经修复。。抱歉。。
2010-4-18 21:44
0
雪    币: 1407
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
前段时间因为某位大牛在某群的提示,也成功让windbg调试TP,没发现TP跟XueTr有什么冲突
2010-4-18 21:53
0
雪    币: 269
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
先加载tp,再加载xuetr 就冲突了。。 tp有内存校验。。xuetr的hook随便恢复。。

我没说清楚~不好意思~
2010-4-18 22:04
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
8
前来围观中……
2010-4-18 22:12
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
9
围观一下,lz爆了利用TP的白名单的方法......
2010-4-18 22:46
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
10
搞定驱动的反调试只需要改3个字节,还有,那个黑名单是ring3通过DeviceIoControl发过去的~
2010-4-18 22:51
0
雪    币: 269
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
11
3个字节?要不要这么帅啊。。。膜拜。。  

看来我的标题要改成不简单xxx了。。哈哈。。

晕Ing...在那个loadimage的回调里面看,黑名单的信息是保存在全局变量里面的~我下了个内存断点看,那个单子时有时无的。。额。。是我的表单没定位准确么。。。
2010-4-18 23:27
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
12
3字节没那么不和谐,另外TP的DeviceIoControl好像没啥用吧,话说不是用int XX通信么~
有图~

2010-4-19 15:34
0
雪    币: 163
活跃值: (103)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
13
邪恶的AGP
2010-4-19 15:59
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
膜拜大牛下
2010-4-19 20:48
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
15
话说我在调试DNF的TesSafe时,没发现intxx处的例程有什么实质用处~
关键数据的传递都还是通过DeviceIoControl传递的,不过传递的数据是加密的,加解密函数如下:
void DecryptOrEntryptBuffer(BYTE *Keys, BOOL bEncrypt, BYTE *bufferToDecrypt, int BufferLen)
{
	ULONG i; 
	
	if ( BufferLen )
	{
		i = 0;
		if ( BufferLen )
		{
			bufferToDecrypt = bufferToDecrypt;
			do
			{
				if ( bEncrypt )
					bufferToDecrypt[i] ^= i;
				bufferToDecrypt[i] ^= Keys[i & 7];
				if ( !bEncrypt )
					bufferToDecrypt[i] ^= i;
				++i;
			}
			while ( i < BufferLen );
		}
	}
}

再贴点其它code:
#define IOCTL_GETPROCPATH		  0x22E4A0  
#define IOCTL_SETTRUSTEDPROCESS       0x22E484  //设置可信程序
#define IOCTL_SETPROTECTEDPROCESS  0x22E488  //设置被保护程序

typedef struct _TRUSTED_PROCESS_INFO{
	ULONG u1;
	ULONG u2;
	ULONG u3;
	ULONG u4;
	ULONG ProcessCnt;		//offset=0x10
	DWORD ProcessId[33];	//offset=0x14
	ULONG Key1;		//offset=0x98
	ULONG Key2;		//offset=0x9C
}TRUSTED_PROCESS_INFO,*PTRUSTED_PROCESS_INFO;	//size=0xA0

typedef struct _PROTECTED_PROCESS_INFO{
	DWORD PidToProtect;	//offset=0
	DWORD u1;
	DWORD u2;
	DWORD u3;
	ULONG Key1;	//offset=0x10
	ULONG Key2;	//offset=0x14
}PROTECTED_PROCESS_INFO,*PPROTECTED_PROCESS_INFO;

/*
设置可信任程序,测试不完全正确
参数说明:
	InputBuffer	:存放Pid
	InputLen	:160
	OutputBuffer:NULL
	OutputLen	:0
*/
BOOL SetTrustedProcessInfo(HANDLE hDevice)
{
	TRUSTED_PROCESS_INFO ProcessInfo;
	BOOL bRet;
	DWORD Pid;
	ULONG Cnt=0;
	DWORD byteRetned=0;
	int i=0;
	char *szTrustedProcName[]={"smss.exe","csrss.exe","winlogon.exe",
		"services.exe","svchost.exe","alg.exe","lsass.exe"};
	int TotalCnt=7;
	ZeroMemory(&ProcessInfo,sizeof(TRUSTED_PROCESS_INFO));
	//下面获取几个进程的PID用做测试
	for (i=0;i<TotalCnt;i++)
	{
		Pid=GetProcessIdByName(szTrustedProcName[i]);
		if (Pid)
		{
			printf("%s \t\tPid=%d\n",szTrustedProcName[i],Pid);
			ProcessInfo.ProcessId[Cnt++]=Pid;
		}
	}
	//开始填充缓冲区
	ProcessInfo.u1=5;
	ProcessInfo.u2=1;
	ProcessInfo.u3=2;
	ProcessInfo.u4=0;
	ProcessInfo.ProcessCnt=Cnt;
	ProcessInfo.Key1=0x12345678;
	ProcessInfo.Key2=0x11223344;
	//对缓冲区进行加密,加密的数据内容当然不包括密钥
	DecryptOrEntryptBuffer((BYTE*)&ProcessInfo.Key1,TRUE,(BYTE*)&ProcessInfo,sizeof(TRUSTED_PROCESS_INFO)-sizeof(ULONG)*2);
	printf("The buffer = 0x%08X\n",&ProcessInfo);
	bRet=DeviceIoControl(hDevice,
		IOCTL_SETTRUSTEDPROCESS,
		&ProcessInfo,
		sizeof(TRUSTED_PROCESS_INFO),
		NULL,
		0,
		&byteRetned,
		NULL);
	printf("The return value=%d\n",bRet);
}
2010-4-19 22:52
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
16
可能是主创离职后,intXX不使用了吧。
2010-4-19 23:07
0
雪    币: 7309
活跃值: (3788)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
17
[QUOTE=cvcvxk;793595]3字节没那么不和谐,另外TP的DeviceIoControl好像没啥用吧,话说不是用int XX通信么~
有图~

[/QUOTE]

你的图怎么还有小衣服啊,太不专业了
2010-4-19 23:20
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
18
小衣服看起来很好看啊~
2010-4-19 23:56
0
雪    币: 636
活跃值: (174)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
19
膜拜AGP!
2010-4-20 11:28
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
20
现在TX恢复硬件断点是利用SEH了吧! 看他家ring3层 KiUserExceptionDispatcher 和  ZwSetContextThread
2010-4-21 17:51
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
21
其次 我觉得OD加载文件名 完全可以实现自身的伪装 没必要和他对抗! 利用壳技术 OD启动可能是系统中任意一个系统文件名! DebugPort 清0 我感觉不用驱动不行
2010-4-21 17:54
0
雪    币: 14
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
对我来说,这是救命的文章 !
2010-4-24 21:25
0
雪    币: 233
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
不用那么麻烦的拉(毕竟他VM了有些代码),IDA分析烦的。
  用KD可以直接轻松反汇编0环的  而且不用比他先加载驱动- -
或者还有几个老办法。。。大家都明白的。。不说了。。
2010-4-27 06:37
0
雪    币: 233
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
getmodulefilenamea              7c80b56F
GETPROCADDRESS                  7c80ae40
gettickcount                    2dfb672
loadlibraryexw                  7c801af5
queryperformancecounter         2DFB6D5
queryperformancefrequency       2DFB6b0
setunhandledexceptionfilter     7c844935
kiuserexceptiondispatcher       7c92e47c
ldrinitializethunk              7c921166
ldrloaddll                      7c9363c3
ntcreatethread                  7c92d1ae
ntsetcontexthread               7c92dbae
zwcreatethread                  7c92d1ae
zwsetcontexthread               7c92dbae

一会就更新了
2010-4-27 06:44
0
雪    币: 233
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
R3关键  不用驱动也行的  
2010-4-27 07:02
0
游客
登录 | 注册 方可回帖
返回
//