5222 / 3192 / 362
Регистрация: 12.12.2009
Сообщений: 8,090
Записей в блоге: 2
1

Запись в /dev/mem

17.04.2011, 17:41. Показов 3674. Ответов 8
Метки нет (Все метки)

Доброго времени суток)
Вот помогаю знакомому (он устраивался совсем не программистом, но на него, как водиться, начальство повесило много всего прочего), а я в программировании под Linux пока нуб. Суть - записать в память по адресу 0xD0000 значение 0xAA. Мне лично это кажется совершенно бесполезным занятием, но ему для чего-то это нужно (там работа с какой-то железякой). Нагуглил такой пример от К.Касперски
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <fcntl.h>
 
#define PAGE_SIZE 0x1000
 
int fd;
char buf[PAGE_SIZE];
 
// открываем /dev/mem на чтение и запись
if ((fd = open("/dev/mem", O_RDWR, 0)) == -1) return printf("/dev/mem open error\n");
 
// перемещаемся в начало (необязательно)
if (lseek(fd, 0, SEEK_SET) == -1) return printf("/dev/mem seek error\n");
 
// чтение данных из /dev/mem
static inline int rkm(int fd, int offset, void *buf, int size)
{
        if (lseek(fd, offset, 0) != offset) return 0;
        if (read(fd, buf, size) != size) return 0;
        return size;
}
 
// запись данных в /dev/mem
static inline int wkm(int fd, int offset, void *buf, int size)
{
        if (lseek(fd, offset, 0) != offset) return 0;
        if (write(fd, buf, size) != size) return 0;
        return size;
}
Адаптировал под свои нужды вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <fcntl.h>
#include <cstdio>
#include <unistd.h>
 
int rkm(int fd, int offset, unsigned char *buf, int size);
int wkm(int fd, int offset,  unsigned char *buf, int size);
 
int main(){
    int fd;
    unsigned char buf;
    // открываем /dev/mem на чтение и запись
    if ((fd = open("/dev/mem", O_RDWR, 0)) == -1)
        return printf("/dev/mem open error\n");
    rkm(fd,0xD0000,&buf, 1);
    printf("Значение по адресу 0xD0000 : %x\n",buf);
    buf=0xAA;
    wkm(fd,0xD0000,&buf,1);
    rkm(fd,0xD0000,&buf,1);
    printf("Теперь 0xD0000 сожержит : %x\n",buf);
    return 0;
}
 int rkm(int fd, int offset, unsigned char *buf, int size)
 
{
    if (lseek(fd, offset, 0) != offset){
        printf("\nlseek rkm error\n");
        return 0;
    }
    if (read(fd, buf, size) != size){
        printf("read errorr\n");
        return 0;
    } 
    return size;
}
 
int wkm(int fd, int offset,  unsigned char*buf, int size)
 
{
    if (lseek(fd, offset, 0) != offset) {
        printf("\nlseek wkm error\n");
        return 0;
    }
    if (write(fd, buf, size) != size){
        printf("write errorr\n");
        return 0; 
    }
    return size;
}
но при чтении всегда считывается значение 0xff. Может я что-то не так сделал? Подскажите, как правильно реализовать подобную задачу.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.04.2011, 17:41
Ответы с готовыми решениями:

Не могу открыть /dev/mem
запускаю программу, получаю в ответ Failed to open /dev/mem, try checking permissions. под рутом...

Constructor delegation follows mem-initializer for
Подскажите пожалуйста из-за чего возникает проблема при объявление конструктора у наследника ...

MEM:Rootkit.Win64.EquationDrug.a
Проблема сходная с проблемой автора темы https://www.cyberforum.ru/viruses/thread1971747.html Раз...

MEM:Rootkit.Win32.TDSS.d
По тупости одного нехорошего человека, имею сабж. Как бороться?

8
мну довольно <(-__-)l
216 / 205 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.04.2011, 18:50 2
Значение равно AA, потому что ты уже 1 или более раз запускал проект и значение в памяти то СОХРАНИЛОСЬ!)
Смени блок памяти)
у меня почему-то на блоке 0x50000 работает, а на 0xD0000 нет. не дает писать и всегда значение 0x55..

Добавлено через 8 минут
интересно, я не сильно напортачил при записи в используемый какой-то программой блок памяти?)
0
5222 / 3192 / 362
Регистрация: 12.12.2009
Сообщений: 8,090
Записей в блоге: 2
17.04.2011, 19:15  [ТС] 3
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
Значение равно AA...
Нет, 0xAA нужно записать, но после записи считывается 0xff, в этом то и проблема.
0
мну довольно <(-__-)l
216 / 205 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.04.2011, 19:40 4
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
у меня почему-то на блоке 0x50000 работает, а на 0xD0000 нет. не дает писать и всегда значение 0x55..
Попробуй сменить блок? у меня тоже на 0xD0000 не работает, а 0x50000 и 0x80000 - работает...
0
5222 / 3192 / 362
Регистрация: 12.12.2009
Сообщений: 8,090
Записей в блоге: 2
17.04.2011, 20:18  [ТС] 5
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
у меня тоже на 0xD0000 не работает, а 0x50000 и 0x80000 - работает...
Да, действительно работает. Может этот адрес пренадлежит ядру и между записью и чтением значение переписывается и из-за этого кажется, что код не работает. Хотя не уверен...
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
18.04.2011, 09:04 6
Лучший ответ Сообщение было отмечено как решение

Решение

В адреса 0xd0000-0xd3fff мэпиться железо (какое именно у вас можно глянуть в логе dmesg или lspci) соответственно не стоит туда вот так-вот, не глядя, на обум что-то писать.
4
5222 / 3192 / 362
Регистрация: 12.12.2009
Сообщений: 8,090
Записей в блоге: 2
18.04.2011, 09:39  [ТС] 7
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
не стоит туда вот так-вот, не глядя, на обум что-то писать.
Это не на обум, есть документация к этой железяке, где сказано, что при записи значения 0xAA по адресу 0xD0000 что-то там происходит, я не вникал.
А может нужно как-то получить доступ к этому участку памяти? Ведь с другими адресами работает.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
18.04.2011, 09:46 8
Так есть у вас этот доступ. Просто ведет себя не как обычная память, например запись туда может быть эквивалентом outb(). Подробности должны быть в спеке на ваше устройство...

Боюсь, что более-менее современных (скажем -10лет) устройств не умеющих настраиваться на произвольный диапазон адресов не осталось. т.е. перед записью нужно убедиться, что это именно ваша железка.
2
25 / 23 / 4
Регистрация: 22.04.2010
Сообщений: 749
18.04.2012, 15:11 9
А разве прям так можно читать/записывать в файл без маппирования физических адресов !?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.04.2012, 15:11
Помогаю со студенческими работами здесь

[Error] mem: No such file or directory
Писал программу где надо работать со списками но дает ошибку на 3 строке #include &lt;stdio.h&gt;...

Где скачать библиотеку mem.h?
где можно скачать библиотеку для MS Visual Studio библтотеку &lt;mem.h&gt;, и вообще где обычно можно...

Как удалить троян mayachok MEM.7?
Утилита др.веб его удаляет но он вскоре опять появляется. Пробовал вручную как вычитал на форуме,...

Самовозобновляющийся MEM:Trojan.Win64.EquationDrug.gen
Здравствуйте. Начал греться при включенном интернете. Наверное майнер. Температуры ЦП 83 °C ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru