首页
社区
课程
招聘
[原创]加壳要细心,我给bambam调错纪实
发表于: 2006-4-19 14:02 7559

[原创]加壳要细心,我给bambam调错纪实

2006-4-19 14:02
7559

给程序加壳就是给程序动手术,一点也马虎不得,稍微一不留神就出问题.
本人一直学习使用c/c++做壳,所以bambam就是最好的参考(源码下载中有所有源码).

学习的过程就是读别人的代码,确实原理上不难,但实际一操作还挺麻烦的.这里讲一个给bambam调错的亲身经历吧.

背景:
bambam是bedrock根据bigboot的文章做的一个壳,代码写的很不错了.但他有的地方处理的不太合理.TLS是这个壳一个亮点,他使用了tls代理技术,巧妙的处理了tls,这个东西还是很实用的,尽管99%的程序不用他.borland编译的程序都有tls,但多数都是0,所以其实也没用.但如果这16个字节处理不好也会有问题.

下面是bambam的代码,
inline void FinaliseTlsStuff()
{
        PIMAGE_DOS_HEADER pDosHdr;
        PIMAGE_NT_HEADERS pNtHdr;
        DWORD dwKatSup;
        LONG lJmp;

        pDosHdr = (PIMAGE_DOS_HEADER)dwLoadAddress;
        lJmp = pDosHdr->e_lfanew;
        dwKatSup = (DWORD)pDosHdr;
        dwKatSup += lJmp;

        pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;

        if(pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0)
        {
                                gev.tlsOriginal.AddressOfIndex = (DWORD*)dwTlsSlotIndex;

                void* pvTlsData;
               
                __asm
                {
                        mov ecx, DWORD PTR dwTlsSlotIndex;
                        mov edx, DWORD PTR fs:[02ch]
                        mov ecx, DWORD PTR [edx+ecx*4]
                        mov pvTlsData, ecx
                }

                int size = gev.tlsOriginal.EndAddressOfRawData - gev.tlsOriginal.StartAddressOfRawData;

                CopyMemory(pvTlsData, (void*)gev.tlsOriginal.StartAddressOfRawData, size);
                FillMemory((void*)gev.tlsOriginal.EndAddressOfRawData, gev.tlsOriginal.SizeOfZeroFill, 0);
        }
        fSafeToCallback = true;
        if(fDelayedTlsCallback)
        {
                TlsCallback(tlsDllHandle, tlsReason, tlsReserved);
        }
}

看上去这个代码写的很漂亮,而且运行起来也没问题,至少在windows9x-2003都可以很好的工作.但其实里面有个bug.

发现bug:
bug发现的很偶然,因为一般运行的时候都没问题.但有一次我在stub中开了一个线程,又在这个线程中开了第二个线程,这样的壳在win2000系列的平台是没问题的,但在win98下会报错.而且只有delphi的程序报错.

起初我以为是stub中线程的错误,就反覆修改,但还是同样的报错.就这样让我郁闷了很长时间.我觉的问题和tls有关,但就是找不到问题.

注意,win98下tls也是先启动的,所以可以确认win98是有tls支持的.

我甚至pediy一个exe,没有tls,他就不报错了.所以现在可以确定bug就在这段代码中.说实话,找这个bug很郁闷,因为很多的地方很难猜测系统运行的过程,因为系统loader报的错,就是olly能做的也很有限了.

只能从代码入手,一点点的看,突然,你可以看到有一个地方似乎有点古怪,gev.tlsOriginal.AddressOfIndex = (DWORD*)dwTlsSlotIndex; 实际上语法是没有问题的,但dwTlsSlotIndex是变量,能这么搞吗?当然可以这样做,其他的地方这样赋值很多,但这里似乎是错误的,应该改为gev.tlsOriginal.AddressOfIndex = (DWORD)&dwTlsSlotIndex;, 这样win98下就ok了.

这个问题修改是成功了,但我心理还是有些疑问,为什么win2000,xp就没事呢?

总结:
打壳就是动手术,一点都不能马虎,否则出了问题不好解决,主要是症状不好调试.这个文章写了我真实的经历,献给那些自己动手做壳的人吧.


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (4)
雪    币: 279
活跃值: (145)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
2
顶上!坐沙发!~
2006-4-19 14:35
0
雪    币: 817
活跃值: (1927)
能力值: ( LV12,RANK:2670 )
在线值:
发帖
回帖
粉丝
3
good!!
2006-4-19 18:30
0
雪    币: 47147
活跃值: (20380)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
谢谢分享
这个帖wwwddd也发现了一些bug:
http://bbs.pediy.com/showthread.php?s=&threadid=18156&perpage=15&highlight=&pagenumber=2
2006-4-19 19:35
0
雪    币: 250
活跃值: (103)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
值得注意!
2006-4-20 18:21
0
游客
登录 | 注册 方可回帖
返回
//