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

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

2010-4-18 20:02
67654
先声明:
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,两个系统线程

一、首先要解决内核调试的问题,有Windbg才好继续。
.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


Ida里面有这么一段,这不新鲜了,直接注册一个LoadImageNotify,启动前IAT hook KdDisableDebugger 和KdDebuggerEnabled,再inline hook 掉TesSafe.sys 里面hook掉KdSendPacket    KdRecivePacket 的函数,跳转回原函数即可。

至此我们已经可以通过WinDbg调试驱动了。

二、放行OllyIce 和 CE

Tp hook 了一大堆,网上写的都是跳来跳去的绕过,但是即使绕过了也有可能过一段时间提示非法软件,原因不明。。总之这么来很费时间。

于是我在其OpenProcess 的hook函数里面找到
.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 跳回去


我们看看EprocessChk这个函数的伪代码
char __stdcall EprocessChk(PEPROCESS pEpro)
{
  unsigned int v1; // ecx@2

  if ( pEpro != (PEPROCESS)dword_100AFAC )
  {
    v1 = 0;
    if ( !process_white_num )
      return 0;
    while ( pEpro != (PEPROCESS) process_white_list [v1] )
    {
      ++v1;
      if ( v1 >= process_white_num )
        return 0;
    }
  }
  return 1;
}

process_white_list 是一个全局数组 有0x20个位子,里面存放的是诸如System.exe之类的系统进程eprocess。
kd> dd tessafe+EEE0
ee1c9ee0  863b57c0 8614cb78 86124598 861109d0
ee1c9ef0  86136da0 860fc3e8 860f6da0 860af510
ee1c9f00  860afda0 85fbada0 00000000 00000000
kd> !process 863b57c0
PROCESS 863b57c0  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 06c28020  ObjectTable: e1001e10  HandleCount: 240.
    Image: System
VadRoot 863b5050 Vads 4 Clone 0 Private 3. Modified 3279. Locked 0.

这个函数在其所有hook函数里面都存在,对方程序对于系统进程的函数调用是全部放行的。
所以,我们就注册一个CreateProcessNotify 把OD和CE加到那个白名单里面~~这样就不用绕hook了。
三、对抗debug port清零
  不熟悉debug port的同学可以去看软件调试,这是eprocess中的一个结构,是调试的关键,对方不停清零将导致OD像傻子一样,我看过的对抗方法有两种
1、  改内核函数DbgkXXX 系列函数中debug port相对于eprocess的偏移值 ,这个工作量太大,受不了。
2、  V大发的 重新编译WRK改eprocess结构。。这个倒是很通用啊~
其实对方程序想清零,也要有偏移,在xp中,0xbc是一个特殊的数字,IDA里面直接ATL+I …找到了3~4处,其中一处就是tp程序初始化硬编码。
char __stdcall IniHardCode(int a1)
{
  int v1; // eax@3

  if ( dword_100A050 == 5 )  //这是版本号
  {
    if ( !dword_100A054 )
    {
      v1 = a1;
。。。。。。
      return 1;
    }
    if ( dword_100A054 == 1 )
    {
      v1 = a1;
      *(_DWORD *)(a1 + 4) = 0xBCu;  //这个值就是dbgport的偏移了
。。。。。。

这个函数的参数是一个申请的内存变量地址,保存在全局变量里,我们等其加载完毕后找到这块内存,修改0xbc为0x78(exit time的值),之后就让它丫清零去吧。
四、最后的疑问
1、至此,windbg可正常使用,OD 可附加可下断,但tufuzi 在其文章中说他会检查硬件断点,所以要hook NtGetContextThread,但我下断这里没见有程序调用。。我下完硬件断点也没见对方有什么反抗。。奇怪啊奇怪
2、虽然CE被加进了白名单,但是会报非法模块,不知其检测机制,驱动里确实找到了教主说的黑名单(名字一遍,特征值一遍),但是两个黑名单自始至终全是零,搞得我以为没有,但是检测函数是实实在在存在的,crc table也存在。我晕啊。
对反调试作者的建议:把你的CV多加一点。。别暴露这么多。。
最后附上idb 和  src 
运行环境:xp sp3  game version:0.5.7  加载顺序: 我们的驱动,对方程序,OD。对方程序加载后windbg会掉一下,但马上恢复~
感谢前辈的研究~参考资料:
说说某游戏保护驱动中驱动黑名单的具体实现 作者:教主
过掉DNF游戏保护 作者:tufuzi
附件在这里 
ts.rar

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 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
活跃值: (1875)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
8
前来围观中……
2010-4-18 22:12
0
雪    币: 8865
活跃值: (2379)
能力值: ( 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
雪    币: 8865
活跃值: (2379)
能力值: ( 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
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
16
可能是主创离职后,intXX不使用了吧。
2010-4-19 23:07
0
雪    币: 7309
活跃值: (3778)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
17
[QUOTE=cvcvxk;793595]3字节没那么不和谐,另外TP的DeviceIoControl好像没啥用吧,话说不是用int XX通信么~
有图~

[/QUOTE]

你的图怎么还有小衣服啊,太不专业了
2010-4-19 23:20
0
雪    币: 8865
活跃值: (2379)
能力值: ( 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
游客
登录 | 注册 方可回帖
返回
//