a531246041 发表于 2016-4-4 16:02:19

通过修改PE结构来实现注入代码加深了解WINDOWS机制


#include "stdafx.h"
#include "AnalyticalPe.h"

#define filePath "F:\\test11111.exe"
#define ToFilePath "C:\\shuchu1.exe"
#defineMessageBoxAddress 0x759BFD3F


/*******************************************************************************
名称:ZrFile
功能:注入EXE
参数:filePath需要注入的EXE路径
时间:9/24/2015 范乐乐
版本:1.0
注意:
*******************************************************************************/
VOID ZrFile(IN LPSTR pfilePath){

        ////定义一个buffer保存返回的PE磁盘格式
        //LPVOID pFileBuffer = NULL;
        //LPVOID pImageBuffer = NULL;
        //LPVOID pNewFileBuffer = NULL;
        ////定义一个文件大小的变量
        //DWORD fileSize = 0;
        ////读取PE磁盘格式
        //fileSize = ReadPeFile(pfilePath,&pFileBuffer);
        //if(fileSize == 0){
        //        printf("读取PE失败");
        //        free(pFileBuffer);
        //        getchar();
        //        return;
        //}

        //fileSize = ZrImageToFile(pFileBuffer,&pImageBuffer);
        //if(!fileSize){
        //        printf("文件结构转内存结构失败");
        //        free(pImageBuffer);
        //        getchar();
        //        return;
        //}

        //定义一个buffer保存返回的PE磁盘格式
        LPVOID pFileBuffer = NULL;
        LPVOID pImageBuffer = NULL;
        LPVOID pNewFileBuffer = NULL;
        //定义一个文件大小的变量
        DWORD fileSize = 0;
        //读取PE磁盘格式
        fileSize = ReadPeFile(filePath,&pFileBuffer);
        if(fileSize == 0){
                printf("读取PE失败");
                free(pFileBuffer);
                getchar();
                return;
        }

        fileSize = FileToImage(pFileBuffer,&pImageBuffer);
        if(!fileSize){
                printf("文件结构转内存结构失败");
                free(pImageBuffer);
                getchar();
                return;
        }

        fileSize = ZrImageToFile(pImageBuffer,&pNewFileBuffer);
        if(!fileSize){
                printf("文件结构转内存结构失败");
                free(pNewFileBuffer);
                getchar();
                return;
        }

        if(SaveFile(ToFilePath,pNewFileBuffer,fileSize)){
                printf("存盘成功!");
        }


        //SaveFile("C:\\0000.exe",pImageBuffer,fileSize);
}

