【问题标题】:How to create a native C++ DLL that I can run with rundll32.exe without specifying an entry point如何创建一个可以使用 rundll32.exe 运行而不指定入口点的本机 C++ DLL
【发布时间】:2021-08-21 01:59:37
【问题描述】:

我将如何创建一个可以使用 rundll32.exe 执行的本机 dll 无需指定入口点:

示例:

C: \> rundll32.exe mydll.dll

我在 Visual Studio 上创建了一个 DLL 项目,但我不知道将代码放在哪里:

  • Visual Studio 生成的 DLL 项目模板
// dllmain.cpp : Définit le point d'entrée de l'application DLL.
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
  • 我想用 dll 运行的代码:
#include <stdio.h>
#include <stdlib.h>

// enable cross compiling
#ifdef __linux__
#include <sys/mman.h>
#elif _WIN32 || _MINGW_
#include <windows.h>
#endif


void main()
{
    const char shellcode[] = "\x48\x83\xec\x48\x48\x83\xe4\xf0\x4c\x8d\x44\x24\x28\x48\x8d\x15\xda\x01\x00\x00\x48\x8d\x0d\xc6\x01\x00\x00\xe8\x64\x00\x00\x00\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x30\x48\x8d\x15\xca\x01\x00\x00\x48\x8d\x0d\xa9\x01\x00\x00\xe8\x47\x00\x00\x00\x48\x8d\x0d\xc3\x01\x00\x00\xff\x54\x24\x28\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x38\x48\x8d\x15\xb9\x01\x00\x00\x48\x8d\x0d\xa7\x01\x00\x00\xe8\x1f\x00\x00\x00\x4d\x31\xc9\x4c\x8d\x05\xcb\x01\x00\x00\x48\x8d\x15\xa8\x01\x00\x00\x48\x31\xc9\xff\x54\x24\x38\x48\x31\xc9\xff\x54\x24\x30\x48\x81\xec\x68\x01\x00\x00\x48\x89\x5c\x24\x28\x48\x89\x6c\x24\x30\x48\x89\x7c\x24\x38\x48\x89\x74\x24\x40\x4c\x89\x64\x24\x48\x4c\x89\x6c\x24\x50\x4c\x89\x74\x24\x58\x4c\x89\x7c\x24\x60\x65\x4c\x8b\x1c\x25\x60\x00\x00\x00\x4d\x8b\x5b\x18\x4d\x8d\x5b\x10\x4d\x89\xdf\x4d\x8b\x1b\xfc\x49\x8b\x7b\x60\x48\x89\xce\xac\x84\xc0\x74\x26\x8a\x27\x80\xfc\x61\x7c\x03\x80\xec\x20\x38\xc4\x75\x08\x48\xff\xc7\x48\xff\xc7\xeb\xe5\x4d\x8b\x1b\x4d\x39\xfb\x75\xd6\x48\x31\xc0\xe9\xb1\x00\x00\x00\x49\x8b\x5b\x30\x44\x8b\x63\x3c\x49\x01\xdc\x49\x81\xc4\x88\x00\x00\x00\x45\x8b\x2c\x24\x4d\x85\xed\x75\x08\x48\x31\xc0\xe9\x8e\x00\x00\x00\x4e\x8d\x1c\x2b\x45\x8b\x74\x24\x04\x4d\x01\xee\x41\x8b\x4b\x18\x45\x8b\x53\x20\x49\x01\xda\xff\xc9\x4d\x8d\x24\x8a\x41\x8b\x3c\x24\x48\x01\xdf\x48\x89\xd6\xa6\x75\x08\x8a\x06\x84\xc0\x74\x09\xeb\xf5\xe2\xe5\x48\x31\xc0\xeb\x55\x45\x8b\x63\x24\x49\x01\xdc\x66\x41\x8b\x0c\x4c\x45\x8b\x63\x1c\x49\x01\xdc\x41\x8b\x04\x8c\x4c\x39\xe8\x7c\x36\x4c\x39\xf0\x73\x31\x48\x8d\x34\x18\x48\x8d\x7c\x24\x68\xa4\x80\x3e\x2e\x75\xfa\xa4\xc7\x07\x44\x4c\x4c\x00\x4d\x89\xc6\x48\x8d\x4c\x24\x68\x41\xff\xd1\x4d\x89\xf0\x48\x8d\x4c\x24\x68\x48\x89\xf2\xe9\x08\xff\xff\xff\x48\x01\xd8\x49\x89\x00\x48\x8b\x5c\x24\x28\x48\x8b\x6c\x24\x30\x48\x8b\x7c\x24\x38\x48\x8b\x74\x24\x40\x4c\x8b\x64\x24\x48\x4c\x8b\x6c\x24\x50\x4c\x8b\x74\x24\x58\x4c\x8b\x7c\x24\x60\x48\x81\xc4\x68\x01\x00\x00\xc3\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x44\x4c\x4c\x00\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x41\x00\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x55\x53\x45\x52\x33\x32\x2e\x44\x4c\x4c\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\x48\x69\x20\x66\x72\x6f\x6d\x20\x69\x6e\x6a\x65\x63\x74\x65\x64\x20\x73\x68\x65\x6c\x6c\x63\x6f\x64\x65\x21\x00\x53\x68\x65\x6c\x6c\x63\x6f\x64\x65\x54\x6f\x4a\x53\x63\x72\x69\x70\x74\x20\x50\x6f\x43\x20\x00";
    PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
    DWORD threadID;
    HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
    WaitForSingleObject(hThread, INFINITE);
}

