来看雪两年多了,到现在还是个相当菜的菜鸟,只索取,从来没有过回报,因为水平太次,实在是写不出来什么~   
这个小程序实际是做毕业设计的时候写的,当时写完之后,没有太大的问题了,就没有再改(能蒙混过关就是目的),里面现在仍然是bug多多。它主要是利用Tls CallBack来实现在运行程序之前先运行我们的代码,我们要把代码写入到exe中才行。

TLS是Thread Local Storage,即线程局部存储。线程局部存储有2种,动态的和静态的。动态线程局部存储使用TlsAlloc, TlsFree, TlsSetValue和TlsGetValue这些API,利用TLS机制可以为进程中的每个线程关联若干个数据,各个线程通过由TLS分配的全局索引来访问与自己关联的数据。
而静态线程局部存储是在Windows的PE/COFF可执行文件格式中所支持的静态线程局部存储。即在PE头中数据目录表中的第10项,这一项指向的是Tls目录,Tls目录的结构如下:

代码:
IMAGE_TLS_DIRECTORY32  STRUCT
StartAddressOfRawData  dd  ?
EndAddressOfRawData  dd  ?
AddressOfIndex    dd  ?
AddressOfCallBacks    dd  ?
SizeOfZeroFill    dd  ?
Characteristics    dd  ?
IMAGE_TLS_DIRECTORY32  ENDS
它的第三项是在线程初始化的时候要用的,使其指向一个可写的无用的数据区即可。第四项即是指向的Tls CallBacks的数组,这个数组以0结尾,在线程刚被创建的时候,系统会遍历这个Tls Callbacks的数组,它会依次调用各个线程回调函数。所以,只须在代码段中找到一些空闲的空间,然后将代码写到里面去,然后将再设置Tls目录的值,这样就实现了将Tls回调函数加入到其他可执行文件中。
具体的解释可以见team509的文章:
http://www.team509.com/modules.php?name=News&file=article&sid=73

我现在大概讲一下思路吧
在Edit中按一定格式写好代码之后,然后点编译,程序会先将Edit中的代码写到一个临时文件temp.asm中,然后加上头之类的,形成一个能编译的基本文件。
然后会调用nmake来编译,makefile3会被调用,然后生成temp.exe
然后从有效位置把有效的数据提取出来,也就是有效代码,在temp.exe中,一般有效代码开始位置为0x1000,然后将其读出来,直到出现MarkLab标记,这个标记是在程序中自己设定的,为了能很好的找到结尾。(主要是在_GetBinaryCode中完成的)

提取出来之后就将这段有效代码,保存到Binary.dat中
然后在判断PE是否有效等,再查找代码段,然后判断代码段是否有足够的空间,如果有足够的空间,则会将Binary.dat中的数据写到exe中,作为Tls Callback
实现起来并不难,主要是算Tls Callback的位置比较繁琐

因为当时写的时候,直接写死的,运行的时候最好放到C:\Temp\Tls,当时好像用当前目录设置有问题,而且Binary.dat每次都会往这个目录下写,所以没办法,就直接把tls.exe放这里面执行就行了。
而且如果要自己编译的话,要改一下makefile和makefile3
将里面的头文件以及库文件的路径设置为正确的

因为有Binary.dat了,所以也可以不编译,直接选择文件往里写,这时候会从当前文件夹下的Binary.dat中取数据,然后到目标exe中
测试了几个简单的exe,正常,但有的exe写的时候会有错……

这马上就要到2009年了,也祝大家新年快乐。
上传的附件 Tls.rar [解压密码:pediy]