吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8970|回复: 22
收起左侧

[其他转载] 简单构造个畸形PE

   关闭 [复制链接]
ximo 发表于 2010-3-17 23:04
本帖最后由 ximo 于 2010-3-18 00:02 编辑

本文主要讲述下如何简单的手动构造个畸形PE,比如使得入口点为0。处理的结果是使得PEiD等PE工具识别出错,导致无法用OD进行调试(貌似被强大的海风的SOD给和谐掉了)。
原理就是TLS的应用,手动添加个TLS就可以用来干坏事了。
方法:
1.找个空白地,构造TLS,填写TLS的值
2.修改PE可选头里的数据目录表里的TLS的RVA为你写入的地址
3.在TLS里的TLS回调地址处修改成原始的入口地址
4.其余的TLS结构,如果原来就存在TLS,比如delphi程序,则写回原来的值,否则可以用0填充
5.此时,原来的入口地址你可以随意修改,比如修改为0,或者修改成很大的一个数,使PE工具无法正常识别

效果为:
未命名.jpg
但是此时文件能够正常运行

下面是核心代码,代码写的很挫,仅仅是示例,有兴趣的自己修改吧

//定义个新的要写入的TLS结构
struct _New_TLS
{
        DWORD dwStartAddressOfRawData;
        DWORD dwEndAddressOfRawData;
        DWORD dwAddressOfIndex;
        DWORD dwAddressOfCallBacks;
        DWORD dwSizeOfZeroFill;
        DWORD dwCharacteristics;
}MyNewTLS;

//2个所要用到的关键转化,RVA跟Offset的互换
//Offset转RVA
DWORD OffsetToRVA(LPVOID lpBase,DWORD FileOffset)
{
        PIMAGE_DOS_HEADER MyDosHeader;
        PIMAGE_NT_HEADERS MyNtHeader;
        PIMAGE_SECTION_HEADER MySectionHeader;
        MyDosHeader=(PIMAGE_DOS_HEADER)lpBase;
        MyNtHeader=(PIMAGE_NT_HEADERS)((long)lpBase+MyDosHeader->e_lfanew);
    MySectionHeader=(PIMAGE_SECTION_HEADER)((UINT32)MyNtHeader+0x18+(UINT32)MyNtHeader->FileHeader.SizeOfOptionalHeader);
        int NumOfSection;
        NumOfSection=MyNtHeader->FileHeader.NumberOfSections;
        DWORD dwSizeOfSection;
        dwSizeOfSection=sizeof(IMAGE_SECTION_HEADER);
        if (FileOffset<MySectionHeader->PointerToRawData)
        {
                return FileOffset;
        }
        else
        {
        for(int i=0;i<NumOfSection;i++)
                {
                        if (FileOffset>=MySectionHeader->PointerToRawData && FileOffset<MySectionHeader->PointerToRawData+MySectionHeader->SizeOfRawData)
                        {
                                DWORD dwTMP=FileOffset-MySectionHeader->PointerToRawData;
                                DWORD dwRVA=MySectionHeader->VirtualAddress+dwTMP;
                                return dwRVA;
                        }
                        else
                        {
                                MySectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)MySectionHeader+dwSizeOfSection);
                        }
                }
        }
        return 0;
}

//RVA转Offset
DWORD RVAToOffset(LPVOID lpBase,DWORD VirtualAddress)

{   
        PIMAGE_DOS_HEADER MyDosHeader;
        PIMAGE_NT_HEADERS MyNtHeader;
        PIMAGE_SECTION_HEADER MySectionHeader;
        MyDosHeader=(PIMAGE_DOS_HEADER)lpBase;
        MyNtHeader=(PIMAGE_NT_HEADERS)((long)lpBase+MyDosHeader->e_lfanew);
        MySectionHeader=(PIMAGE_SECTION_HEADER)((UINT32)MyNtHeader+0x18+(UINT32)MyNtHeader->FileHeader.SizeOfOptionalHeader);
        int NumOfSection;
        NumOfSection=MyNtHeader->FileHeader.NumberOfSections;
        DWORD dwSizeOfSection;
        dwSizeOfSection=sizeof(IMAGE_SECTION_HEADER);
        if (VirtualAddress<MySectionHeader->VirtualAddress)
        {
                return VirtualAddress;
        }
        else
        {
                for(int i=0;i<NumOfSection;i++)
                {
                        if(VirtualAddress>=MySectionHeader->VirtualAddress&&VirtualAddress<MySectionHeader->VirtualAddress+MySectionHeader->Misc.VirtualSize)
                        {
                                DWORD dwTmp=MySectionHeader->VirtualAddress-MySectionHeader->PointerToRawData;
                                DWORD Offset=VirtualAddress-dwTmp;
                                return Offset;
                        }
                        else
                        {
                                MySectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)MySectionHeader+dwSizeOfSection);
                        }
                }
        }
        return 0;
}