【问题讨论】:

    标签: c++ visual-c++ dll shellcode rundll32


    【解决方案1】:

    rundll32的入口点参数非可选,必须指定入口点,否则rundll32不知道调用哪个函数。没有“默认”入口点。

    要被 rundll32 调用,您必须导出具有以下签名之一的函数:

    void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR pszCmdLine, int nCmdShow)
    
    void CALLBACK EntryPointA(HWND hwnd, HINSTANCE hinst, LPSTR pszCmdLine, int nCmdShow)
    
    void CALLBACK EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR pszCmdLine, int nCmdShow)
    

    例如:

    #include "pch.h"
    
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
                         )
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        }
        return TRUE;
    }
    
    __declspec(dllexport) void CALLBACK myFunc(HWND, HINSTANCE, LPSTR, int)
    {
        const char shellcode[] = "\x48\x83\xec\x48\x48\x83\xe4\xf0\x4c\x8d\x44\x24\x28\x48\x8d\x15\xda\x01\x00\x00\x48\x8d\x0d\xc6\x01\x00\x00\xe8\x64\x00\x00\x00\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x30\x48\x8d\x15\xca\x01\x00\x00\x48\x8d\x0d\xa9\x01\x00\x00\xe8\x47\x00\x00\x00\x48\x8d\x0d\xc3\x01\x00\x00\xff\x54\x24\x28\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x38\x48\x8d\x15\xb9\x01\x00\x00\x48\x8d\x0d\xa7\x01\x00\x00\xe8\x1f\x00\x00\x00\x4d\x31\xc9\x4c\x8d\x05\xcb\x01\x00\x00\x48\x8d\x15\xa8\x01\x00\x00\x48\x31\xc9\xff\x54\x24\x38\x48\x31\xc9\xff\x54\x24\x30\x48\x81\xec\x68\x01\x00\x00\x48\x89\x5c\x24\x28\x48\x89\x6c\x24\x30\x48\x89\x7c\x24\x38\x48\x89\x74\x24\x40\x4c\x89\x64\x24\x48\x4c\x89\x6c\x24\x50\x4c\x89\x74\x24\x58\x4c\x89\x7c\x24\x60\x65\x4c\x8b\x1c\x25\x60\x00\x00\x00\x4d\x8b\x5b\x18\x4d\x8d\x5b\x10\x4d\x89\xdf\x4d\x8b\x1b\xfc\x49\x8b\x7b\x60\x48\x89\xce\xac\x84\xc0\x74\x26\x8a\x27\x80\xfc\x61\x7c\x03\x80\xec\x20\x38\xc4\x75\x08\x48\xff\xc7\x48\xff\xc7\xeb\xe5\x4d\x8b\x1b\x4d\x39\xfb\x75\xd6\x48\x31\xc0\xe9\xb1\x00\x00\x00\x49\x8b\x5b\x30\x44\x8b\x63\x3c\x49\x01\xdc\x49\x81\xc4\x88\x00\x00\x00\x45\x8b\x2c\x24\x4d\x85\xed\x75\x08\x48\x31\xc0\xe9\x8e\x00\x00\x00\x4e\x8d\x1c\x2b\x45\x8b\x74\x24\x04\x4d\x01\xee\x41\x8b\x4b\x18\x45\x8b\x53\x20\x49\x01\xda\xff\xc9\x4d\x8d\x24\x8a\x41\x8b\x3c\x24\x48\x01\xdf\x48\x89\xd6\xa6\x75\x08\x8a\x06\x84\xc0\x74\x09\xeb\xf5\xe2\xe5\x48\x31\xc0\xeb\x55\x45\x8b\x63\x24\x49\x01\xdc\x66\x41\x8b\x0c\x4c\x45\x8b\x63\x1c\x49\x01\xdc\x41\x8b\x04\x8c\x4c\x39\xe8\x7c\x36\x4c\x39\xf0\x73\x31\x48\x8d\x34\x18\x48\x8d\x7c\x24\x68\xa4\x80\x3e\x2e\x75\xfa\xa4\xc7\x07\x44\x4c\x4c\x00\x4d\x89\xc6\x48\x8d\x4c\x24\x68\x41\xff\xd1\x4d\x89\xf0\x48\x8d\x4c\x24\x68\x48\x89\xf2\xe9\x08\xff\xff\xff\x48\x01\xd8\x49\x89\x00\x48\x8b\x5c\x24\x28\x48\x8b\x6c\x24\x30\x48\x8b\x7c\x24\x38\x48\x8b\x74\x24\x40\x4c\x8b\x64\x24\x48\x4c\x8b\x6c\x24\x50\x4c\x8b\x74\x24\x58\x4c\x8b\x7c\x24\x60\x48\x81\xc4\x68\x01\x00\x00\xc3\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x44\x4c\x4c\x00\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x41\x00\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x55\x53\x45\x52\x33\x32\x2e\x44\x4c\x4c\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\x48\x69\x20\x66\x72\x6f\x6d\x20\x69\x6e\x6a\x65\x63\x74\x65\x64\x20\x73\x68\x65\x6c\x6c\x63\x6f\x64\x65\x21\x00\x53\x68\x65\x6c\x6c\x63\x6f\x64\x65\x54\x6f\x4a\x53\x63\x72\x69\x70\x74\x20\x50\x6f\x43\x20\x00";
        PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (shellcode_exec) {
            RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
            DWORD dwOldProtect;
            if (VirtualProtect(shellcode_exec, sizeof shellcode, PAGE_EXECUTE, &dwOldProtect)) {
                FlushInstructionCache(GetCurrentProcess(), shellcode_exec, sizeof shellcode);
                DWORD threadID;
                HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
                if (hThread) {
                    WaitForSingleObject(hThread, INFINITE);
                    CloseHandle(hThread);
                }
            }
            VirtualFree(shellcode_exec, 0, MEM_RELEASE);
        }
    }
    
    C: \> rundll32.exe mydll.dll,myFunc <optional parameters here>
    

    仅供参考,您实际上根本不需要工作线程,您可以像任何其他函数一样直接执行 shell 代码:

    __declspec(dllexport) void CALLBACK myFunc(HWND hwnd, HINSTANCE hinst, LPSTR pszCmdLine, int nCmdShow)
    {
        const char shellcode[] = "\x48\x83\xec\x48\x48\x83\xe4\xf0\x4c\x8d\x44\x24\x28\x48\x8d\x15\xda\x01\x00\x00\x48\x8d\x0d\xc6\x01\x00\x00\xe8\x64\x00\x00\x00\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x30\x48\x8d\x15\xca\x01\x00\x00\x48\x8d\x0d\xa9\x01\x00\x00\xe8\x47\x00\x00\x00\x48\x8d\x0d\xc3\x01\x00\x00\xff\x54\x24\x28\x4c\x8b\x4c\x24\x28\x4c\x8d\x44\x24\x38\x48\x8d\x15\xb9\x01\x00\x00\x48\x8d\x0d\xa7\x01\x00\x00\xe8\x1f\x00\x00\x00\x4d\x31\xc9\x4c\x8d\x05\xcb\x01\x00\x00\x48\x8d\x15\xa8\x01\x00\x00\x48\x31\xc9\xff\x54\x24\x38\x48\x31\xc9\xff\x54\x24\x30\x48\x81\xec\x68\x01\x00\x00\x48\x89\x5c\x24\x28\x48\x89\x6c\x24\x30\x48\x89\x7c\x24\x38\x48\x89\x74\x24\x40\x4c\x89\x64\x24\x48\x4c\x89\x6c\x24\x50\x4c\x89\x74\x24\x58\x4c\x89\x7c\x24\x60\x65\x4c\x8b\x1c\x25\x60\x00\x00\x00\x4d\x8b\x5b\x18\x4d\x8d\x5b\x10\x4d\x89\xdf\x4d\x8b\x1b\xfc\x49\x8b\x7b\x60\x48\x89\xce\xac\x84\xc0\x74\x26\x8a\x27\x80\xfc\x61\x7c\x03\x80\xec\x20\x38\xc4\x75\x08\x48\xff\xc7\x48\xff\xc7\xeb\xe5\x4d\x8b\x1b\x4d\x39\xfb\x75\xd6\x48\x31\xc0\xe9\xb1\x00\x00\x00\x49\x8b\x5b\x30\x44\x8b\x63\x3c\x49\x01\xdc\x49\x81\xc4\x88\x00\x00\x00\x45\x8b\x2c\x24\x4d\x85\xed\x75\x08\x48\x31\xc0\xe9\x8e\x00\x00\x00\x4e\x8d\x1c\x2b\x45\x8b\x74\x24\x04\x4d\x01\xee\x41\x8b\x4b\x18\x45\x8b\x53\x20\x49\x01\xda\xff\xc9\x4d\x8d\x24\x8a\x41\x8b\x3c\x24\x48\x01\xdf\x48\x89\xd6\xa6\x75\x08\x8a\x06\x84\xc0\x74\x09\xeb\xf5\xe2\xe5\x48\x31\xc0\xeb\x55\x45\x8b\x63\x24\x49\x01\xdc\x66\x41\x8b\x0c\x4c\x45\x8b\x63\x1c\x49\x01\xdc\x41\x8b\x04\x8c\x4c\x39\xe8\x7c\x36\x4c\x39\xf0\x73\x31\x48\x8d\x34\x18\x48\x8d\x7c\x24\x68\xa4\x80\x3e\x2e\x75\xfa\xa4\xc7\x07\x44\x4c\x4c\x00\x4d\x89\xc6\x48\x8d\x4c\x24\x68\x41\xff\xd1\x4d\x89\xf0\x48\x8d\x4c\x24\x68\x48\x89\xf2\xe9\x08\xff\xff\xff\x48\x01\xd8\x49\x89\x00\x48\x8b\x5c\x24\x28\x48\x8b\x6c\x24\x30\x48\x8b\x7c\x24\x38\x48\x8b\x74\x24\x40\x4c\x8b\x64\x24\x48\x4c\x8b\x6c\x24\x50\x4c\x8b\x74\x24\x58\x4c\x8b\x7c\x24\x60\x48\x81\xc4\x68\x01\x00\x00\xc3\x4b\x45\x52\x4e\x45\x4c\x33\x32\x2e\x44\x4c\x4c\x00\x4c\x6f\x61\x64\x4c\x69\x62\x72\x61\x72\x79\x41\x00\x45\x78\x69\x74\x50\x72\x6f\x63\x65\x73\x73\x00\x55\x53\x45\x52\x33\x32\x2e\x44\x4c\x4c\x00\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x00\x48\x69\x20\x66\x72\x6f\x6d\x20\x69\x6e\x6a\x65\x63\x74\x65\x64\x20\x73\x68\x65\x6c\x6c\x63\x6f\x64\x65\x21\x00\x53\x68\x65\x6c\x6c\x63\x6f\x64\x65\x54\x6f\x4a\x53\x63\x72\x69\x70\x74\x20\x50\x6f\x43\x20\x00";
        PVOID shellcode_exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (shellcode_exec) {
            RtlCopyMemory(shellcode_exec, shellcode, sizeof shellcode);
            DWORD dwOldProtect;
            if (VirtualProtect(shellcode_exec, sizeof shellcode, PAGE_EXECUTE, &dwOldProtect)) {
                PTHREAD_START_ROUTINE proc = (PTHREAD_START_ROUTINE) shellcode_exec;
                proc(NULL);
            }
            VirtualFree(shellcode_exec, 0, MEM_RELEASE);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 2013-11-09
      • 1970-01-01
      • 2012-08-23
      • 1970-01-01
      • 2010-12-15
      相关资源
      最近更新 更多