如何创建可以使用 rundll32.exe 运行而无需指定入口点的本机 C++ DLL

2024-04-01

我将如何创建一个可以使用 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);
}

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

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

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);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建可以使用 rundll32.exe 运行而无需指定入口点的本机 C++ DLL 的相关文章

随机推荐