-
-
[原创]菜鸟注释PEMaker6源代码(三)
-
发表于: 2007-9-19 00:09 5867
-
今天大概看了一下精华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 int, unsigned 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;
}
}
//----------------------------------------------------------------
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!
赞赏
- 出售二手驱动、内核、漏洞、加密解密等编程书籍 4382
- [原创]python获取QQ空间前100篇blog的地址和标题的方法 8251
- [求助]翻译求助 4936
- [原创]对PeCompact 2.x--IAT加密壳详解 6944
- [原创]简单的堆栈平衡原理脚本 5176