在系统自带的计算器上添加按钮或菜单

本文介绍如何通过注入DLL到系统计算器中,实现添加一个菜单项来弹出预设网页的功能。涉及进程注入、菜单修改及使用ShellExecute启动浏览器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     这几天碰到一个题目:在系统自带的计算器上添加一个按钮或菜单,弹出一个网页

     好了  废话不多说 上代码。

      G:\Calc_Remot<span style="font-family: Arial, Helvetica, sans-serif;">e
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">          </span><pre name="code" class="cpp">void CCalc_RemoteDlg::OnBnClickedButton1()
{
    HWND hWnd = ::FindWindow(NULL, _T("计算器"));
    if (hWnd == NULL)
    {
        AfxMessageBox(_T("获取句柄失败"));
    }

    DWORD dwPid = 0;
    GetWindowThreadProcessId(hWnd, &dwPid);
    Zhuru(dwPid);
}

int CCalc_RemoteDlg::Zhuru(DWORD dwPid)
{
    TCHAR szDllName[] = _T("G:\\Calc_Remote\\Debug\\TestDll.dll");

    // 1 打开进程
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    if (hProcess == INVALID_HANDLE_VALUE)
    {
        return -1;
    }
    // 2 在远程进程中申请空间
    LPVOID pszDllName = VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (pszDllName == NULL)
    {
        return -1;
    }
    // 3 向远程进程中写入数据
    if (!WriteProcessMemory(hProcess, pszDllName, szDllName, MAX_PATH, NULL))
    {
        return -1;
    }
    // 4 在远程进程 中 创建 远程线程
    HANDLE hInjecThread = CreateRemoteThread(
        hProcess,                            // 远程进程句柄
        NULL,                                // 安全属性
        0,                                   // 栈大小
        (LPTHREAD_START_ROUTINE)LoadLibrary, // 进程处理函数
        pszDllName,                          // 传入参数
        NULL,                                // 默认创建后的状态
        NULL);                               // 线程ID
    if (hInjecThread == NULL)
    {
        return -1;
    }
    // 5 等待线程结束返回
    DWORD dw = WaitForSingleObject(hInjecThread, -1);

    // 6 获取线程退出码,即LoadLibrary的返回值,即DLL的首地址
    DWORD dwExitCode;
    GetExitCodeThread(hInjecThread, &dwExitCode);
    HMODULE hMod = (HMODULE)dwExitCode;
    // 7 释放空间
    if (!VirtualFreeEx(hProcess, pszDllName, 4096, MEM_DECOMMIT))
    {
        return -1;
    }
    CloseHandle(hProcess);

    return 1;
}


<span style="font-family: Arial, Helvetica, sans-serif;">



</span><div> // dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <shellapi.h>

#define IDM_TEST    12345

WNDPROC lpfnOldProc = 0;


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    switch (message)
    {
    case WM_COMMAND:
        wmId = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        switch (wmId)
        {
        case IDM_TEST:
            ShellExecute(NULL, _T("open"), _T("<img src="file:///" alt="" /><img src="file:///" alt="" />www.baidu.com"), NULL, NULL, SW_SHOWNORMAL);
        }
    }
    return CallWindowProc(lpfnOldProc, hWnd, message, wParam, lParam);
}

DWORD WINAPI ThreadProc(PVOID pParam)
{
    HWND hwnd = FindWindow(NULL, _T("计算器"));
    if (hwnd == NULL)
    {
        MessageBox(NULL, _T("没有找到窗口"), NULL, NULL);
    }
    else
    {
        HMENU hMenu = GetMenu(hwnd);
        if (hMenu == NULL)
        {
            MessageBox(NULL, _T("获取菜单失败!"), NULL, NULL);
        }
        else
        {
            if (AppendMenu(hMenu, MF_STRING, IDM_TEST, _T("Test Dll")) == FALSE)
            {
                MessageBox(NULL, _T("AppendMenu失败"), NULL, NULL);
            }
            SetMenu(hwnd, hMenu);
            lpfnOldProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WndProc);
        }
    }
    return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
        CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}
</div><div>
</div>
<span style="font-family: Arial, Helvetica, sans-serif;">C:\Windows\SysWOW64\calc.exe
</span>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值