كيفية تفكيك وتعديل ثم إعادة تركيب لينكس للتنفيذ ؟

StackOverflow https://stackoverflow.com/questions/4309771

سؤال

هناك على أية حال هذا يمكن القيام به ؟ لقد استعملت objdump ولكن هذا لا تنتج الجمعية الناتج من شأنها أن تكون مقبولة من قبل أي مجمع علمي.أود أن تكون قادرة على تغيير التعليمات داخل قابل للتنفيذ ومن ثم اختباره بعد ذلك.

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

المحلول

لا أعتقد أن هناك أي طريقة موثوقة للقيام بذلك. تنسيقات رمز الجهاز معقدة للغاية ، وأكثر تعقيدًا من ملفات التجميع. ليس من الممكن حقًا أخذ ثنائي متجمع (على سبيل المثال ، بتنسيق ELF) وإنتاج برنامج تجميع المصدر الذي سيجمع إلى نفس الثنائي (أو ما شابه ذلك بما فيه الكفاية). لاكتساب فهم للاختلافات ، قارن إخراج تجميع GCC مباشرة إلى المجمع (gcc -S) مقابل إخراج objdump على القابل للتنفيذ (objdump -D).

هناك مضاعفتان رئيسيتان يمكنني التفكير فيهما. أولاً ، لا يعد رمز الجهاز نفسه مراسلات من 1 إلى 1 مع رمز التجميع ، بسبب أشياء مثل إزاحة المؤشر.

على سبيل المثال ، ضع في اعتبارك رمز C إلى Hello World:

int main()
{
    printf("Hello, world!\n");
    return 0;
}

هذا يجمع إلى رمز التجميع x86:

.LC0:
    .string "hello"
    .text
<snip>
    movl    $.LC0, %eax
    movl    %eax, (%esp)
    call    printf

حيث .LCO هو ثابت مسمى ، و printf هو رمز في جدول رمز المكتبة المشتركة. قارن بإخراج OBJDump:

80483cd:       b8 b0 84 04 08          mov    $0x80484b0,%eax
80483d2:       89 04 24                mov    %eax,(%esp)
80483d5:       e8 1a ff ff ff          call   80482f4 <printf@plt>

أولاً ، أصبح الثابت .lc0 الآن مجرد إزاحة عشوائية في الذاكرة في مكان ما - سيكون من الصعب إنشاء ملف مصدر تجميع يحتوي على هذا الثابت في المكان الصحيح ، نظرًا لأن المجمع والرابط مجاني في اختيار مواقع لهذه الثوابت.

ثانياً ، لست متأكدًا تمامًا من هذا (ويعتمد على أشياء مثل الرمز المستقل للموضع) ، لكنني أعتقد أن الإشارة إلى PrintF ليست مشفرة فعليًا على عنوان المؤشر في هذا الرمز هناك على الإطلاق ، ولكن رؤوس ELF تحتوي على A جدول البحث الذي يحل محل عنوانه ديناميكيًا في وقت التشغيل. لذلك ، لا يتوافق الرمز المفكك تمامًا مع رمز تجميع المصدر.

باختصار ، تجميع المصدر لديه حرف او رمز بينما يحتوي رمز الجهاز المترجم عناوين التي يصعب عكسها.

التعقيد الرئيسي الثاني هو أن ملف مصدر التجميع لا يمكن أن يحتوي على جميع المعلومات التي كانت موجودة في رؤوس ملفات ELF الأصلية ، مثل المكتبات التي تربطها ديناميكيًا ، وغيرها من البيانات الوصفية التي يتم وضعها هناك بواسطة برنامج التحويل البرمجي الأصلي. سيكون من الصعب إعادة بناء هذا.

كما قلت ، من المحتمل أن يمكن للأداة الخاصة معالجة كل هذه المعلومات ، ولكن من غير المرجح أن يؤدي المرء ببساطة إلى إنتاج رمز التجميع الذي يمكن إعادة تجميعه إلى القابل للتنفيذ.

