吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7184|回复: 6
收起左侧

[C&C++ 原创] [vc] dll永久注入exe文件

  [复制链接]
舒默哦 发表于 2020-5-22 18:45
本帖最后由 舒默哦 于 2020-5-22 20:07 编辑




说明:
就是把dll文件拉伸贴在exe文件后面,先执行dll,然后跳回主程序入口继续执行。(其实,dll想什么时候执行就什么时候执行,具体看需求)



遇到的问题:
这儿修复IAT表,不能是静态修复,因为计算机每次重启,系统dll映射到exe程序所在的地址都会变,IAT表必须动态修复。
修复IAT表需要用到"LoadLibraryA"和GetProcAddress两个函数,这两个函数存在于KERNEL32这个DLL中,
可以通过FS寄存器找到进程环境块PEB,得到kernel32的地址,找到GetProcAddress函数所在地址,再通过GetProcAddress找到LoadLibraryA的地址。




具体步骤:
1、分别加载exe和dll到内存
2、给exe添加新节
3、处理dll(拉伸dll和以及修复重定位表)
4、申请新内存(大小=exe文件大小+新节大小)
5、获取dll的入口函数的指针
6、构造ShellCode
7、修改程序入口,跳到ShellCode地址处执行
8、保存文件




实验测试文件用到了LoadPE.exe和test_dll.dll,最后输出的文件是newfile.exe。

test_dll.dll
[C] 纯文本查看 复制代码
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
CString str = "\t注入成功!!!!!\r\n\r\n";
str = str + "\tDLL模块在进程空间中的起始地址:" + (DWORD)hModule;
MessageBox(NULL, str.GetString(), "恭喜", MB_OK);


}

case DLL_THREAD_ATTACH:
//MessageBox(NULL, "DLL_THREAD_ATTACH", "", MB_OK);
case DLL_THREAD_DETACH:
//MessageBox(NULL, "DLL_THREAD_DETACH", "", MB_OK);
case DLL_PROCESS_DETACH:
//MessageBox(NULL, "DLL_PROCESS_DETACH", "", MB_OK);
break;
}
return TRUE;
}


main.cpp
[C] 纯文本查看 复制代码
#include <iostream>
#include <Windows.h>
#include "CString.h"
#include "Shellcode.h"
#define path_exe "c:\\LoadPE.exe"
#define out_path "c:\\newfile.exe"
#define path_dll "C:\\Users\\daddy\\Desktop\\软件代码区\\dll库\\test_dll\\Release\\test_dll.dll"

#define GET_HEADER_DICTIONARY(module, idx)        &(module)->headers->OptionalHeader.DataDirectory[idx]

#ifdef _WIN64
#define POINTER_TYPE ULONGLONG
#else
#define POINTER_TYPE DWORD
#endif

//获取文件的在内存的地址和大小
int GetBuffAddrAndSizeofFile(char* FilePath, _Out_  DWORD* buff, _Out_ DWORD* FileSize, _Out_ DWORD* FileSize1);
//修复重定位表
void PerformBaseRelocation(char* buff, DWORD Value);
//处理dll的函数
DWORD StretchDLL(DWORD pFileBuff,DWORD FileSize,DWORD BaseAddress);
//拉伸文件
DWORD StretchEXE(DWORD pFileBuff, DWORD FileSize);
//文件对齐,返回对齐后的大小
DWORD FileAlignment(DWORD pFileBuf, DWORD FileSize);
//保存文件
void SaveFile(DWORD buffer,DWORD nLength);
//添加新节
void addSeciton(DWORD pFileBuff,DWORD AddSize);


