简体   繁体   中英

Code Injection With C#

Can you use windows hooks or other methods to do code injection with c#? I've seen lots of things about code injection but all of them are done in C/C++. I don't know either of those languages and have a really hard time translating. Does anyone have any ideas on how to do this?

Kevin, it is possible. You can create library with window hook proc using managed C++. All you need to do is to inject this hook into some application using standard WinAPI (SetWindowsHookEx etc.). Inside this hook you can call System::AppDomain::CurrentDomain->Load method to load your assembly into target application's AppDomain. Then you can call methods defined in your assembly using reflection. For example, Snoop uses this method.

Mike Stall has this sample , that uses CreateRemoteThread. It has the advantage of not requiring any C++.

EDIT: I seem to have misinterpreted the question .... I was under the impression that the question was about code injection into the current process.


I am joining the party rather late, but I have just used exactly this a few weeks ago:

A delegate contains the private fields IntPtr _methodPtr and IntPtr _methodPtrAux , which represent the body's memory address. By setting the field (via reflection) to specific values, one can alter the memory address, to which the EIP will be pointing.
Using this information, one can do the following:

  1. Create an array with assembly bytes, which are to be executed
  2. Move the delegate's method pointer to the bytes in question
  3. Call the delegate
  4. Profit ???

(Of course, you can change the _methodPtr -value to any memory address -- even in the kernel space, but this might require appropriate execution privileges).


I have a working code example here, if you want:

 public static unsafe int? InjectAndRunX86ASM(this Func<int> del, byte[] asm) { if (del != null) fixed (byte* ptr = &asm[0]) { FieldInfo _methodPtr = typeof(Delegate).GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance); FieldInfo _methodPtrAux = typeof(Delegate).GetField("_methodPtrAux", BindingFlags.NonPublic | BindingFlags.Instance); _methodPtr.SetValue(del, ptr); _methodPtrAux.SetValue(del, ptr); return del(); } else return null; } 

Which can be used as follows:

 Func<int> del = () => 0; byte[] asm_bytes = new byte[] { 0xb8, 0x15, 0x03, 0x00, 0x00, 0xbb, 0x42, 0x00, 0x00, 0x00, 0x03, 0xc3 }; // mov eax, 315h // mov ebx, 42h // add eax, ebx // ret int res = del.InjectAndRunX86ASM(asm_bytes); // should be 789 + 66 = 855 

Of course, on could also write the following method:

 public static unsafe int RunX86ASM(byte[] asm) { Func<int> del = () => 0; // create a delegate variable Array.Resize(ref asm, asm.Length + 1); // add a return instruction at the end to prevent any memory leaks asm[asm.Length - 1] = 0xC3; fixed (byte* ptr = &asm[0]) { FieldInfo _methodPtr = typeof(Delegate).GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance); FieldInfo _methodPtrAux = typeof(Delegate).GetField("_methodPtrAux", BindingFlags.NonPublic | BindingFlags.Instance); _methodPtr.SetValue(del, ptr); _methodPtrAux.SetValue(del, ptr); return del(); } } 

The same could probably be done to existing methods (not delegates) via reflection:

 // UNTESTED // Action new_method_body = () => { }; MethodInfo nfo = typeof(MyType).GetMethod( ..... ); IntPtr ptr = nfo.MethodHandle.Value; // ptr is a pointer to the method in question InjectX86ASM(new_method_body, new byte[] { ......., 0xC3 }); // assembly bytes to be injected int target = new_method_body.Method.MethodHandle.Value.ToInt32(); byte[] redirector = new byte[] { 0xE8, // CALL INSTRUCTION + TARGET ADDRESS IN LITTLE ENDIAN (byte)(target & 0xff), (byte)((target >> 8) & 0xff), (byte)((target >> 16) & 0xff), (byte)((target >> 24) & 0xff), 0xC3, // RETURN INSTRUCTION }; Marshal.Copy(redirector, 0, ptr, redirector.Length); 


Use any code at your own risk. The code examples must be compiled with the /unsafe -compiler switch .

You can check out CInject for code injection into .NET assemblies at CodePlex site http://codeinject.codeplex.com/ . You don't need to have any knowledge about code injection to inject any code when you are using CInject.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM