在32位PE文件中的任意一个节中添加代码

// SectionOp.cpp : 定义控制台应用程序的入口点。

//

/************************************************

*程序说明:在32位PE文件中的任意一个节中添加代码

*          第一个参数为PE文件 第二个参数为第N个节

*

* 时间: 20170718

* Win10 VS2010 测试通过  ver 0.01

**************************************************/

#include "stdafx.h"

unsigned char DEMOCODE[] = {0X6A,0X00,0X6A,0X00,0X6A,0X00,0X6A,0X00,0XE8,0X00,0X00,0X00,0X00,0XE9,0X00,0X00,0X00,0X00};

int _tmain(int argc, _TCHAR* argv[])

{
     unsigned char* FileBuff;
     errno_t err;
     _TCHAR NewFile[1024] = L"New_";

if(argc >1)
     {
         FileBuff = FileBuffer(argv[1]);
     }
     else
     {
         printf("No PE File\n");
         return 1;
     }
     int NumOfSection = 1;
     if (argc >2 )
     {
         size_t i;
         size_t num = wcslen(argv[2]);
         char* pMBBuffer = (char*)malloc(num*2);
         wcstombs_s(&i,pMBBuffer,num*2,argv[2],num);
         NumOfSection = atoi(pMBBuffer);

if(NumOfSection < 1)
             NumOfSection = 1;
     }
    
     if(AddCodeAtSection(FileBuff,NumOfSection,DEMOCODE,sizeof(DEMOCODE)) != 0)
     {
         free(FileBuff);
         return -1;
     }
    
     err = wcscat_s(NewFile,argv[1]);
     if(err != 0)
     {
         return -1;
     }

SaveFile(FileBuff,NewFile);
     free(FileBuff);
     return 0;

}

==================================================================

////功能文件

#include "stdafx.h"

#define FUN_AD 0x7497D330 //修改成本机的MessageBoxW的地址

/*********************************************

在任意节添加代码

输入:FileBuffer NoOfSection  Code CodeSize

输出:添加了Code的FileBuffer,运行程序时,先运行Code再转到原来的程序入口

实现步聚:    (假定FileBuffer 为Pe格式)

1、NoOfSection 数量不要超过 节数量

2、相应节的文件对齐空间要足够代码Code存放

3、找到程序的OEP

3、计算IMAGEBUFF和FILEBUFF之间节的位置转化关系

4、算出JMP <原OEP> CALL〈MessageBoxW〉把位置填入Code中

5、找到节的空白起始区域,存放Code

6、将OEP的值改成Code的RV

**************************************************/

//unsigned char CODE[] = {0X6A,0X00,0X6A,0X00,0X6A,0X00,0X6A,0X00,0XE8,0X00,0X00,0X00,0X00,0XE9,0X00,0X00,0X00,0X00};

int AddCodeAtSection(unsigned char* FileBuffer,int NoOfSection,unsigned char* Code,int CodeSize)

{
     PIMAGE_DOS_HEADER pDosHeader;
     PIMAGE_NT_HEADERS32 pNt32Header;
     PIMAGE_SECTION_HEADER pSectionHeader;

//1、NoOfSection 数量不要超过 节数量    
     pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
     pNt32Header = (PIMAGE_NT_HEADERS32)(FileBuffer+pDosHeader->e_lfanew);
     if(int(pNt32Header->FileHeader.NumberOfSections) < NoOfSection)
     {
         printf("NoOfSection Bigger NumberOfSections\n");
         return -1;
     }

//2、相应节的文件对齐空间要足够代码Code存放   
     //unsigned int CodeSize = sizeof(Code);
     //printf("CodeSize %d\n",CodeSize);
     pSectionHeader =(PIMAGE_SECTION_HEADER)(pNt32Header+1);
     pSectionHeader = pSectionHeader +(NoOfSection-1);
     if(CodeSize > int(pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize))
     {
         printf("No space to write Code\n");
         return -2;
     }

//3、找到程序的OEP           
     int OEP = pNt32Header->OptionalHeader.AddressOfEntryPoint;

//3、计算IMAGEBUFF和FILEBUFF之间节的位置转化关系       
    
     long InsImageRV = pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;
     long InsPostionRV = pSectionHeader->PointerToRawData + pSectionHeader->Misc.VirtualSize;
     long ImageBase = pNt32Header->OptionalHeader.ImageBase;

//4、算出JMP <原OEP> CALL〈MessageBoxW〉把位置填入Code中 X = 真实要跳的地址-下一条指令地址

// YY = ImageBase+OEP - Imagebase+NEXT_Y

// XX = [email protected] - ImageBase+NEXT_X
     int* YY = (int*)(Code+JMP_Y);
     int* XX = (int*)(Code+CALL_X);
     *YY = (ImageBase+OEP)-(ImageBase+InsImageRV+NEXT_Y);
     *XX = FUN_AD - (ImageBase+InsImageRV+NEXT_X);

//5、找到节的空白起始区域,存放Code
     unsigned char* InsCode = FileBuffer+InsPostionRV;
     unsigned int x  = 0;
     for (;x<CodeSize;x++)
     {
         InsCode[x] = Code[x];   
     }

//6、将OEP的值改成Code的RV
     pNt32Header->OptionalHeader.AddressOfEntryPoint = pSectionHeader->Misc.VirtualSize + pSectionHeader->VirtualAddress;

return 0;

}