void File_Forever_Inject()
 {
     //1.0 把exe文件加载到内存
     DWORD pFileBuf_exe = 0;//exe在内存中的地址
     DWORD FileSize_exe = 0;//exe的内存大小
     DWORD FileSize_exe_1 = 0;//exe的文件大小
     if (GetBuffAddrAndSizeofFile((char*)path_exe, &pFileBuf_exe, &FileSize_exe, &FileSize_exe_1) == 0)
     {
         return;
     }

     //1.1 把dll文件加载到内存
     DWORD pFileBuf_dll = 0;//dll在内存中的地址
     DWORD FileSize_dll = 0;//dll的内存大小
     DWORD FileSize_dll_1 = 0;//dll的文件大小
     if (GetBuffAddrAndSizeofFile((char*)path_dll, &pFileBuf_dll, &FileSize_dll, &FileSize_dll_1) == 0)
     {
         return;
     }


     //计算添加新节需要的大小
     DWORD NewSectionSize = FileSize_dll + sizeof(Getkernel32Addr) + sizeof(GetprocessAddress) + sizeof(RebuildimportTable) + 0x100;

     //2.添加新节
     addSeciton(pFileBuf_exe, NewSectionSize);


     //3.处理dll(拉伸dll和修复重定位表)
     PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf_exe;
     PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf_exe + pDosHeader->e_lfanew);

     DWORD New_Filesize_dll = StretchDLL(pFileBuf_dll, FileSize_dll, pNtHeader->OptionalHeader.ImageBase + FileSize_exe);
  
      //4.申请新内存 = exe文件大小 + 新节大小
     DWORD nLength = FileSize_exe_1 + NewSectionSize;
     char* TotalBuff = new char[nLength];
     memset(TotalBuff, 0, nLength);
     memcpy(TotalBuff, (void*)pFileBuf_exe, FileSize_exe_1);
     memcpy(TotalBuff + FileSize_exe_1, (char*)New_Filesize_dll, FileSize_dll);
     memcpy(TotalBuff + FileSize_exe_1 + FileSize_dll, Getkernel32Addr, sizeof(Getkernel32Addr));
     memcpy(TotalBuff + FileSize_exe_1 + FileSize_dll + sizeof(Getkernel32Addr), GetprocessAddress, sizeof(GetprocessAddress));
     memcpy(TotalBuff + FileSize_exe_1 + FileSize_dll + sizeof(Getkernel32Addr) + sizeof(GetprocessAddress), RebuildimportTable, sizeof(RebuildimportTable));

     char GetProcAddress_Code[] = {
            0x47 ,0x65 ,0x74 ,0x50 ,0x72 ,0x6F ,0x63 ,0x41 ,0x64 ,0x64 ,0x72 ,0x65 ,0x73 ,0x73
     };

     char LoadLibraryA_Code[] = {
           0x4C ,0x6F  ,0x61  ,0x64  ,0x4C  ,0x69  ,0x62  ,0x72  ,0x61  ,0x72  ,0x79 ,0x41
     };

     memcpy(TotalBuff + nLength - 0x40, GetProcAddress_Code, sizeof(GetProcAddress_Code));
     memcpy(TotalBuff + nLength - 0x30, LoadLibraryA_Code, sizeof(LoadLibraryA_Code));

   
     // 5.获取DLL的入口函数的指针 = exe的基址 + exe添加新节前的内存对齐后的大小 + dll入口

     PIMAGE_DOS_HEADER pDosHeader_dll = (PIMAGE_DOS_HEADER)pFileBuf_dll;
     PIMAGE_NT_HEADERS pNtHeader_dll = (PIMAGE_NT_HEADERS)(pFileBuf_dll + pDosHeader_dll->e_lfanew);
     DWORD OEP_dll = pNtHeader_dll->OptionalHeader.AddressOfEntryPoint;
     DWORD DllEntry = pNtHeader->OptionalHeader.ImageBase + FileSize_exe + OEP_dll;

           
 
     //6.构造shellcode

     //call GetKernel32Addr
     //E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
     DWORD temp = pNtHeader->OptionalHeader.ImageBase + FileSize_exe + FileSize_dll;
     DWORD temp_1 = sizeof(Getkernel32Addr) + sizeof(GetprocessAddress) + sizeof(RebuildimportTable);
     DWORD s_GetKernel32Addr = temp - (temp + temp_1+6) - 5;

     //call MyGetProcessAddress
     //E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
     DWORD s_MyGetProcessAddress = temp + sizeof(Getkernel32Addr) - (temp + temp_1 + 0x14) - 5;

     //call RebuildImportTable
     //E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
     DWORD s_RebuildImportTable = temp + sizeof(Getkernel32Addr) + sizeof(GetprocessAddress) -
         (temp + temp_1 + 0x38) - 5;

     //call DllFunc   调用dll
     //E8 XXXXXXXX = 要跳转的地址-E8所在的地址-5
     DWORD DllFunc = DllEntry - (temp + temp_1 + 0x49) - 5;

     //"GetProcAddress"字符串所在的地址
     DWORD GPA = pNtHeader->OptionalHeader.ImageBase + FileSize_exe + NewSectionSize - 0x40;

     //"LoadLibraryA"字符串所在的地址
     DWORD LLA= pNtHeader->OptionalHeader.ImageBase + FileSize_exe + NewSectionSize - 0x30;

     //DLL模块在进程虚拟空间中的起始地址
     DWORD DLLAddr = pNtHeader->OptionalHeader.ImageBase + FileSize_exe;

     //主程序的入口
     DWORD jmp_orig = pNtHeader->OptionalHeader.AddressOfEntryPoint + pNtHeader->OptionalHeader.ImageBase;

     char ShellCode[] = {
         0x55,
         0x8B,0xEC,
         0x83,0xEC,0x50,
         //0xE8,0x2F,0x7C,0xCE,0xFF,
         0xE8,
         s_GetKernel32Addr & 0xFF,(s_GetKernel32Addr & 0xFF00) >> 8,(s_GetKernel32Addr & 0xFF0000) >> 16,s_GetKernel32Addr >> 24,
         0x89,0x45,0xFC,
         0x68,//0x00,0x00,0x89,0x00,
         GPA & 0xFF,(GPA & 0xFF00) >> 8,(GPA & 0xFF0000) >> 16,GPA >> 24,
         0x50,
         //0xE8,0x21,0x7C,0xFE,0xFF,
         0xE8,
         s_MyGetProcessAddress & 0xFF,(s_MyGetProcessAddress & 0xFF00) >> 8,(s_MyGetProcessAddress & 0xFF0000) >> 16,s_MyGetProcessAddress >> 24,
         0x83,0xC4,0x08,
         0x89,0x45,0xF8,
         0x68,//0x00,0x00,0x45,0x00,
         LLA & 0xFF,(LLA & 0xFF00) >> 8,(LLA & 0xFF0000) >> 16,LLA >> 24,
         0x8B,0x5D,0xFC,
         0x53,
         0xFF,0xD0,
         0x89,0x45,0xF4,
                 
         0x8B,0x5D,0xF8,
         0x53,
         0x8b,0xD0,
         0xB9,
          DLLAddr & 0xFF,(DLLAddr & 0xFF00) >> 8,(DLLAddr & 0xFF0000) >> 16,DLLAddr >> 24,
         //0xE8,0xFB,0x7B,0xC3,0xFF,
         0xE8,
         s_RebuildImportTable & 0xFF,(s_RebuildImportTable & 0xFF00) >> 8,(s_RebuildImportTable & 0xFF0000) >> 16,s_RebuildImportTable >> 24,
         0x83,0xC4,0x04,
         0x6A,0x00,
         0x6A,0x01,
         0x68,//0x00,0x00,0x40,0x00,
         DLLAddr & 0xFF,(DLLAddr & 0xFF00) >> 8,(DLLAddr & 0xFF0000) >> 16,DLLAddr >> 24,
         //0xE8,0xEA,0x7B,0xBE,0x04,
         0xE8,
         DllFunc & 0xFF,(DllFunc & 0xFF00) >> 8,(DllFunc & 0xFF0000) >> 16,DllFunc >> 24,
         0x68,
         //0x00,0x00,0x04,0x00,
         jmp_orig & 0xFF,(jmp_orig & 0xFF00) >> 8,(jmp_orig & 0xFF0000) >> 16,jmp_orig >> 24,
         0xC3
     };
  
     //计算shellcode存放的地址
     DWORD Addr = (DWORD)TotalBuff + FileSize_exe_1 + NewSectionSize - 0x100;

     for (int i = 0; i < sizeof(ShellCode); i++)
     {
         ((char*)Addr)[i] = ShellCode[i];
     }
     

     //7.修改入口
     PIMAGE_DOS_HEADER pDosHeader_New = (PIMAGE_DOS_HEADER)TotalBuff;
     PIMAGE_NT_HEADERS pNtHeader_New = (PIMAGE_NT_HEADERS)(TotalBuff + pDosHeader_New->e_lfanew);
     DWORD New_OEP = FileSize_exe+ NewSectionSize-0x100;
     *&(pNtHeader_New->OptionalHeader.AddressOfEntryPoint) = New_OEP;


     //8.保存文件
     SaveFile((DWORD)TotalBuff, nLength);
 }


