簡體   English   中英

C#代碼注入

[英]Code Injection With C#

你可以使用Windows鈎子或其他方法用c#進行代碼注入嗎? 我已經看到很多關於代碼注入的東西,但所有這些都是用C / C ++完成的。 我不知道這些語言中的任何一種,並且很難翻譯。 有沒有人對如何做到這一點有任何想法?

凱文,這是有可能的。 您可以使用托管C ++使用window hook proc創建庫。 您需要做的就是使用標准WinAPI(SetWindowsHookEx等)將此掛鈎注入到某個應用程序中。 在這個鈎子里面你可以調用System :: AppDomain :: CurrentDomain-> Load方法將你的程序集加載到目標應用程序的AppDomain中。 然后,您可以使用反射調用程序集中定義的方法。 例如, Snoop使用此方法。

Mike Stall有這個使用CreateRemoteThread的示例 它的優點是不需要任何C ++。

編輯:我似乎誤解了這個問題....我的印象是問題是關於代碼注入當前進程。


我很晚才參加聚會,但幾周前我剛剛使用過這個:

委托包含私有字段IntPtr _methodPtrIntPtr _methodPtrAux ,它們表示正文的內存地址。 通過將字段(通過反射)設置為特定值,可以改變EIP將指向的存儲器地址。
使用此信息,可以執行以下操作:

  1. 創建一個包含要執行的匯編字節的數組
  2. 將委托的方法指針移動到相關字節
  3. 打電話給代表
  4. 利潤???

(當然,您可以將_methodPtr更改為任何內存地址 - 即使在內核空間中,但這可能需要適當的執行權限)。


我有一個工作代碼示例,如果你想:

 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; } 

可以使用如下:

 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 

當然,也可以編寫以下方法:

 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(); } } 

可以通過反射對現有方法(而不是委托)進行相同的操作:

 // 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); 


使用任何代碼需要您自擔風險。 必須使用/unsafe -compiler開關編譯代碼示例。

您可以在CodePlex站點http://codeinject.codeplex.com/上查看CInject代碼注入.NET程序集。 在使用CInject時,您無需了解代碼注入以注入任何代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM