首页
社区
课程
招聘
[求助]加壳时TLS应该怎样处理?
发表于: 2007-10-5 21:54 7248

[求助]加壳时TLS应该怎样处理?

2007-10-5 21:54
7248
小弟正在写一个壳,一个超简单的一点即破的壳……

我壳的思路:写两部分,一部分是PACKER,负责把被加壳的程序打包放到LOADER的后面。另一部分是LOADER,负责把它后面的那个被加壳程序的数据加载到内容进运行。

下面是处理TLS的部分,pLdr是Loader在内存中的起始指针,pExe是被加壳程序在内存中的起始指针。

bool FixTls(char *pLdr, char *pExe)
{
	_IMAGE_NT_HEADERS *LdrPEoffset=(_IMAGE_NT_HEADERS *)(*(DWORD*)(pLdr+0x3c)+pLdr);
	_IMAGE_NT_HEADERS *ExePEoffset=(_IMAGE_NT_HEADERS *)(*(DWORD*)(pExe+0x3c)+pExe);
	if(ExePEoffset->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress!=0)		
	{
		IMAGE_TLS_DIRECTORY32 *ExeTlsDir=(IMAGE_TLS_DIRECTORY32*)(RVAtoRW((PBYTE)pExe,ExePEoffset->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress)+pExe);
		if (*(DWORD*)(RVAtoRW((PBYTE)pExe,((DWORD)ExeTlsDir->AddressOfCallBacks-ExePEoffset->OptionalHeader.ImageBase))+pExe)!=0)
		{
			printf("TLS Callback Functions are not supportted.");
			exit(1);
		}
		IMAGE_TLS_DIRECTORY32 *LdrTlsDir=(IMAGE_TLS_DIRECTORY32*)(0x7e00+pLdr);
		memcpy(LdrTlsDir,ExeTlsDir,sizeof(IMAGE_TLS_DIRECTORY32));    		
		LdrPEoffset->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress=0x7e00;
		LdrPEoffset->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size=0x18;
		LdrTlsDir->StartAddressOfRawData=0x40a920;
		LdrTlsDir->EndAddressOfRawData=ExeTlsDir->EndAddressOfRawData-ExeTlsDir->StartAddressOfRawData+LdrTlsDir->StartAddressOfRawData;		
		LdrTlsDir->AddressOfCallBacks=0;
		LdrTlsDir->SizeOfZeroFill=0;
		LdrTlsDir->Characteristics=0;
	}
	
	return true;
}



为什么被这个函数处理过的程序会运行不了呢?
加壳的其它部分都没有问题,只是新加了这个TLS处理之后就出错了。

附上加了壳之后运行不了的程序,请各位大哥帮我看一下。

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 377
活跃值: (432)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
其实我的要求只是可以运行一般的DELPHI程序,那些真正用到TLS CALLBACK FUNCTION的我都不支持。
2007-10-6 10:21
0
雪    币: 58782
活跃值: (21961)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
那你直接将DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]所指的数据复制到外壳里,并修正DataDirectory。应可以运行的。
2007-10-6 10:35
0
雪    币: 377
活跃值: (432)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
[QUOTE=kanxue;367864]那你直接将DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]所指的数据复制到外壳里,并修正DataDirectory。应可以运行的。[/QUOTE]

但是加过壳的程序的基址是0x3F0000,原程序的基址是0x400000,
我已经复制了
memcpy(LdrTlsDir,ExeTlsDir,sizeof(IMAGE_TLS_DIRECTORY32));        

也修正了DataDirectory
LdrPEoffset->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress=0x7e00;
LdrPEoffset->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size=0x18;

还是不行啊……
2007-10-6 12:20
0
雪    币: 377
活跃值: (432)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
我看了一下别人的代码,都是直接复制TLS那0x18个字节再修正DataDirectory的。我和他做的事情一样啊,为什么我的就不行呢?

是不是一定要在我的Loader里写一句TLSAlloc()?
	;;;;;;;;;;;;;对TLS的处理
	mov	eax,FileBuffer
	add	eax,NtHeaderRav
	assume	edi:ptr	IMAGE_NT_HEADERS
	mov	edi,eax
	mov	esi,[edi].OptionalHeader.DataDirectory[9*SIZE IMAGE_DATA_DIRECTORY].VirtualAddress
	;;;;判断是否有线程局部存储
	.if	esi!=0
		add	esi,MapOfFile
		mov	eax,TlsTable-shellcode0
		add	eax,NotPackResDataSize
		add	eax,SizeOfImage
		mov	[edi].OptionalHeader.DataDirectory[9*SIZE IMAGE_DATA_DIRECTORY].VirtualAddress,eax
		mov	edi,TlsTable-shellcode0
		add	edi,shell0buf
		mov	ecx,18h
		rep	movsb
	.endif
	assume	edi:nothing
2007-10-6 19:11
0
雪    币: 272
活跃值: (143)
能力值: ( LV15,RANK:930 )
在线值:
发帖
回帖
粉丝
6
加壳的时候要注意,如果 tls callback 数组的值个数非 0,就不能简单的拷贝一份。
你需要构造一份 dummy callback, 先有自己接管处理。
如果在原 code 没有解开之前,发生调用要立即返回,不要往下传递。其他情况,call 一下 原 tls callback 就可以了.
在解原 code 的时候完成后,要修正系统自动分配的 tls (这块数据是由于没有解压,导致系统错误拷贝的数据)。
2007-10-7 12:55
0
雪    币: 8209
活跃值: (4559)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
7
似乎主要不是tls的问题
你的基址是0x3F0000,delphi找不到资源了
2007-10-7 15:15
0
雪    币: 334
活跃值: (22)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
我也在思考如何处理TLS的问题
2008-1-25 16:08
0
游客
登录 | 注册 方可回帖
返回