Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Ассемблер процессора ARM  (Прочитано 11625 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
zuuuuk
Постоялец

ru
Offline Offline

« : 01-11-2016 13:41 » 

Добрый день.
Я использую ARM процессор. Пишу программу на Си.
Подскажите возможно ли вызвать ассембреный код функции, расположенной
по известному адресу?

я знаю что функция, которая мне нужна, в асемлерном, виде выглядит так.
Код: (ASM)
Disassembly of section .rel.dyn:

00000258 <.rel.dyn>:
 258:   00008404        andeq   r8, r0, r4, lsl #8
 25c:   00000d15        andeq   r0, r0, r5, lsl sp

Disassembly of section .text:

00000260 <f_all>:
 260:   e52db004        push    {fp}            ; (str fp, [sp, #-4]!)
 264:   e28db000        add     fp, sp, #0
 268:   e59f3030        ldr     r3, [pc, #48]   ; 2a0 <f_all+0x40>
 26c:   e08f3003        add     r3, pc, r3
 270:   e59f202c        ldr     r2, [pc, #44]   ; 2a4 <f_all+0x44>
 274:   e7932002        ldr     r2, [r3, r2]
 278:   e5922000        ldr     r2, [r2]
 27c:   e2821001        add     r1, r2, #1
 280:   e59f001c        ldr     r0, [pc, #28]   ; 2a4 <f_all+0x44>
 284:   e7933000        ldr     r3, [r3, r0]
 288:   e5831000        str     r1, [r3]
 28c:   e1a03002        mov     r3, r2
 290:   e1a00003        mov     r0, r3
 294:   e24bd000        sub     sp, fp, #0
 298:   e49db004        pop     {fp}            ; (ldr fp, [sp], #4)
 29c:   e12fff1e        bx      lr
 2a0:   00008184        andeq   r8, r0, r4, lsl #3
 2a4:   0000000c        andeq   r0, r0, ip
 

код в памяти выглядит следующим образом
Код: (ActionScript)
addr         data
0x10260  04 b0 2d e5   00 b0 8d e2  30 30 9f e5    03 30 8f e0
0x10270  2c 20 9f e5    02 20 93 e7  00 20 92 e5   01 10 82 e2
0x10280  1c 00 9f e5    00 30 93 e7  00 10 83 e5   02 30 a0 e1
0x10290  03 00 a0 e1   00 d0 4b e2  04 b0 9d e4   1e ff 2f e1
0x102a0  84 81 00 00   0c 00 00 00  04 b0 2d e5   00 b0 8d e2

мне нужно вызвать функцию f_all()
и вернуться обратно в программу.

Возможно ли такое сделать?





Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 01-11-2016 15:01 » 

Сам язык Си позволяет вызывать функцию по её адресу (указателю). Желательно при этом сделать её предварительное объявление, чтобы компилятор правильно реагировал на синтаксис. Также, если передаются параметры необходимо указать каким методом. ARM даже стек позволяет крутить в разном направлении.
Отсюда вопросы: какой комплект компилятора, ассемблера и линковщика используете?

Лучше не пытаться использовать какую-то функцию внутри тела чужого кода, если Вы дизассемблировали код, то его стоит отладить отдельно и вынести в собственный модуль. Вариантов два: первый - если компилятор Си поддерживает встроенный ассемблер, второй - отдельная запись ассемблерного кода с компиляцией в объектный файл.
Если принципиально необходимо запустить именно код из чужого модуля - не подскажу, так как ARM - это общая архитектура и основная система команд довольно широкого ряда процессоров, как в каком из них реализуется система вычисления адреса при загрузке и система защиты (Если таковая есть.) стоит отдельного разбора.
Записан
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #2 : 01-11-2016 18:22 » 

Цитата
Отсюда вопросы: какой комплект компилятора, ассемблера и линковщика используете?
компилятор gcc  4.8

Цитата
как в каком из них реализуется система вычисления адреса при загрузке и система защиты (Если таковая есть.) стоит отдельного разбора.

ядро арма M4.
функция f_all(). находится в библиотеке. которая является динамической.
скомпилирована ключами
Код: (Bash)
gcc -nostartfiles -fpic -shared .....

Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 01-11-2016 18:45 » 

Код: (C)
#include <stdio.h>

int __stdcall example(int a, int b) // Это базовая функция
{
return (a + b);
}

int __stdcall (*func)(int a, int b) = &example; // Это функция заданная,
                                                 // как указатель на базовую по её адресу

int __stdcall (*unknown)(int a, int b) = (void*)0x55667788; // А это от балды я адрес задаю,
                                                             // и программа крашится

int main(int argc, char* argv[])
{
int x = 5;
int y = 15;

printf("Example result = %i\n", example(x, y));

printf("Func result = %i\n", func(x, y));

printf("Unknown result = %i\n", unknown(x, y));

// При запуске первые две выдадут результат, затем краш

return 0;
}

Вот только вопрос: знаете ли Вы действительно адрес своей функции в динамической библиотеке после её загрузки в память, а также её адресное пространство?
« Последнее редактирование: 01-11-2016 19:08 от Aether » Записан
zuuuuk
Постоялец

ru
Offline Offline

« Ответ #4 : 02-11-2016 07:46 » 

Цитата
Вот только вопрос: знаете ли Вы действительно адрес своей функции в динамической библиотеке после её загрузки в память, а также её адресное пространство?
Да, знаю. В топике я написал отображение в памяти этой функции.
Она расположена по адресу 0х10260.

 
Цитата
int __stdcall (*unknown)(int a, int b) = (void*)0x55667788; // А это от балды я адрес задаю,
                                                             // и программа крашится

меня интересует   как раз это выражение.
вы могли бы немного пояснить...
__stdcall необходим ? что означает?

(void*) можно на что то заменить?
например вот на такое выражение?
Код: (C)
int (*f_mall) (void) = (  int(*)(void) ) 0x10260 ;

заранее спасибо.
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #5 : 02-11-2016 09:49 » 

Цитата
Вот только вопрос: знаете ли Вы действительно адрес своей функции в динамической библиотеке после её загрузки в память, а также её адресное пространство?

Да, знаю. В топике я написал отображение в памяти этой функции.
Она расположена по адресу 0х10260.

Цитата
int __stdcall (*unknown)(int a, int b) = (void*)0x55667788; // А это от балды я адрес задаю,
                                                             // и программа крашится

меня интересует   как раз это выражение.
вы могли бы немного пояснить...
__stdcall необходим ? что означает?

stdcall - Соглашение о вызове. С ARM-ом дела не имел, так-что не знаю, есть-ли у него более одного соглашения о вызове и надо-ли ему специально указывать какое оно..

Цитата
Вот только вопрос: знаете ли Вы действительно адрес своей функции в динамической (void*) можно на что то заменить?
например вот на такое выражение?
Код: (C)
int (*f_mall) (void) = (  int(*)(void) ) 0x10260 ;

Имхо, можно заменить и на такое.
« Последнее редактирование: 02-11-2016 09:53 от darkelf » Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 02-11-2016 10:11 » new

Цитата
Вот только вопрос: знаете ли Вы действительно адрес своей функции в динамической библиотеке после её загрузки в память, а также её адресное пространство?
Да, знаю. В топике я написал отображение в памяти этой функции.
Она расположена по адресу 0х10260.

 
Цитата
int __stdcall (*unknown)(int a, int b) = (void*)0x55667788; // А это от балды я адрес задаю,
                                                             // и программа крашится

меня интересует   как раз это выражение.
вы могли бы немного пояснить...
__stdcall необходим ? что означает?

(void*) можно на что то заменить?
например вот на такое выражение?
Код: (C)
int (*f_mall) (void) = (  int(*)(void) ) 0x10260 ;

заранее спасибо.
Я в первую очередь хочу уделить внимание того, что: всегда ли эта функция при загрузке её библиотеки окажется там?
Предположим сейчас всё нормально, потом придёт обновление или потребуется пересборка модуля, и функция окажется в другом месте - это прямой путь к проблемам. Возможно, Ваша ОС, которая и загружает эту библиотеку, предоставляет нормальные средства для работы с ней.
Вот пример из Windows:
- явная загрузка динамической библиотеки:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
- затем поиск в ней указателя на нужную функцию:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx

На __stdcall ссылку уже дали, от себя отмечу, что из-за возможности расширенного управления стеком по сравнению с x86 необходимо изучить вопрос передачи параметров детально. Начать лучше с изучения заголовочных файлов Ваших библиотек для ARM, скорее всего метод вызова будет переопределён через #define и придётся полазить. Также, стоит отметить, что некоторые соглашения о вызове, например, __fastcall в разных средах могут быть выполнены немного по разному.

Мой компилятор на int(*)(void) будет ругаться. По смыслу я присваиваю функции значение универсального указателя непосредственным образом. Возможно, кто-то укажет мне и на мои ошибки.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines