注册 登录
编程论坛 C语言论坛

C求助如下,实在是找不到问题了,大佬帮忙看下

fsnsn 发布于 2021-02-21 11:57, 2048 次点击
程序在最后结束的地方会释放内存。
在直接运行exe的时候,会出现程序崩溃(如果是运行文件对齐和内存对齐一致的文件,没有任何问题;运行文件对齐和内存对齐不一致的会有问题)。
但是加断点单步执行没有任何问题。。哭了...实在是找不到问题了
程序代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>

#define DWORD unsigned int
#define WORD unsigned short
#define BYTE unsigned char

int FileSize(char* filePath)            
{
    int fileLength = 0;
    FILE* fp = fopen(filePath,"rb");   
    if(fp==NULL)
    {
        printf("open file failed!\n");
        return 0;
    }

    fseek(fp,0,SEEK_END);               
    fileLength = ftell(fp);               
    fseek(fp,0,SEEK_SET);               

    fclose(fp);                                
    fp = NULL;
    return fileLength;
}

BYTE* CreateMemory(int size)            
{
    BYTE* memory = (BYTE*)malloc(size);        
    if(memory==NULL)                    
    {
        printf("malloc failed!\n");
        return NULL;
    }
    memset(memory,0,size);               
    return memory;                        
}

BYTE* ToFileBuffer(char* filePath)
{
    int fileLength = FileSize(filePath);

    BYTE* fileBuffer = CreateMemory(fileLength);

    FILE* filePointer = fopen(filePath,"rb");

    fread(fileBuffer,1,fileLength,filePointer);

    fclose(filePointer);
    filePointer = NULL;
    printf("tofilebuffer success!\n");
    printf("fileBuffer:%p\n",fileBuffer);
    return fileBuffer;
}

BYTE* FileBufferToImageBuffer(BYTE* fileBuffer)
{
    DWORD i = 0;
    DWORD j = 0;
    DWORD e_lfanew = *((DWORD*)(fileBuffer + 0x3C));
    WORD SizeOfOptionalHeader = *((WORD*)(fileBuffer + e_lfanew + 0x14));

    DWORD SIZE_PE_signature = 0x4;
    DWORD SIZE_FILE_HEADER = 0x14;
    WORD NUM_SECTION = *((WORD*)(fileBuffer + e_lfanew + 0x6));
    DWORD SIZE_SECTION = NUM_SECTION * 40;
    DWORD SIZE_IMAGE = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x38));
    DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader;
    DWORD SIZE_HEADERS = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x3C));

    BYTE* imageBuffer = CreateMemory(SIZE_IMAGE);

    for(i=0;i<SIZE_HEADERS;i++)
    {
        *(imageBuffer+i) = *(fileBuffer+i);
    }

    i = 0;
    while(i<NUM_SECTION)
    {
        DWORD Misc = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x8 + i*0x28));                    
        DWORD PointerToRawData = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x14 + i*0x28));        
        DWORD VirtualAddress = *((DWORD*)(fileBuffer + SIZE_HEADER + 0xc + i*0x28));        
        
        for(j=0;j<Misc;j++)
        {
            *(imageBuffer+VirtualAddress+j) = *(fileBuffer+PointerToRawData+j);
        }

        i++;
    }
    printf("FileBufferToImageBuffer success!\n");
    printf("fileBuffer:%p\n",fileBuffer);
    printf("imageBuffer:%p\n",imageBuffer);
    return imageBuffer;
}

BYTE* ImageBufferToNewBuffer(BYTE* imageBuffer,char* filePath)
{
    int fileLength = FileSize(filePath);            

    DWORD i = 0;
    DWORD j = 0;
    DWORD e_lfanew = *((DWORD*)(imageBuffer + 0x3C));
    WORD SizeOfOptionalHeader = *((WORD*)(imageBuffer + e_lfanew + 0x14));

    DWORD SIZE_PE_signature = 0x4;
    DWORD SIZE_FILE_HEADER = 0x14;
    WORD NUM_SECTION = *((WORD*)(imageBuffer + e_lfanew + 0x6));
    DWORD SIZE_SECTION = NUM_SECTION * 40;
    DWORD SIZE_IMAGE = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x38));
    DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader;
    DWORD SIZE_HEADERS = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x3C));

    BYTE* newBuffer = CreateMemory(fileLength);

    for(i=0;i<SIZE_HEADERS;i++)
    {
        *(newBuffer+i) = *(imageBuffer+i);
    }

    i = 0;
    while(i<NUM_SECTION)
    {
        DWORD Misc = *((DWORD*)(imageBuffer + SIZE_HEADER + 0x8 + i*0x28));                    
        DWORD PointerToRawData = *((DWORD*)(imageBuffer + SIZE_HEADER  + 0x14 + i*0x28));        
        DWORD VirtualAddress = *((DWORD*)(imageBuffer + SIZE_HEADER  + 0xc + i*0x28));        
        
        for(j=0;j<Misc;j++)
        {
            *(newBuffer+PointerToRawData+j) = *(imageBuffer+VirtualAddress+j);
        }

        i++;
    }
    printf("ImageBufferToNewBuffer success!\n");
    printf("imageBuffer:%p\n",imageBuffer);
    printf("newBuffer:%p\n",newBuffer);
    return newBuffer;
}

