作业:
几个很重要的注意事项。
1 我们模拟的是内核如何将一个文件硬盘中拉伸到内存中,但是我们做的仅仅是
模拟拉伸过程。也就是说其中的属性字段是无差别的拷贝的。
但是加载exe的时候 ,imagebase 是随机分配的。
我们打开内存中的exe, imagebase就很有可能发生变化。
所以我们需要文件到内存中,将属性字段更改。
PFILEHEADER->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED
在PE文件硬盘中属性 -> 固定动态基址的那个二进制位。
不用详细了解也可以,反正知道修改上面那个属性就可以了。
2 重新开机的时候 弹窗地址也是会发生变化,需要改。
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stddef.h>
#include<Windows.h>
#define FILEPATH_IN "c:\\oep.exe" //自己改路径
#define FILEPATH_OUT "c:\\newoep11111.exe" //自己改路径
#define SHELLCODELENGTH 0X12
#define MESSAGEBOX 0X773fadc0 //每次开机需要重新设置
int READPEFILE_(char * filepath, char ** pfilebuffer );
int FILEBUFFERTOIMAGBBUFFER_(char * pfilebuffer , char ** imagebuffer );
int IMAGEBUFFERTONEWBUFFER_(char* imagebuffer, char** newbuffer);
int MESSAGEBOXIN_(char * pbuffer );
//展示PE信息
int PEIMFORMATION_(char* pfilebuffer);
int WRITEPEFILE_(char* pfilepath, char* pfilebuffer, int filesize);
int FREEBUFFER_(char* pfilebuffer);
#include"header.h"
char ShellCode[SHELLCODELENGTH] =
{
0x6a,0x00,0x6a,0x00,0x6a,0x00,0x6a,0x00,
0xe8,0x00 ,0x00,0x00,0x00,
0xe9,0x00,0x00,0x00,0x00
};
int READPEFILE_(char* filepath, char ** pfilebuffer )
{
FILE* PFILE = NULL;
PFILE = fopen(filepath, "rb");
if (!PFILE)
{
printf("读取失败\n");
return 0;
}
fseek(PFILE , 0, SEEK_END );
int FILESIZE = ftell(PFILE);
fseek(PFILE, 0, SEEK_SET);
char* PFILETEMPBUFFER = (char * )malloc(sizeof(char) * FILESIZE);
if (!PFILETEMPBUFFER)
{
free(PFILETEMPBUFFER);
PFILETEMPBUFFER = NULL;
fclose(PFILE);
return 0;
}
memset(PFILETEMPBUFFER, 0, sizeof(char) * FILESIZE );
size_t n = fread(PFILETEMPBUFFER, FILESIZE ,1 ,PFILE);
if (!n )
{
free(PFILETEMPBUFFER);
PFILETEMPBUFFER = NULL;
fclose(PFILE);
return 0;
}
*pfilebuffer = PFILETEMPBUFFER;
PFILETEMPBUFFER = NULL;
fclose(PFILE);
return FILESIZE;
}
int FILEBUFFERTOIMAGBBUFFER_(char* pfilebuffer, char** imagebuffer)
{
if (!pfilebuffer)
{
MessageBox(0, TEXT("缓冲区不存在"), 0, 0);
return 0;
}
if (*(short*)(pfilebuffer) != 0X5A4D)
{
MessageBox(0, TEXT("不是一个mz文件标志"), 0, 0);
return 0;
}
PIMAGE_DOS_HEADER PDOSHEADER = (PIMAGE_DOS_HEADER)pfilebuffer;
if (*(PDWORD)((char*)pfilebuffer + PDOSHEADER->e_lfanew) != IMAGE_NT_SIGNATURE)
{
MessageBox(0, TEXT("不是一个NT标记"), 0, 0);
return 0;
}
PIMAGE_NT_HEADERS PNTHEADER = (PIMAGE_NT_HEADERS)((char*)pfilebuffer + PDOSHEADER->e_lfanew);
PIMAGE_FILE_HEADER PFILEHEADER = (PIMAGE_FILE_HEADER)(((char*)PNTHEADER) + 0X4);
PIMAGE_OPTIONAL_HEADER POPTIONHEADER = (PIMAGE_OPTIONAL_HEADER)((char*)PFILEHEADER + 0x14);
PIMAGE_SECTION_HEADER PSECTIONHEADER = (PIMAGE_SECTION_HEADER)((char*)POPTIONHEADER + PFILEHEADER->SizeOfOptionalHeader);
//固定动态基址
PFILEHEADER->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
char* PIMAGETEMPBUFFER = malloc(sizeof(char) * POPTIONHEADER->SizeOfImage);
if (!PIMAGETEMPBUFFER)
{
return 0;
}
memset(PIMAGETEMPBUFFER , 0, sizeof(char )* POPTIONHEADER->SizeOfImage);
memcpy( (void *)PIMAGETEMPBUFFER , PDOSHEADER, POPTIONHEADER->SizeOfHeaders);
PIMAGE_SECTION_HEADER PTEMPSECTION = (PIMAGE_SECTION_HEADER)PSECTIONHEADER;
for (int i = 0; i < PFILEHEADER->NumberOfSections; i++)
{
memcpy
(
(void *) ( (char *)PIMAGETEMPBUFFER + PTEMPSECTION[i].VirtualAddress),
(void * ) ((char *)PDOSHEADER + PTEMPSECTION[i].PointerToRawData),
PTEMPSECTION[i].SizeOfRawData
);
}
*imagebuffer = PIMAGETEMPBUFFER;
PIMAGETEMPBUFFER = NULL;
return POPTIONHEADER->SizeOfImage;
}
int IMAGEBUFFERTONEWBUFFER_(char* pimagebuffer, char** newbuffer)
{
if (!pimagebuffer)
{
MessageBox(0, TEXT("缓冲区不存在"), 0, 0);
return 0;
}
if (*(short*)(pimagebuffer) != 0X5A4D)
{
MessageBox(0, TEXT("不是一个mz文件标志"), 0, 0);
return 0;
}
PIMAGE_DOS_HEADER PDOSHEADER = (PIMAGE_DOS_HEADER)pimagebuffer;
if (*(PDWORD)((char*)pimagebuffer + PDOSHEADER->e_lfanew) != IMAGE_NT_SIGNATURE)
{
MessageBox(0, TEXT("不是一个NT标记"), 0, 0);
return 0;
}
PIMAGE_NT_HEADERS PNTHEADER = (PIMAGE_NT_HEADERS)((char*)pimagebuffer + PDOSHEADER->e_lfanew);
PIMAGE_FILE_HEADER PFILEHEADER = (PIMAGE_FILE_HEADER)(((char*)PNTHEADER) + 0X4);
PIMAGE_OPTIONAL_HEADER POPTIONHEADER = (PIMAGE_OPTIONAL_HEADER)((char*)PFILEHEADER + 0x14);
PIMAGE_SECTION_HEADER PSECTIONHEADER = (PIMAGE_SECTION_HEADER)((char*)POPTIONHEADER + PFILEHEADER->SizeOfOptionalHeader);
char* PTEMPNEWBUFFER = malloc(sizeof(char) * POPTIONHEADER->SizeOfImage);
if (!PTEMPNEWBUFFER)
{
return 0;
}
memset(PTEMPNEWBUFFER , 0, sizeof(char ) * POPTIONHEADER->SizeOfImage) ;
memcpy((void *)PTEMPNEWBUFFER , PDOSHEADER, POPTIONHEADER->SizeOfHeaders);
PIMAGE_SECTION_HEADER PTEMPSECTION = (PIMAGE_SECTION_HEADER)PSECTIONHEADER;
for (int i = 0; i < PFILEHEADER->NumberOfSections; i++)
{
memcpy
(
(void * ) ( (char *)PTEMPNEWBUFFER + PTEMPSECTION[i].PointerToRawData ) ,
(void * )((char *)pimagebuffer + PTEMPSECTION[i].VirtualAddress),
PTEMPSECTION[i].SizeOfRawData
);
}
*newbuffer = PTEMPNEWBUFFER;
PTEMPNEWBUFFER = NULL;
return POPTIONHEADER->SizeOfImage;
}
int MESSAGEBOXIN_(char* pbuffer)
{
if (!pbuffer)
{
MessageBox(0, TEXT("缓冲区不存在"), 0, 0);
return 0;
}
if (*(short*)(pbuffer) != 0X5A4D)
{
MessageBox(0, TEXT("不是一个mz文件标志"), 0, 0);
return 0;
}
PIMAGE_DOS_HEADER PDOSHEADER = (PIMAGE_DOS_HEADER)pbuffer;
if (*(PDWORD)((char*)pbuffer + PDOSHEADER->e_lfanew) != IMAGE_NT_SIGNATURE)
{
MessageBox(0, TEXT("不是一个NT标记"), 0, 0);
return 0;
}
PIMAGE_NT_HEADERS PNTHEADER = (PIMAGE_NT_HEADERS)((char*)pbuffer + PDOSHEADER->e_lfanew);
PIMAGE_FILE_HEADER PFILEHEADER = (PIMAGE_FILE_HEADER)(((char*)PNTHEADER) + 0X4);
PIMAGE_OPTIONAL_HEADER POPTIONHEADER = (PIMAGE_OPTIONAL_HEADER)((char*)PFILEHEADER + 0x14);
PIMAGE_SECTION_HEADER PSECTIONHEADER = (PIMAGE_SECTION_HEADER)((char*)POPTIONHEADER + PFILEHEADER->SizeOfOptionalHeader);
if ( ( PSECTIONHEADER[1].VirtualAddress - PSECTIONHEADER[0].VirtualAddress ) - PSECTIONHEADER[0].Misc.VirtualSize < SHELLCODELENGTH)
{
MessageBox(0,TEXT ("空间不足,无法注入shellcode"), 0, 0);
return 0;
}
int codebegin = (char*)pbuffer + PSECTIONHEADER[0].VirtualAddress + PSECTIONHEADER[0].Misc.VirtualSize;
memcpy((void *)codebegin, ShellCode ,SHELLCODELENGTH );
int call = (char*)codebegin + 0x9;
*(int*)call = MESSAGEBOX - ( POPTIONHEADER->ImageBase + ( codebegin - (int )PDOSHEADER ) + 0xd);
int jump = (char*)codebegin + 0xe ;
*(int*)jump = ( POPTIONHEADER->ImageBase + POPTIONHEADER->AddressOfEntryPoint) - (POPTIONHEADER->ImageBase + (codebegin - (int)PDOSHEADER + 0X12) );
POPTIONHEADER->AddressOfEntryPoint = codebegin - (int )PDOSHEADER;
}
int WRITEPEFILE_(char * pfilepath, char * pfilebuffer ,int filesize )
{
FILE* PFILE = NULL;
PFILE = fopen(pfilepath , "wb");
if (!PFILE)
{
return 0;
}
size_t n = fwrite(pfilebuffer , filesize , 1 , PFILE);
if (!n)
{
fclose(PFILE);
return 0;
}
fclose(PFILE);
return 1;
}
int FREEBUFFER_(char * pfilebuffer)
{
if (!pfilebuffer)
{
return 0;
}
else
{
free(pfilebuffer);
pfilebuffer = NULL;
}
}
注入成功
运行成功,不再一一演示。