c#,Powershell,mmsys.cpl,使用Win32 API展示音频设备属性对话框 常识基础众所周知mmsys.cpl使管理音频设备的控制面板小工具其能产生一个对话框属性表让我们查看和修改各设备的详细属性在音量合成器中单击音频输出设备的小图标也能实现这个效果分析查看进程后发现其原来调用了RunDll32.exeC:\Windows\system32\rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,{0.0.0.00000000}.{46f5d09f-309e-4ec5-8919-4a881d3fc9e1},general那我们是不是可以试着调用一下呢本质上rundll调用了mmsys.cpl中的一个函数但是mmsys.cpl中只有CPlApplet一个函数怎么办观察{0.0.0.00000000}.{46f5d09f-309e-4ec5-8919-4a881d3fc9e1},general提供数据字符串由两组构成分别为前面的ID与后面的general组成这是一个很迷惑人的字符串实际上他们应作为一组字符串输入进阶那怎样获取ID呢根据DEEPSEEK帮忙我编制了一个小C#using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace AudioDeviceEnumerator { public static class Win32AudioAPI { // 常量定义 public const int DEVICE_STATE_ACTIVE 0x00000001; // 枚举定义 public enum EDataFlow { eRender 0, eCapture 1, eAll 2 } public enum ERole { eConsole 0, eMultimedia 1, eCommunications 2 } // COM 接口定义 [ComImport, Guid(A95664D2-9614-4F35-A746-DE8DB63617E6), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IMMDeviceEnumerator { int EnumAudioEndpoints(EDataFlow dataFlow, int stateMask, out IMMDeviceCollection devices); int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice endpoint); int GetDevice(string id, out IMMDevice device); int RegisterEndpointNotificationCallback([MarshalAs(UnmanagedType.Interface)] object handler); int UnregisterEndpointNotificationCallback([MarshalAs(UnmanagedType.Interface)] object handler); } [ComImport, Guid(0BD7A1BE-7A1A-44DB-8397-CC5392387B5E), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IMMDeviceCollection { int GetCount(out int numDevices); int Item(int index, out IMMDevice device); } [ComImport, Guid(D666063F-1587-4E43-81F1-B948E807363F), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IMMDevice { int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int clsCtx, IntPtr activationParams, [MarshalAs(UnmanagedType.IUnknown)] out object interfacePtr); int OpenPropertyStore(int access, out IPropertyStore properties); int GetId([MarshalAs(UnmanagedType.LPWStr)] out string id); int GetState(out int state); } [ComImport, Guid(886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IPropertyStore { int GetCount(out int count); int GetAt(int index, out PropertyKey key); int GetValue(ref PropertyKey key, out PropVariant value); int SetValue(ref PropertyKey key, ref PropVariant value); int Commit(); } [StructLayout(LayoutKind.Sequential)] public struct PropertyKey { public Guid fmtid; public int pid; } [StructLayout(LayoutKind.Sequential)] public struct CNM { public string Name; public string ID; } [StructLayout(LayoutKind.Sequential)] public struct PropVariant { public short vt; public short wReserved1; public short wReserved2; public short wReserved3; public IntPtr pointerValue; public int intValue; } // COM 类标识 [ComImport, Guid(BCDE0395-E52F-467C-8E3D-C4579291692E)] public class MMDeviceEnumerator { } // 辅助函数获取设备友好名称 public static string GetDeviceFriendlyName(IMMDevice device) { IPropertyStore propStore; device.OpenPropertyStore(0, out propStore); PropertyKey key new PropertyKey { fmtid new Guid(A45C254E-DF1C-4EFD-8020-67D146A850E0), pid 14 }; PropVariant value; propStore.GetValue(ref key, out value); return Marshal.PtrToStringUni(value.pointerValue); } // 枚举音频设备并返回设备信息 public static ListCNM EnumerateAudioDevices(EDataFlow dataFlow) { var enumerator (IMMDeviceEnumerator)new MMDeviceEnumerator(); IMMDeviceCollection devices; enumerator.EnumAudioEndpoints(dataFlow, DEVICE_STATE_ACTIVE, out devices); ListCNM L new ListCNM(); int count; devices.GetCount(out count); for (int i 0; i count; i) { IMMDevice device; devices.Item(i, out device); string id; device.GetId(out id); string name GetDeviceFriendlyName(device); CNM c new CNM(); c.Name name; c.ID id; L.Add(c); } return L; } } }在Powershell中我们只需要使用ADd-type加载一下然后调用[AudioDeviceEnumerator.Win32AudioAPI]::EnumerateAudioDevices([AudioDeviceEnumerator.Win32AudioAPIEDataFlow]::eAll)即可获取名称和ID熟悉WIN32编程的同学都知道CPlApplet函数的标准声明为CPlAppletIntPtr,int,ver,ver而要得到对话框我们就需要将第二个参数设置为10[DllImport(mmsys.cpl, SetLastError true, CharSet CharSet.Unicode)] public static extern int CPlApplet( IntPtr hwndCpl, int msg, string lParam1, string lParam2 );简单一调用CPlApplet(0,10,null,{0.0.0.00000000}.{46f5d09f-309e-4ec5-8919-4a881d3fc9e1},general)成功拓展然而{0.0.0.00000000}.{46f5d09f-309e-4ec5-8919-4a881d3fc9e1},general中前面ID已经明白后面的general是什么意思呢用IDA逆向一下得到了以下字符串playback recording sounds spatial listento custom vendor sysfx advanced levels tone hdmi spdif general communications所以说这写字符串对应的是选项卡的默认起始位置结束。备注下期更精彩

