Dll 文件脱壳

在分析样本时偶尔会遇到加保护壳的 Dll 文件,脱起来比较麻烦。由于加壳 Dll 文件的壳代码都是在 DllMain() 函数中,在调用 LoadLibrary() 加载 Dll 文件时,主函数就会执行。因此可以写个程序加载 Dll 文件,然后 Dump 出来,即可完成脱壳。虽然不能确定入口点和修复导入表,但代码部分应该都是正常的。具体代码如下:

#include <windows.h>
#include <winnt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    if (argc>3 || argc<2)
    {
        printf("Usage: DllUnpack <filename> [dumplength]/n");
        return -1;
    }

    int nRetVal = 0;
    HMODULE hModule = NULL;
    unsigned uModuleOffset, uLength, uSectionNum;
    unsigned i;
    char szUnpackFileName[MAX_PATH];
    char *endptr = NULL;
    FILE *pFileOut = NULL;
    DWORD dwOldProtect;
    IMAGE_DOS_HEADER *pDosHeader;
    IMAGE_FILE_HEADER *pFileHeader;
    IMAGE_SECTION_HEADER *pSectionHeader = NULL;
    IMAGE_SECTION_HEADER *pLastSectionHeader = NULL;

    hModule = LoadLibrary(argv[1]);
    if (hModule == NULL)
    {
        printf("Error: cannot load dll %s!/n", argv[1]);
        return -1;
    }
    strncpy(szUnpackFileName, argv[1], MAX_PATH-5);
    strcat(szUnpackFileName, "_un");
    uModuleOffset = (unsigned)hModule;
    //Get unapcked file size
    VirtualProtect((LPVOID)uModuleOffset, 0x1000, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    pDosHeader = (IMAGE_DOS_HEADER *)uModuleOffset;
    pFileHeader = (IMAGE_FILE_HEADER *)(uModuleOffset + pDosHeader->e_lfanew + sizeof(DWORD));
    uSectionNum = pFileHeader->NumberOfSections;
    pSectionHeader = (IMAGE_SECTION_HEADER *)((unsigned)pFileHeader +
                        sizeof(IMAGE_FILE_HEADER) + pFileHeader->SizeOfOptionalHeader);
    if (argc == 3)
    {       
        uLength = (unsigned)strtol(argv[2], &endptr, 16);
    }
    else
    {
        pLastSectionHeader = (IMAGE_SECTION_HEADER *)((unsigned)pSectionHeader +
                                (uSectionNum-1)*sizeof(IMAGE_SECTION_HEADER));
        uLength = pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize;
    }
    //Modify the section table
    for (i=0; i<uSectionNum;i++)
    {
        pSectionHeader[i].PointerToRawData = pSectionHeader[i].VirtualAddress;
        pSectionHeader[i].SizeOfRawData = pSectionHeader[i].Misc.VirtualSize;
    }
    VirtualProtect((LPVOID)uModuleOffset, 0x1000, dwOldProtect, NULL);

    //Creates the unpacked file
    if ((pFileOut=fopen(szUnpackFileName, "wb")) == NULL)
    {
        printf("Error: cannot create file %s/n", szUnpackFileName);
        nRetVal = -1;
        goto Exit0;
    }
    if (fwrite((void *)uModuleOffset, uLength, 1, pFileOut) != 1)
    {
        printf("Error: cannot write to file %s/n", szUnpackFileName);
        nRetVal = -1;       
    }
Exit0:
    if (pFileOut)
    {
        fclose(pFileOut);
        pFileOut = NULL;
    }
    if (hModule)
    {
        FreeLibrary(hModule);
    }   
    return nRetVal;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值