///////////////////////////////////////////////////////////

//将PE文件读到FileBuffer

unsigned char* FileBuffer(const _TCHAR* FileName)

{
     unsigned char* Heap = NULL;
     FILE* Stream;
     errno_t err;
     //打开文件
     err = _wfopen_s(&Stream,FileName,L"rb");
     if(err != 0)
     {
         perror("Open File Error:");
         return NULL;
     }
     //计算文件大小
     fseek(Stream,0L,SEEK_END);
     long FileSize = ftell(Stream);
     fseek(Stream,0L,SEEK_SET);
     //分配堆空间
     Heap = (unsigned char*)malloc(sizeof(char)*FileSize);
     //将文件拷到堆
     fread(Heap,sizeof(char),FileSize,Stream);
     fclose(Stream);

return Heap;

}

//////////////////////////////////////////

//将FileBuffer 保存成文件

int SaveFile(unsigned char* FileBuffer,const _TCHAR* FileName)

{
     FILE* Stream;
     errno_t err;

err = _wfopen_s(&Stream,FileName,L"wb");
     if(err != 0)
     {
         perror("File Create Error:");
         return -1;
     }

//计算FileBuff大小
     PIMAGE_DOS_HEADER pDosHeader;
     PIMAGE_NT_HEADERS32 pNt32Header;
     PIMAGE_SECTION_HEADER pSecHeader;
     pDosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
     pNt32Header = (PIMAGE_NT_HEADERS32)(FileBuffer + pDosHeader->e_lfanew);
     pSecHeader = (PIMAGE_SECTION_HEADER)(pNt32Header+1);
    
     long FileSize = pNt32Header->OptionalHeader.SizeOfHeaders;
     int NumOfSec = pNt32Header->FileHeader.NumberOfSections;
     int x;
     for(x=0;x<NumOfSec;x++)
     {
         FileSize += pSecHeader->SizeOfRawData;
         pSecHeader++;
     }

// 写入文件
     fwrite(FileBuffer,sizeof(char),FileSize,Stream);
     fclose(Stream);
     return 0;

}

========================================================

// stdafx.h : 标准系统包含文件的包含文件,

// 或是经常使用但不常更改的

// 特定于项目的包含文件

//

#pragma once

#include "targetver.h"

#include <stdio.h>

#include <tchar.h>

#include <stdlib.h>

#include <Windows.h>

#include <WinNT.h>

#include <assert.h>

// TODO: 在此处引用程序需要的其他头文件

int AddCodeAtSection(unsigned char* FileBuffer,int NoOfSection,unsigned char* Code,int CodeSize);

unsigned char* FileBuffer(const _TCHAR* FileName);

int SaveFile(unsigned char* FileBuffer,const _TCHAR* FileName);

#ifndef _DEMO_CODE

#define _DEMO_CODE

#define CALL_X 9         //填写X的超始地址

#define JMP_Y  14        //填写Y的超始地址

#define NEXT_X 13        //X的下一条指令的地址

#define NEXT_Y 18        //Y的下一条指令的地址

#endif

时间: 2024-08-05 11:14:56

在32位PE文件中的任意一个节中添加代码的相关文章

32位PE文件信息查看器(WIN32控制台)

