移动导出表

#include<iostream>
#include<malloc.h>
#include<Windows.h>
#include<tchar.h>
#include<string.h>
#pragma warning(disable:4996)
#pragma warning(disable:6387)
using namespace std;
int filelen(FILE* pfile)
{
    fseek(pfile, 0, SEEK_END);
    int result = ftell(pfile);
    rewind(pfile);
    return result;
}
int Align(int x, int y)
{
    if (x % y == 0)
    {
        return int(x / y)*y;
    }
    else
    {
        return int(x / y)*y + y;
    }
}
int rvaTofoa(int rva, char* buffer)
{
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    if (rva <= int(pOH->SizeOfHeaders))
    {
        return rva;
    }
    else
    {
        for (int i = 0; i < int(pFH->NumberOfSections); i++)
        {
            if ((rva >= int(pSecH[i].VirtualAddress)) &&( rva <=  int(pSecH[i].VirtualAddress + pSecH[i].Misc.VirtualSize)))
            {
                return rva - pSecH[i].VirtualAddress + pSecH[i].PointerToRawData;
            }
        }
    }
    printf(" rvaTofoa error\r\n");
    return 0;
}
int foaTorva(int foa, char* buffer)
{
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    if (foa <= int(pOH->SizeOfHeaders))
    {
        return foa;
    }
    else
    {
        for (int i = 0; i < int(pFH->NumberOfSections); i++)
        {
            if ((foa >= int(pSecH[i].PointerToRawData)) && (foa <= int(pSecH[i].PointerToRawData + pSecH[i].SizeOfRawData)))
            {
                return foa - pSecH[i].PointerToRawData + pSecH[i].VirtualAddress;
            }
        }
    }
    printf(" foaTorva error\r\n");
    return 0;
}
/*
    typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;                // 未使用
        DWORD   TimeDateStamp;                // 时间戳
        WORD    MajorVersion;                // 未使用
        WORD    MinorVersion;                // 未使用
        DWORD   Name;                // 指向该导出表文件名字符串
        DWORD   Base;                // 导出函数起始序号
        DWORD   NumberOfFunctions;                // 所有导出函数的个数
        DWORD   NumberOfNames;                // 以函数名字导出的函数个数
        DWORD   AddressOfFunctions;     // 导出函数地址表RVA
        DWORD   AddressOfNames;         // 导出函数名称表RVA
        DWORD   AddressOfNameOrdinals;  // 导出函数序号表RVA
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

*/
void printExportDir(PIMAGE_EXPORT_DIRECTORY pED,char* buffer)
{
    int nameFAddress = rvaTofoa(pED->Name, buffer);
    char* name = buffer + nameFAddress;
    printf("导出表文件名字为:%s\r\n", name);
    printf("Characteristics:  %08x\r\n", pED->Characteristics);
    printf("TimeDateStamp:  %08x\r\n", pED->TimeDateStamp);
    printf("MajorVersion:  %04x\r\n", pED->MajorVersion);
    printf("MinorVersion:  %04x\r\n", pED->MinorVersion);
    printf("Name:  %08x\r\n", pED->Name);
    printf("Base:  %08x\r\n", pED->Base);
    printf("NumberOfFunctions:  %08x\r\n", pED->NumberOfFunctions);
    printf("NumberOfNames:  %08x\r\n", pED->NumberOfNames);
    printf("AddressOfFunctions:  %08x\r\n", pED->AddressOfFunctions);
    printf("AddressOfNames:  %08x\r\n", pED->AddressOfNames);
    printf("AddressOfNameOrdinals:  %08x\r\n", pED->AddressOfNameOrdinals);
}
int GetFunctionAddrByName(char* buffer, char* name)
{
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
    int exportVAddress = pDD->VirtualAddress;
    //printf("%08x\r\n", exportAddress);
    int exportFAddress = rvaTofoa(exportVAddress, buffer);
    PIMAGE_EXPORT_DIRECTORY pED = (PIMAGE_EXPORT_DIRECTORY)(buffer + exportFAddress);
    //先在DWORD   AddressOfNames; // 导出函数名称表RVA中寻找
    int* FAddressOfNames = (int*)(rvaTofoa(pED->AddressOfNames,buffer)+buffer);//先得到函数名表在文件中的地址
    printf("函数名表在文件中的地址%08x\r\n", rvaTofoa(pED->AddressOfNames, buffer));
    int num = -1;
    for (int i = 0; i < int(pED->NumberOfNames); i++)
    {
        //从中取出函数名的rva地址
        int rvaOfname = (int) * (FAddressOfNames + i);
        //转化为函数名在文件中地址
        char* fileOfname = (char*)(buffer + rvaTofoa(rvaOfname, buffer));
        printf("%s\r\n", fileOfname);
        if (strcmp(fileOfname, name) == 0)
        {
            num = i;
            break;
        }
    }
    printf("%d\r\n", num);
    //用获得的索引从序号表中找函数的序号 此处易错类型为word
    WORD ord = *((WORD*)(rvaTofoa(pED->AddressOfNameOrdinals,buffer) + buffer) + num);
    printf("%d\r\n", ord);
    //用查到的序号查函数地址
    int add = *((int*)(rvaTofoa(pED->AddressOfFunctions,buffer) + buffer) + ord);
    return add;
}
int GetFunctionAddrByOrdinals(char* buffer, int num)
{
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
    int exportVAddress = pDD->VirtualAddress;
    int exportFAddress = rvaTofoa(exportVAddress, buffer);
    PIMAGE_EXPORT_DIRECTORY pED = (PIMAGE_EXPORT_DIRECTORY)(buffer + exportFAddress);
    int ordbase = pED->Base;
    int ord = num - ordbase;
    int add = *((int*)(rvaTofoa(pED->AddressOfFunctions, buffer) + buffer) + ord);
    return add;
}
void printReloc(char* buffer)
{
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
    int relocVAddress = pDD[5].VirtualAddress;
    //printf("%08x\r\n", relocVAddress);
    PIMAGE_BASE_RELOCATION pBR = (PIMAGE_BASE_RELOCATION)(rvaTofoa(relocVAddress, buffer) + buffer);
    //printf("%08x\r\n", rvaTofoa(relocVAddress, buffer));
    for (int i = 0; (int*)pBR->VirtualAddress != 0; i++)
    {
        printf("===========BASEreloc[%d]==========\r\n", i);
        printf("VirtualAddress:%08x\r\n", pBR->VirtualAddress);
        printf("SizeofBlock:%08x\r\n", pBR->SizeOfBlock);
        int SizeofBlock = pBR->SizeOfBlock;
        int num = (SizeofBlock - 8) / 2;
        PWORD p = (PWORD)((char*)pBR + 8);
        for (int j = 0; j < num; j++)
        {
            int type = (*(p + j) & 0xF000) >> 12;
            int Address = (*(p + j) & 0x0FFF)+ pBR->VirtualAddress;
            printf("type:%x  Address:%08x\r\n", type, Address);
        }
        pBR=(PIMAGE_BASE_RELOCATION)((char*)pBR+pBR->SizeOfBlock);
    }

}
char* AddNewSection(char* buffer, int newLen,int len)
{
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    int numOfsection = pFH->NumberOfSections;
    //修改节的数目
    pFH->NumberOfSections = numOfsection + 1;
    int agoImageSize = pOH->SizeOfImage;
    pOH->SizeOfImage = pOH->SizeOfImage + newLen - len;
    int space = 0;
    int ord = 0;
    for (int i = 0; i < numOfsection; i++)
    {
        if (strcmp((char*) & (pSecH[i].Name), ".text") == 0)
        {
            ord = i;
        }
    }
    //cout << ord << endl;
    space = int(buffer)+pSecH[ord].PointerToRawData - int( & pSecH[numOfsection]);
    //cout << hex<<space << endl;
    if (space < 80)
    {
        cout << "space not enough" << endl;
        exit(0);
    }
    memcpy(&pSecH[numOfsection], &pSecH[ord], 0x28);
    char* name = (char*)(&pSecH[numOfsection].Name);
    memcpy(name, ".NewSec", 7);
    pSecH[numOfsection].Misc.VirtualSize = newLen - len;
    pSecH[numOfsection].PointerToRawData = len;
    pSecH[numOfsection].SizeOfRawData = newLen - len;
    pSecH[numOfsection].VirtualAddress = agoImageSize;
    char* newbuffer = NULL;
    newbuffer = (char*)malloc(newLen * sizeof(char));
    memcpy(newbuffer, buffer, len);
    return newbuffer;
}
void moveExport(char* buffer)
{
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    PIMAGE_DATA_DIRECTORY pDD = (PIMAGE_DATA_DIRECTORY)(pOH->DataDirectory);
    int vaOfexport = pDD[0].VirtualAddress;
    int numOfsec = pFH->NumberOfSections;
    PIMAGE_EXPORT_DIRECTORY pED = (PIMAGE_EXPORT_DIRECTORY)(buffer + rvaTofoa(vaOfexport, buffer));
    //    复制AddressOfFunctions
    int numofFun = pED->NumberOfFunctions;
    int VAofFuntable = pED->AddressOfFunctions;
    char* FAofFuntable = buffer + rvaTofoa(VAofFuntable, buffer);
    int numOfsecs = pFH->NumberOfSections;
    char* begin = pSecH[numOfsecs - 1].PointerToRawData+buffer;
    memcpy(begin, FAofFuntable, numofFun * 4);
    //复制AddressOfNameOrdinals
    int numofname = pED->NumberOfNames;
    int VAofNameOrdinals = pED->AddressOfNameOrdinals;
    char* FAofNameOrdinals = buffer + rvaTofoa(VAofNameOrdinals, buffer);
    char* ordbegin = begin +numofFun*4;
    memcpy(ordbegin, FAofNameOrdinals, numofname * 2);
    //复制AddressOfNames
    int VAofAddressOfNames = pED->AddressOfNames;
    char* FAofAddressOfNames = buffer + rvaTofoa(VAofAddressOfNames, buffer);
    char* nameAbegin = ordbegin + numofname * 2;
    memcpy(nameAbegin, FAofAddressOfNames, numofname*4);
    //复制函数名并修正AddressOfNames
    char* namebegin = nameAbegin + numofname * 4;
    for (int j = 0; j < numofname; j++)
    {
        //得到某个函数名虚拟地址
        int VAofname = *((int*)FAofAddressOfNames + j);
        //得到其文件地址
        char* FAofname = buffer + rvaTofoa(VAofname, buffer);
        //计算其长度,记得保留\0的位置
        int namelen = strlen(FAofname)+1;
        //复制过去
        memcpy(namebegin, FAofname, namelen);
        //复制过去之后,计算其虚拟地址
        int VAnamebegin = (int)foaTorva(int(namebegin-buffer), buffer);
        //修正
        int* nameAddress = (int*)(nameAbegin + 4 * j);
        *nameAddress = VAnamebegin;
        namebegin = namebegin + namelen;
    }
    //复制IMAGE_EXPORT_DIRECTORY
    memcpy(namebegin, (char*)pED, sizeof(IMAGE_EXPORT_DIRECTORY) / sizeof(char));
    //修正IMAGE_EXPORT_DIRECTORY
    pED->AddressOfFunctions = pSecH[numOfsecs - 1].PointerToRawData;
    pED->AddressOfNameOrdinals = pSecH[numOfsecs - 1].PointerToRawData + numofFun * 4;
    pED->AddressOfNames = pSecH[numOfsecs - 1].PointerToRawData + numofFun * 4 + numofname * 2;
    //修改目录项中的值
    pDD[0].VirtualAddress = (int)foaTorva(int(namebegin - buffer), buffer);
    
}