إذا كنت مهتمًا بتعديل قسم صغير من القابل للتنفيذ ، فإنني أوصي بنهج أكثر دقة من إعادة تجميع التطبيق بأكمله. استخدم OBJDump للحصول على رمز التجميع للوظائف (الوظائف) التي تهتم بها. وتعديله كما يحلو لك. عند الانتهاء من ذلك ، إعادة ترجمة فقط تلك الوظائف (الوظائف) واستخدم OBJDump لمعرفة رمز الجهاز لبرنامجك المعدل. بعد ذلك ، استخدم محرر Hex للصق رمز الجهاز الجديد يدويًا على الجزء العلوي من الجزء المقابل من البرنامج الأصلي ، مع الحرص على أن رمزك الجديد هو بالضبط نفس عدد البايتات مثل الكود القديم (أو كل الإزاحة سيكون خاطئًا ). إذا كان الرمز الجديد أقصر ، فيمكنك وضعه باستخدام تعليمات NOP. إذا كان الأمر أطول ، فقد تكون في ورطة ، وقد تضطر إلى إنشاء وظائف جديدة والاتصال بها بدلاً من ذلك.

نصائح أخرى

لتغيير التعليمات البرمجية داخل مجموعة ثنائية ، هناك عمومًا 3 طرق للقيام بذلك.

  • إذا كان الأمر مجرد شيء تافهة مثل ثابت ، فعليك تغيير الموقع مع محرر سداسي عشرية. على افتراض أنه يمكنك العثور عليه لتبدأ.
  • إذا كنت بحاجة إلى تغيير التعليمات البرمجية ، فاستخدم LD_PRELOAD للكتابة فوق بعض الوظائف في البرنامج. هذا لا يعمل إذا لم تكن الوظيفة في جداول الوظائف.
  • اخترق الرمز في الوظيفة التي تريد إصلاحها لتكون قفزة مباشرة إلى وظيفة تقوم بتحميلها عبر LD_PRELOAD ثم القفز مرة أخرى إلى نفس الموقع (هذا هو combi من اثنين أعلاه)

Ofcourse فقط سيعمل الشخص الثاني ، إذا قامت الجمعية بأي نوع من الفحص الذاتي.

تحرير: إذا لم يكن الأمر واضحًا ، فإن اللعب مع التجميعات الثنائية هو مواد مطورة عالية المستوى للغاية ، وستواجه صعوبة في السؤال هنا ، إلا إذا كانت أشياء محددة حقًا تسأل.

لقد عالجت Mgiuca هذه الإجابة بشكل صحيح من وجهة نظر فنية. في الواقع ، فإن تفكيك برنامج قابل للتنفيذ في مصدر تجميع سهل الإنقاذ ليس مهمة سهلة.

لإضافة بعض البتات إلى المناقشة ، هناك بعض التقنيات/الأدوات التي قد تكون مثيرة للاهتمام لاستكشافها ، على الرغم من أنها معقدة من الناحية الفنية.

  1. أجهزة ثابتة/ديناميكية. تستلزم هذه التقنية تحليل التنسيق القابل للتنفيذ ، وإدراج/حذف/استبدال تعليمات تجميع محددة لغرض معين ، وإصلاح جميع الإشارات إلى المتغيرات/الوظائف في القابلة للتنفيذ ، و EMIT قابلة للتنفيذ جديدة. بعض الأدوات التي أعرفها هي: دبوس, حجائر, الحصى, Dynamorio. ضع في اعتبارك أن تكوين مثل هذه الأدوات لغرض مختلف عما تم تصميمه من أجله يمكن أن يكون صعبًا ، ويتطلب فهم كل من التنسيقات القابلة للتنفيذ ومجموعات التعليمات.
  2. إزالة القابلة للتنفيذ الكاملة. تحاول هذه التقنية إعادة بناء مصدر تجميع كامل من قابلة للتنفيذ. قد ترغب في تقديم نظرة على disassembler عبر الإنترنت, الذي يحاول القيام بهذه المهمة. تفقد معلومات على أي حال حول وحدات المصدر المختلفة وربما الأسماء/الأسماء المتغيرة.
  3. إزالة الاستهداف. تحاول هذه التقنية استخراج مزيد من المعلومات من القابل للتنفيذ ، والنظر في البصمات المترجم (أي أنماط الكود التي تم إنشاؤها بواسطة المترجمين المعروفين) وغيرها من الأشياء الحتمية. الهدف الرئيسي هو إعادة بناء رمز المصدر ذي المستوى الأعلى ، مثل مصدر C ، من القابل للتنفيذ. هذا في بعض الأحيان قادر على استعادة المعلومات حول أسماء الوظائف/المتغيرات. النظر في أن تجميع المصادر مع -g غالبًا ما يوفر نتائج أفضل. قد ترغب في إعطاء إعادة الاستهداف decompiler محاولة.