相关新闻

最新新闻

KMS智能激活工具:5分钟搞定Windows和Office永久激活终极指南

KMS智能激活工具:5分钟搞定Windows和Office永久激活终极指南

KMS智能激活工具:5分钟搞定Windows和Office永久激活终极指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统弹出激活提示而烦恼吗?Office突然变成只读…

2026/8/11 19:11:31
从源码到应用:csvtomd核心函数详解与自定义开发指南

从源码到应用:csvtomd核心函数详解与自定义开发指南

从源码到应用:csvtomd核心函数详解与自定义开发指南 【免费下载链接】csvtomd 📝📊 Convert your CSV files into Markdown tables. 项目地址: https://gitcode.com/gh_mirrors/cs/csvtomd csvtomd是一款轻量级实用工具,能…

2026/8/11 19:11:31
RedCloud-OS开发者指南:贡献代码前必须了解的架构设计

RedCloud-OS开发者指南:贡献代码前必须了解的架构设计

RedCloud-OS开发者指南:贡献代码前必须了解的架构设计 【免费下载链接】RedCloud-OS RedCloudOS is a Cloud Adversary Simulation Operating System for Red Teams to assess the Cloud Security of Leading Cloud Service Providers (CSPs) 项目地址: https://g…

2026/8/11 19:11:31
.NET Core Serverless 实战:Azure Functions 与 AWS Lambda 部署指南

.NET Core Serverless 实战:Azure Functions 与 AWS Lambda 部署指南

.NET Core Serverless 实战:Azure Functions 与 AWS Lambda 部署指南Serverless 架构让开发者专注于业务逻辑,无需管理服务器。本文将对比 Azure Functions 和 AWS Lambda 两大主流 Serverless 平台,并给出 .NET Core 项目的完整部署方案。一…

2026/8/11 19:11:31
为什么React开发者应该拥抱Functional CSS?10个令人惊叹的优势解析

为什么React开发者应该拥抱Functional CSS?10个令人惊叹的优势解析

为什么React开发者应该拥抱Functional CSS?10个令人惊叹的优势解析 【免费下载链接】react-functional-css-protips :sunglasses: Functional CSS - The Good, The Bad, and Some Protips for React.js Users 项目地址: https://gitcode.com/gh_mirrors/re/react-…

2026/8/11 19:11:31
技术实战中代价最高的错误:数据库事务、缓存与分布式系统避坑指南

技术实战中代价最高的错误:数据库事务、缓存与分布式系统避坑指南

最近在整理巡回赛技术复盘时,发现一个普遍现象:很多团队在技术选型和架构设计上投入巨大,却在一些看似基础的“技术操作”上反复踩坑,导致线上故障、性能瓶颈甚至数据丢失。这些错误往往不是高深算法或复杂架构的问题,…

2026/8/11 19:06:31