ImportDll



#include <windows.h>
#include <ShellAPI.h>
#include <tchar.h>
#include <Tlhelp32.h>
#include <Shlwapi.h>


BOOL ImportDll(LPTSTR PeFileName, char* dllName, char* funName)
{
    // 先备份一个
    size_t len = _tcslen(PeFileName);
    LPTSTR bakfile = (LPTSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len+4)*sizeof(TCHAR));
    _tcscpy(bakfile, PeFileName);
    int i;
    for (i=4; ; i--)
    {
        if ( *(bakfile+len-i) == TEXT('.') || i == 0)
        {
            _tcscpy(bakfile+len-i, (".bak"));
            break;
        }
    }
    CopyFile(PeFileName, bakfile, TRUE);
    HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, bakfile);

    // 读取pe所有数据
    HANDLE handle = CreateFile(PeFileName,
        GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (handle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    DWORD dwBytes = 0;
    DWORD dwsize = GetFileSize(handle, NULL);
    PBYTE buf = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwsize*sizeof(BYTE));
    ReadFile(handle, buf, dwsize, &dwBytes, NULL);

    // 解析
    PIMAGE_DOS_HEADER Header = (PIMAGE_DOS_HEADER)buf;
    PIMAGE_NT_HEADERS peheader =
        (PIMAGE_NT_HEADERS)((LPBYTE)Header + Header->e_lfanew);
    

    // 加一个区段
    IMAGE_SECTION_HEADER new_section = {0};
    strcpy((char*)new_section.Name, ".Patch");
    
    PIMAGE_SECTION_HEADER SectionHeader = (PIMAGE_SECTION_HEADER)( (DWORD)peheader +
                                            sizeof(peheader->FileHeader) +
                                            sizeof(peheader->Signature) +
                                            peheader->FileHeader.SizeOfOptionalHeader ); // 节表项的开始

    // IAT地址
    DWORD VirtualAddress = peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    
    new_section.SizeOfRawData = peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size + strlen(dllName) + strlen(funName) + 14;
    new_section.SizeOfRawData += sizeof(IMAGE_IMPORT_DESCRIPTOR); // 文件大小
    new_section.Misc.VirtualSize = (new_section.SizeOfRawData/peheader->OptionalHeader.SectionAlignment + 1 )*peheader->OptionalHeader.SectionAlignment; // 内存大小
    new_section.Characteristics = IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_INITIALIZED_DATA;

    // 枚举现有区段地址
    for (i=0; i<peheader->FileHeader.NumberOfSections; i++)
    {
        DWORD ulsize = SectionHeader[i].Misc.VirtualSize;
        if ( ulsize > SectionHeader[i].SizeOfRawData )
        {
            ulsize = SectionHeader[i].SizeOfRawData;
        }

        // 找到导入表文件偏移
        if (VirtualAddress >= SectionHeader[i].VirtualAddress &&
            VirtualAddress <= SectionHeader[i].VirtualAddress+SectionHeader[i].Misc.VirtualSize)
        {
            VirtualAddress = VirtualAddress- SectionHeader[i].VirtualAddress + SectionHeader[i].PointerToRawData;
        }
        
        // 加在最后一个区段后面
        if (new_section.VirtualAddress <= SectionHeader[i].VirtualAddress)
        {
            DWORD temp = ulsize%peheader->OptionalHeader.SectionAlignment? (ulsize/peheader->OptionalHeader.SectionAlignment+1)*peheader->OptionalHeader.SectionAlignment: ulsize;
            new_section.VirtualAddress = SectionHeader[i].VirtualAddress + temp;
        }
        if (new_section.PointerToRawData <= SectionHeader[i].PointerToRawData )
        {
            DWORD temp = SectionHeader[i].SizeOfRawData%peheader->OptionalHeader.FileAlignment?
                        (SectionHeader[i].SizeOfRawData/peheader->OptionalHeader.FileAlignment+1)*peheader->OptionalHeader.FileAlignment:
                        SectionHeader[i].SizeOfRawData;
            new_section.PointerToRawData = SectionHeader[i].PointerToRawData + temp;
                
        }
    }

    new_section.SizeOfRawData = peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size+sizeof(IMAGE_IMPORT_DESCRIPTOR)+strlen(dllName)+3+strlen(funName)+1+8;
    memcpy(&SectionHeader[peheader->FileHeader.NumberOfSections], &new_section, sizeof(new_section));

    SetFilePointer(handle, 0, NULL, FILE_BEGIN); // 设置文件尾部
    WriteFile(handle, buf, dwsize, &dwBytes, NULL);
    SetFilePointer(handle, new_section.PointerToRawData, NULL, FILE_BEGIN);
    WriteFile(handle, dllName, strlen(dllName)+1, &dwBytes, NULL);
    WriteFile(handle, "\0\0\0", 2, &dwBytes, NULL);
    WriteFile(handle, funName, strlen(funName)+1, &dwBytes, NULL);
    DWORD FileStart = new_section.VirtualAddress+strlen(dllName)+1;
    WriteFile(handle, &FileStart, 4, &dwBytes, NULL);
    WriteFile(handle, "\0\0\0\0", 4, &dwBytes, NULL);
    WriteFile(handle, buf+VirtualAddress, peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size-sizeof(IMAGE_IMPORT_DESCRIPTOR), &dwBytes, NULL);

    FileStart = new_section.VirtualAddress+strlen(dllName)+3+strlen(funName)+1;
    WriteFile(handle, &FileStart, 4, &dwBytes, NULL);
    WriteFile(handle, "\0\0\0\0\0\0\0\0", 8, &dwBytes, NULL);
    WriteFile(handle, &new_section.VirtualAddress, 4, &dwBytes, NULL);
    WriteFile(handle, &FileStart, 4, &dwBytes, NULL);
    WriteFile(handle, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 0x14, &dwBytes, NULL);

    // 修改Image大小
    DWORD dwIDEI = peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
    if (dwIDEI%peheader->OptionalHeader.SectionAlignment)
    {
        dwIDEI = dwIDEI/peheader->OptionalHeader.SectionAlignment + 1;
    }
    else
    {
        dwIDEI = dwIDEI/peheader->OptionalHeader.SectionAlignment;
    }
    peheader->OptionalHeader.SizeOfImage += peheader->OptionalHeader.SectionAlignment * dwIDEI; // Image 大小变大

    // 输入表地址修改
    peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = new_section.VirtualAddress+strlen(dllName)+3+strlen(funName)+1+8;
    peheader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size += sizeof(IMAGE_IMPORT_DESCRIPTOR);

    // 区段加1
    peheader->FileHeader.NumberOfSections++;

    SetFilePointer(handle, 0, NULL, FILE_BEGIN);
    WriteFile(handle, buf, peheader->OptionalHeader.FileAlignment, &dwBytes, NULL);
    HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, buf);
    CloseHandle(handle);
    return TRUE;
}


int main(int argc, char* argv[])
{
    ImportDll("C:\\YGDP_Assembly.exe", "nilldll.dll", "?nNilldll@@3HA");
    return 0;

}

//from lgj

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值