using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace hake
{
public partial class Form1 : Form
{
public Form1( )
{
InitializeComponent ();
}
//参数定义
#region
string txtpath = @"d:\a.txt";
string exepath = @"d:\a.exe";
int handler;
int pointer;
int process;
string[,] tempStr;//二维数组
public const int SW_SHOW = 5;
public const int SW_HIDE = 0;
private const uint LVM_FIRST = 0x1000;
private const uint LVM_GETHEADER = LVM_FIRST + 31;
private const uint LVM_GETITEMCOUNT = LVM_FIRST + 4;//获取列表行数
private const uint LVM_GETITEMTEXT = LVM_FIRST + 45;//获取列表内的内容
private const uint LVM_GETITEMW = LVM_FIRST + 75;
private const uint HDM_GETITEMCOUNT = 0x1200;//获取列表列数
private const uint PROCESS_VM_OPERATION = 0x0008;//允许函数VirtualProtectEx使用此句柄修改进程的虚拟内存
private const uint PROCESS_VM_READ = 0x0010;//允许函数访问权限
private const uint PROCESS_VM_WRITE = 0x0020;//允许函数写入权限
private const uint MEM_COMMIT = 0x1000;//为特定的页面区域分配内存中或磁盘的页面文件中的物理存储
private const uint MEM_RELEASE = 0x8000;
private const uint MEM_RESERVE = 0x2000;//保留进程的虚拟地址空间,而不分配任何物理存储
private const uint PAGE_READWRITE = 4;
private int LVIF_TEXT = 0x0001;
#endregion
// API调用
#region
[DllImport ("User32")]
private static extern int FindWindow(string className, string windowName);
[DllImportAttribute ("user32.dll", EntryPoint = "ShowWindow")]
public static extern bool ShowWindow(int hWnd, int nCmdShow);
[DllImport ("user32.dll")]//在窗口列表中寻找与指定条件相符的第一个子窗口
private static extern int FindWindowEx(
int hwndParent, // handle to parent window
int hwndChildAfter, // handle to child window
string className, //窗口类名
string windowName // 窗口标题
);
[DllImport ("user32.DLL")]
private static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
[DllImport ("user32.dll")]//找出某个窗口的创建者(线程或进程),返回创建者的标志符
private static extern int GetWindowThreadProcessId(int hwnd, out int processId);
[DllImport ("kernel32.dll")]//打开一个已存在的进程对象,并返回进程的句柄
private static extern int OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int processId);
[DllImport ("kernel32.dll")]//为指定的进程分配内存地址:成功则返回分配内存的首地址
private static extern int VirtualAllocEx(int hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport ("kernel32.dll")]//从指定内存中读取字节集数据
private static extern bool ReadProcessMemory(
int hProcess, //被读取者的进程句柄
int lpBaseAddress,//开始读取的内存地址
IntPtr lpBuffer, //数据存储变量
int nSize, //要写入多少字节
ref uint vNumberOfBytesRead//读取长度
);
[DllImport ("kernel32.dll")]//将数据写入内存中
private static extern bool WriteProcessMemory(
int hProcess,//由OpenProcess返回的进程句柄
int lpBaseAddress, //要写的内存首地址,再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据
IntPtr lpBuffer, //指向要写的数据的指针
int nSize, //要写入的字节数
ref uint vNumberOfBytesRead
);
[DllImport ("kernel32.dll")]
private static extern bool CloseHandle(int handle);
[DllImport ("kernel32.dll")]//在其它进程中释放申请的虚拟内存空间
private static extern bool VirtualFreeEx(
int hProcess,//目标进程的句柄,该句柄必须拥有PROCESS_VM_OPERATION的权限
int lpAddress,//指向要释放的虚拟内存空间首地址的指针
uint dwSize,
uint dwFreeType//释放类型
);
#endregion//API调用
//调用方法
#region
private struct LVITEM //结构体
{
public int mask;//说明此结构中哪些成员是有效的
public int iItem;//项目的索引值(可以视为行号)从0开始
public int iSubItem; //子项的索引值(可以视为列号)从0开始
public int state;//子项的状态
public int stateMask; //状态有效的屏蔽位
public IntPtr pszText; //主项或子项的名称
public int cchTextMax;//pszText所指向的缓冲区大小
}
private int ListView_GetItemRows(int handle)
{
return SendMessage (handle, LVM_GETITEMCOUNT, 0, 0);
}//获取行数
private int ListView_GetItemCols(int handle)
{
return SendMessage (handle, HDM_GETITEMCOUNT, 0, 0);
}//获取列数
private string[,] GetListViewItmeValue(int rows, int cols)
{
string[,] tempStr = new string[rows, cols];//二维数组:保存LV控件的文本信息
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
byte[] vBuffer = new byte[256];//定义一个临时缓冲区
LVITEM[] vItem = new LVITEM[1];
vItem[0].mask = LVIF_TEXT;//说明pszText是有效的
vItem[0].iItem = i; //行号
vItem[0].iSubItem = j; //列号
vItem[0].cchTextMax = vBuffer.Length;//所能存储的最大的文本为256字节
vItem[0].pszText = (IntPtr)((int)pointer + Marshal.SizeOf (typeof (LVITEM)));
uint vNumberOfBytesRead = 0;
//把数据写到vItem中
//pointer为申请到的内存的首地址
//UnsafeAddrOfPinnedArrayElement:获取指定数组中指定索引处的元素的地址
WriteProcessMemory (process, pointer, Marshal.UnsafeAddrOfPinnedArrayElement (vItem, 0), Marshal.SizeOf (typeof (LVITEM)), ref vNumberOfBytesRead);
//发送LVM_GETITEMW消息给hwnd,将返回的结果写入pointer指向的内存空间
SendMessage (handler, LVM_GETITEMW, i, pointer);
//从pointer指向的内存地址开始读取数据,写入缓冲区vBuffer中
ReadProcessMemory (process, ((int)pointer + Marshal.SizeOf (typeof (LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement (vBuffer, 0), vBuffer.Length, ref vNumberOfBytesRead);
string vText = Encoding.Unicode.GetString (vBuffer, 0, (int)vNumberOfBytesRead); ;
tempStr[i, j] = vText;
}
}
VirtualFreeEx (process, pointer, 0, MEM_RELEASE);//在其它进程中释放申请的虚拟内存空间,MEM_RELEASE方式很彻底,完全回收
CloseHandle (process);//关闭打开的进程对象
return tempStr;
}//获取数据
#endregion