/*******************************************************************************
名称:ZrImage (作废)
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ZrImage(IN LPVOID pFileBuffer,OUT LPVOID* pImageBuffer);

/*******************************************************************************
名称:ZrImageToFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ZrImageToFile(IN LPVOID pImageBuffer,OUT LPVOID* pFileBuffer){
        //定义一系列变量
        PIMAGE_DOS_HEADER pDosHeader = NULL; //DOS头
        PIMAGE_NT_HEADERS32 pNtHeader = NULL; //NT头
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; //扩展头
        PIMAGE_FILE_HEADER pFileHeader = NULL; //标准头
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头

        //判断取出来的磁盘PE格式格式是否正确 (DOS)
        if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE){
                printf("DOS格式错误");
                free(pImageBuffer);
                return 0;
        }

        pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
        printf("pDosHeader->e_magic:%x\n",pDosHeader->e_magic);
        printf("pDosHeader->e_lfanew:%x\n",pDosHeader->e_lfanew);

        pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
        if(pNtHeader->Signature != IMAGE_NT_SIGNATURE){
                printf("PE格式错误");
        }
        printf("pNtHeader->Signature:%x\n",pNtHeader->Signature);

        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader+4);
        printf("pFileHeader->NumberOfSections:%x\n",pFileHeader->NumberOfSections);
        printf("pFileHeader->SizeOfOptionalHeader:%x\n",pFileHeader->SizeOfOptionalHeader);

        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader+IMAGE_SIZEOF_FILE_HEADER);
        DWORD fileSize = pOptionalHeader->SizeOfImage;
        printf("pOptionalHeader->ImageBase:%x\n",pOptionalHeader->ImageBase);
        printf("pOptionalHeader->SizeOfImage:%x\n",pOptionalHeader->SizeOfImage);
        printf("pOptionalHeader->SizeOfHeaders:%x\n",pOptionalHeader->SizeOfHeaders);

        //***********************************修改pe**********************************************************
        //开始赋值节
        DWORD MyTextJie = 0;
        DWORD SectionTwo = 0;
        for (int i =0; i < pFileHeader->NumberOfSections;i++)
        {
                pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
                if(i == 1){
                        MyTextJie = pSectionHeader->Misc.VirtualSize;
                        SectionTwo = pSectionHeader->VirtualAddress;
                }
        }

        printf("------------->%x,--------------------->%x,-------------->%x",MyTextJie,SectionTwo,(DWORD)pImageBuffer);
        void * thisCode = (void*)((DWORD)pImageBuffer+SectionTwo+MyTextJie);
        BYTEmyByte = {0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00,0xE8,0x00,0x00,0x00,0x00,0xE9,0x00,0x00,0x00,0x00};
        memcpy(thisCode,myByte,18);

        //修正E8
        DWORD E8Address =        MessageBoxAddress - ((pOptionalHeader->ImageBase + (DWORD)thisCode+0xD) - (DWORD)pImageBuffer);
        *(PDWORD)((DWORD)thisCode + 0x9) = E8Address;

        //修正E9
        DWORD E9Address =        (pOptionalHeader->ImageBase + pOptionalHeader->AddressOfEntryPoint ) - ((pOptionalHeader->ImageBase + (DWORD)thisCode+0x12) - (DWORD)pImageBuffer);
        *(PDWORD)((DWORD)thisCode + 0xE) = E9Address;

        //修正EOP
        pOptionalHeader->AddressOfEntryPoint =(DWORD)thisCode-(DWORD)pImageBuffer;

        //***********************************创建Image存储结构***************************************************
        LPVOIDpFileBuffer_Buffer = malloc(pOptionalHeader->SizeOfImage); //开辟了一个空间用来保存在内存中结构

        memset(pFileBuffer_Buffer,0,pOptionalHeader->SizeOfImage);
        //因为NT头是不会有任何变化的,所以可以直接拷贝过去
        memcpy(pFileBuffer_Buffer,pImageBuffer,pOptionalHeader->SizeOfHeaders); //这里的pimage_buffer已经有了头部

        //开始赋值节

        for (int i =0; i < pFileHeader->NumberOfSections;i++)
        {
                pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
                memcpy((void*)((DWORD)pFileBuffer_Buffer+pSectionHeader->PointerToRawData),(void*)((DWORD)pImageBuffer+pSectionHeader->VirtualAddress),pSectionHeader->SizeOfRawData);
        }

        *pFileBuffer = pFileBuffer_Buffer;

        free(pImageBuffer);
        pDosHeader = NULL; //DOS头
        pNtHeader = NULL; //NT头
        pOptionalHeader = NULL; //扩展头
        pFileHeader = NULL; //标准头
        pSectionHeader = NULL;//节表头

        return fileSize;
}

int _tmain(int argc, _TCHAR* argv[])
{
        //TestZh();

        //定义注入程序


        ZrFile(filePath);

        getchar();
        return 0;
}

/*******************************************************************************
名称:TestZh
功能:测试转换
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
*******************************************************************************/
VOID TestZh(){

        //定义一个buffer保存返回的PE磁盘格式
        LPVOID pFileBuffer = NULL;
        LPVOID pImageBuffer = NULL;
        LPVOID pNewFileBuffer = NULL;
        //定义一个文件大小的变量
        DWORD fileSize = 0;
        //读取PE磁盘格式
        fileSize = ReadPeFile(filePath,&pFileBuffer);
        if(fileSize == 0){
                printf("读取PE失败");
                free(pFileBuffer);
                getchar();
                return;
        }

        fileSize = FileToImage(pFileBuffer,&pImageBuffer);
        if(!fileSize){
                printf("文件结构转内存结构失败");
                free(pImageBuffer);
                getchar();
                return;
        }

        fileSize = ImageToFile(pImageBuffer,&pNewFileBuffer);
        if(!fileSize){
                printf("文件结构转内存结构失败");
                free(pNewFileBuffer);
                getchar();
                return;
        }

        if(SaveFile(ToFilePath,pNewFileBuffer,fileSize)){
                printf("存盘成功!");
        }

}

