загрузить файл ELF в память
я пытаюсь поместить файл elf в память, а затем выполнить его, вот шаги:
1-файл для ввода в память
int main()
{
printf("Hello world! n");
return 0;
}
2 - скомпилировать его gcc -o hello hello.c -static
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: ARM
Version: 0x1
Entry point address: 0x8120
Start of program headers: 52 (bytes into file)
Start of section headers: 119864 (bytes into file)
Flags: 0x5000000, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 4
Size of section headers: 40 (bytes)
Number of section headers: 18
Section header string table index: 17
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x00008000 0x00008000 0x16828 0x16828 R E 0x1000
LOAD 0x016840 0x0001f840 0x0001f840 0x00250 0x02660 RW 0x1000
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0
EXIDX 0x015f40 0x0001df40 0x0001df40 0x008e8 0x008e8 R 0x4
3-пишу загрузчик (скомпилирован для ARM)
mmap2(0x8000, 92200, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x8000
mmap2(0x1f000, 65536, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x1f000
3.1-тогда я скопировал все байты elf в распределения
3.2-jmp к главной функции
ldr r0, =0x008160
blx r0
.text:00008160 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00008160 EXPORT main
.text:00008160 main ; DATA XREF: _start+8o
.text:00008160 ; .text:off_8150o
.text:00008160 STMFD SP!, {R11,LR}
.text:00008164 ADD R11, SP, #4
.text:00008168 LDR R3, =(aHelloWorld - 0x8174)
.text:0000816C ADD R3, PC, R3 ; "Hello world! "
.text:00008170 MOV R0, R3
.text:00008174 BLX puts
.text:00008178 MOV R3, #0
.text:0000817C MOV R0, R3
.text:00008180 LDMFD SP!, {R11,PC}
.text:00008180 ; End of function main
проблема в том, что каждый раз, когда я добираюсь до строки 0x8174, затем прыгаю в, после немного инструкций у меня всегда есть SIGSEGV в случайном положении, больше времени инструкция аварии => 0x9cc0: ldr r0, [r0, #4]
С r0=0x70a34
00008000-0002f000 rwxp 00000000 00:00 0
80000000-80001000 r-xp 00000000 b3:18 129754 /data/local/tmp/main
80001000-8001a000 rwxp 00001000 b3:18 129754 /data/local/tmp/main
becdf000-bed00000 rwxp 00000000 00:00 0
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
это больше инструкций после аварии:
.text:00009CB4 loc_9CB4 ; CODE XREF: pthread_mutex_lock_impl+18j
.text:00009CB4 MOV R3, #0xFFFF0FE0
.text:00009CBC BLX R3
.text:00009CC0 LDR R0, [R0,#4]
в этом месте 0x9CB4
, стоимостью r0
is 0x1f96c
(это нормально), после blx значение r0
is 0x70a34
(gdb) x/10x 0xffff0fe0
0xffff0fe0: 0xee1d0f70 0xe12fff1e 0xee1d0f70 0x00000000
0xffff0ff0: 0x00000000 0x00000000 0x00000000 0x00000005
0xffff1000: Cannot access memory at address 0xffff1000
спасибо!
2 ответов
Я пытаюсь поместить файл elf в память, а затем выполнить его,
для полностью статически связанного исполняемого файла ваши шаги будут работать (за исключением того, что вам нужно перейти к _start
== точка входа 0x8120
, не main
).
тогда я скопировал все байты elf в распределения
еще одна возможная проблема-не обращая внимания на .p_offset
. Ваш memcpy
ies должен выглядеть примерно так это:
unsigned char buf1[0x16828]; // read 0x16828 bytes from start of file
memcpy(0x8000, buf1, 0x16828);
unsigned char buf2[0x250]; // read 0x250 bytes from offset 0x016840 into the file
memcpy(0x0001f840, buf2, 0x250);
ваша проблема в том, что вам нужно использовать правильную точку входа, и вам нужно инициализировать стек программы (и, возможно, регистры) так же, как и ОС. Вам нужно использовать правильную точку входа, чтобы библиотека времени выполнения C была инициализирована, иначе ваш вызов printf
(или puts
как это может быть) почти наверняка произойдет сбой. Вам нужно правильно настроить стек, потому что именно там код инициализации библиотеки времени выполнения C будет искать аргументы программы и окружающая среда (и, возможно, другие вещи).
вы не сказали, какую операционную систему вы используете, но если вы используете Linux, вы можете посмотреть как ответ на другой вопрос, заданный CesarB описание начального состояния стека в arm Linux.