注释PEMaker6源代码(三)

今天大概看了一下精华8《向PE中注入代码》的译文,之前没有仔细看过,因为发现看过之后对源代码还是不是很明白,所以就没有参照这篇译文进行注释,大多都是自己理解+网上搜索,今天发现很多地方有失误。  
大框的地方一定要参照译文,不要被我蒙蔽了。  
继续注释CPECryptor类,如下:
//在pecrypt.cpp里,我提供了另外一个类――CPECryptor,用它组建新区段的数据。
//然而,新区段的数据是被loader.cpp里的DynLoader()(在DynLoader Step 1中介绍的)创建的。
//因此,我们用CPECryptor类把这些数据(也有其它的数据)输入新区段。
//看完这段翻译基本没懂
const  char *szWindowsAPIs[]=
{
     "Kernel32.dll",
     "GetModuleHandleA",
     "VirtualProtect",
     "GetModuleFileNameA",
     "CreateFileA",
     "GlobalAlloc",
     "VirtualAlloc",
     "LoadLibraryA",
     "GetProcAddress",
    0,
     "User32.dll",
     "MessageBoxA",
    0,
    0,
};
//================================================================
//----------------------------------------------------------------
// Function: ReturnToBytePtr
// void* FuncNum:   Function Name
// DWORD findstr:   String to find
// This code was written by FEUERRADER [AHTeam], Thanks him!
//在loader.cpp文件中的DynLoader函数里寻找指定字符串,并返回其地址
void* CPECryptor::ReturnToBytePtr( void* FuncName, DWORD findstr)
{
     void* tmpd;
     __asm
    {
         mov  eax, FuncName
         jmp df
hjg:     inc  eax
df:         mov  ebx, [ eax]
         cmp  ebx, findstr
         jnz hjg
         mov tmpd,  eax
    }
     return tmpd;
}
//================================================================
//此函数构建新节及导入表----------------------------------------------------------------
void CPECryptor::CryptFile( int( __cdecl *progress) ( unsigned  intunsigned  int))
{
    PCHAR ch_temp;
    PIMAGE_SECTION_HEADER pimage_section_header;
    DWORD dwNewSectionSize;
    DWORD dwCodeSize;
    DWORD dwCodeOffset;
     //进度条控件----------------------------------------
    progress(0,0);
     //是否DLL
     if((image_nt_headers->FileHeader.Characteristics&IMAGE_FILE_DLL)==IMAGE_FILE_DLL)
    {
         //构造CITMaker类
        ImportTableMaker =  new CITMaker(IMPORT_TABLE_OCX);
    }
     else
    {
        ImportTableMaker =  new CITMaker(IMPORT_TABLE_EXE);
    }
     //----------------------------------------
     //========================================
     //ch_temp指向DYN_LOADER_START_MAGIC之后的地址
    ch_temp=(PCHAR)DWORD(ReturnToBytePtr(DynLoader, DYN_LOADER_START_MAGIC))+4;
     //计算DynLoader函数代码长度
    dwCodeSize=DWORD(ReturnToBytePtr(DynLoader, DYN_LOADER_END_MAGIC))-DWORD(ch_temp);
     //自定义导入表大小
    dwCodeOffset = ImportTableMaker->dwSize;
     //新节大小=DynLoader函数代码长度+自定义导入表大小
    dwNewSectionSize = dwCodeSize + ImportTableMaker->dwSize;
     //分配空间
    pNewSection= new TCHAR[dwNewSectionSize];
     //复制DynLoader函数代码到偏移dwCodeOffset的位置之后
    memcpy(pNewSection+dwCodeOffset, ch_temp, dwCodeSize);
     //========================================
     //----------------------------------------
     //添加新节,并返回新节指针
    pimage_section_header=AddNewSection( ".xxx",dwNewSectionSize);
     //----------------------------------------
     //========================================
     //参数为新节在内存的偏移地址
    CopyData1(pimage_section_header->VirtualAddress);
     //参数同上,构建自定义导入表
    ImportTableMaker->Build(pimage_section_header->VirtualAddress); // build import table by the current virtual address
     //构建的导入表在新节数据前,注意相互位置
    memcpy(pNewSection, ImportTableMaker->pMem, ImportTableMaker->dwSize);
     //========================================
     //将新节数据复制到image_section(已经初始化)----------------------------------------
    memcpy(image_section[image_nt_headers->FileHeader.NumberOfSections-1],
           pNewSection,
           dwNewSectionSize);
     //入口地址更改为新节的DynLoader函数代码处
    image_nt_headers->OptionalHeader.AddressOfEntryPoint=pimage_section_header->VirtualAddress + dwCodeOffset;
     //导入表地址更改为新导入表地址
    image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=pimage_section_header->VirtualAddress;
    image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size=ImportTableMaker->dwSize;
    image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress=0;
    image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size=0;
    SetSectionsWritePermission();
     //----------------------------------------
     delete []pNewSection;
     delete ImportTableMaker;
     //----------------------------------------
    progress(100,0);
}
//这个结构对应DynLoader函数里DYN_LOADER_START_DATA1标志后面的东西,具体
//是自定义结构?请高手指点,本人水平到此,分析不出了
//译文:为了找到OEP的virtual address,我们立即保存原始的OEP和Image Base。
//我在DynLoader()的尾部预留了一块空地来保存它们
typedef  struct
{
     //保留
    DWORD dwReserved1;
     //文件类型
    DWORD dwFileType;
     //基地址
    DWORD dwImageBase;
     //原始入口点
    DWORD dwOrgEntryPoint;
     //导入表虚拟地址
    DWORD dwImportVirtualAddress;
     //重定位表虚拟地址及大小
    DWORD dwRelocationVirtualAddress;
    DWORD dwRelocationSize;
     //TLS
    IMAGE_TLS_DIRECTORY32 image_tls_directory;
}t_DATA_1,*pt_DATA_1;
//此函数将实际数据填充到DynLoader函数指定位置里
void CPECryptor::CopyData1(DWORD dwVirtualAddress)
{
     int i, API_num;
    PCHAR pData1;
    DWORD dwOffset;
    size_t l;
    UCHAR temp;
     //为结构分配内存
    pt_DATA_1 pDataTable= new(t_DATA_1);
     //----------------------------------------
     //保留,0xcccccccc应该没有意义
    pDataTable->dwReserved1=0xCCCCCCCC;
     //如果为DLL,填入文件类型
     if((image_nt_headers->FileHeader.Characteristics&IMAGE_FILE_DLL)==IMAGE_FILE_DLL)
        pDataTable->dwFileType=IMPORT_TABLE_OCX;
     else
        pDataTable->dwFileType=IMPORT_TABLE_EXE;
     //填充镜像首地址
    pDataTable->dwImageBase=image_nt_headers->OptionalHeader.ImageBase;
     //填充入口点
    pDataTable->dwOrgEntryPoint=image_nt_headers->OptionalHeader.AddressOfEntryPoint;
     //填充导入表地址(RVA)
    pDataTable->dwImportVirtualAddress=image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
     if((image_nt_headers->FileHeader.Characteristics&IMAGE_FILE_DLL)==IMAGE_FILE_DLL)
    {
         //如果是DLL,填充重定位表
        pDataTable->dwRelocationVirtualAddress=image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
        pDataTable->dwRelocationSize=image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
    }
     //前面已经将DynLoader函数读入我们申请的内存中----------------------------------------
     //故在pNewSection指向的内存中找到DYN_LOADER_START_DATA1标志,返回地址
    pData1=(PCHAR)ReturnToBytePtr(pNewSection, DYN_LOADER_START_DATA1);
     //看了好几个TLS了,是什么?
     //通过使用线程本地储存(TLS),一个程序能够执行多线程程序,
     //这样子的程序大多数是用Borland链接器:Delphi和C++, Builder. 
     //当你包装一个PE文件时,你应该小心的清空TLS,
     //否则,你的打包器就不支持Borland Delphi 和 C++ Builder链接的EXE文件。
     //修正可选头部TLS目录入口是很有必要的。
     if(image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress!=0)
    {
         //image_tls_directory定义在pelib.cpp中
        memcpy(&pDataTable->image_tls_directory,
                image_tls_directory,
                 sizeof(IMAGE_TLS_DIRECTORY32));
        dwOffset=DWORD(pData1)-DWORD(pNewSection);
         //计算偏移
        dwOffset+= sizeof(t_DATA_1)- sizeof(IMAGE_TLS_DIRECTORY32);
         //更新文件头,指向新的TLS表
         //传递的参数在这里应用
        image_nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress=dwVirtualAddress + dwOffset;
    }
     //替换为实际数值----------------------------------------
    memcpy(pData1,pDataTable, sizeof(t_DATA_1));
    dwOffset= sizeof(t_DATA_1);
    i=API_num=0;
    temp=0;
     //循环填充实际数值
     do
    {
        l=strlen(szWindowsAPIs[i])+1;
         //复制动态库名
        memcpy(pData1+dwOffset,szWindowsAPIs[i],l);
         //偏移长度
        dwOffset+=l;
         do
        {
            i++;
             if(szWindowsAPIs[i]!=0)
            {
                 //复制下一个函数名
                l=strlen(szWindowsAPIs[i])+1;
                memcpy(pData1+dwOffset,szWindowsAPIs[i],l);
                dwOffset+=l;
                 //API数量
                API_num++;
            }
             else
            {
                 //放置0
                CopyMemory(pData1+dwOffset,&temp,1);
                dwOffset++;
            }
        } while(szWindowsAPIs[i]!=0);
        i++;
    }
     while(szWindowsAPIs[i]!=0);
     //----------------------------------------
     delete pDataTable;
}
//----------------------------------------------------------------
void CPECryptor::SetSectionsWritePermission()
{
     for( int i=0;i<image_nt_headers->FileHeader.NumberOfSections;i++)
    {
         //设置所有表的标志
        image_section_header[i]->Characteristics=0xC0000040;
    }
}
//----------------------------------------------------------------
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值