/*******************************************************************************
名称:ReadPeFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ReadPeFile(IN LPSTRpFilePath,OUT LPVOID* pFileBuffer ){
        //1.创建一个File指针
        FILE * pFile = NULL;
        //2.创建一个变量保存文件的大小
        DWORD fileSize = 0;
        //3.创建一个Buffer保存文件内容
        LPVOIDmyFileBuffer = NULL;

        errno_t errNum = 0;
        errNum = fopen_s(&pFile,pFilePath,"rb");
        if(errNum != 0){
                printf("打开文件失败了!");
                return 0;
        }

        fseek(pFile,0,SEEK_END);
        fileSize = ftell(pFile);
        fseek(pFile,0,SEEK_SET);

        myFileBuffer = malloc(fileSize);

        size_t n =fread(myFileBuffer,fileSize,1,pFile);
        if(!n){
                printf("加载缓冲区失败");
                //关闭file
                fclose(pFile);
                //释放开辟的内存
                free(myFileBuffer);

                return 0;
        }

        *pFileBuffer = myFileBuffer;
        //关闭file
        fclose(pFile);

        return fileSize;
}

/*******************************************************************************
名称:FileToImage
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD FileToImage(IN LPVOID pFileBuffer,OUT LPVOID* pImageBuffer){
        //定义一系列变量
        PIMAGE_DOS_HEADER pDosHeader = NULL; //DOS头
        PIMAGE_NT_HEADERS32 pNtHeader = NULL; //NT头
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; //扩展头
        PIMAGE_FILE_HEADER pFileHeader = NULL; //标准头
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头

        //判断取出来的磁盘PE格式格式是否正确 (DOS)
        if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE){
                printf("DOS格式错误");
                free(pFileBuffer);
                free(pImageBuffer);
                return 0;
        }
        pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
        printf("pDosHeader->e_magic:%x\n",pDosHeader->e_magic);
        printf("pDosHeader->e_lfanew:%x\n",pDosHeader->e_lfanew);

        pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
        if(pNtHeader->Signature != IMAGE_NT_SIGNATURE){
                printf("PE格式错误");
                free(pFileBuffer);
                free(pImageBuffer);
                return 0;
        }
        printf("pNtHeader->Signature:%x\n",pNtHeader->Signature);

        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader+4);
        printf("pFileHeader->NumberOfSections:%x\n",pFileHeader->NumberOfSections);
        printf("pFileHeader->SizeOfOptionalHeader:%x\n",pFileHeader->SizeOfOptionalHeader);

        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader+IMAGE_SIZEOF_FILE_HEADER);
        printf("pOptionalHeader->ImageBase:%x\n",pOptionalHeader->ImageBase);
        printf("pOptionalHeader->SizeOfImage:%x\n",pOptionalHeader->SizeOfImage);
        printf("pOptionalHeader->SizeOfHeaders:%x\n",pOptionalHeader->SizeOfHeaders);
        DWORD fileSize = pOptionalHeader->SizeOfImage;

        for (int i =0; i < pFileHeader->NumberOfSections;i++)
        {
                pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);
                BYTE * name = (BYTE)(pSectionHeader->Name);
                printf("pSectionHeader->Name:%s\n",name);
                printf("pSectionHeader->VirtualAddress:%x\n",pSectionHeader->VirtualAddress);
                printf("pSectionHeader->PointerToRawData:%x\n",pSectionHeader->PointerToRawData);
        }

        //***********************************创建Image存储结构***************************************************
        LPVOIDpImage_Buffer = malloc(pOptionalHeader->SizeOfImage); //开辟了一个空间用来保存在内存中结构

        memset(pImage_Buffer,0,pOptionalHeader->SizeOfImage);
        fileSize = pOptionalHeader->SizeOfImage;

        //因为NT头是不会有任何变化的,所以可以直接拷贝过去
        memcpy(pImage_Buffer,pFileBuffer,pOptionalHeader->SizeOfHeaders); //这里的pimage_buffer已经有了头部

        //开始赋值节

        for (int i =0; i < pFileHeader->NumberOfSections;i++)
        {
                pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);

                memcpy((void*)((DWORD)pImage_Buffer+pSectionHeader->VirtualAddress),(void*)((DWORD)pFileBuffer+pSectionHeader->PointerToRawData),pSectionHeader->SizeOfRawData);
        }

        *pImageBuffer = pImage_Buffer;

        free(pFileBuffer);
        pDosHeader = NULL; //DOS头
        pNtHeader = NULL; //NT头
        pOptionalHeader = NULL; //扩展头
        pFileHeader = NULL; //标准头
        pSectionHeader = NULL;//节表头

        return fileSize;
}

/*******************************************************************************
名称:ImageToFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:返回0表示失败 返回非0则是文件大小
*******************************************************************************/
DWORD ImageToFile(IN LPVOID pImageBuffer,OUT LPVOID* pFileBuffer){
        //定义一系列变量
        PIMAGE_DOS_HEADER pDosHeader = NULL; //DOS头
        PIMAGE_NT_HEADERS32 pNtHeader = NULL; //NT头
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; //扩展头
        PIMAGE_FILE_HEADER pFileHeader = NULL; //标准头
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;//节表头

        //判断取出来的磁盘PE格式格式是否正确 (DOS)
        if(*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE){
                printf("DOS格式错误");
                free(pImageBuffer);
                return 0;
        }

        pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
        printf("pDosHeader->e_magic:%x\n",pDosHeader->e_magic);
        printf("pDosHeader->e_lfanew:%x\n",pDosHeader->e_lfanew);

        pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pImageBuffer+pDosHeader->e_lfanew);
        if(pNtHeader->Signature != IMAGE_NT_SIGNATURE){
                printf("PE格式错误");
        }
        printf("pNtHeader->Signature:%x\n",pNtHeader->Signature);

        pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeader+4);
        printf("pFileHeader->NumberOfSections:%x\n",pFileHeader->NumberOfSections);
        printf("pFileHeader->SizeOfOptionalHeader:%x\n",pFileHeader->SizeOfOptionalHeader);

        pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader+IMAGE_SIZEOF_FILE_HEADER);
        DWORD fileSize = pOptionalHeader->SizeOfImage;
        printf("pOptionalHeader->ImageBase:%x\n",pOptionalHeader->ImageBase);
        printf("pOptionalHeader->SizeOfImage:%x\n",pOptionalHeader->SizeOfImage);
        printf("pOptionalHeader->SizeOfHeaders:%x\n",pOptionalHeader->SizeOfHeaders);

        //***********************************创建Image存储结构***************************************************
        LPVOIDpFileBuffer_Buffer = malloc(pOptionalHeader->SizeOfImage); //开辟了一个空间用来保存在内存中结构

        memset(pFileBuffer_Buffer,0,pOptionalHeader->SizeOfImage);
        //因为NT头是不会有任何变化的,所以可以直接拷贝过去
        memcpy(pFileBuffer_Buffer,pImageBuffer,pOptionalHeader->SizeOfHeaders); //这里的pimage_buffer已经有了头部

        //开始赋值节

        for (int i =0; i < pFileHeader->NumberOfSections;i++)
        {
                pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+pFileHeader->SizeOfOptionalHeader+sizeof(_IMAGE_SECTION_HEADER)*i);

                memcpy((void*)((DWORD)pFileBuffer_Buffer+pSectionHeader->PointerToRawData),(void*)((DWORD)pImageBuffer+pSectionHeader->VirtualAddress),pSectionHeader->SizeOfRawData);
        }

        *pFileBuffer = pFileBuffer_Buffer;

        free(pImageBuffer);
        pDosHeader = NULL; //DOS头
        pNtHeader = NULL; //NT头
        pOptionalHeader = NULL; //扩展头
        pFileHeader = NULL; //标准头
        pSectionHeader = NULL;//节表头

        return fileSize;
}