int main()
{
    FILE* pfile = fopen("C://Users//52511//Desktop//1.dll","rb");
    FILE* pfile1 = fopen("C://Users//52511//Desktop//2.dll", "wb");
    char* buffer = NULL;
    int len = filelen(pfile);
    buffer = (char*)malloc(len * sizeof(char));
    if (buffer == NULL)
    {
        exit(0);
    }
    memset(buffer, 0, len);
    fread(buffer, 1, len, pfile);
    PIMAGE_DOS_HEADER pDosH = (PIMAGE_DOS_HEADER)(buffer);
    PIMAGE_NT_HEADERS pNTH = (PIMAGE_NT_HEADERS)(buffer + pDosH->e_lfanew);
    PIMAGE_FILE_HEADER pFH = (PIMAGE_FILE_HEADER)((char*)pNTH + 0x4);
    PIMAGE_OPTIONAL_HEADER pOH = (PIMAGE_OPTIONAL_HEADER)((char*)pFH + 0x14);
    int opHeaderLen = int(pFH->SizeOfOptionalHeader);
    PIMAGE_SECTION_HEADER pSecH = (PIMAGE_SECTION_HEADER)((char*)pOH + opHeaderLen);
    int sectionLen = 0x1000;
    int newLen = len + sectionLen;
    char* newbuffer = AddNewSection(buffer, newLen, len);
    moveExport(newbuffer);
    fwrite(newbuffer, 1, newLen, pfile1);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力不当无业游民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值