声明

本文所涉及程序均在本地运行测试,用于学习目的,请勿用于非法用途。

前言

编写可以被rundll32调用的函数。

程序分析

程序见文末。

rundll32可以直接调用dll中导出的函数,需要函数类型定义满足对应定义,如代码中的runme函数。
lpszCmdLine为参数,由于其类型为LPSTR,使用MessageBox输出时,与LPCWSTR类型不一致,输出为乱码。
程序中将参数输出到文件中进行显示。实际使用时可对参数进行自定义处理。

运行

rundll32 mydll.dll,runme hello world,每次重新执行时,需先将test.txt删除掉。

源代码

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>

extern "C" __declspec(dllexport) void __cdecl runme(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
    MessageBox(NULL, L"ok", L"alert", MB_OK);

    HANDLE hFile;
    char *DataBuffer = lpszCmdLine;
    DWORD dwBytesToWrite = (DWORD)strlen(DataBuffer);
    DWORD dwBytesWritten = 0;
    BOOL bErrorFlag = FALSE;

    hFile = CreateFile(L"test.txt",                // name of the write
        GENERIC_WRITE,          // open for writing
        0,                      // do not share
        NULL,                   // default security
        CREATE_NEW,             // create new file only
        FILE_ATTRIBUTE_NORMAL,  // normal file
        NULL);                  // no attr. template

    if (hFile == INVALID_HANDLE_VALUE)
    {
        _tprintf(TEXT("Terminal failure: Unable to open file \"\" for write.\n"));
        return;
    }


    bErrorFlag = WriteFile(
        hFile,           // open file handle
        DataBuffer,      // start of data to write
        dwBytesToWrite,  // number of bytes to write
        &dwBytesWritten, // number of bytes that were written
        NULL);            // no overlapped structure

    if (FALSE == bErrorFlag)
    {
        printf("Terminal failure: Unable to write to file.\n");
    }
    else
    {
        if (dwBytesWritten != dwBytesToWrite)
        {
            // This is an error because a synchronous write that results in
            // success (WriteFile returns TRUE) should write all data as
            // requested. This would not necessarily be the case for
            // asynchronous writes.
            printf("Error: dwBytesWritten != dwBytesToWrite\n");
        }
        else
        {
     
        }
    }

    CloseHandle(hFile);

    return ;
}


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
   // MessageBox(NULL, L"in dllmain", L"info", MB_OK);
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    //    MessageBox(NULL, L"1 in DLL_PROCESS_ATTACH", L"1", MB_OK);
        break;
    case DLL_THREAD_ATTACH:
    //    MessageBox(NULL, L"2 in DLL_THREAD_ATTACH", L"2", MB_OK);
        break;
    case DLL_THREAD_DETACH:
    //    MessageBox(NULL, L"3 in DLL_THREAD_DETACH", L"3", MB_OK);
        break;
    case DLL_PROCESS_DETACH:
    //    MessageBox(NULL, L"4 in DLL_PROCESS_DETACH", L"4", MB_OK);
        break;
    }
    return TRUE;
}

引用

  1. https://blog.csdn.net/anda0109/article/details/40111997
  2. https://docs.microsoft.com/zh-cn/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-160
  3. https://docs.microsoft.com/en-us/windows/win32/fileio/opening-a-file-for-reading-or-writing