मैं libelf का उपयोग कर एक साधारण स्थिर ईएलएफ उत्पन्न करने की कोशिश कर रहा हूँ, लेकिन मुझे परेशानी हो रही है।ईएलएफ पीढ़ी libelf संकेत का उपयोग कर
मैं ऑब्जेक्ट फ़ाइल जेनरेट नहीं करना चाहता हूं और फिर इसे w/lD लिंक करना चाहता हूं, इसके बजाय मैं इसे स्वयं उत्पन्न करना चाहता हूं।
इस कार्यक्रम का मुख्य उद्देश्य एक लोड सेगमेंट के साथ एक स्थिर ईएलएफ उत्पन्न करना और कोड निष्पादित करना है।
मुख्य समस्या शेलकोड में नहीं है, लेकिन शायद कुछ शीर्षकों में मैं गलत तरीके से उत्पादन करने की कोशिश करता हूं। जब मैं जेनरेट किए गए ईएलएफ को चलाने की कोशिश करता हूं तो यह मारे जाते हैं जैसे कि कर्नेल इसे लोड करने वाले सेगमेंट को प्रबंधित नहीं करता है, आदि।
यदि आप मुझे संकेत दे सकते हैं तो मुझे शौक होगा।
create_elf.3.c
#include <err.h>
#include <fcntl.h>
#include <libelf.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
unsigned char code[] =
"\x0b\x58\x99\x52\x66\x68\x2d\x70"
"\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61"
"\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52"
"\x51\x53\x89\xe1\xcd\x80";
int main(int argc, char *argv[])
{
int fd;
Elf *e;
Elf_Scn *scn;
Elf_Data *data;
Elf32_Ehdr *ehdr;
Elf32_Phdr *phdr;
Elf32_Shdr *shdr;
if (argc != 2)
errx(EX_USAGE,"input... ./%s filename\n",argv[0]);
if (elf_version(EV_CURRENT) == EV_NONE)
errx(EX_SOFTWARE,"elf_version is ev_none, wtf? %s\n",elf_errmsg(-1));
if ((fd = open(argv[1], O_WRONLY | O_CREAT, 0777)) < 0)
errx(EX_OSERR, "open %s\n",elf_errmsg(-1));
if ((e = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL)
errx(EX_SOFTWARE,"elf_begin %s\n",elf_errmsg(-1));
if ((ehdr = elf32_newehdr(e)) == NULL)
errx(EX_SOFTWARE,"elf32_newehdr %s\n",elf_errmsg(-1));
/*
without these definitions objdump/readelf/strace/elf loader
will fail to load the binary correctly
be sure to pick them carefully and correctly, preferred exactly like the
ones like the system you are running on (so if you are running x86,
pick the same values you seen on a regular readelf -a /bin/ls
*/
ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
ehdr->e_ident[EI_CLASS] = ELFCLASS32;
ehdr->e_machine = EM_386;
ehdr->e_type = ET_EXEC;
ehdr->e_entry = 0x8040800;
if ((phdr = elf32_newphdr(e,1)) == NULL)
errx(EX_SOFTWARE,"elf32_newphdr %s\n",elf_errmsg(-1));
if ((scn = elf_newscn(e)) == NULL)
errx(EX_SOFTWARE,"elf32_newscn %s\n",elf_errmsg(-1));
if ((data = elf_newdata(scn)) == NULL)
errx(EX_SOFTWARE,"elf32_newdata %s\n",elf_errmsg(-1));
data->d_align = 4;
data->d_off = 0LL;
data->d_buf = code;
data->d_type = ELF_T_WORD; // code :x
data->d_size = sizeof(code);
data->d_version = EV_CURRENT;
if ((shdr = elf32_getshdr(scn)) == NULL)
errx(EX_SOFTWARE,"elf32_getshdr %s\n",elf_errmsg(-1));
shdr->sh_name = 0;
shdr->sh_type = SHT_PROGBITS;
shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
shdr->sh_entsize = 0; // only used if we hold a table
if (elf_update(e, ELF_C_NULL) < 0)
errx(EX_SOFTWARE,"elf_update_1 %s\n",elf_errmsg(-1));
phdr->p_type = PT_LOAD;
phdr->p_offset = ehdr->e_phoff;
phdr->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT);
phdr->p_vaddr = 0x8040800;
phdr->p_paddr = 0x8040800;
phdr->p_align = 4;
phdr->p_filesz = sizeof(code);
phdr->p_memsz = sizeof(code);
phdr->p_flags = PF_X | PF_R;
elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);
if (elf_update(e, ELF_C_WRITE) < 0)
errx(EX_SOFTWARE,"elf32_update_2 %s\n",elf_errmsg(-1));
elf_end(e);
close(fd);
return 1;
}
अगर किसी ने मुझे संकेत हो सकता है कि क्या गलत यहाँ
धन्यवाद
संपादित
अधिक जानकारी देने के लिए नहीं खेद है कि मैं शौकीन होगा ,
ईएलएफ पीढ़ी ठीक काम कर रही है, मुझे कोई वाक्यविन्यास त्रुटियां आदि नहीं मिलती हैं, हालांकि जब भी मैं ईएलएफ उत्पन्न करने की कोशिश करता हूं, उदाहरण के लिए ./create_elf.3 foo14 (और foo14 जेनरेट ईएलएफ है)
यह की हत्या कर दी हो जाता है execve/गिरी इसे ठीक से लोड करने के लिए मैं इसे डब्ल्यू लोड हो रहा है की कोशिश की इच्छा नहीं है के रूप में अगर/आईडीए लेकिन आईडीए disassembled कोड ठीक पर्याप्त
यहाँसे पता चलता readelf
readelf -a foo14
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8040800
Start of program headers: 52 (bytes into file)
Start of section headers: 116 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 2
Section header string table index: 0
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] <no-name> NULL 00000000 000000 000000 00 0 0 0
[ 1] <no-name> PROGBITS 00000000 000054 000020 00 AX 0 0 4
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000034 0x08040800 0x08040800 0x00021 0x00021 R E 0x4
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
No version information found in this file.
हो सकता है आप हमें यह बताएं कि क्या गलत है:
उत्पन्न निष्पादन की संरचना इस प्रकार हो सकता है? – steabert
त्रुटि क्या है? क्या हो रहा है? आप क्या उम्मीद करते हैं? 'Objdump' आपको बीमार जेनरेट की गई ईएलएफ फ़ाइल के बारे में क्या बताता है? 'कोड' क्या करना है (हम में से अधिकांश अपने सिर में अलग-अलग नहीं हो पाएंगे)? –
आपका 'मुख्य' 'रिटर्न 1 'के साथ क्यों समाप्त होता है? यह आमतौर पर 'वापसी 0' होना चाहिए, या 'वापसी EXIT_SUCCESS; ' –