最近重新撸了一遍PE文件的文件格式,这个程序算是复习的产物吧. 说明与警告: 1.只适用于32位PE文件,可以读取符合标准的32位PE文件的DOS头.NT头.节区头.导入表.导出表信息,想要其他功能请在PEFile类中找,没有请留言 2.因为是边复习功能边写的,所以不要纠结程序架构.编码风格.鲁棒性等各种问题,我会再改的 3.翻译可能是不准的,仅供参考 4.所有计数从0开始,程序不对是否越界进行检查 5.转载请注明出处,本人不对引用此源码后程序产生的任何问题负责 单独的PEFile类 class

64位系统下注册32位dll文件

64位系统下注册32位dll文件 在64位系统里注册32位软件所需的一些dll会提示不兼容,大概因为32 位进程不能加载64位Dll,64位进程也不可以加载32的导致. 若要支持的32 位和64 位COM 注册和程序共存状态,需要WOW64 子系统. 故可以把这些32的dll.ax从C:\Windows\system32\复制到C:\Windows\sysWOW64\下注册即可. 如:regsvr32 C:\Windows\sysWOW64\MakerCom.dll 原文地址:https://w

C语言学习_C如何在一个文件里调用另一个源文件中的函数

问题 C如何在一个文件里调用另一个源文件中的函数,如题. 解决办法 当程序大了代码多了之后,想模块化开发,不同文件中存一点,是很好的解决办法,那我们如何做才能让各个文件中的代码协同工作呢?我们知道,main函数是程序入口,我们希望把不同的功能写在不同的函数中,并把这些函数统一放到另外一个文件里,以便main函数显得太长,main函数可以在用到某方法的时候调用来处理.为了实现这个步骤,我们这样做.首先定义一个c代码的头文件,如function.h,在里面声明将要实现的函数,如int add(int

[转载]android工程中引入另一个工程中的资源

原文地址:android工程中引入另一个工程中的资源作者:87fayuan 在项目中可能遇到这样的问题:项目过大,于是细分为N个子模块来做,每个模块都是不同的工程.涉及到activity传数据时,可以用intent等方法来解决.但是如果涉及到要共用资源,而又不能像传统java程序那样打成jar包,比如程序中有大量自定义view,而这些自定义view都引用了的一些资源文件时,就可以用这个方法. 工程一:MyViews 代码如下: public class MyTextView extends Te

32位Linux文件限制大小

线上程序不断重新启动,查看log发现是进程由于SIGXFSZ信号退出.对过大的文件进行操作的时候会产生此信号,一般仅仅在32位机器上出现,文件限制大小为2G.用lsof查看进程打开的文件,果然有一个文件达到2G. 解决方式:编译时加上參数:-D_FILE_OFFSET_BITS=64:代码中调用lseek时參数为off_t(不要为int或long,否则在32位和64位中表现不同). 附上一个链接,linux大文件支持:http://users.suse.com/~aj/linux_lfs.htm

win7旗舰版 32位 esd文件 590.2M

win7旗舰版 32位 链接: http://pan.baidu.com/s/1nvjJ3vF 密码: 1svg

在PE中,新增节,添加代码

一.先判断节表后是否有空闲位置,添加节表信息,必须多出两个节表位置,最后以零结尾. 二.新增节后,需要修改以下信息 1.添加一个新节,可以复制一份,最好是拥有可执行属性的节,如.text. 2.在节表区,新增节的后面,填充一个节,用零填充. 3.修改标准PE头中节的数量. 4.修改SizeOfImage的大小. 5.在原有数据的后面,新增一个节的数据(内存对齐的整倍数). 6.修正新增节表的属性. 三.新节各个属性修改说明 1.Name:名字随便修改,不能超过八个字节. 2.VirtualSiz

怎样在一个fragment or 随意类中操作还有一个fragment中的方法

1 怎样在acitivty中运行fragment中的方法: 首先获得这个Fragment的对象 xxxFragment fragmentObject = (xxxFragment) getFragmentManager.findFragmentByTag("xx"); 2 怎样在Fragment中运行activity中的方法: 第一种:让acitivity继承接口 另外一种:在fragment中使用getActivity()可是要加上acitivity的名字,即: ((MainActi

从一个字符串中删除另一个字符串中出现过的字符

定义一个函数,输入两个字符串,从第一个字符串中删除在第二个中出现过的所偶字符串.例如从第一个字符串"We are students."中删除第二个字符中"auiou"中出现过的字符得到的结果是"W r stdnts" 解题思路:利用哈希查找. #include <stdio.h> void deleteStr2FromStr1(char* str1, char* str2) { if(str1 == NULL || str2 == N