//打开文件,创建文件映射
        HANDLE hFile;
        hFile=CreateFile(m_path,GENERIC_WRITE|GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
        if (hFile==INVALID_HANDLE_VALUE)
        {
                return;
        }
        HANDLE hMap;
        hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,NULL,NULL,NULL);
        if (hMap==NULL)
        {
                CloseHandle(hFile);
                return;
        }
        LPVOID lpBase;
        lpBase=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
        if (lpBase==NULL)
        {
               
                CloseHandle(hMap);
                CloseHandle(hFile);
                return;
        }

//验证PE的有效性
        PIMAGE_DOS_HEADER MyDosHeader;
        MyDosHeader=(PIMAGE_DOS_HEADER)lpBase;
        if (MyDosHeader->e_magic!='ZM')
        {
                UnmapViewOfFile(lpBase);
                CloseHandle(hMap);
                CloseHandle(hFile);
                return;
        }
        DWORD FileSize;
        FileSize=GetFileSize(hFile,NULL);
        if (MyDosHeader->e_lfanew>FileSize)
        {
                UnmapViewOfFile(lpBase);
                CloseHandle(hMap);
                CloseHandle(hFile);
                return;
        }
        PIMAGE_NT_HEADERS MyNtHeader;
        MyNtHeader=(PIMAGE_NT_HEADERS)((long)lpBase+MyDosHeader->e_lfanew);
        if (MyNtHeader->Signature!='EP')
        {
                UnmapViewOfFile(lpBase);
                CloseHandle(hMap);
                CloseHandle(hFile);
                return;
        }
        if (MyNtHeader->OptionalHeader.AddressOfEntryPoint==0)
        {
                UnmapViewOfFile(lpBase);
                CloseHandle(hMap);
                CloseHandle(hFile);
                return;
        }

//搜索32个字节的空隙,目的是用来写TLS
//起始地址可以选择从第一个区段开始
        PIMAGE_SECTION_HEADER MySectionHeader;
        MySectionHeader=(PIMAGE_SECTION_HEADER)((UINT32)MyNtHeader+0x18+(UINT32)MyNtHeader->FileHeader.SizeOfOptionalHeader);
        DWORD dwBegin=MySectionHeader->VirtualAddress;
        int iCount=0;
        DWORD dwAddr;
     for (int i=dwBegin;i<FileSize;i++)
     {
                 BYTE tmp=(BYTE)*(DWORD*)((DWORD)lpBase+i);
                 if (tmp==0)
                 {
                         iCount++;
                 }
                 else
                 {
             if (iCount>=32 &&((i-iCount)%2==0))
             {
                 dwAddr=i-iCount;
                                 break;
             }
                         else
                         {
                  iCount=0;
                         }
                        
                        
                 }

     }

//判断所要写入的地址的所在区段,然后修改区段属性使得可写
int NumOfSection;
         NumOfSection=MyNtHeader->FileHeader.NumberOfSections;
         DWORD dwSizeOfSection;
         dwSizeOfSection=sizeof(IMAGE_SECTION_HEADER);
     for(int j=0;j<NumOfSection;j++)
         {
                 if (dwAddr>=MySectionHeader->PointerToRawData && dwAddr<MySectionHeader->PointerToRawData+MySectionHeader->SizeOfRawData)
                 {
             MySectionHeader->Characteristics=0xE0000040;
                         break;
                 }
                 else
                 {
             MySectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)MySectionHeader+dwSizeOfSection);
               
                 }
         }

