十六、2008年04月10日
作者:青青子衿
email:anzijin@sina.com
1、CPolymorph 类
//推测该类的目标是实现bot对正常可执行程序的感染
class CPolymorph
{
public:
CPolymorph();
CPolymorph(const char *szFile);
~CPolymorph();
bool MapFile(const char *szFile, char **szBuffer);
void UnmapFile(char **szBuffer);
bool DoPolymorph(const char *szFile);
};
2、CPolymorph() 构造函数
//
//
//函数功能:构造函数
//参数: 无
//
//
CPolymorph::CPolymorph()
{
DoPolymorph("c://winnt//system32//notepad.exe");
}
3、CPolymorph::CPolymorph(const char *szFile) 构造函数
/
//
//函数功能:构造函数
//参数: const char *szFile 文件路径
//
//
CPolymorph::CPolymorph(const char *szFile)
{
DoPolymorph(szFile);
}
4、CPolymorph::~CPolymorph() 析构函数,无任何操作
/
//
//函数功能:析构函数
//
/
CPolymorph::~CPolymorph()
{
}
5、:MapFile(const char *szFile, char **szBuffer) 函数
//
//
//函数功能:根据文件的路径,读取文件的内容
//参数: const char *szFile 文件的路径
// char **szBuffer 保存文件内容的指针,注意该变量的类型
//返回值: 如果调用成功返回true,否则返回false
//
//
bool CPolymorph::MapFile(const char *szFile, char **szBuffer)
{
FILE *fp=fopen(szFile, "rb");
if(!fp)
{
return false;
}
//获得文件长度
fseek(fp, 0, SEEK_END);
int iFileSize=(int)ftell(fp);
fseek(fp, 0, SEEK_SET);
*szBuffer=(char*)malloc(iFileSize); //根据文件的长度,申请相应长度的空间
if(!*szBuffer)
{
fclose(fp); return false;
}
if(fread(*szBuffer, sizeof(char), iFileSize, fp)<iFileSize) //读取文件内容,如果实际读取长度小于真实长度,函数返回
{
fclose(fp);
return false;
}
fclose(fp);
return true;
}
6、:UnmapFile(char **szBuffer) 函数
///
//
//函数功能:释放保存文件内容的空间
//参数: char **szBuffer 保存文件内容buffer的指针变量
//
//
///
void CPolymorph::UnmapFile(char **szBuffer)
{
free(*szBuffer);
}
7、DoPolymorph(const char *szFile) 函数
/
//
//函数功能:从代码上推测,应该是实现Bot感染正常文件的功能,
// 但并没有完全实现,只是对目标可执行文件的PE结构
// 进行了解析。
//参数: const char *szFile 被感染的目标可执行程序的路径
//返回值: 调用正确返回true,否则返回false
//
bool CPolymorph::DoPolymorph(const char *szFile)
{
char *szBuffer;
if(!MapFile(szFile, &szBuffer)) //打开文件
{
return false;
}
//对可执行文件中的PE结构进行解析
IMAGE_DOS_HEADER *iDosHeader=(IMAGE_DOS_HEADER*)szBuffer;
if(iDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) //判断是否有MZ标识,判断是否是可执行文件
{
UnmapFile(&szBuffer); return false;
}
char *pTemp=(char*)iDosHeader+iDosHeader->e_lfanew;
DWORD *dwSignature=(DWORD*)pTemp;
pTemp+=sizeof(DWORD);
IMAGE_FILE_HEADER *iFileHead=(IMAGE_FILE_HEADER*)pTemp;
pTemp+=sizeof(IMAGE_FILE_HEADER);
IMAGE_OPTIONAL_HEADER *iOptHead=(IMAGE_OPTIONAL_HEADER*)pTemp;
pTemp+=sizeof(IMAGE_OPTIONAL_HEADER);
IMAGE_SECTION_HEADER *iSectHead=(IMAGE_SECTION_HEADER*)pTemp;
if(*dwSignature!=IMAGE_NT_SIGNATURE) //判断是否有PE标识符
{
UnmapFile(&szBuffer);
return false;
}
int iSection;
IMAGE_SECTION_HEADER *iSectPtr; //对PE头的各段的信息进行解析
for(iSection=0, iSectPtr=iSectHead; iSection<iFileHead->NumberOfSections; iSection++, iSectPtr++)
{
if(iSectPtr->Characteristics&IMAGE_SCN_CNT_CODE) //寻找代码段
{
// Code section :P
char *szBuf=(char*)malloc(iSectPtr->SizeOfRawData);
memcpy(szBuf, (char*)szBuffer+iSectPtr->PointerToRawData, iSectPtr->SizeOfRawData);
MessageBox(NULL, "Bla", "Debug", MB_OK);//从这里开始,真正的功能似乎还没有实现
free(szBuf);
}
}
UnmapFile(&szBuffer); return true;
}