Skip to content

A C# class library for interacting with processes.

Notifications You must be signed in to change notification settings

bangush/Process.NET

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

21 Commits

Repository files navigation

Process.NET

Process.NET is a tool for interacting with processes based around a library called "MemorySharp" by Jämes Ménétrey aka ZenLulz under the license on the pages linked below. Below are the mentioned authors original library's and his official website for the library.

https://github.com/ZenLulz/MemorySharp/

http://binarysharp.com/

Process.NET is simply a result of both me learning to program as a newer developer interested in both C# and native code, and the lack of a few features I desired in the library I enjoyed using as a new programmer.

Features and notes

The core features of the original MemorySharp all or mostly library still exist. However, they have been implemented as a set of interfaces instead.

This is to allow different implementations of the already great design MemorySharp has, such as support for internal (aka, injected) operations or the need for specific implementation details.

Original features

**General feature, changes, and additions from the original library **

  • Interface based design.
  • Keyboard and mouse hooks.
  • Pattern scanning for both functions and data patterns.
  • Reduced dependency on FASM.net and Improved x64 support.
  • Patches.

Internal process (aka injected) support

  • Detours
  • Hooks
  • Fast memory reads using pointers/marshaling tricks
  • Implementation of existing features to better suite internal-process operations.

The main interface that brings others together

publicinterfaceIProcess:IDisposable{System.Diagnostics.ProcessNative{get;}SafeMemoryHandleHandle{get;}IMemoryMemory{get;}IThreadFactoryThreadFactory{get;}IModuleFactoryModuleFactory{get;}IMemoryFactoryMemoryFactory{get;}IWindowFactoryWindowFactory{get;}IProcessModulethis[stringmoduleName]{get;}IPointerthis[IntPtraddr]{get;}}

Also, this abstraction is used to provide easier memory read/write implementations.

publicabstractclassProcessMemory:IMemory{protectedreadonlySafeMemoryHandleHandle;protectedProcessMemory(SafeMemoryHandlehandle){Handle=handle;}publicabstractbyte[]Read(IntPtrintPtr,intlength);publicstringRead(IntPtrintPtr,Encodingencoding,intmaxLength){varbuffer=Read(intPtr,maxLength);varret=encoding.GetString(buffer);if(ret.IndexOf('\0')!=-1)ret=ret.Remove(ret.IndexOf('\0'));returnret;}publicabstractTRead<T>(IntPtrintPtr);publicT[]Read<T>(IntPtrintPtr,intlength){varbuffer=newT[length];for(vari=0;i<buffer.Length;i++)buffer[i]=Read<T>(intPtr);returnbuffer;}publicabstractintWrite(IntPtrintPtr,byte[]bytesToWrite);publicvoidWrite(IntPtrintPtr,stringstringToWrite,Encodingencoding){if(stringToWrite[stringToWrite.Length-1]!='\0')stringToWrite+='\0';varbytes=encoding.GetBytes(stringToWrite);Write(intPtr,bytes);}publicvoidWrite<T>(IntPtrintPtr,T[]values){foreach(varvalueinvalues)Write(intPtr,value);}publicabstractvoidWrite<T>(IntPtrintPtr,Tvalue);}

Examples of new (and old) features##

Pattern scanning

The way pattern scanning has been added is through interfaces, and a default implementation for both function and data patterns have been included. In most cases, they will be all you need. Here are the default implementation examples.

Pattern scanning for a function offset:

publicclassTestClass{publicreadonlyIMemoryPatternDataAddressPattern=newDwordPattern("48 8B 05 ?? ?? ?? ?? 48 85 C0 48 0F 44 05 ?? ?? ?? ?? C3",0x40);publicreadonlyIMemoryPatternFuncOffsetPattern=newDwordPattern("48 8B 05 ?? ?? ?? ?? 48 85 C0 48 0F 44 05 ?? ?? ?? ?? C3");publicPatternScanResultFind(stringmoduleName,IMemoryPatternpattern){varprocess=newProcessSharp(System.Diagnostics.Process.GetCurrentProcess());process.Memory=newExternalProcessMemory(process.Handle);varscanner=newPatternScanner(process[moduleName]);returnscanner.Find(pattern);}}

