【问题标题】:C# LVM_DELETEITEM from listview来自列表视图的 C# LVM_DELETEITEM
【发布时间】:2015-02-07 23:10:55
【问题描述】:

所以,我正在使用 C# 进行编程,并且尝试从 SysListView32 中获取项目 ID,然后发送 LVM_DELETEITEM 消息以从列表视图中删除该项目。

我的代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;

namespace projone
{

    class Hooker
    {
        [DllImport("user32.dll", EntryPoint = "FindWindowA")]
        private static extern Int32 apiFindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindowExA")]
        private static extern Int32 apiFindWindowEx(Int32 hWnd1, Int32 hWnd2, string lpsz1, string lpsz2);

        [DllImport("user32.dll", EntryPoint = "SendMessageA")]
        private static extern Int32 apiSendMessage(int hWnd, int wMsg, int wParam, int lParam);

        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        private static extern Int32 apiGetDesktopWindow();

        static Int32 LVM_FIRST = 4096;
        static Int32 LVM_DELETEITEM = LVM_FIRST + 8;
        static Int32 LVM_SORTITEMS = LVM_FIRST + 48;
        static Int32 LVM_DELETECOLUMN = LVM_FIRST + 28;
        static Int32 LVM_FINDITEM = LVM_FIRST + 13;
        static Int32 LVM_GETITEMTEXT = LVM_FIRST + 45;


        public static void withdrawProcess()
        {
            Int32 lhWndParent = apiFindWindow(null, "Windows Task Manager");
            Int32 lhWndProcessList = 0;
            Int32 lhWndDialog = 0;

            for (int i = 1; (i < 7); i++)
            {
                lhWndDialog = apiFindWindowEx(lhWndParent, lhWndDialog, null, null);

                if((lhWndProcessList == 0))
                {
                    lhWndProcessList = apiFindWindowEx(lhWndDialog, 0, "SysListView32", "Processes");
                }
            }

            // Create List

            List<string> processes = new List<string>();

            // Loops

            int processItemCount = 0;
            Process[] processlist = Process.GetProcesses();
            foreach (Process theprocess in processlist)
            {
                processItemCount += 1;
                processes.Add(theprocess.ProcessName.ToString());
                if (theprocess.ProcessName.Equals("notepad"))
                {
                    apiSendMessage(lhWndProcessList, LVM_SORTITEMS, 0, 0);
                    apiSendMessage(lhWndProcessList, LVM_DELETEITEM, theprocess.Id, 0);
                }
            }

            Console.WriteLine(processItemCount);
            //processes.ForEach(Console.WriteLine);

            //apiSendMessage(lhWndProcessList, LVM_DELETEITEM, 0, "0"); // third entry is item id in listview
        }
    }
}

关于如何更正它以便成功删除该项目的任何想法?不,这不是针对任何类型的“病毒”,我想看看是否可以不直接挂钩和拦截 NtQuerySystemInformation。

【问题讨论】:

  • 有什么问题?它在哪里失败?它是如何失败的?
  • 它不会从列表视图中删除该项目。
  • 你为什么要编写恶意软件?
  • @DavidHeffernan 正如我所指出的,这不是恶意软件。这是一个测试,看看是否确实可以在不必挂钩 NtQuerySystemInformation 的情况下进行。

标签: c# winapi hook


【解决方案1】:

发送 LVM_DELETEITEM 时 SendMessage 调用的 wparam 参数必须是要删除的项目的索引;您正在传递进程 ID。

发送 LVM_DELETEITEM 时 SendMessage 调用的 lparam 参数必须为零;您正在传递一个指向字符串的指针。

【讨论】:

  • 所以,我已将 lparam 更改为 int,现在对于 wparam,我将如何根据进程名称获取项目的索引?
  • 您需要发送 LVM_ 消息来枚举所有项目,并使用您感兴趣的名称搜索项目,但我不确定 listview 项目是否可以跨进程枚举,因为您不能跨进程传递指针。
  • 在另一个进程中分配内存并获得指向该内存的指针,这在另一个进程的上下文中是有意义的。我不知道如何做这样的事情,但如果你真的有兴趣,(而且你没有什么对你的生活更有用的事情),那么这些信息应该足以让你开始使用谷歌搜索。
  • 那么有没有办法获取所有项目的索引,创建一个循环,然后删除列表视图中的每个项目?
  • 好吧,回到绘图板。感谢迈克的帮助!
【解决方案2】:

如果任务管理器有保护措施来阻止你做你想做的事情,我不会感到惊讶。如果它没有,我会感到惊讶。 Do not hide programs from Task Manager.

【讨论】:

  • 是的,它当然有办法阻止它,但实际上有两种方法可以防止项目被看到。 1 是挂钩 NtQuerySystemInformation 并让所有内容都通过您的自定义函数并找到您的条目,在显示之前将其删除,或者 2 是在计时器上有一个功能,查找任务管理器是否打开,并删除任务管理器中的条目在用户看到之前。
  • Why are you still trying to do something that is user-hostile? 现在你说的是玩系统调用;从这里开始会变得更加疯狂。
猜你喜欢
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 2019-07-13
  • 2023-03-26
  • 1970-01-01
  • 2018-11-03
相关资源
最近更新 更多