
مُسطِّح ملفات ELF غير معتمد على المعمارية لشفرة الصدفة
elfloader هو مُحمّل بسيط جدًا لملفات ELF يُنشئ تمثيلًا مسطحًا في الذاكرة لملف ELF.
اقرن هذا مع Rust والآن يمكنك كتابة الشيل كود الخاص بك بلغة مناسبة وآمنة وعالية المستوى. يمكن استخدام أي هدف يمكن لـ LLVM استهدافه، بما في ذلك مواصفات الأهداف المخصصة للمنصات وABIs الغريبة حقًا. استمتع باستخدام أشياء مثل u64 على أنظمة 32-bit، والمصفوفات ذات فحص الحدود، ومعالجة drop للتخصيصات، إلخ :)
إنه ببساطة يدمج جميع أقسام LOAD معًا، باستخدام حشو الأصفار إذا كانت هناك فجوات، في ملف مسطح كبير واحد.
يتضمن هذا الملف تهيئة صفرية لأقسام .bss، وبالتالي يمكن استخدامه مباشرة كحمولة شيل كود.
إذا كنت لا تريد إضاعة الوقت مع نصوص linker التي تفشل مفتوحة، فمن المحتمل أن تكون هذه طريقة رائعة.
هذا لا يعالج أي عمليات إعادة تموضع، الأمر متروك لك للتأكد من أن ELF الأصلي مبني على العنوان الذي تريده.
لاستخدام هذه الأداة، ببساطة:
Usage: elfloader [--perms] [--binary] [--base=<addr>] <input ELF> <output>
--binary - Don't output a FELF, output the raw loaded image with no
metadata
--perms - Create a FELF0002 which includes permission data, overrides
--binary
--base=<addr> - Force the output to start at `<addr>`, zero padding from
the base to the start of the first LOAD segment if needed.
`<addr>` is default hex, can be overrided with `0d`, `0b`,
`0x`, or `0o` prefixes.
Warning: This does not _relocate_ to base, it simply starts
the output at `<addr>` (adding zero bytes such that the
output image can be loaded at `<addr>` instead of the
original ELF base)
<input ELF> - Path to input ELF
<output> - Path to output file
لتثبيت هذه الأداة، قم بتشغيل:
cargo install --path .
الآن يمكنك استخدام elfloader من أي مكان في شاشتك!
تم تطوير هذا المشروع مباشر هنا:
https://www.youtube.com/watch?v=x0V-CEmXQCQ
يوجد مثال في example_small_program، فقط قم بتشغيل make أو nmake وسيؤدي هذا إلى إنشاء example.bin بحجم 8 بايت.
pleb@gamey ~/elfloader/example_small_program $ make
cargo build --release
Finished release [optimized] target(s) in 0.03s
elfloader --binary target/aarch64-unknown-none/release/example_small_program example.bin
pleb@gamey ~/elfloader/example_small_program $ ls -l ./example.bin
-rw-r--r-- 1 pleb pleb 8 Nov 8 12:27 ./example.bin
pleb@gamey ~/elfloader/example_small_program $ objdump -d target/aarch64-unknown-none/release/example_small_program
target/aarch64-unknown-none/release/example_small_program: file format elf64-littleaarch64
Disassembly of section .text:
00000000133700b0 <_start>:
133700b0: 8b000020 add x0, x1, x0
133700b4: d65f03c0 ret
الآن يمكنك كتابة الشيل كود الخاص بك في Rust، ولن تضطر إلى القلق بشأن ما إذا كنت تُصدر .data، .rodata، .bss، إلخ. هذا سيتعامل مع كل ذلك من أجلك!
يوجد أيضًا مثال مع .bss و .rodata
pleb@gamey ~/elfloader/example_program_with_data $ make
cargo build --release
Finished release [optimized] target(s) in 0.04s
elfloader --binary target/aarch64-unknown-none/release/example_program_with_data example.bin
pleb@gamey ~/elfloader/example_program_with_data $ ls -l ./example.bin
-rw-r--r-- 1 pleb pleb 29 Nov 8 12:39 ./example.bin
pleb@gamey ~/elfloader/example_program_with_data $ objdump -d target/aarch64-unknown-none/release/example_program_with_data
target/aarch64-unknown-none/release/example_program_with_data: file format elf64-littleaarch64
Disassembly of section .text:
0000000013370124 <_start>:
13370124: 90000000 adrp x0, 13370000 <_start-0x124>
13370128: 90000008 adrp x8, 13370000 <_start-0x124>
1337012c: 52800029 mov w9, #0x1 // #1
13370130: 91048000 add x0, x0, #0x120
13370134: 3904f109 strb w9, [x8, #316]
13370138: d65f03c0 ret
pleb@gamey ~/elfloader/example_program_with_data $ readelf -l target/aarch64-unknown-none/release/example_program_with_data
Elf file type is EXEC (Executable file)
Entry point 0x13370124
There are 4 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000120 0x0000000013370120 0x0000000013370120
0x0000000000000004 0x0000000000000004 R 0x1
LOAD 0x0000000000000124 0x0000000013370124 0x0000000013370124
0x0000000000000018 0x0000000000000018 R E 0x4
LOAD 0x000000000000013c 0x000000001337013c 0x000000001337013c
0x0000000000000000 0x0000000000000001 RW 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x0
Section to Segment mapping:
Segment Sections...
00 .rodata
01 .text
02 .bss
03
هذه الأداة لا تهتم بأي شيء باستثناء أقسام LOAD. تحدد endianness (صغير مقابل كبير) والبتية (32 مقابل 64) من رأس ELF، ومن هناك تقوم بإنشاء صورة مسطحة بناءً على العناوين الافتراضية لرأس البرنامج (حيث يتم تحميلها)، وحجم الملف (عدد البايتات المهيأة) وحجم الذاكرة (حجم منطقة الذاكرة الفعلية). يتم تهيئة البايتات من الملف بناءً على الإزاحة وحجم الملف، ثم يتم تمديدها بالأصفار حتى حجم الذاكرة (أو اقتطاعها إذا كان حجم الذاكرة أصغر من حجم الملف).
ثم يتم دمج أقسام LOAD هذه معًا مع حشو بايت صفري للفجوات.
هذا مصمم ليكون بسيطًا بشكل لا يصدق، ومستقل عن مدخلات ELF. يمكن أن يكون ملفًا تنفيذيًا، ملف كائن، كائن مشترك، تفريغ أساسي، إلخ، لا يهم حقًا. سيعطيك ببساطة التمثيل المسطح للذاكرة، لا أكثر.
هذا يسمح لك بتحويل أي ELF إلى شيل كود، أو تنسيق ملف أبسط يسهل تحميله في المناطق التي يصعب الوصول إليها، مثل الأجهزة المضمنة. شخصيًا، قمت بتطوير هذا لمُحمّل MIPS NT 4.0 الخاص بي والذي يسمح لي بتشغيل كود Rust.
هذه الأداة بشكل افتراضي تُنشئ تنسيق ملف FELF. هذا هو Falk ELF. هذا تنسيق ملف بسيط:
FELF0001 - Magic header
entry - 64-bit little endian integer of the entry point address
base - 64-bit little endian integer of the base address to load the image
<image> - Rest of the file is the raw image, to be loaded at `base` and jumped
into at `entry`
هذه الأداة بشكل افتراضي تُنشئ تنسيق ملف FELF. هذا هو Falk ELF. هذا تنسيق ملف بسيط مع أذونات:
FELF0002 - Magic header
entry - 64-bit little endian integer of the entry point address
base - 64-bit little endian integer of the base address to load the image
<image> - Rest of the file is the raw image, to be loaded at `base` and jumped
into at `entry`
<perms> - Permissions, matching the bytes of <image> where the byte contains
the following flags bitwise or-ed together:
0x01 - Executable, 0x02 - Writable, 0x04 - Readable
Padding bytes will be 0x00, and thus have no permissions for any
access