文件头
// globlepdd.h: interface for the globlepdd class.
//
//
#if !defined(AFX_GLOBLEPDD_H__DDA6AB97_A94D_41F9_B3B9_8426B6CB7934__INCLUDED_)
#define AFX_GLOBLEPDD_H__DDA6AB97_A94D_41F9_B3B9_8426B6CB7934__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <windows.h>
#include <stdio.h>
//#define FILEPATH_IN "C:\\WINDOWS\\system32\\kernel32.dll"
//#define FilePath_In "C:\\cntflx\\notepad.exe"
#define FilePath_In "C:\\cntflx\\ipmsg.exe"
//#define FilePath_Out "C:\\cntflx\\notepadnewpes.exe"
#define FilePath_Out "C:\\cntflx\\ipmsgnewpeaddcodes.exe"
#define MESSAGEBOXADDR 0x77D5050B
#define SHELLCODELENGTH 0x12 //16进制的,转换为十进制就是18
extern BYTE ShellCode[];
DWORD ReadPEFile(IN LPSTR lpszFile,OUT LPVOID* pFileBuffer);
DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer,OUT LPVOID* pImageBuffer);
DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer);
BOOL MemeryTOFile(IN LPVOID pMemBuffer,IN size_t size,OUT LPSTR lpszFile);
//DWORD RvaToFileOffset(IN LPVOID pFileBuffer,IN DWORD dwRva);
VOID AddCodeInCodeSec();
#endif // !defined(AFX_GLOBLEPDD_H__DDA6AB97_A94D_41F9_B3B9_8426B6CB7934__INCLUDED_)
核心代码部分
// globlepdd.cpp: implementation of the globlepdd class.
//
//
#include "stdafx.h"
#include "globlepdd.h"
#include <string.h>
#include <windows.h>
#include <stdlib.h>
//
// Construction/Destruction
//
//定义一个全局变量
BYTE ShellCode[] =
{
0x6A,00,0x6A,00,0x6A,00,0x6A,00, //MessageBox push 0的硬编码
0xE8,00,00,00,00, // call汇编指令E8和后面待填充的硬编码
0xE9,00,00,00,00 // jmp汇编指令E9和后面待填充的硬编码
};
//ExeFile->FileBuffer 返回值为计算所得文件大小
DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer)
{
//下面有个IN和OUT,大致意思就是参数的类型传入进来之后不进行宏扩展;
//啥也不干,即使理解成干,也是扩展成空白,这个是C++语法中允许的;
//LPSTR ----> typedef CHAR *LPSTR, *PSTR; 意思就是char* 指针;在WINNT.H头文件里面
FILE* pFile = NULL;
//定义一个FILE结构体指针,在标准的Stdio.h文件头里面
//可参考:https://blog.csdn.net/qq_15821725/article/details/78929344
DWORD fileSize = 0;
// typedef unsigned long DWORD; DWORD是无符号4个字节的整型
LPVOID pTempFileBuffer = NULL;
//LPVOID ----> typedef void far *LPVOID;在WINDEF.H头文件里面;别名的void指针类型
//打开文件
pFile = fopen(lpszFile,"rb"); //lpszFile是当作参数传递进来
if (!pFile)
{
printf("打开文件失败!\r\n");
return 0;
}
/*
关于在指针类型中进行判断的操作,下面代码出现的情况和此一样,这里解释下:
1.因为指针判断都要跟NULL比较,相当于0,假值,其余都是真值
2.if(!pFile)和if(pFile == NULL), ----> 为空,就执行语句;这里是两个等于号不是一个等于号
3.if(pFile)就是if(pFile != NULL), 不为空,就执行语句;
*/
//读取文件内容后,获取文件的大小
fseek(pFile,0,SEEK_END);
fileSize = ftell(pFile);
fseek(pFile,0,SEEK_SET);
/*
fseek 通过使用二进制的方式打开文件,移动文件读写指针的位置,在stdio.h头文件里
int fseek(FILE * stream, long offset, int fromwhere);
上面是fseek的函数原型
第一个参数stream 为文件指针
第二个参数offset 为偏移量,整数表示正向偏移,负数表示负向偏移
第三个参数fromwhere 为指针的起始位置,设定从文件的哪里开始偏移,可能取值为:SEEK_CUR,SEEK_END,SEEK_SET
SEEK_SET 0 文件开头
SEEK_CUR 1 当前读写的位置
SEEK_END 2 文件尾部
下面是相关用法和例子:
fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,100L,2);把fp指针退回到离文件结尾100字节处。
fseek(fp,0,SEEK_SET);将读写位置移动到文件开头;
fseek(fp,0,SEEK_END);将读写位置移动到文件尾时;
fseek(fp,100L,SEEK_SET);将读写位置移动到离文件开头100字节处;
fseek(fp,100L,SEEK_CUR);将读写位置移动到离文件当前位置100字节处;
fseek(fp,-100L,SEEK_END);将读写指针退回到离文件结尾100字节处;
fseek(fp,1234L,SEEK_CUR);把读写位置从当前位置向后移动1234字节;
fseek(fp,0L,2);把读写位置移动到文件尾;
其中 ---> L后缀表示长整数
ftell()用于返回文件当前指针指向的位置,与fseek配合可以算出文件元素数据总数。
参考:http://c.biancheng.net/cpp/html/2519.html
ftell()函数用来获取文件读写指针的当前位置,其原型为:long ftell(FILE * stream); 同样在stdio.h头文件里
参数:stream 为已打开的文件指针。
*/
//动态申请内存空间
pTempFileBuffer = malloc(fileSize);
/*
参考:http://c.biancheng.net/cpp/html/137.html
原型:void* malloc (size_t size);
size_t ---> typedef unsigned int size_t; 无符号整型别名是size_t
void* ---> 函数的返回值类型是 void* ;void并不是说没有返回值或者返回空指针,而是返回的指针类型未知;
所以在使用 malloc() 时通常需要进行强制类型转换,将 void 指针转换成我们希望的类型;
例如:char *ptr = (char *)malloc(10); //分配10个字节的内存空间,用来存放字符
参数说明 ---> size 为需要分配的内存空间的大小,以字节(Byte)计。
函数说明 ---> malloc()在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化;
它们的值是未知的,所以分配完成内存之后需要初始化;
返回值:分配成功返回指向该内存的地址,失败则返回 NULL。
*/
if (!pTempFileBuffer)
{
printf("内存分配失败!\r\n");
fclose(pFile);