معظم هذا يأتي من مجالات أبحاث تقييم الضعف وتحليل التنفيذ. إنها تقنيات معقدة وغالبًا ما لا يمكن استخدام الأدوات على الفور خارج الصندوق. ومع ذلك ، فإنها توفر مساعدة لا تقدر بثمن عند محاولة عكس بعض البرامج.

لا تفعل هذا مع hexdump و محرر نص.عليك أن تكون حقا مريحة مع رمز الجهاز و تنسيق ملف تخزين و مرنة مع ما يعتبر "تفكيك أو تعديل و من ثم تجميعها".

إذا كان يمكنك الحصول بعيدا مع جعل مجرد "بقعة التغييرات" (كتابة بايت ، ولكن ليس إضافة أو إزالة وحدات البايت), سيكون من السهل (نسبيا).

لك حقا لا تريد أن تحل محل أي القائمة تعليمات ، لأن ثم عليك أن ضبط يدويا أي تنفذ النسبية تعويض داخل رمز الجهاز ، ليقفز/فروع/كميات/مخازن نسبة إلى عداد البرنامج, سواء ضمنية فورا القيم و تلك المحسوبة من خلال يسجل.

يجب أن تكون دائما قادرة على الحصول على بعيدا مع عدم إزالة بايت.مضيفا بايت قد يكون من الضروري أكثر تعقيدا التعديلات ، ويحصل الكثير من الجهد.

خطوة 0 (إعداد)

بعد أن كنت قد فعلا تفكيكها الملف بشكل صحيح مع objdump -D أو ما كنت عادة استخدام أول من فهم الواقع و إيجاد البقع تحتاج إلى تغيير ، سوف تحتاج إلى أن تأخذ علما الأمور التالية لمساعدتك على تحديد الصحيح بايت تعديل:

  1. "عنوان" (الأوفست من بداية الملف) من وحدات البايت كنت بحاجة إلى تغيير.
  2. الخام قيمة تلك بايت كما أنها حاليا هي ( --show-raw-insn الخيار objdump هو حقا مفيدة هنا).

الخطوة 1

تفريغ الخام تمثيل عشري من ملف ثنائي مع hexdump -Cv.

الخطوة 2

فتح hexdumpإد الملف تجد بايت في العنوان كنت تبحث عن التغيير.

سريعة مكثفة في hexdump -Cv الإخراج:

  1. أقصى اليسار عمود عناوين بايت (نسبة إلى بداية ملف ثنائي نفسها مثل objdump توفر).
  2. العمود أقصى اليمين (محاطة | الشخصيات) هو مجرد "الإنسان للقراءة" تمثيل بايت - أحرف ASCII مطابقة كل بايت هو مكتوب هناك ، . واقفا في جميع وحدات البايت التي لا خريطة ASCII حرف للطباعة.
  3. الاشياء الهامة في بين كل بايت اثنين عرافة أرقام مفصولة بمسافات, 16 بايت لكل خط.