int main() 
{
    File_Forever_Inject();
    system("pause");
    return 0;
}



//处理dll的函数
DWORD StretchDLL(DWORD pFileBuff,DWORD FileSize,DWORD BaseAddress)
{
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuff + pDosHeader->e_lfanew);

    //1.1 根据内存大小 申请内存
    char* NewFileBuff = new char[FileSize];
    if (NewFileBuff==NULL)
    {
        printf("内存申请失败!");
        return 0;
    }
    memset(NewFileBuff, 0, FileSize);

    //1.2 拉伸文件
     // 拷贝DOS头 + DOS STUB + PE头到headers地址处
    memcpy(NewFileBuff, pDosHeader, pNtHeader->OptionalHeader.SizeOfHeaders);

    // 从dll文件内容中拷贝每个section(节)的数据到新的内存区域
    PIMAGE_OPTIONAL_HEADER32 OptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileBuff + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)OptionalHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);

    for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++, pSectionHeader++)
    {
        char* x = (char*)NewFileBuff + pSectionHeader->VirtualAddress;
        char* y = (char*)pFileBuff + pSectionHeader->PointerToRawData;
        memcpy(x ,y, pSectionHeader->SizeOfRawData);
    }

    //1.3 修复重定位表
    // 检查加载到进程地址空间的位置和之前PE文件中指定的基地址是否一致,如果不一致,则需要重定位
    int locationDelta = (SIZE_T)((DWORD)BaseAddress - pNtHeader->OptionalHeader.ImageBase);
    if (locationDelta != 0) 
    {
        //修复重定位表
        PerformBaseRelocation((char*)NewFileBuff, locationDelta);

    }

    //1.4 修复IAT表
    // 加载依赖dll,并构建"PEHeader.OptionalHeader.DataDirectory.Image_directory_entry_import"导入表
    /*if (!RebuildImportTable((char*)NewFileBuff, myLoadLibrary, myGetProcAddress))
    {
        printf("修复失败!");
        return 0;
    }*/

    return (DWORD)NewFileBuff;

}

