《加密与解密》书中的壳,不过为了加深印象还是手写一下
抄代码的时候突然想起了以前见过的一个VS插件,代码高亮,自动完成等功能都相当完美,写起代码来也爽很多。。
壳的流程(写到再更新):
1 把文件各区块按照内存对齐的方式加载到内存
3 转储输入表
源码:
void LoadFile(char *szFileName)
{
HANDLE hFile;
IMAGE_DOS_HEADER dosHeader;
IMAGE_NT_HEADERS ntHeader;
PIMAGE_SECTION_HEADER psecHeader;
long nFileSize;
long nFileAlign;
long nSectionAlign;
long nNTHeaderSize;
int nHeaderSize;
int nSectionNum;
int nIndex;
long nRawDataSize;
long nRawDataOffset;
long nVirtualAddress;
long nVirtualSize;
unsigned long NumberOfBytesRead;
//读取文件信息
hFile=CreateFile(szFileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
//printf("打开文件失败\n");
}
ReadFile(hFile,&dosHeader,sizeof(dosHeader),&NumberOfBytesRead,NULL);
//判断MZ标志
if (dosHeader.e_magic!=0x5A4D)
{
//Not Standard PE File
}
SetFilePointer(hFile,dosHeader.e_lfanew,NULL,FILE_BEGIN);
ReadFile(hFile,&ntHeader,sizeof(ntHeader),&NumberOfBytesRead,NULL);
//判断PE标志
if (ntHeader.Signature!=0x4550)
{
//Not Standard PE File
}
nFileSize=GetFileSize(hFile,NULL);
nSectionNum=ntHeader.FileHeader.NumberOfSections;
m_nImageSize=ntHeader.OptionalHeader.SizeOfImage;
nFileAlign=ntHeader.OptionalHeader.FileAlignment;
nSectionAlign=ntHeader.OptionalHeader.SectionAlignment;
nHeaderSize=ntHeader.OptionalHeader.SizeOfHeaders; //这是从开头一直包括到区块表的大小
m_nImageSize=Align_Size(m_nImageSize,nSectionAlign);
m_pImageBase=(char*)malloc(m_nImageSize);
memset(m_pImageBase,0,m_nImageSize);
SetFilePointer(hFile,0,NULL,FILE_BEGIN);
ReadFile(hFile,m_pImageBase,nHeaderSize,&NumberOfBytesRead,NULL);
m_pntHeaders=(PIMAGE_NT_HEADERS)((DWORD)m_pImageBase+dosHeader.e_lfanew);
nNTHeaderSize=sizeof(ntHeader.Signature)+sizeof(ntHeader.FileHeader)+ntHeader.FileHeader.SizeOfOptionalHeader; //由于数据目录个数不一定所以需要自己计算
m_psecHeaders=(PIMAGE_SECTION_HEADER)((DWORD)m_pntHeaders+nNTHeaderSize);
//把各个节的数据复制到对应位置
for(nIndex=0,psecHeader=m_psecHeaders;nIndex<nSectionNum;++nIndex,++psecHeader)
{
nRawDataSize=psecHeader->SizeOfRawData;
nRawDataOffset=psecHeader->PointerToRawData;
nVirtualAddress=psecHeader->VirtualAddress;
nVirtualSize=psecHeader->Misc.VirtualSize;
SetFilePointer(hFile,nRawDataOffset,NULL,FILE_BEGIN);
ReadFile(hFile,&m_pImageBase[nVirtualAddress],nRawDataSize,&NumberOfBytesRead,NULL);
}
//此时指向最后一个节,顺便保存下附加数据
SaveExtraData(hFile,psecHeader,nFileSize);
}
long Align_Size(long nImageSize,long nSectionAlign)
{
return (nImageSize+nSectionAlign-1) / nSectionAlign * nSectionAlign;
}
void SaveExtraData(HANDLE hFile,PIMAGE_SECTION_HEADER pLastSectionHead,long nFileSize)
{
long nExtraDataSize=nFileSize-(pLastSectionHead->PointerToRawData+pLastSectionHead->SizeOfRawData);
unsigned long NumberOfBytesRead;
if (nExtraDataSize>0)
{
pExtraData=new char[nExtraDataSize];
memset(pExtraData,0,nExtraDataSize);
ReadFile(hFile,pExtraData,nExtraDataSize,&NumberOfBytesRead,NULL);
}
else
{
//no extra data
}
}
PCHAR RVAToPtr(DWORD dwRva)
{
if ((UINT)dwRva<m_nImageSize)
{
return PCHAR(dwRva+(DWORD)m_pImageBase);
}
else
{
return NULL;
}
}
UINT AddressImportTable(PCHAR m_pImportTable)
{
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor=NULL,pDescriptor=NULL;
PIMAGE_DATA_DIRECTORY pImportDir=NULL;
UINT nSize=0;
PCHAR pData=NULL;
PCHAR pFuncNum=0;
PCHAR pszDllName;
PIMAGE_THUNK_DATA32 pFirstThunk=NULL;
PIMAGE_IMPORT_BY_NAME pImportName=NULL;
pImportDir=&m_pntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
pImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)RVAToPtr(pImportDir->VirtualAddress);
//移动输入表
for(pData=m_pImportTable,pDescriptor=pImportDescriptor;pDescriptor->Name!=0;pDescriptor++)
{
//保存FirstThunk
*(DWORD*)pData=pDescriptor->FirstThunk;
pData=pData+sizeof(DWORD);
pszDllName=(PCHAR)RVAToPtr(pDescriptor->Name);
//保存dll名长度
*(BYTE*)(pData)=(BYTE)(strlen(pszDllName));
pData=pData+sizeof(BYTE);
//保存dll名
memcpy(pData,pszDllName,strlen(pszDllName+1));
pData=pData+strlen(pszDllName)+1;
//保存函数个数记录变量
pFuncNum=pData;
*(BYTE*)pFuncNum=0;
pData=pData+sizeof(DWORD);
if (pDescriptor->OriginalFirstThunk!=0)
{
pFirstThunk=(PIMAGE_THUNK_DATA32)RVAToPtr(pDescriptor->OriginalFirstThunk);
}
else
{
pFirstThunk=(PIMAGE_THUNK_DATA32)RVAToPtr(pDescriptor->FirstThunk);
}
while(pFirstThunk->u1.AddressOfData!=NULL)
{
if (IMAGE_SNAP_BY_ORDINAL32(pFirstThunk->u1.Ordinal))
{
//序号导入
*(BYTE*)pData=0;
pData=pData+sizeof(BYTE);
*(DWORD*)pData=(DWORD)pFirstThunk->u1.Ordinal & 0x7FFFFFFF;
pData=pData+sizeof(DWORD)+1;
(*(DWORD*)pFuncNum)++;
}
else
{
//字符串导入
pImportName=(PIMAGE_IMPORT_BY_NAME)RVAToPtr((DWORD)pFirstThunk->u1.AddressOfData);
*(BYTE*)pData=(BYTE)(strlen((char*)pImportName->Name));
(*(DWORD*)pFuncNum)++;
pData=pData+(strlen((char*)pImportName->Name))+1;
}
pFirstThunk++;
}
}
*(DWORD*)pData=(DWORD)0;
pData=pData+sizeof(DWORD);
return (pData-m_pImportTable);
}