首页
社区
课程
招聘
[求助]PE文件用到的输入库
发表于: 2007-8-22 13:50 4442

[求助]PE文件用到的输入库

2007-8-22 13:50
4442
#include "StdAfx.h"
#include <malloc.h>
#include ".\joperatpe.h"

JoperatPe::JoperatPe(TCHAR *path):m_IsPe(0),m_IsNt(0)
{
        tpath = NULL;
        tpath = (char*)malloc(strlen(path)+1);
        memset(tpath,0,strlen(path)+1);
        strcpy(tpath,path);
        m_lpf = NULL;
        m_lpf = fopen(tpath,"rb+");
        if(m_lpf == NULL)
        {
                OutputDebugString("无文件操作权限!\n");
       
        }
}

JoperatPe::~JoperatPe(void)
{
        if(tpath != NULL )
                free(tpath);
        if(m_lpf != NULL)
                fclose(m_lpf);
}
/*------------------------------------------------------------------------------------
                                        检查目标文件是否为正确的PE格式文件
                                       
                                        返回该PE文件格式类型
-------------------------------------------------------------------------------------*/
HRESULT        JoperatPe::check()
{
        if(m_lpf == NULL)        //文件读取错误
                return E_FAIL;
       
        WORD IsMZ = 0;
        fread(&IsMZ,sizeof(WORD),1,m_lpf);
        if(IsMZ == 0x5a4d)
        {
                //合法文件
                if(fseek(m_lpf,0x3c,SEEK_SET) == 0)
                {
                        //获取偏移地址
                        fread(&m_IsNt,sizeof(DWORD),1,m_lpf);
                        //
                        fseek(m_lpf,m_IsNt,SEEK_SET);
                        fread(&m_IsPe,sizeof(DWORD),1,m_lpf);
                        if(m_IsPe != 0x00004550)
                        {
                                return JE_NOTWIN;
                        }
                        else
                        {
                                return JE_WINPE;
                               
                        }
                }
                return E_FAIL;        //偏移地址错误
        }
        else
        {
                return JE_FAIL;
        }
}
//
//得到DOS头对于Win32程序来所只有2个数据项有用一个是头表示一个文件的正确性
//另一个是尾表示该PE文件的(文件内)偏移
//
HRESULT        JoperatPe::SetImageDosHeaderLong(IMAGE_DOS_HEADER *pDosHeader,DWORD dIndx)
{
        if(m_lpf == NULL || dIndx == 0 || pDosHeader == NULL)
        {
                OutputDebugString("操作不明确,或文件没有被打开!\n");
                return E_FAIL;
        }
        fseek(m_lpf,0x00,SEEK_SET);
        try
        {
                switch(dIndx)
                {
                case SCL_GET:
                        fread(pDosHeader,sizeof(IMAGE_DOS_HEADER),1,m_lpf);
                        m_IsNt = pDosHeader->e_lfanew;
                        break;
                case SCL_SET:
                        fwrite(pDosHeader,sizeof(IMAGE_DOS_HEADER),1,m_lpf);
                }
        }
        catch(...)
        {
                OutputDebugString("文件操作错误!\n");
                return S_FALSE;               
        }
        return S_OK;
}
/*--------------------------------------------------------------------------------
                                        读取或设置PE文件头

---------------------------------------------------------------------------------*/
HRESULT        JoperatPe::SetFileHeaderLong(IMAGE_NT_HEADERS *pFileHeader,DWORD dIndx)
{
        if(m_lpf == NULL || dIndx == 0)
        {
                OutputDebugString("操作不明确,或文件没有打开!\n");
                return E_FAIL;
        }
        try
        {
                //跳过DOS程式
                //现在都是win32程式,DOS程式不处理
                //m_IsNt纪录了该PE文件的偏移地址
                //每个PE文件的该偏移地址都不太一样
                //所以某些文档说该地址是固定的这个结论是错误的
                if(m_IsNt == 0)
                {
                        OutputDebugString("偏移地址错误!\n");
                        return E_FAIL;
                }
                if(fseek(m_lpf,m_IsNt,SEEK_SET) == 0)
                {
                        switch(dIndx)
                        {
                        case SCL_GET:
                                fread(pFileHeader,sizeof(IMAGE_NT_HEADERS),1,m_lpf);
                                break;
                        case SCL_SET:
                                fwrite(pFileHeader,sizeof(IMAGE_FILE_HEADER),1,m_lpf);                       
                                break;
                        default:
                                break;
                        }
                        m_dwFileAlignment = pFileHeader->OptionalHeader.FileAlignment;
                        return S_OK;
                }
        }
        catch(...)
        {
                OutputDebugString("文件操作错误!\n");
                return S_FALSE;
        }
        return E_FAIL;
}
//
//直接的到节数
//
WORD JoperatPe::GetSection(WORD *num)
{
        if(m_lpf == NULL || num == NULL)        //文件读取错误
                return 0;

        if(fseek(m_lpf,m_IsNt+0x06,SEEK_SET) == 0)
        {
           fread(num,sizeof(WORD),1,m_lpf);
           m_dSctnCnt = *num;
        }
        return *num;
}
//
//获得可选头尺寸
//
WORD JoperatPe::SizeofOpetionHeader(WORD *num)
{
        if(m_lpf == NULL || num==NULL )
                return E_FAIL;
        if(fseek(m_lpf,m_IsNt+0x14,SEEK_SET) == 0)
        {
                fread(num,sizeof(WORD),1,m_lpf);
        }
        return *num;
}
/*-----------------------------------------------------------
                说明:该函数用来设置获取字符标志位
                参数:dIndex = SCL_SET,设置该字符标志位为num
                          dIndex = SCL_GET,获取该标志为标志num为输出
-------------------------------------------------------------*/
HRESULT JoperatPe::SetCharactLong(WORD *num,DWORD dIndex)
{
        if(m_lpf==NULL || num == NULL)
                return E_FAIL;
        int icout = 0;
        if(fseek(m_lpf,m_IsNt+0x16,SEEK_SET) == 0)
        {
                switch(dIndex)
                {
                case SCL_SET:
                        icout = fwrite(num,sizeof(WORD),1,m_lpf);
                        return S_OK;
                case SCL_GET:
                        fread(num,sizeof(WORD),1,m_lpf);
                        return S_OK;
                default:
                        return E_FAIL;
                }
                return S_OK;
        }
        return E_FAIL;
}
/*----------------------------------------------------------------------------
                                        可选头的读取/设置
-----------------------------------------------------------------------------*/
HRESULT JoperatPe::SetOpHdStrcLong(IMAGE_OPTIONAL_HEADER32 *iph,DWORD dIndex)
{
        if( m_lpf == NULL|| iph == NULL)
                return E_FAIL;
        if(fseek(m_lpf,m_IsNt+0x18,SEEK_SET) == 0)       
        {
                switch(dIndex)
                {
                case SCL_SET:       
                        fwrite(iph,sizeof(IMAGE_OPTIONAL_HEADER32),1,m_lpf);
                        break;
                case SCL_GET:
                        fread(iph,sizeof(IMAGE_OPTIONAL_HEADER32),1,m_lpf);
                        if(iph->Magic != 0x010b)
                                return JE_FAIL;
                        break;
                default:
                        return E_FAIL;
                }
                return S_OK;
        }
        return E_FAIL;
}
/*----------------------------------------------------------------------------------
                                                块表信息
                                                注意: pSctnHdr必须为使用malloc分配的内存且该内存长度必须
                                                          为/块表长度 == 0
-----------------------------------------------------------------------------------*/
HRESULT        JoperatPe::SetSectionHeaderLong(IMAGE_SECTION_HEADER *pSctnHdr,DWORD dIndx)
{
        if(m_lpf == NULL || pSctnHdr == NULL || dIndx == 0 )
        {
                OutputDebugString("操作不明确!\n");
                return E_FAIL;
        }
        int nlen = 0;
        IMAGE_NT_HEADERS MgNtHdr = { 0 };
        try
        {
                //只能使用malloc分配内存
                nlen = _msize((void*)pSctnHdr);               
                if( nlen < sizeof(IMAGE_SECTION_HEADER)*m_dSctnCnt)
                {
                        OutputDebugString("请分配节数的内存空间!");
                        return E_FAIL;
                }
                if(FAILED(SetFileHeaderLong(&MgNtHdr,SCL_GET)))
                {
                        return E_FAIL;
                }
                nlen = MgNtHdr.FileHeader.SizeOfOptionalHeader+FIELD_OFFSET(IMAGE_NT_HEADERS32,OptionalHeader);
                //这里通过计算得到首块的位置
                if(fseek(m_lpf,m_IsNt+nlen,SEEK_SET) == 0)
                {
                        nlen = 0 ;
                        switch(dIndx)
                        {
                        case SCL_GET:
                                nlen = fread(pSctnHdr,sizeof(IMAGE_SECTION_HEADER),m_dSctnCnt,m_lpf);       
                                if(nlen < m_dSctnCnt)
                                        return E_FAIL;
                                break;
                        case SCL_SET:
                                nlen = fwrite(pSctnHdr,sizeof(IMAGE_SECTION_HEADER),m_dSctnCnt,m_lpf);
                                if(nlen < m_dSctnCnt)
                                        return E_FAIL;
                                break;
                        default:
                                return E_FAIL;
                        }
                        return S_OK;
                }
        }
        catch(...)
        {       
                OutputDebugString("文件操作失败\n");
                return S_FALSE;       
        }
        return E_FAIL;
}
/*-------------------------------------------------------------------------------
                                Out Parament:引入函数表指的是该PE文件编译的时候所使用的相关
                                                          PE文件信息
--------------------------------------------------------------------------------*/
HRESULT JoperatPe::SetImportTable(IMAGE_IMPORT_DESCRIPTOR *pImprtDscrptr,DWORD dIndex)
{
        if(pImprtDscrptr == NULL || dIndex == 0)
        {
                return E_FAIL;
        }
        IMAGE_OPTIONAL_HEADER32 MgPtnlHd = { 0 };
        IMAGE_IMPORT_DESCRIPTOR        MgMprtDscrp = { 0 };
        if(FAILED(SetOpHdStrcLong(&MgPtnlHd,SCL_GET)))
        {
                return E_FAIL;
        }
        try
        {
                fseek(m_lpf,MgPtnlHd.DataDirectory[1].VirtualAddress,SEEK_SET);
                fread(&MgMprtDscrp,sizeof(IMAGE_IMPORT_DESCRIPTOR),1,m_lpf);
                char p[MAX_PATH] = { 0 };
                sprintf(p,"%",(char)MgMprtDscrp.Name);

        }
        catch(...)
        {
               
        }

        return E_FAIL;
}
请问PE块中的输入库在PE文件的什么位置或则说只能通过RAV动态得到

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
你是说pe头格式里面的import table吧,看看icelion的PE教程里面有
2007-8-23 09:34
0
游客
登录 | 注册 方可回帖
返回