//拉伸文件
DWORD StretchEXE(DWORD pFileBuff, DWORD FileSize)
{
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuff + pDosHeader->e_lfanew);

    //1.1 根据内存大小 申请内存
    char* NewFileBuff = new char[FileSize];
    if (NewFileBuff == NULL)
    {
        printf("内存申请失败!");
        return 0;
    }
    memset(NewFileBuff, 0, FileSize);

    //1.2 拉伸文件
     // 拷贝DOS头 + DOS STUB + PE头到headers地址处
    memcpy(NewFileBuff, pDosHeader, pNtHeader->OptionalHeader.SizeOfHeaders);

    // 从dll文件内容中拷贝每个section(节)的数据到新的内存区域
    PIMAGE_OPTIONAL_HEADER32 OptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileBuff + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)OptionalHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);

    for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++, pSectionHeader++)
    {
        char* x = (char*)NewFileBuff + pSectionHeader->VirtualAddress;
        char* y = (char*)pFileBuff + pSectionHeader->PointerToRawData;
        memcpy(x, y, pSectionHeader->SizeOfRawData);
    }

    return (DWORD)NewFileBuff;
}



//获取文件的在内存的地址和大小
int GetBuffAddrAndSizeofFile(char* FilePath, _Out_ DWORD* buff, _Out_ DWORD* FileSize ,_Out_ DWORD* FileSize1)
{
    //1.1 获取文件句柄
    HANDLE hFile = CreateFile(
        FilePath,
        GENERIC_READ,
        0,
        NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    //1.2 获取文件大小
    DWORD dwFileSize = GetFileSize(hFile, NULL);
    CHAR *pFileBuf = new CHAR[dwFileSize];
    memset(pFileBuf, 0, dwFileSize);

    //1.3 将文件读取到内存
    DWORD ReadSize = 0;
    ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL);

    //1.4 关闭句柄
    CloseHandle(hFile);


    //2.1 判断是否为PE文件
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    {
        printf("不是MZ开头\n");
        return 0;
    }
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
    if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
    {
        printf("不是PE文件\n");
        return 0;
    }

    //2.2 把文件的在内存中的地址和大小分别赋值输出参数
    *buff = (DWORD)pFileBuf;
    *FileSize = (pNtHeader->OptionalHeader.SizeOfImage % pNtHeader->OptionalHeader.SectionAlignment==0) ? 
        (pNtHeader->OptionalHeader.SizeOfImage) : 
        (pNtHeader->OptionalHeader.SizeOfImage- (pNtHeader->OptionalHeader.SizeOfImage % pNtHeader->OptionalHeader.SectionAlignment)+ pNtHeader->OptionalHeader.SectionAlignment);
    *FileSize1 = dwFileSize;
    return 1;
}