void WriteFile(char* Path,char* filePath,BYTE* memory)
{
    int fileLength = FileSize(Path);
    FILE* fileBuffer = fopen(filePath,"wb");
    fwrite(memory,1,fileLength,fileBuffer);
    fclose(fileBuffer);
    fileBuffer = NULL;
    printf("WriteFile success!\n");
    return ;
}

int main()
{
    char* Path = "C:\\dscalltest.exe";                //调试的时候,此处需要进行修改下,这是原始文件名称
    char* DstPath = "C:\\dscalltest111.exe";        //此处是将原来的文件加载到内存后,再从内存中提取出来,然后生成目标文件
    BYTE* p = ToFileBuffer(Path);
    BYTE* p1 = FileBufferToImageBuffer(p);
    BYTE* p2 = ImageBufferToNewBuffer(p1,Path);
    WriteFile(Path,DstPath,p2);
    printf("文件生成成功!\n");
    printf("p:%p\n",p);
    printf("p1:%p\n",p1);
    printf("p2:%p\n",p2);

    free(p1);                                            //此处存在问题
    printf("free(p1) success!  p1:%p\n",p1);
    p1 = NULL;
    printf("p1 = NULL!\n");

    free(p2);
    printf("free(p2) success!  p2:%p\n",p2);
    p2 = NULL;
    printf("p2 = NULL!\n");

    free(p);
    printf("free(p) success!  p:%p\n",p);
    p = NULL;
    printf("p = NULL!\n");

    return 0;
}
2 回复
#2
yuma2021-02-21 16:53
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>

#define DWORD unsigned int
#define WORD unsigned short
#define BYTE unsigned char

int FileSize(char* filePath)            
{
    int fileLength = 0;
    FILE* fp = fopen(filePath,"rb");   
    if(fp==NULL)
    {
        printf("open file failed!\n");
        return 0;
    }

    fseek(fp,0,SEEK_END);               
    fileLength = ftell(fp);               
    fseek(fp,0,SEEK_SET);               

    fclose(fp);                                
    fp = NULL;
    return fileLength;
}

BYTE* CreateMemory(int size)            
{
    BYTE* memory = (BYTE*)malloc(size);        
    if(memory==NULL)                    
    {
        printf("malloc failed!\n");
        return NULL;
    }
    memset(memory,0,size);               
    return memory;                        
}

BYTE* ToFileBuffer(char* filePath)
{
    int fileLength = FileSize(filePath);

    BYTE* fileBuffer = CreateMemory(fileLength);

    FILE* filePointer = fopen(filePath,"rb");

    fread(fileBuffer,1,fileLength,filePointer);

    fclose(filePointer);
    filePointer = NULL;
    printf("tofilebuffer success!\n");
    printf("fileBuffer:%p\n",fileBuffer);
    return fileBuffer;
}

