V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Yeen
V2EX  ›  程序员

问个 win32 技术问题

  •  
  •   Yeen · 2023-02-15 09:40:04 +08:00 · 1898 次点击
    这是一个创建于 651 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有没有办法把一个文件(如 exe 格式)打进一个 dll ,然后在另外一个程序中,调用这个 dll ,释放并执行 exe ?

    13 条回复    2023-02-15 14:08:56 +08:00
    lysS
        1
    lysS  
       2023-02-15 09:44:26 +08:00   ❤️ 1
    可以,exe dll 都是 PE ,PE 有.data 之类的区段
    hhaobao
        2
    hhaobao  
       2023-02-15 09:46:22 +08:00   ❤️ 1
    exe 可以作为资源文件弄进 dll 吧. 然后 dll 运行后释放这个文件到硬盘, 然后运行就好.
    https://learn.microsoft.com/en-us/cpp/windows/resource-files-visual-studio?view=msvc-170
    littlefishcc
        3
    littlefishcc  
       2023-02-15 09:46:53 +08:00   ❤️ 1
    可以,exe 当成资源放进自己的 dll,然后 dll 释放资源然后执行,但这种逻辑容易当成病毒
    Cloutain
        4
    Cloutain  
       2023-02-15 09:49:56 +08:00
    有啥不可以。。。打包文件释放文件,和文件格式无关
    ibinary
        5
    ibinary  
       2023-02-15 10:05:00 +08:00   ❤️ 2
    那不简单,直接把 EXE 当 DLL 的资源. DLL 提供个接口来释放这个资源. 更有甚者可以进行如下操作.
    1.网络下发,DLL 请求网络下载 EXE. exe 是加密的.
    2.直接用 16 进制工具(winhex 010edit)复制 exe 的二进制为 C 代码. 然后 dll 工程新建个.h. 直接将复制的 c 代码粘贴到.h 里面.
    DLL 直接引用. 比如复制的 C 代码如下 char g_exe[0x32342] = {xxx}; DLL 里面提供接口 ReleaseResource();
    代码里这样写 size = sizeof(g_exe)/sizeof(g_exe[0]); writfile(...g_exe,size);
    3.如果当作资源 有对应 API.你需要学一下. 我记得好像有一个叫做 UpdataResource 等相关. 你去搜搜把.
    注意:
    ibinary
        6
    ibinary  
       2023-02-15 10:05:45 +08:00
    注意: exe 最好加密.资源方式等会被杀软报毒.
    Yeen
        7
    Yeen  
    OP
       2023-02-15 10:17:12 +08:00
    @ibinary 好的,试试先,发布前肯定要提交杀软加白
    shellus
        8
    shellus  
       2023-02-15 10:17:46 +08:00   ❤️ 1
    一种可能的方法:

    使用 Visual Studio 创建一个空的 DLL 项目。在该项目中添加一个新的资源文件,将其类型设置为“二进制”,并将要嵌入的 exe 文件添加到该资源文件中。

    编写一个导出函数,该函数将加载并释放嵌入的 exe 文件。例如,下面是一个 C++ 的示例代码:
    ```c++
    #include <windows.h>

    BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    return TRUE;
    }

    extern "C" __declspec(dllexport) int ExecuteEmbeddedFile() {
    HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_EXE_FILE), RT_RCDATA);
    HGLOBAL hResData = LoadResource(NULL, hRes);
    LPVOID lpResData = LockResource(hResData);
    DWORD dwResSize = SizeofResource(NULL, hRes);

    WCHAR szTempPath[MAX_PATH];
    GetTempPath(MAX_PATH, szTempPath);

    WCHAR szTempFileName[MAX_PATH];
    GetTempFileName(szTempPath, L"exe", 0, szTempFileName);

    HANDLE hTempFile = CreateFile(szTempFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hTempFile == INVALID_HANDLE_VALUE) {
    return GetLastError();
    }

    DWORD dwBytesWritten;
    if (!WriteFile(hTempFile, lpResData, dwResSize, &dwBytesWritten, NULL)) {
    CloseHandle(hTempFile);
    return GetLastError();
    }

    CloseHandle(hTempFile);

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (!CreateProcess(szTempFileName, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
    return GetLastError();
    }

    return 0;
    }

    ```
    该函数将在 DLL 中导出,它会在 DLL 被加载时执行。它首先会通过 FindResource 和 LoadResource 函数加载嵌入的 exe 文件,然后通过 GetTempFileName 函数获取一个临时文件名,再通过 CreateFile 函数创建该临时文件并将嵌入的 exe 文件写入其中。最后,它调用 CreateProcess 函数启动该临时文件并执行嵌入的 exe 文件。
    forcecharlie
        9
    forcecharlie  
       2023-02-15 10:34:41 +08:00
    类似自解压软件的逻辑,可以把 exe 追加到 dll 尾部,然后解析 PE ,算出所有 sections 的大小就可以得出 exe 的偏移,然后解压出来。PE 文件可以,POSIX 系统中 ELF 也可以这么玩。
    Chad0000
        10
    Chad0000  
       2023-02-15 10:36:51 +08:00
    OP 你有 ChatGPT 或许就不用上 V 站问了。
    ming61177
        11
    ming61177  
       2023-02-15 10:52:06 +08:00
    你好,这是必应。根据我在网上找到的信息,有一些方法可以把一个 exe 文件打包到一个 dll 中,然后在另一个程序中调用这个 dll ,释放并执行 exe 。¹²³⁴⁵⁶

    一种方法是使用 winrar 这样的压缩软件,把 exe 文件和 dll 文件以及图标文件放到一个文件夹内,然后选择“添加到压缩文件”,并勾选“创建自解压格式压缩文件”框。然后在“高级”选项卡中,点击“自解压选项”,在“设置”选项卡中,选择“隐藏全部”和“暂时解压到临时文件夹”,在“模式”选项卡中,选择“解压后运行”并填入 exe 文件的名称,最后点击“确定”和“确定”完成打包。²³

    另一种方法是使用代码,把 exe 文件作为嵌入的资源打包到 dll 文件中,然后在 dll 文件中定义一个导出函数,用于释放和执行 exe 文件。具体的步骤如下:

    - 在 dll 项目中,添加 exe 文件到资源文件夹中,右键选择“属性”,在“生成操作”中选择“嵌入的资源”,在“复制到输出目录”中选择“始终复制”。
    - 在 dll 项目中,添加一个类,定义一个导出函数,比如 RunExe ,用于释放和执行 exe 文件。在函数中,使用 Assembly.GetExecutingAssembly().GetManifestResourceNames() 获取嵌入的资源名称,使用 Assembly.GetExecutingAssembly().GetManifestResourceStream() 获取嵌入的资源流,使用 File.WriteAllBytes() 将资源流写入到临时文件夹中,使用 Process.Start() 启动临时文件,使用 File.Delete() 删除临时文件。
    - 在 dll 项目中,添加一个 Module ,使用 <Module: _declspec(dllexport)> 修饰符,将 RunExe 函数导出到 dll 文件中。
    - 在调用 dll 的程序中,使用 LoadLibrary() 加载 dll 文件,使用 GetProcAddress() 获取 RunExe 函数的地址,使用 Invoke() 调用 RunExe 函数,使用 FreeLibrary() 释放 dll 文件。⁴

    希望这些信息对你有帮助。😊

    Source: Conversation with Bing, 2023/2/15(1) dll 打进 exe ,打包成单一的启动文件_nuolo 的博客-CSDN 博客. https://blog.csdn.net/qq_37574876/article/details/97808554 Accessed 2023/2/15.
    (2) 将 exe 和 dll 文件打包成单一的启动文件 - Alvin-fan - 博客园. https://www.cnblogs.com/fxd980519/articles/4807756.html Accessed 2023/2/15.
    (3) 快速把 exe 文件和 dll 文件打包成一个可执行文件_不打烊的咩的博客-CSDN 博客. https://blog.csdn.net/weixin_42479416/article/details/109011648 Accessed 2023/2/15.
    (4) exe 可执行文件与 dll 动态库打包_DylanHe215 的博客-CSDN 博客_exe+dll 打包单文件工具. https://blog.csdn.net/qq_24601427/article/details/104569045 Accessed 2023/2/15.
    (5) 如何把 EXE 文件封装到 DLL 文件中-CSDN 社区. https://bbs.csdn.net/topics/330172096 Accessed 2023/2/15.
    (6) 如何将.exe 改为.dll_zhuyun1111 的博客-CSDN 博客_exe 转 dll. https://blog.csdn.net/zhuyun1111/article/details/612568 Accessed 2023/2/15.






    我只是想知道 Bing 的回答有没有用,没有灌水的意思,本人也不懂 win32
    blinue
        12
    blinue  
       2023-02-15 11:48:29 +08:00
    好奇你的使用场景,为什么不直接分发 exe ?
    r3a1ex0n0
        13
    r3a1ex0n0  
       2023-02-15 14:08:56 +08:00
    这么搞肯定报毒
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4632 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 10:09 · PVG 18:09 · LAX 02:09 · JFK 05:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.