//文件对齐,返回对齐后的大小
DWORD FileAlignment(DWORD pFileBuf, DWORD FileSize)
{
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf;
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew);
    DWORD filealign = pNtHeader->OptionalHeader.FileAlignment;
    if (FileSize % filealign==0)
    {
        return FileSize;
    }
    else
    {
        return FileSize - FileSize % filealign + filealign;
    }
}

//保存文件
void SaveFile(DWORD buffer,DWORD nLength)
{
    FILE* fp;
    errno_t err = 0;
    err = fopen_s(&fp,(char*)out_path, "wb");
    if (err!=0)
    {
        printf("file cannot open\n");
        return;
    }

    if (fwrite((char*)buffer, nLength, 1, fp))
        printf("存盘成功!\n");
    else
        printf("存盘失败!\n");

    if (fclose(fp))
        printf("\nfile cannot be closed\n");
}

//添加新节
void addSeciton(DWORD pFileBuff,DWORD AddSize)
{
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuff;
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuff + pDosHeader->e_lfanew);

    PIMAGE_OPTIONAL_HEADER32 OptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileBuff + pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
    PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)OptionalHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);

    //判断节表尾部是否有80个字节的空闲区域
    PIMAGE_SECTION_HEADER pse_temp = pSectionHeader + pNtHeader->FileHeader.NumberOfSections;//节表新增节的首地址
    PIMAGE_SECTION_HEADER pse_temp_b = pSectionHeader + pNtHeader->FileHeader.NumberOfSections - 1;//节表最后一节的首地址
    int space = OptionalHeader->SizeOfHeaders - ((DWORD)pse_temp - pFileBuff);

    //space空间指的是节表最后都是0,没有其他数据,如果有其他数据,则即使满足了有80个字节的空间,也不能添加数据,这样会破坏其他数据
    //如果空间不够,那么,doc头下面的垃圾数据不要了,后面的PE头 标准PE头 和节表上提;
    //并且要判断pDosHeader->e_lfanew-64这段距离是否大于80,否则上提没有意义
    if (pDosHeader->e_lfanew - 64 > 80 && space < 80)
    {
        int len = ((DWORD*)pse_temp - &(pNtHeader->Signature)) * 4;
        for (int i = 0; i < len; i++)
        {
            *((char*)pFileBuff + 64 + i) = *((char*)pFileBuff + i + pDosHeader->e_lfanew);
        }
        pDosHeader->e_lfanew = 0x40;
        
        pse_temp = pSectionHeader + pNtHeader->FileHeader.NumberOfSections;
        pse_temp_b = pSectionHeader + pNtHeader->FileHeader.NumberOfSections - 1;
        for (int i = 0; i < 80; i++)//把节表尾部80个字节格式化
            *((char*)pFileBuff + 64 + i + len) = 0;
        space = pDosHeader->e_lfanew - 64;//更新space空间
    }
    if (space > 80)
    {
        BYTE(*p)[8] = &(pse_temp->Name);
        int name[8] = { 0x2E,0x74,0x74,0x74,0x74 };
        for (int i = 0; i < 8; i++)
            p[0][i] = name[i];

        pse_temp->Misc.VirtualSize = AddSize;

        if (pse_temp_b->Misc.VirtualSize > pse_temp_b->SizeOfRawData)//比较内存大小和文件大小
        {
            //检测内存大小是否对齐
            pse_temp->VirtualAddress = 
                ((pse_temp_b->Misc.VirtualSize % OptionalHeader->SectionAlignment)==0)? pse_temp_b->Misc.VirtualSize :
                (pse_temp_b->Misc.VirtualSize - pse_temp_b->Misc.VirtualSize % OptionalHeader->SectionAlignment + OptionalHeader->SectionAlignment )+
                pse_temp_b->VirtualAddress;
            printf("%X\n", *&(pse_temp->VirtualAddress)); 
        }
        else
        {
            pse_temp->VirtualAddress = 
                ((pse_temp_b->SizeOfRawData % OptionalHeader->SectionAlignment) == 0) ? pse_temp_b->SizeOfRawData :
                (pse_temp_b->SizeOfRawData - pse_temp_b->SizeOfRawData % OptionalHeader->SectionAlignment + OptionalHeader->SectionAlignment) +
                pse_temp_b->VirtualAddress;
        }

        pse_temp->SizeOfRawData = AddSize;
        pse_temp->PointerToRawData = pse_temp_b->SizeOfRawData + pse_temp_b->PointerToRawData;
        pse_temp->Characteristics = 0xE0000020;
        pNtHeader->FileHeader.NumberOfSections = pNtHeader->FileHeader.NumberOfSections + 1;
        pNtHeader->OptionalHeader.SizeOfImage = pNtHeader->OptionalHeader.SizeOfImage + AddSize;        
    }
    else
        printf("添加节失败,没有空间添加新的节!");
}