BYTE* FileBufferToImageBuffer(BYTE* fileBuffer)
{
    DWORD i = 0;
    DWORD j = 0;
    DWORD e_lfanew = *((DWORD*)(fileBuffer + 0x3C));
    WORD SizeOfOptionalHeader = *((WORD*)(fileBuffer + e_lfanew + 0x14));

    DWORD SIZE_PE_signature = 0x4;
    DWORD SIZE_FILE_HEADER = 0x14;
    WORD NUM_SECTION = *((WORD*)(fileBuffer + e_lfanew + 0x6));
    DWORD SIZE_SECTION = NUM_SECTION * 40;
    DWORD SIZE_IMAGE = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x38));
    DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader;
    DWORD SIZE_HEADERS = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x3C));

    BYTE* imageBuffer = CreateMemory(SIZE_IMAGE);

    for(i=0;i<SIZE_HEADERS;i++)
    {
        *(imageBuffer+i) = *(fileBuffer+i);
    }

    i = 0;
    while(i<NUM_SECTION)
    {
        DWORD Misc = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x8 + i*0x28));                    
        DWORD PointerToRawData = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x14 + i*0x28));        
        DWORD VirtualAddress = *((DWORD*)(fileBuffer + SIZE_HEADER + 0xc + i*0x28));        
        
        for(j=0;j<Misc;j++)
        {
            *(imageBuffer+VirtualAddress+j) = *(fileBuffer+PointerToRawData+j);
        }

        i++;
    }
    printf("FileBufferToImageBuffer success!\n");
    printf("fileBuffer:%p\n",fileBuffer);
    printf("imageBuffer:%p\n",imageBuffer);
    return imageBuffer;
}

BYTE* ImageBufferToNewBuffer(BYTE* imageBuffer,char* filePath)
{
    int fileLength = FileSize(filePath);            

    DWORD i = 0;
    DWORD j = 0;
    DWORD e_lfanew = *((DWORD*)(imageBuffer + 0x3C));
    WORD SizeOfOptionalHeader = *((WORD*)(imageBuffer + e_lfanew + 0x14));

    DWORD SIZE_PE_signature = 0x4;
    DWORD SIZE_FILE_HEADER = 0x14;
    WORD NUM_SECTION = *((WORD*)(imageBuffer + e_lfanew + 0x6));
    DWORD SIZE_SECTION = NUM_SECTION * 40;
    DWORD SIZE_IMAGE = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x38));
    DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader;
    DWORD SIZE_HEADERS = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x3C));

    BYTE* newBuffer = CreateMemory(fileLength);

    for(i=0;i<SIZE_HEADERS;i++)
    {
        *(newBuffer+i) = *(imageBuffer+i);
    }

    i = 0;
    while(i<NUM_SECTION)
    {
        DWORD Misc = *((DWORD*)(imageBuffer + SIZE_HEADER + 0x8 + i*0x28));                    
        DWORD PointerToRawData = *((DWORD*)(imageBuffer + SIZE_HEADER  + 0x14 + i*0x28));        
        DWORD VirtualAddress = *((DWORD*)(imageBuffer + SIZE_HEADER  + 0xc + i*0x28));        
        
        for(j=0;j<Misc;j++)
        {
            *(newBuffer+PointerToRawData+j) = *(imageBuffer+VirtualAddress+j);
        }

        i++;
    }
    printf("ImageBufferToNewBuffer success!\n");
    printf("imageBuffer:%p\n",imageBuffer);
    printf("newBuffer:%p\n",newBuffer);
    return newBuffer;
}

void WriteFile(char* Path,char* filePath,BYTE* memory)
{
    int fileLength = FileSize(Path);
    FILE* fileBuffer = fopen(filePath,"wb");
    fwrite(memory,1,fileLength,fileBuffer);
    fclose(fileBuffer);
    fileBuffer = NULL;
    printf("WriteFile success!\n");
    return ;
}

int main()
{
    char* Path = "C:\\Windows\\notepad.exe";                //调试的时候,此处需要进行修改下,这是原始文件名称
    char* DstPath = "D:\\dscalltest111.exe";        //此处是将原来的文件加载到内存后,再从内存中提取出来,然后生成目标文件
    BYTE* p = ToFileBuffer(Path);
    BYTE* p1 = FileBufferToImageBuffer(p);
    BYTE* p2 = ImageBufferToNewBuffer(p1,Path);
    WriteFile(Path,DstPath,p2);
    printf("文件生成成功!\n");
    printf("p:%p\n",p);
    printf("p1:%p\n",p1);
    printf("p2:%p\n",p2);

    free(p1);                                            //此处存在问题
    printf("free(p1) success!  p1:%p\n",p1);
    p1 = NULL;
    printf("p1 = NULL!\n");

    free(p2);
    printf("free(p2) success!  p2:%p\n",p2);
    p2 = NULL;
    printf("p2 = NULL!\n");

    free(p);
    printf("free(p) success!  p:%p\n",p);
    p = NULL;
    printf("p = NULL!\n");
    getchar();
}


随便改了一下,运行正常了。
只有本站会员才能查看附件,请 登录

只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2021-2-21 16:54编辑过]

#3
fsnsn2021-02-21 18:45
回复 2楼 yuma
你这改动没有意义啊,如果你用我的程序也能正常跑
1