سؤال

هل يمكنك استخدام خطافات Windows أو طرق أخرى لإجراء حقن التعليمات البرمجية باستخدام C#؟لقد رأيت الكثير من الأشياء حول حقن التعليمات البرمجية ولكن تم إجراؤها جميعًا في C/C++.لا أعرف أيًا من هاتين اللغتين وأواجه صعوبة كبيرة في الترجمة.هل لدى أي شخص أي أفكار حول كيفية القيام بذلك؟

هل كانت مفيدة؟

المحلول

كيفن ، هذا ممكن.يمكنك إنشاء مكتبة باستخدام window Hook proc باستخدام لغة C++ المُدارة.كل ما عليك فعله هو إدخال هذا الخطاف في بعض التطبيقات باستخدام WinAPI القياسي (SetWindowsHookEx وما إلى ذلك).داخل هذا الخطاف، يمكنك الاتصال بأسلوب System::AppDomain::CurrentDomain->Load لتحميل التجميع الخاص بك في AppDomain الخاص بالتطبيق المستهدف.ثم يمكنك استدعاء الأساليب المحددة في التجميع الخاص بك باستخدام الانعكاس.على سبيل المثال، تجسس يستخدم هذه الطريقة.

نصائح أخرى

مايك ستال لديه هذه العينة, ، الذي يستخدم CreateRemoteThread.لديها ميزة عدم الحاجة إلى أي لغة C++.

يحرر: يبدو أنني أخطأت في تفسير السؤال....كان لدي انطباع بأن السؤال كان حول إدخال الكود في العملية الحالية.


لقد انضممت إلى الحفلة متأخرًا نوعًا ما، لكنني استخدمت هذا بالضبط منذ بضعة أسابيع:

يحتوي المفوض على الحقول الخاصة IntPtr _methodPtr و IntPtr _methodPtrAux, والتي تمثل عنوان ذاكرة الجسم.من خلال ضبط الحقل (من خلال الانعكاس) على قيم محددة، يمكن للمرء تغيير عنوان الذاكرة، الذي سيشير إليه EIP.
باستخدام هذه المعلومات، يمكن القيام بما يلي:

  1. قم بإنشاء مصفوفة تحتوي على بايتات التجميع التي سيتم تنفيذها
  2. انقل مؤشر أسلوب المفوض إلى وحدات البايت المعنية
  3. اتصل بالمندوب
  4. ربح ؟؟؟

(بالطبع، يمكنك تغيير _methodPtr-قيمة لأي عنوان ذاكرة - حتى في مساحة kernel، ولكن هذا قد يتطلب امتيازات التنفيذ المناسبة).


لدي مثال على كود العمل هنا، إذا كنت تريد:

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- تبديل المترجم.

يمكنك التحقق من CInject لإدخال التعليمات البرمجية في تجميعات .NET على موقع CodePlex http://codeinject.codeplex.com/.لا تحتاج إلى أي معرفة حول حقن التعليمات البرمجية لحقن أي تعليمات برمجية عند استخدام CInject.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top