Internal - Implementing the base WndProc hook class to invoke code inside the main thread from your injected C# program

publicclassWindowHook:WndProcHook{publicenumUserMessage{SayHi,SayBye}publicWindowHook(IntPtrhandle):base(handle,"ExampleWndProc"){}publicboolHandleUserMessage(IntPtrwpparam){// ReSharper disable once SwitchStatementMissingSomeCasesswitch((UserMessage)wpparam){caseUserMessage.SayHi:MessageBox.Show("Hi");returntrue;caseUserMessage.SayBye:MessageBox.Show("Bye");returntrue;}returnfalse;}publicvoidInvoke(UserMessagemsg){SendMessage((int)WindowsMessages.User,(IntPtr)msg);}protectedoverrideIntPtrWndProc(IntPtrhWnd,intmsg,IntPtrwParam,IntPtrlParam){if(msg==(int)WindowsMessages.User&&HandleUserMessage(wParam))returnIntPtr.Zero;returnbase.WndProc(hWnd,msg,wParam,lParam);}}

And an example of using it:

publicclassTestClass{privateWindowHook_window;publicvoidInstall(IntPtrhandle){_window=newWindowHook(handle);_window.Enable();_window.Invoke(UserMessage.SayHi);}publicvoidUninstall(){_window.Invoke(WindowHook.UserMessage.SayBye);_window.Disable();}}

Keyboard / Mouse hooks

A basic keyboard hook use

publicclassTestClass{privateKeyboardHook_keyboardHook;publicvoidInstall(stringname){_keyboardHook=newKeyboardHook(name);_keyboardHook.KeyDownEvent+= args =>{if(args.IsAltPressed&&args.Key==Keys.A)Console.WriteLine("The A and alt keys were pressed together.");};}}

And the mouse hook

publicclassTestClass{privateMouseHook_mouseHook;publicvoidInstall(){_mouseHook=newMouseHook();_mouseHook.LeftButtonDown+=(sender,args)=>Console.WriteLine($"The mouse was at the position: {args.Position} when left clicked.");_mouseHook.Enable();}}

Remote and unmanaged code execution

Using the Marshal.GetDelegateForFunctionPointer to call user32.dll messagebox

publicstaticclassProgram{publicstaticProcessSharpProcessSharp{get;set;}publicdelegatevoidMessageBox(IntPtrhWnd,stringtext,stringcaption,uinttype);publicstaticvoidMain(string[]args){ProcessSharp=newProcessSharp(System.Diagnostics.Process.GetCurrentProcess());ProcessSharp.Memory=newExternalProcessMemory(process.Handle);// get a process function instance for MessageBox function in user32.dllvarprocessFunction=ProcessSharp.ModuleFactory["user32"]["MessageBoxA"];// create a delegate for it.var@delegate=processFunction.GetDelegate<MessageBox>();// show a message box using the user32.dll MessageBox api.@delegate.Invoke(IntPtr.Zero,"Hello world!","title",0);}}

Implementing the assembly factory the way MemorySharp does with FASM.Net and using it

publicclassFasm32Assembler:IAssembler{publicbyte[]Assemble(stringasm){returnAssemble(asm,IntPtr.Zero);}publicbyte[]Assemble(stringasm,IntPtrbaseAddress){asm=$"use32\norg 0x{baseAddress.ToInt64():X8}\n"+asm;returnFasmNet.Assemble(asm);}}publicstaticclassProgram{publicstaticProcessSharpProcessSharp{get;set;}publicstaticAssemblyFactoryFactory{get;set;}publicstaticvoidMain(string[]args){ProcessSharp=newProcessSharp(System.Diagnostics.Process.GetProcessesByName("ProcessName").FirstOrDefault());ProcessSharp.Memory=newExternalProcessMemory(ProcessSharp.Handle);Factory=newAssemblyFactory(ProcessSharp,newFasm32Assembler());// int(int input) => input * 2;varprocessFunction=ProcessSharp.ModuleFactory["SomeLib.dll"]["SomeFunc"];vara=Factory.Execute<int>(processFunction.BaseAddress,5);// out put would be 10.Console.WriteLine(a);// All the classic examples from the MemorySharp lib are applicable.varaddress=IntPtr.Zero;// Execute code and get the return value as booleanvarret=Factory.Execute<bool>(address);Console.WriteLine(ret.ToString());varparameterA=newIntPtr(0x500);varpoint=Factory.Execute<Point>(address,CallingConventions.Stdcall,parameterA,"parameterB");Console.WriteLine(point.ToString());// Inject mnemonicsFactory.Inject(new[]{"push 0","add esp, 4","retn"},address);// Inject and execute code lazily.using(vart=Factory.BeginTransaction()){t.AddLine("mov eax,{0}",address);t.AddLine("call eax");t.AddLine("retn");}}}

Samples of the original library functionality included with this library below are included for more exposure of the features. The original documentation of them is better and still apples.

Window operations

varprocess=newProcessSharp(System.Diagnostics.Process.GetCurrentProcess());process.Memory=newExternalProcessMemory(process.Handle);// Find Scintillavarscintilla=ProcessSharp.WindowFactory.GetWindowsByClassName("Scintilla").FirstOrDefault();// If scintilla was found, write somethingscintilla?.Keyboard.Write("Hello, World!");varprocess=newProcessSharp(System.Diagnostics.Process.GetCurrentProcess());process.Memory=newExternalProcessMemory(process.Handle);// Get the windowvarwindow=process.WindowFactory.MainWindow;// Activate it to be in foregroundwindow.Activate();// Move the cursorwindow.Mouse.MoveTo(0,0);// Perform a left clickwindow.Mouse.ClickLeft();varprocess=newProcessSharp(System.Diagnostics.Process.GetCurrentProcess());process.Memory=newExternalProcessMemory(process.Handle);// Get the windowvarwindow=process.WindowFactory.MainWindow;// Press the bottom arrow down and repeat the message every 20mswindow.Keyboard.Press(Keys.Down,TimeSpan.FromMilliseconds(20));// Wait 3 secondsThread.Sleep(3000);// Release the keywindow.Keyboard.Release(Keys.Down);

Memory operations

varprocess=newProcessSharp(System.Diagnostics.Process.GetCurrentProcess());process.Memory=newExternalProcessMemory(process.Handle);varaddress=IntPtr.Zero;// Read an array of 3 integers varintegers=process.Memory.Read<int>(address,3);foreach(varintegerinintegers)Console.WriteLine(integer);// Write a stringprocess.Memory.Write(address,"I love managed languages.");varprocess=newProcessSharp(System.Diagnostics.Process.GetCurrentProcess());process.Memory=newExternalProcessMemory(process.Handle);varaddress=IntPtr.Zero;varoffset=0x500;// Read an array of 3 integers at address + offset.varintegersA=process[address].Read<int>(offset,3);foreach(varintegerinintegersA)Console.WriteLine(integer);// You can also do it from a module instance.varmoduleName="SomeModule.dll";varintegersB=process[moduleName].Read<int>(offset,3);foreach(varintegerinintegersB)Console.WriteLine(integer);// Write a string.process[address].Write(offset,"I love managed languages.");process[moduleName].Write(offset,"I love managed languages.");

Credits

  • Jämes Ménétrey aka ZenLulz for writing the MemorySharp library.
  • Apoc for his good post and GreyMagic library from which Detours and Patches are implemented.
  • Zat from unknowncheats.me for just good post and decency to new programmers such as myself in general.
  • aganonki from unknowncheats.me for his HackTools library and help with writing better more flexible code in general.
  • Jadd @ ownedcore.com for his help with everything in general, but most specifically his WndProc hook example which got me started programming more seriously as the newb I was and am.
  • miceiken for his icedflake project to reference.
  • jeffora for his extmemory project to reference
  • aevitas for his BlueRain project and Orion project to reference and is actually where the the base memory abstraction is based from.

Links to check out

About

A C# class library for interacting with processes.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C#100.0%