حذار:على عكس objdump -D, الذي يمنحك عنوان كل التعليمات ويظهر الخام عرافة من التعليمات استنادا إلى كيفية توثيق يجري تشفيرها ، hexdump -Cv مقالب كل بايت بالضبط في النظام يبدو في الملف.هذا يمكن أن يكون مربكا بعض الشيء الأول على آلات حيث التعليمات بايت في مقابل النظام بسبب endianness الاختلافات التي يمكن أيضا أن يكون مربكا عندما كنت تتوقع معين بايت كما عنوان محدد.

الخطوة 3

تعديل بايت التي تحتاج إلى تغيير - من الواضح أنك بحاجة إلى معرفة الخام آلة تعليمات الترميز (وليس الجمعية الإستذكار) يدويا الكتابة في الصحيح بايت.

ملاحظة:لك لا تحتاج إلى تغيير الإنسان للقراءة التمثيل في العمود أقصى اليمين. hexdump سيتم تجاهل ذلك عند "الأمم المتحدة-تفريغ" عليه.

الخطوة 4

"الأمم المتحدة-تفريغ" تعديل الملف باستخدام hexdump hexdump -R.

الخطوة 5 (التعقل التحقق)

objdump حديثا الأمم المتحدةhexdumpإد الملف والتحقق من أن التفكيك التي غيرت تبدو صحيحة. diff ضد objdump من الأصل.

بجد لا تخطي هذه الخطوة.أخطأت في أكثر الأحيان عندما يدويا تحرير رمز الجهاز و هذا هو كيف لي أن قبض على معظمهم.

على سبيل المثال

هنا الحياة الحقيقية عملت سبيل المثال من أجل تعديل أحد ARMv8 (little endian) الثنائية في الآونة الأخيرة.(أنا أعرف السؤال هو الموسومة x86, ولكن أنا لم يكن لديك x86 سبيل المثال مفيد و المبادئ الأساسية هي نفسها ، مجرد تعليمات مختلفة.)