//修复重定位表
void PerformBaseRelocation(char* buff, DWORD Value)
{
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)buff;
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(buff + pDosHeader->e_lfanew);

    //获取目录表头指针
    PIMAGE_DATA_DIRECTORY pDataDirectory = pNtHeader->OptionalHeader.DataDirectory;
    if (pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > 0)
    {
        PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)((DWORD)buff + pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
        while (relocation->VirtualAddress > 0)
        {
            BYTE* dest = (PBYTE)((DWORD)buff + relocation->VirtualAddress);
            WORD* relInfo = (PWORD)((DWORD)relocation + sizeof(IMAGE_BASE_RELOCATION));
            for (int i = 0; i < ((relocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2); ++i, ++relInfo)
            {
                DWORD *patchAddrHL;
                int type, offset;

                //the upper 4 bits define the type of relocation
                type = *relInfo >> 12;
                //the lower 12 bits define the offset
                offset = *relInfo & 0xFFF;

                switch (type)
                {
                case IMAGE_REL_BASED_ABSOLUTE:
                    //skip relocation
                    break;
                case IMAGE_REL_BASED_HIGHLOW:
                    //change comlete 32 bit address
                    patchAddrHL = (PDWORD)(dest + offset);
                    *patchAddrHL += Value;
                    break;
                default:
                    break;
                }
            }
            //advance to next relocation block
            relocation = PIMAGE_BASE_RELOCATION((DWORD)relocation + relocation->SizeOfBlock);
        }
    }

}






结语:
newfile.exe能够在win10上运行,不能在win7上跑(32位和64位都失败)。
有低版本的编译器的老铁可以试一下,在支持win7的编译器上编译,然后在win7上跑看能不能跑得动


clipboard.png
clipboard1.png
clipboard2.png
clipboard3.png

LoadPE.7z

21.58 KB, 下载次数: 202, 下载积分: 吾爱币 -1 CB

PE解析器

Shellcode.7z

2.88 KB, 下载次数: 137, 下载积分: 吾爱币 -1 CB

Shellcode.h

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

gaobb 发表于 2021-9-11 10:26
这是来骗C币的吗?
hj170520 发表于 2020-5-22 19:10
 楼主| 舒默哦 发表于 2020-5-22 19:13
 楼主| 舒默哦 发表于 2020-5-22 19:17
奇安信要拦截这个dll
clipboard5.png
不名物 发表于 2020-5-23 10:49
纯学习一下吧,包装exe,典型的shellcode模式啊
 楼主| 舒默哦 发表于 2020-5-23 17:20
不名物 发表于 2020-5-23 10:49
纯学习一下吧,包装exe,典型的shellcode模式啊

我只想到这种,还有其他方式吗?还有种方法是把dll分离出exe,放到一个临时文件加载后删掉,这样可以不用修复重定位和IAT表
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 02:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表