/*******************************************************************************
名称:SaveFile
功能:
参数:无
时间:9/24/2015 范乐乐
版本:1.0
注意:
返回值:保存成功true 保存失败false
*******************************************************************************/
BOOL SaveFile(IN LPSTR pfilePath,IN LPVOID pFileBuffer,IN DWORD fileSize){
        //获取文件指针
        FILE *pFile = NULL;
        errno_t et = 0;
        et = fopen_s(&pFile,pfilePath,"wb+");

        if(pFile == NULL){
                printf("打开失败");
                return 0;
        }

        fwrite(pFileBuffer,fileSize,1,pFile);

        fflush(pFile);
        fclose(pFile);

        free(pFileBuffer);
        return 1;
}


pcwind 发表于 2016-5-16 17:30:05

#include "stdafx.h"

PLVOID ReadPEFile (LPSTRpath ){
{

        FILE *pFile =NULL ;
        DWORD fileSize = 0 ;
        LPVOID pFileBuffer = NULL;

       
        /* 1 打开文件 */   
       
        if(!(pFile = fopen(path,"rb")))
        {
               
                printf("can not open file %s \n",path);
               
                return NULL;
               
        }
       
       
        /* 2.获取文件大小 */
       
        fseek(pFile,0,SEEK_END);
       
        fileSize =ftell(pFile);
       
        fseek(pFile,0,SEEK_SET);
        //rewind(fp);
       
       
        /* 3 分配缓冲区 */
       
pFileBuffer = malloc(fileSize);
        if (!pFileBuffer)
    {
                printf("buffer devided error!\n");
               
                fclose(pFile);
      return NULL;
    }
       
        /* 4 将文件拷贝到buffer中 */
       
       
        size_t n = fread(pFileBuffer,fileSize,1,pFile);
       
        if(!n){
               
                printf("read file error !\n");
               
                free(pFileBuffer);
               
                fclose(pFile);
                return NULL;
        }
       
        fclose(pFile);
       

        return pFilBuffer;

}

/*
VOID PrintNTHeaders()
{

        LPVOID pFileBuffer = NULL;

        PIMAGE_DOS_HEADER pDosHeader = NULL;

        PIMAGE_DOS_HEADER pDosHeader = NULL;
        PIMAGE_NT_HEADERS pNTHeader = NULL;
        PIMAGE_FILE_HEADER pPEHeader = NULL;
        PIMAGE_OPTION_HEADER32 pOptionHeader = NULL;
        PIMAGE_SECTION_HEADER pSectionHeader = NULL;

       
        pFileBuffer = ReadPEFile(FILEPATH);
   
        if(!pFileBuffer){
       
                printf("read file error! \n")
          
                        return ;
        }

        //判断是否有效的mz

        if(*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)

        {
          printf("invalid mz \n");

          free(pFileBuffer);
          return ;
       
       
        }

    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;

    // printf

        printf("*****************************************\n");

        printf("   mz:      %X\n",pDOSHeader->e_magic);
    printf(" pe offset: %X\n",pDOSHeader->e_lfanew);

        if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
        {
                printf("invalid pe signature \n");
          free(pFileBuffer);
          return;       

        }

        pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
        //printf nt
       
        printf("*****************************************\n");

        printf("nt : %x\n ",pNTHeader->Signature);

        pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
       
        printf("*****************************************\n");

        printf("pe: %x \n",pPEHeader->Machine);

        printf("section: %x \n",pPEHeader->NumberOfSections);

        printf("size of optionalHeader: %x \n",pPEHeader->SizeOfOptionalHeader);

    // optionalheader

        pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);

        printf("*****************************************\n");

        printf("option_pe: %X \n",pOptionHeader->Magic);


   free(pFileBuffer);
*/

}

int main(int argc, char* argv[])
{

char * string;
string= ReadPEFile("c:/c.exe");
       
        printf("%d\n",string);
   

// PrintNTHeaders();
        return 0;
}


pcwind 发表于 2016-5-16 17:31:25

我编译不过,你能看下为什么吗?出错在第一句呀
页: [1]
查看完整版本: 通过修改PE结构来实现注入代码加深了解WINDOWS机制