في حالتي أنا في حاجة إلى تعطيل محددة "لا يجب أن تفعل هذا" اليد القابضة تحقق:في بلدي على سبيل المثال الثنائية ، objdump --show-raw-insn -d إخراج خط اهتممت بدا مثل هذا (تعليمة واحدة قبل وبعد إعطاء السياق):

     f40:   aa1503e3    mov x3, x21
     f44:   97fffeeb    bl  af0 <error@plt>
     f48:   f94013f7    ldr x23, [sp, #32]

كما يمكنك أن ترى, برنامجنا هو "مفيد" الخروج قبل القفز إلى error وظيفة (الذي ينهي البرنامج).غير مقبول.لذلك نحن ذاهبون لتشغيل هذه التعليمات في أي المرجع.لذلك نحن نبحث عن بايت 0x97fffeeb العنوان/ملف تعويض 0xf44.

هنا hexdump -Cv خط تحتوي على تعويض.

00000f40  e3 03 15 aa eb fe ff 97  f7 13 40 f9 e8 02 40 39  |..........@...@9|

لاحظ كيف ذات الصلة بايت فعلا انقلبت (little endian الترميز في العمارة ينطبق على تعليمات الجهاز مثل أي شيء آخر) وكيف أن هذا قليلا unintuitively تتعلق بما بايت في ما إزاحة البايت:

00000f40  -- -- -- -- eb fe ff 97  -- -- -- -- -- -- -- --  |..........@...@9|
                      ^
                      This is offset f44, holding the least significant byte
                      So the *instruction as a whole* is at the expected offset,
                      just the bytes are flipped around. Of course, whether the
                      order matches or not will vary with the architecture.

على أي حال, أنا أعرف من النظر الأخرى التفكيك التي 0xd503201f يفكك على nop بحيث يبدو وكأنه مرشح جيد بالنسبة لي لا-op التعليمات.أنا يعدل الخط في hexdumpإد الملف تبعا لذلك:

00000f40  e3 03 15 aa 1f 20 03 d5  f7 13 40 f9 e8 02 40 39  |..........@...@9|

تحويلها مرة أخرى إلى ثنائي مع hexdump -R, تفكيكها الثنائية الجديدة مع objdump --show-raw-insn -d و التحقق من أن التغيير الصحيح:

     f40:   aa1503e3    mov x3, x21
     f44:   d503201f    nop
     f48:   f94013f7    ldr x23, [sp, #32]

ثم ركضت الثنائية وحصلت على سلوك أردت - ذات الصلة تحقق لم تعد تسبب البرنامج إلى إحباط.

آلة تعديل الرمز ناجحة.

!!!تحذير !!!

أو كنت ناجحة ؟ هل بقعة ما فاتني في هذا المثال ؟

أنا متأكد من أنك فعلت - بما أنك تسأل عن كيفية يدويا تعديل رمز الجهاز من البرنامج ، ويفترض أن تعرف ما تفعلونه.ولكن لصالح أي القراء الذين قد تكون القراءة لمعرفة سوف تفصيلا:

أنا فقط غيرت آخر التعليمات في الخطأ-حالة فرع!الانتقال إلى وظيفة إنهاء المشكلة.ولكن كما يمكنك أن ترى, تسجيل x3 تم تعديل من قبل mov فقط فوق!في الواقع ، ما مجموعه أربعة (4) سجلات تم تعديل كجزء من ديباجة الاتصال error, و واحدة السجل.هنا الجهاز كامل رمز لهذا الفرع ، بدءا من الشرطي القفز فوق if كتلة وتنتهي حيث القفز يذهب إلى إذا كان مشروطا ، if لا تؤخذ:

     f2c:   350000e8    cbnz    w8, f48
     f30:   b0000002    adrp    x2, 1000
     f34:   91128442    add x2, x2, #0x4a1
     f38:   320003e0    orr w0, wzr, #0x1
     f3c:   2a1f03e1    mov w1, wzr
     f40:   aa1503e3    mov x3, x21
     f44:   97fffeeb    bl  af0 <error@plt>
     f48:   f94013f7    ldr x23, [sp, #32]

كافة التعليمات البرمجية بعد فرع تم إنشاؤها بواسطة المحول البرمجي على افتراض أن برنامج الدولة كما كان من قبل الشرطي القفز!ولكن فقط عن طريق جعل القفزة النهائية إلى error وظيفة كود عدم المرجع ، أنا خلق مسار رمز حيث نصل إلى هذا الرمز مع تتعارض/البرنامج غير صحيح الدولة!

في حالتي هذه في الواقع يبدو لا يسبب أي مشاكل.إذا كنت محظوظا. جدا محظوظ:إلا بعد سبق ركض بلدي تعديل الثنائية (الذي بالمناسبة ، الأمنية الحرجة الثنائية:فقد القدرة على setuid, setgid, و تغيير سيلينو السياق!) لم أدرك أنني نسيت فعلا تتبع مسارات التعليمات البرمجية سواء تلك التي سجل التغييرات أثرت على مسارات التعليمات البرمجية التي جاءت في وقت لاحق!

كان يمكن أن يكون كارثيا - أي واحدة من هذه السجلات قد تم استخدامها في وقت لاحق رمز مع افتراض أنه يحتوي على القيمة السابقة التي حصلت الآن على الكتابة!و أنا من النوع الذي يعرف الناس عن الدقيق التفكير بعناية حول رمز و المتحذلق و المتمسك دائما الضميري من أمن الكمبيوتر.

ما إذا كنت استدعاء دالة حيث الحجج امتد من السجلات إلى المكدس (كما هو شائع جدا ، على سبيل المثال ، x86)?ما إذا كان هناك في الواقع عدة المشروط تعليمات في مجموعة التعليمات التي سبقت المشروط القفز (كما هو شائع ، على سبيل المثال ، من كبار السن الذراع الإصدارات)?كنت في أكثر بتهور غير متناسقة الدولة بعد أن فعلت ذلك أبسط يبدو التغيير!

لذلك هذا تحذيرية تذكير: يدويا twiddling مع الثنائيات حرفيا تجريد كل السلامة بينك و بين ما الجهاز و نظام التشغيل سوف تسمح.حرفيا كل التقدم الذي أحرزناه في الأدوات تلقائيا التقاط الأخطاء برامجنا ، ذهب.

لذلك كيف يمكننا إصلاح هذا بشكل صحيح ؟ على قراءة.

إزالة التعليمات البرمجية

إلى بشكل فعال/منطقيا "إزالة" أكثر من تعليمة واحدة ، يمكنك استبدال التعليمة الأولى تريد "حذف" غير المشروط مع القفزة الأولى التعليمات في نهاية "حذف" التعليمات.لهذا ARMv8 الثنائية التي تبدو مثل هذا:

     f2c:   14000007    b   f48
     f30:   b0000002    adrp    x2, 1000
     f34:   91128442    add x2, x2, #0x4a1
     f38:   320003e0    orr w0, wzr, #0x1
     f3c:   2a1f03e1    mov w1, wzr
     f40:   aa1503e3    mov x3, x21
     f44:   97fffeeb    bl  af0 <error@plt>
     f48:   f94013f7    ldr x23, [sp, #32]

أساسا أنت "قتل" كود (تحويلها إلى "رمز ميت").وي:يمكنك أن تفعل شيئا مماثلا مع سلاسل حرفية جزءا لا يتجزأ في الثنائية:طالما كنت ترغب في استبداله مع أصغر سلسلة يمكنك دائما تقريبا الحصول على بعيدا مع الكتابة سلسلة (بما في ذلك إنهاء null byte إذا كان "C-string") و إذا كان من الضروري الكتابة فوق القرص الثابت تلوينها حجم السلسلة في رمز الجهاز الذي يستخدمه.

يمكنك أيضا استبدال غير المرغوب فيه جميع التعليمات مع أي العمليات.وبعبارة أخرى, نحن يمكن أن تتحول غير المرغوب فيه رمز إلى ما يسمى "عدم المرجع زلاجات":

     f2c:   d503201f    nop
     f30:   d503201f    nop
     f34:   d503201f    nop
     f38:   d503201f    nop
     f3c:   d503201f    nop
     f40:   d503201f    nop
     f44:   d503201f    nop
     f48:   f94013f7    ldr x23, [sp, #32]

أتوقع أن الأمر مجرد إضاعة دورات وحدة المعالجة المركزية بالنسبة إلى القفز فوقها ، ولكن فمن أبسط وهكذا أكثر أمانا ضد الأخطاء, لأنك لا يجب أن يدويا معرفة كيفية ترميز القفز التعليمات بما في ذلك معرفة أوفست/عنوان لاستخدامها في أنه لا يجب أن اعتقد الكثير من أجل عدم المرجع زلاجات.

أن تكون واضحة, الخطأ هو سهل:لقد أخطأت اثنين (2) مرات عندما يدويا ترميز أن المشروط فرع التعليمات.وانها ليست دائما خطأنا:في المرة الأولى كان بسبب الوثائق كان قد عفا عليه الزمن/من الخطأ و قال بت واحد تم تجاهله في الترميز ، عندما لم يكن في الواقع, إذا كنت تعيين إلى صفر في أول محاولة.

إضافة التعليمات البرمجية

لك يمكن أن نظريا استخدام هذه التقنية إضافة تعليمات الجهاز أيضا ولكن الأمر أكثر تعقيدا, و لم يسبق لي أن تفعل ذلك حتى لا يكون مثال عمل في هذا الوقت.

من رمز الجهاز منظور انها نوعا ما سهلة:اختيار تعليمة واحدة في المكان الذي تريد إضافة رمز ، وتحويله إلى قفزة التعليمات البرمجية الجديدة التي تحتاج إضافة (لا تنسى أن إضافة التعليمات(s) وبالتالي يمكنك استبدال في القانون الجديد إلا إذا كنت لا تحتاج أن تضاف المنطق ، للقفز مرة أخرى إلى تعليمات تريد أن تعود في نهاية ذلك).أساسا أنت "الربط" القانون الجديد في.

ولكن عليك أن تجد مكانا لوضع الحقيقة أن القانون الجديد و هذا هو الجزء الصعب.

إذا كنت حقا محظوظ أنك يمكن أن مجرد إلحاق الجهاز الجديد الكود في نهاية الملف و سوف "تعمل فقط":القانون الجديد سوف تحصل على تحميل جنبا إلى جنب مع بقية في نفس المتوقع آلة تعليمات إلى العنوان الخاص بك الفضاء الفضاء الذي يقع في صفحة الذاكرة بشكل صحيح وضع علامة قابل للتنفيذ.

في تجربتي hexdump -R يتجاهل ليس فقط العمود أقصى اليمين ولكن أقصى اليسار عمود جدا حتى يمكنك حرفيا فقط ضع صفر عناوين جميع يدويا إضافة الخطوط و سوف تنجح.

إذا كنت أقل حظا ، بعد إضافة الكود عليك فعلا ضبط بعض رأس القيم داخل نفس الملف:إذا كان محمل نظام التشغيل الخاص بك تتوقع الثنائية تحتوي على البيانات الوصفية التي تصف حجم القسم القابل للتنفيذ (لأسباب تاريخية غالبا ما يسمى "النص" القسم) سيكون لديك للعثور على ضبط ذلك.في الأيام القديمة الثنائيات كانت مجرد الخام رمز الجهاز - في الوقت الحاضر رمز الجهاز ملفوفة في مجموعة من البيانات الوصفية (على سبيل المثال العفريت على لينكس و البعض الآخر).

إذا كنت لا تزال قليلا من الحظ ، قد يكون بعض "ميتة" بقعة في الملفات التي لا تحصل على تحميلها بشكل صحيح كجزء من الثنائية في نفس النسبية إزاحة مثل باقي التعليمات البرمجية في الملف (وهذا بقعة ميتة يمكن أن يصلح الكود الخاص بك و يتم محاذاة بشكل صحيح إذا كانت وحدة المعالجة المركزية الخاصة بك يتطلب كلمة الانحياز تعليمات وحدة المعالجة المركزية).ثم يمكنك الكتابة عليه.

إذا كنت سيئ الحظ لا يمكنك إلحاق رمز وليس هناك قتلى الفضاء يمكنك ملء الخاص بك مع رمز الجهاز.في تلك المرحلة كنت في الأساس يجب أن تكون على دراية وثيقة قابلة للتنفيذ شكل ونأمل أن تتمكن من معرفة شيء داخل تلك القيود التي إنسانيا من الممكن سحب قبالة يدويا في غضون فترة معقولة fo الوقت مع فرصة معقولة لا تفسدي.

"Disassembler الخاص بي CI Assembler" هو النظام الوحيد الذي أعرفه هو أنه تم تصميمه حول مبدأ أنه مهما كان التفكيك ، يجب إعادة تجميعها إلى البايت لنفس الثنائي.

https://github.com/albertvanderhorst/ciasdis

هناك مثالان مُعطى على elef-executables مع تفكيكهما وإعادة التجميع. تم تصميمه في الأصل لتكون قادرة على تعديل نظام التمهيد ، يتكون من التعليمات البرمجية والرمز المفسر والبيانات والأحرف الرسومية ، مع وجود مثل هذه النطاقات من الوضع الحقيقي إلى المحمي. (نجحت.) توضح الأمثلة أيضًا استخراج النص من الموظفين التنفيذيين ، والذي يستخدم لاحقًا للتسميات. حزمة Debian مخصصة لـ Intel Pentium ، ولكن المكونات الإضافية متاحة لشركة Dec Alpha ، 6809 ، 8086 إلخ.

تعتمد جودة التفكيك على مقدار الجهد الذي بذلته فيه. على سبيل المثال ، إذا لم تقم حتى بتزويد المعلومات بأنها ملف قزم ، فإن التفكيك يتكون من بايتات واحدة ، وإعادة التجميع تافهة. في الأمثلة ، أستخدم البرنامج النصي الذي يستخرج الملصقات ، ويجعل برنامجًا هندسيًا عكسيًا قابل للاستخدام غير قابل للاستخدام يمكن تعديله. يمكنك إدراج أو حذف شيء ما وسيتم إعادة حساب الملصقات الرمزية التي تم إنشاؤها تلقائيًا.

لا يتم افتراض على الإطلاق حول النقطة الثنائية ، ولكن بالطبع لا يتم تفكيك Intel إلى ثنائي Dec alpha.

miasm

https://github.com/cea-sec/miasm

يبدو أن هذا هو الحل الخرساني الأكثر واعدة. وفقًا لوصف المشروع ، يمكن للمكتبة:

  • فتح / تعديل / توليد PE / ELF 32 /64 LE / كن باستخدام Elfesteem
  • تجميع / تفكيك x86 / ARM / MIPS / SH4 / MSP430

لذلك ينبغي أن يكون أساسا:

  • تحليل قزم في تمثيل داخلي (تفكيك)
  • تعديل ما تريد
  • توليد قزم جديد (التجميع)

لا أظن أنه يولد تمثيلًا نصيًا تفكيكًا ، فمن المحتمل أن تضطر إلى السير عبر هياكل بيانات Python.

تجد TODO أدنى مثال على كيفية القيام بكل ذلك باستخدام المكتبة. يبدو أن نقطة انطلاق جيدة مثال/عزل/full.py, ، الذي يخلع ملف قزم معين. هيكل المستوى الأعلى الرئيسي هو Container, ، الذي يقرأ ملف قزم مع Container.from_stream. تودو كيف يعيد تجميعه بعد ذلك؟ يبدو أن هذا المقال يفعل ذلك: http://www.miasm.re/blog/2016/03/24/re150_rebuild.html

يسأل هذا السؤال عما إذا كانت هناك أي مكتبات أخرى: https://reverseengineering.stackexchange.com/questions/1843/what-are-the-avable-libraries-to-stly-sodify-elf-executables

أسئلة ذات صلة:

أعتقد أن هذه المشكلة ليست قابلة للأوتاد

أعتقد أن المشكلة العامة ليست قابلة للتلقائية بالكامل ، والحل العام يعادل أساسًا "كيفية عكس هندسة" ثنائي.

من أجل إدراج أو إزالة البايتات بطريقة ذات معنى ، يتعين علينا التأكد من أن جميع القفزات الممكنة تستمر في القفز إلى نفس المواقع.

من الناحية الرسمية ، نحتاج إلى استخراج الرسم البياني لتدفق التحكم للثنائي.

ومع ذلك ، مع الفروع غير المباشرة على سبيل المثال ، https://en.wikipedia.org/wiki/indirect_branch ، ليس من السهل تحديد هذا الرسم البياني ، انظر أيضًا: حساب وجهة القفز غير المباشر

شيء آخر قد تكون مهتمًا بفعله:

  • الأجهزة الثنائية - تغيير الكود الحالي

إذا كنت مهتمًا ، تحقق من: PIN ، Valgrind (أو مشاريع القيام بذلك: NACL - عميل Google الأصلي ، ربما QEMU.)

يمكنك تشغيل القابل للتنفيذ تحت إشراف PTRACE (بمعنى آخر ، مصحح الأخطاء مثل GDB) وبهذه الطريقة ، تتحكم في التنفيذ كما تذهب ، دون تعديل الملف الفعلي. بطبيعة الحال ، يتطلب مهارات التحرير المعتادة مثل العثور على أين تعليمات معينة تريد التأثير عليها في التنفيذ.

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