- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当 ActiveXObject 托管在 Windows 桌面/边栏小工具中时,该 ActiveXObject 会被缓存,并且它的 DLL 文件会被锁定(意味着它无法移动、删除或重命名)。问题是这样的;当该小工具随后关闭时,DLL 仍被 Windows 边栏锁定并且无法删除。这会导致一个严重的问题,即无法在旧版本小工具的基础上安装新版本的小工具,在删除小工具的过程中会失败,且不会出现任何错误消息。
这对于用户来说不是很友好,因此我正在寻找一种在小工具卸载事件期间以某种方式“切断”与 ActiveX 控件的联系的方法。我希望有人能告诉我这是否可行,如果可行,请给我一些关于如何实现它的想法。
仅供引用,Windows 边栏小工具实际上只是 Internet Explorer 服务器窗口,因此可以安全地假设 IE 表现出相同的行为。
编辑: Unlocker似乎做了我需要做的事情,那么我如何在 .NET 中以编程方式实现同样的事情?
最佳答案
好吧,这是一个相当复杂的问题。我以前见过这种行为,我不熟悉 Windows 桌面/侧边栏小工具,因为我不使用它。不过,我设法想出了三种可能的攻击方法
<强>1。 Handle来自 TechNet
这不是我的主意,there is another StackOverflow thread就推荐这个方法。但我对这是否有效持怀疑态度。文件锁(该实用程序处理的内容)和“加载库”锁之间存在差异,我认为这就是您在使用 ActiveX 时遇到的问题。
我稍微修改了该线程的代码,他们使用 Process.Kill() 来释放锁,我认为最好使用handle.exe来释放锁。
public struct LockInfo
{
public int PID;
public string Handle;
public LockInfo(int pid, string handle)
{
this.PID = pid;
this.Handle = handle;
}
}
static List<LockInfo> getLockingInfo(string fileName)
{
List<LockInfo> lockingProcesses = new List<LockInfo>();
Process tool = new Process();
tool.StartInfo.FileName = "handle.exe";
tool.StartInfo.Arguments = fileName;
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();
// I;m not so hot with regex, so a bit of regex and a bit of manual splitting
string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(\s+)\b(\S+:)";
foreach (Match match in Regex.Matches(outputTool, matchPattern))
{
string[] temp = match.Value.Replace(":", "").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (temp.Length == 2)
{
lockingProcesses.Add(new LockInfo(int.Parse(temp[0].Trim()), temp[1].Trim()));
}
}
return lockingProcesses.Count > 0 ? lockingProcesses : null;
}
static bool closeFileHandle(List<LockInfo> lockingInfo)
{
if ((lockingInfo == null) || (lockingInfo.Count == 0))
{
throw new ArgumentException("lockingProcesses cannot be null or empty");
}
bool fileClosed = true;
foreach (LockInfo lockInfo in lockingInfo)
{
Process tool = new Process();
tool.StartInfo.FileName = "handle.exe";
tool.StartInfo.Arguments = string.Format("-c {0} -y -p {1}", lockInfo.Handle, lockInfo.PID.ToString());
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();
if (outputTool.IndexOf("Handle closed") == -1)
{
fileClosed = false;
}
}
return fileClosed;
}
public static void Main()
{
//Path to locked file, make sure the full path is in quotes
string fileName = "\"" + @"C:\Your_Path\To_The\ActiveX.ocx" + "\"";
List<LockInfo> lockInfo = getLockingInfo(fileName);
if ((lockInfo != null) && (lockInfo.Count > 0))
{
closeFileHandle(lockInfo);
}
}
...
<小时/><强>2。 Win32 风格
互联网上没有太多关于此的信息,而且似乎需要一些未记录的 API 调用才能顺利完成此任务。
这些 C++ 示例可能会有所帮助。
不幸的是我无法让它无缝地工作。我已经使用 MS Word 中加载的 ActiveX 测试了此方法。然后我尝试解锁ActiveX,它不是很稳定,经常导致word崩溃。我想我没有正确破译上述程序所需的 C++ war 创伤。
连同 CreateRemoteThread in C# 的这个例子我确实将这段代码放在一起。
public struct ProcessInfo
{
public Process Process;
public ProcessModule Module;
public ProcessInfo(Process process, ProcessModule module)
{
this.Process = process;
this.Module = module;
}
}
private static List<ProcessInfo> getProcessInfo(string fileName, bool partialMatch)
{
List<ProcessInfo> myProcesses = new List<ProcessInfo>();
Process[] runningProcesses = Process.GetProcesses();
int i = 0;
for (i = 0; i < runningProcesses.Length; i++)
{
Process currentProcess = runningProcesses[i];
try
{
if (!currentProcess.HasExited)
{
try
{
ProcessModuleCollection modules = currentProcess.Modules;
int j = 0;
for (j = 0; j < modules.Count; j++)
{
if (partialMatch)
{
if ((modules[j].FileName.ToLower().IndexOf(fileName.ToLower()) != -1))
{
myProcesses.Add(new ProcessInfo(currentProcess, modules[j]));
break;
}
}
else
{
if ((modules[j].FileName.ToLower().CompareTo(fileName.ToLower()) == 0))
{
myProcesses.Add(new ProcessInfo(currentProcess, modules[j]));
break;
}
}
}
}
catch (NotSupportedException)
{
// You are attempting to access the Modules property for a process that is running on a remote computer.
// This property is available only for processes that are running on the local computer.
}
catch (InvalidOperationException)
{
// The process Id is not available.
}
catch (Win32Exception)
{
// You are attempting to access the Modules property for either the system process or the idle process.
// These processes do not have modules.
}
}
}
catch (InvalidOperationException)
{
// There is no process associated with the object.
}
catch (Win32Exception)
{
// The exit code for the process could not be retrieved.
}
catch (NotSupportedException)
{
// You are trying to access the HasExited property for a process that is running on a remote computer.
// This property is available only for processes that are running on the local computer.
}
}
return myProcesses.Count > 0 ? myProcesses : null;
}
private static void forceRemoteCloseHandle(ProcessInfo processInfo)
{
// Open remote process for write
IntPtr hProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_CREATE_THREAD | NativeMethods.PROCESS_VM_OPERATION |
NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_VM_READ, false, processInfo.Process.Id);
// Get the handle to CloseHandle in kernel32.dll
IntPtr hKernel32 = NativeMethods.LoadLibrary("kernel32.dll");
IntPtr hCloseHandle = NativeMethods.GetProcAddress(hKernel32, "CloseHandle");
uint temp = 0;
// Create the remote thread and point it to CloseHandle
IntPtr hCreateRemoteThread = NativeMethods.CreateRemoteThread((IntPtr)hProcess, (IntPtr)0, 0, hCloseHandle, (IntPtr)processInfo.Module.BaseAddress, 0, out temp);
// Wait for thread to end
NativeMethods.WaitForSingleObject(hCreateRemoteThread, 2000);
//Closes the remote thread handle
NativeMethods.CloseHandle(hCreateRemoteThread);
//Free up the kernel32.dll
if (hKernel32 != null)
NativeMethods.FreeLibrary(hKernel32);
//Close the process handle
NativeMethods.CloseHandle(hProcess);
}
private static void forceRemoteFreeLibrary(ProcessInfo processInfo)
{
// Open remote process for write
IntPtr hProcess = NativeMethods.OpenProcess(NativeMethods.PROCESS_CREATE_THREAD | NativeMethods.PROCESS_VM_OPERATION |
NativeMethods.PROCESS_VM_WRITE | NativeMethods.PROCESS_VM_READ, false, processInfo.Process.Id);
// Get the handle to FreeLibrary in kernel32.dll
IntPtr hKernel32 = NativeMethods.LoadLibrary("kernel32.dll");
IntPtr hFreeHandle = NativeMethods.GetProcAddress(hKernel32, "FreeLibrary");
// Create the remote thread and point it to FreeLibrary
uint temp = 0;
IntPtr hCreateRemoteThread = NativeMethods.CreateRemoteThread((IntPtr)hProcess, (IntPtr)0, 0, hFreeHandle, (IntPtr)processInfo.Module.BaseAddress, 0, out temp);
// Wait for thread to end
NativeMethods.WaitForSingleObject(hCreateRemoteThread, 2000);
//Closes the remote thread handle
NativeMethods.CloseHandle(hCreateRemoteThread);
//Free up the kernel32.dll
if (hKernel32 != null)
NativeMethods.FreeLibrary(hKernel32);
// Close the process handle
NativeMethods.CloseHandle(hProcess);
}
public static void Main()
{
string strFile = @"C:\Program Files\Microsoft Office\OFFICE11\MSCAL.OCX";
List<ProcessInfo> lockingProcesses = getProcessInfo(strFile, false);
foreach (ProcessInfo processInfo in lockingProcesses)
{
forceRemoteCloseHandle(processInfo);
// OR
forceRemoteFreeLibrary(processInfo);
}
// OR
foreach (ProcessInfo procInfo in lockingProcesses)
{
procInfo.Process.Kill();
}
}
internal static class NativeMethods
{
internal const int PROCESS_TERMINATE = 0x0001;
internal const int PROCESS_CREATE_THREAD = 0x0002;
internal const int PROCESS_VM_OPERATION = 0x0008;
internal const int PROCESS_VM_READ = 0x0010;
internal const int PROCESS_VM_WRITE = 0x0020;
internal const int PROCESS_QUERY_INFORMATION = 0x0400;
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
internal static extern int WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);
[DllImport("kernel32", SetLastError = true)]
internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
internal static extern int CloseHandle(IntPtr hPass);
}
...
<小时/><强>3。只需使用 Unlocker
这是我最好的推荐。来自 technet 的句柄无法处理加载的 dll/ocx 锁(根据我的测试)。 Win32 很困惑并且没有文档。
Unlocker 提供命令行访问,因此您可以按照与handle.exe 完全相同的方式调用它。只是搞怪一个/?在命令提示符下执行unlocker.exe 后即可查看开关。
还有一个portable version of Unlocker available 这样您就可以将其捆绑到您的部署中,而无需强制最终用户安装该应用程序。
如果所有其他方法都失败,您可以联系 Unlocker 的作者,从他的自述文件中查看此内容。
Licensing
If you are interested in redistributing Unlocker, either in original or modified form, or wish to use Unlocker source code in a product, please send e-mail to ccollomb@yahoo.com with details.
...
<小时/><强>4。使用 Process Hacker 共享库
我刚刚发现了这个出色的工具:Process Hacker它是用 100% C# 代码编写的(尽管它在底层确实通过 P/Invoke 使用了很多 WinAPI 函数)。
最好的一点是:它是开源的(LGPL),并提供了两个开发人员可以在其解决方案中引用的库:ProcessHacker.Common ProcessHacker.Native。
我下载了源代码,只是警告一句,这是一个相当大的解决方案,因此可能需要一些时间才能弄清楚到底什么/如何使用它。
它使用我在选项 2 中谈到的未记录的 API 函数 (ntdll.dl),并且可以执行 Unlocker 可以执行的所有操作,甚至更多。
关于.net - 将 .NET COM Interop 程序集与其托管进程断开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1492869/
是否可以在蓝牙设备连接到 iOS 或从 iOS 断开连接时收到通知,即使我的应用程序处于后台?在 Android 上,我使用 ACTION_ACL_CONNECTED 和 ACTION_ACL_DIS
我对使用 Delphi 使用 USB 设备感到不舒服,并且对编写设备驱动程序的细节几乎一无所知(尽管我在学习使用 GoASM 进行汇编时遇到过一些)。 该设备可以是 USB 调制解调器或 USB 打印
我正在使用 java/servlet 和前端 JSP 开发 Web 应用程序。 我的页面为用户显示一些信息。 是否有任何适当的方法来检查网络连接是否处于 Activity 状态(开/关)以及支持所有浏
这个问题在这里已经有了答案: C# -- TcpListener.Start() causing SocketException with message "Only one usage of ea
我想向我的应用程序添加功能,以允许在 Windows 操作系统上检测播放/捕获设备的到达和断开连接。就像在 Skype 中一样 - 当您拔下设备时 - 它会显示设备丢失的通知,例如要求您选择另一个。
如何断开 org. apache. http. client.HttpClient 对象? 我正在这样创建它,但它没有任何 disconnect() 或 getHttpConnectionManage
我们正在开发一个 .NET 应用程序,其中一个要求是监视系统是否连接到 Internet。 我们能够获得“以太网电缆断开连接”的 .NET 事件,但如果调制解调器被重置,则不会触发此事件。我不想一直通
我正在尝试与使用自签名证书的后端服务器建立 websocket 连接。在 Firefox 中,我为自签名证书添加了一个异常(exception)。 但是我的 websocket 连接 wss://连接
我正在使用由 Excel 生成的用户窗体来修改 PowerPoint 演示文稿(这是避免需要启用宏的电子表格的迂回方法)。该表单工作得很好,但每次我将焦点放在它上时,Excel 应用程序都会获得焦点(
您好,我成功地开始了视频通话,但是当我断开视频通话时,摄像头 LED 指示灯仍然亮着。我怎样才能完全断开通话? Video.createLocalVideoTrack().then(track =>
您好,我成功地开始了视频通话,但是当我断开视频通话时,摄像头 LED 指示灯仍然亮着。我怎样才能完全断开通话? Video.createLocalVideoTrack().then(track =>
我正在尝试断开客户端与服务器的连接,但服务器仍将其视为已连接。我找不到解决这个问题的方法,关机、断开连接和关闭都不起作用。 我与客户端断开连接并检查服务器的一些代码: 客户: private vo
我正在使用 magic record 来完成我所有的核心数据工作。 一切都很好,除了有时我在后台进行更新时我需要从上下文中分离或断开实体。 例如 ButtonList = [Buttons MR_fi
我正在尝试实现一个颜色选择器,它从屏幕上各处的像素中获取颜色。为此,我计划使用全局鼠标 Hook 来监听 WM_MOUSEMOVE,以便在鼠标四处移动时更新颜色,并监听鼠标点击以确认 (WM_LBUT
我有一个使用 C# 编写的 TLS 连接的客户端/服务器 TCP 场景。 客户端在安静并恢复后无法传递消息(不活动时间约为 25 分钟)。但如果我让客户聊天(每 30 秒),就没有问题。 客户端和服务
我编写的这段代码完美运行,但我担心每 2 秒执行一次 ping 操作会消耗太多资源,或者可能导致互联网连接出现一些问题。 new Thread(() => {
关闭带有附加 MediaPlayer 的 MediaController 的正确方法是什么? 您不能执行 mediaController.setMediaPlayer(null) - 立即调用 upd
从我的笔记本电脑上断开外接显示器后,我丢失了一些应用程序,因为断开连接的显示器仍设置为默认显示器。我的一些窗口试图在断开连接的显示器上显示。 我有一个解决方法,例如右键单击应用程序图标并选择移动,然后
是否可以将分片节点从分片集中取出并独立运行? 例如,每个分片都有一个特定的客户。 谢谢。 最佳答案 是的,这是可能的。 MongoDB“主”节点不知道分片。只有路由器(和配置服务器)知道。如果您使用正
我正在探索 Cassandra 及其复制系统。为此,我在本地创建了 3 个节点并测试了不同的场景。我想暂停节点之间的通信,用相同的键写入不同的值,然后观察它们将决定什么。 那么问题来了:如何限制节点在
我是一名优秀的程序员,十分优秀!