//填充TLS
DWORD dwTLS,dwTLSCallBack,dwTLSIndex;
        dwTLS=dwAddr;  //TLSRVA
        dwTLSCallBack=dwAddr+24;
        dwTLSIndex=dwAddr+28;
        DWORD dwTLSRVA=MyNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
        if (dwTLSRVA!=0)
        {
         PIMAGE_TLS_DIRECTORY MyOldTLSHeader=(PIMAGE_TLS_DIRECTORY)((DWORD)lpBase+RVAToOffset(lpBase,dwTLSRVA));
                 MyNewTLS.dwStartAddressOfRawData=MyOldTLSHeader->StartAddressOfRawData;
                 MyNewTLS.dwEndAddressOfRawData=MyOldTLSHeader->EndAddressOfRawData;
                 MyNewTLS.dwAddressOfIndex=MyOldTLSHeader->AddressOfIndex;
                 MyNewTLS.dwAddressOfCallBacks=(OffsetToRVA(lpBase,dwTLSCallBack)+MyNtHeader->OptionalHeader.ImageBase);
                 MyNewTLS.dwSizeOfZeroFill=MyOldTLSHeader->SizeOfZeroFill;
                 MyNewTLS.dwCharacteristics=MyOldTLSHeader->Characteristics;
        }
        else
        {   
                MyNewTLS.dwStartAddressOfRawData=0;
                MyNewTLS.dwEndAddressOfRawData=0;
                MyNewTLS.dwAddressOfIndex=(OffsetToRVA(lpBase,dwTLSIndex)+MyNtHeader->OptionalHeader.ImageBase);
                MyNewTLS.dwAddressOfCallBacks=(OffsetToRVA(lpBase,dwTLSCallBack)+MyNtHeader->OptionalHeader.ImageBase);
                MyNewTLS.dwSizeOfZeroFill=0;
                MyNewTLS.dwCharacteristics=0;
        }

        MyNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress=OffsetToRVA(lpBase,dwTLS);  //修正tls的RVA
        PIMAGE_TLS_DIRECTORY MyNewTlsHeader=(PIMAGE_TLS_DIRECTORY)(dwTLS+(DWORD)lpBase);
        MyNewTlsHeader->StartAddressOfRawData=MyNewTLS.dwStartAddressOfRawData;
        MyNewTlsHeader->EndAddressOfRawData=MyNewTLS.dwEndAddressOfRawData;
        MyNewTlsHeader->AddressOfIndex=MyNewTLS.dwAddressOfIndex;
        MyNewTlsHeader->AddressOfCallBacks=MyNewTLS.dwAddressOfCallBacks;
        MyNewTlsHeader->SizeOfZeroFill=MyNewTLS.dwSizeOfZeroFill;
        MyNewTlsHeader->Characteristics=MyNewTLS.dwCharacteristics;

//修改TLS的回调地址处为原始的入口地址
DWORD dwOEP=MyNtHeader->OptionalHeader.ImageBase+MyNtHeader->OptionalHeader.AddressOfEntryPoint;
        DWORD dwWrite;
        SetFilePointer(hFile,dwTLSCallBack,NULL,FILE_BEGIN);
    WriteFile(hFile,&dwOEP,sizeof(DWORD),&dwWrite,NULL);

//改写入口地址,随意修改,比如我修改为0
MyNtHeader->OptionalHeader.AddressOfEntryPoint=0; //入口为0

//收尾
        UnmapViewOfFile(lpBase);
        CloseHandle(hMap);
        CloseHandle(hFile);

O了,这样就构造完了。最后放个bin吧,试了下,效果还行。

[LCG]:http://www.52pojie.cn
[DFJG]:http://www.80dfj.org

SpecialPE.rar

4.79 KB, 下载次数: 74, 下载积分: 吾爱币 -1 CB

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2010-3-17 23:14
恩,这么好的贴就不用加精华了.
fulee 发表于 2010-3-17 23:07
czjh2008 发表于 2010-3-17 23:35
blueapplez 发表于 2010-3-17 23:57
膜拜ing。。。
悄悄的告诉楼主, 兼容性还有带提高。。。哈哈
icy 发表于 2010-3-18 00:05
这个好玩,我准备加到我修改的link 实现之

呵呵
rwr 发表于 2010-3-18 17:13
哈哈,我喜欢
libicheng 发表于 2010-3-19 00:08
好东西啊   不错不错!!!!
cool168 发表于 2010-5-28 20:25
这个不错,学习一下
zq784161329 发表于 2010-5-29 14:42
东西不错,支持!!!!!!!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 02:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表