Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > exception : 0xC0000005: Access Violation


Автор: batex 2.8.2012, 10:46
Разработка идет по windows mobile 6. Возникла необходимость в определенном случае менять данные в памяти по адресу 0x02020000 cо смещение 0x4a. Написал в лоб:
Код

int offset = 0x4a;
int Addr = 0x02020000;
Addr += offset;
char * c = (char *) Addr;
*c = 0x1;


Выдает исключение: exception : 0xC0000005: Access Violation. Нет доступа к памяти. Попытался сделать через ReadProccessMemory и WriteProccessMemory. Вроде через эти функции можно писать в память другого процесса. Но для этого надо знать Handle процесса. Вопрос в следующем: Как узнать какому процессу принадлежит память(хотя есть такое ощущение, что это вообще реестр) или как получить доступ и писать в защищенную память?

Автор: korian 2.8.2012, 11:27
А оно вам надо?  smile
От куда вообще взялся такой адрес? Вы уверены, что он не изменится при перезагрузке например?
Если вы знаете от куда он взялся, вы поидее должны знать, какой процесс им обладает.

Автор: batex 2.8.2012, 11:42
Цитата(korian @ 2.8.2012,  11:27)
А оно вам надо?  smile
От куда вообще взялся такой адрес? Вы уверены, что он не изменится при перезагрузке например?
Если вы знаете от куда он взялся, вы поидее должны знать, какой процесс им обладает.

этот адрес дало начальство сверху. Откуда конкретно он взялся - я не знаю

Автор: magesi 2.8.2012, 11:58
Цитата(batex @  2.8.2012,  10:46 Найти цитируемый пост)
Возникла необходимость в определенном случае менять данные в памяти по адресу 0x02020000 cо смещение 0x4a.

Вам нужно сместить сам адрес или значение по адресу? ( думаю второе )

Вам именно как сместить нужно? побитовые сдвиги через << или тупо прибавить значение к существующему?

Обычно, как вы выразились в вопросе, имеют в виду побитовые сдвигы, но судя по коду ( точнее по логике кода , которую Вы хотели бы видеть, однако не то делаете ), Вы просто получаете "как бы" новый адрес в виде 0x02020000 + offset ( 0x4a ) = 0x0202004A и пытаетесь по нему записать *c = 0x1; значение , но это в концептуальном плане, как у Вас выглядит судя по коду ( реально код Ваш этого конечно не делает )

Если Вам нужно само значение по адресу 0x02020000 увеличить на 0x4a

Код

int offset = 0x4a;
*(int*)0x02020000 += offset;


Но мне, что-то внутри подсказывает, что Вам скорее нужно по адресу просто значение сдвинуть << 0x4a побитово ) Вы поконкретнее объясните, что требуется.

PS
Что-то какой-то метод разработки микроконтроллеров у ТС причем голых , Венда Мобайл будет слать конечно запросто за такие попытки, да и цель сильно смущает...
В целом, Вам вряд ли дадут менять так данные ОС, Вам хотя бы в ring0 в kernel надо gate открыть, если неймется ( хотя конечно, что за контроллер у Вас, у АРМ - концепции колец безопасности - нет, но зато есть безопасные режимы с различными диапазонами, но если у Вас Intel Atom, который сейчас пихают во всем мобильники... то там уже кольца x86, но у Вас Венда 6 скорее всего для такой ОС, там какой-нибудь АРМ стоит, но Венда Мобайл режимы тоже фильтрует, и просто так значения в адресах не получится, там и protected mode и еще несколько... ), хотя не понимаю, для чего нужно проекту на Винде Мобайл изменять по адресам значения

Автор: batex 2.8.2012, 12:06
Требуется именно сменить значение по адресу 0x02020000 + offset ( 0x4a ) = 0x0202004A на 0x1. Адрес записан в виде базовый + смещение, потому что смещение для некоторых случаев - разное.

Автор: magesi 2.8.2012, 12:09
Цитата(batex @  2.8.2012,  12:06 Найти цитируемый пост)
Требуется именно сменить значение по адресу 0x02020000 + offset ( 0x4a ) = 0x0202004A на 0x1. Адрес записан в виде базовый + смещение, потому что смещение для некоторых случаев - разное. 

Код

int addr = 0x02020000;
int offset = 0x4a;

*(int*)(addr + offset) += 0x1; // или *(int*)(addr + offset) = 0x1; если просто присвоить, а не увеличить на 0x1


Но только Венда Мобайл не должна позволять такое делать ) Вы по логике access violation все равно будете получать

Автор: batex 2.8.2012, 12:18
Цитата(magesi @ 2.8.2012,  12:09)
Цитата(batex @  2.8.2012,  12:06 Найти цитируемый пост)
Требуется именно сменить значение по адресу 0x02020000 + offset ( 0x4a ) = 0x0202004A на 0x1. Адрес записан в виде базовый + смещение, потому что смещение для некоторых случаев - разное. 

Код

int addr = 0x02020000;
int offset = 0x4a;

*(int*)(addr + offset) += 0x1; // или *(int*)(addr + offset) = 0x1; если просто присвоить, а не увеличить на 0x1


Но только Венда Мобайл не должна позволять такое делать ) Вы по логике access violation все равно будете получать

Ага, получу эксепшн. Вопрос в том, как получить доступ к этому участку памяти

Автор: magesi 2.8.2012, 12:26
batex, через Cи-синатксис именно так, как я написал, но Вы ни слова не сказали откуда Вы пытаетесь такой код запустить, если из под самой ОС из некого подобия user-mode, то такой код не будет работать.

Поскольку, скорее всего у Вас - АРМ микрконтроллер ( хотя Вы не уточнили ), то Вам нужно читать документацию про свой микроконтроллер на сайте АРМ, про диапазоны адресов различных режимов ( mode ) и попасть в Supervisor mode, и учить как попадать туда из под Венды Мобайл и только так уже записывать в памяти.

У АРМ такие моды:

Код

The ARM architecture specifies the following CPU modes.
At any moment in time, the CPU can be in only one mode, but it can switch modes due to external events (interrupts) or programmatically.

User mode
    The only non-privileged mode.
System mode
    The only privileged mode that is not entered by an exception.
 It can only be entered by executing an instruction that explicitly writes to the mode bits of the CPSR.
Supervisor (svc) mode
    A privileged mode entered whenever the CPU is reset or when a SWI instruction is executed.
Abort mode
    A privileged mode that is entered whenever a prefetch abort or data abort exception occurs.
Undefined mode
    A privileged mode that is entered whenever an undefined instruction exception occurs.
Interrupt mode
    A privileged mode that is entered whenever the processor accepts an IRQ interrupt.
Fast Interrupt mode
    A privileged mode that is entered whenever the processor accepts an FIQ interrupt.
Hyp mode
    A hypervisor mode introduced in armv-7a for cortex-A15 processor for providing hardware virtualization support. 


http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/Cihhcjia.html

Автор: bems 2.8.2012, 12:29
Дело в том, что в разных процессах в по этому адресу лежат разные данные, поэтому вопрос "какому процессу принадлежит адрес" некорректен (в общем случае)
Опиши подробнее что вы делаете? может имеется в виду доступ к внутренним данным длл, загруженной по адресу 02020000? тогда нужно грузить длл в свой процесс, и тогда менять в своём процессе, предварительно получив права на запись (VirtualProtect)

Автор: bsa 2.8.2012, 15:56
скорее всего, необходим доступ к физическому адресу. Если это так, то необходимо действительно переходить в привелигерованный режим (драйвер?) и делать это оттуда.
Требуй от начальства подробностей. Что это, зачем и так далее.

Автор: magesi 2.8.2012, 16:13
Цитата(bsa @  2.8.2012,  15:56 Найти цитируемый пост)
скорее всего, необходим доступ к физическому адресу. Если это так, то необходимо действительно переходить в привелигерованный режим (драйвер?) и делать это оттуда.
Требуй от начальства подробностей. Что это, зачем и так далее.

тут скорее спецификации микропроцессора и Венды Мобайл читать надо, чем начальство мучать  smile хотя судя по задаче, больно странное начальство 

Автор: batex 2.8.2012, 18:06
да в том то все и дело, что пришло письмо с требованием, при таком-то случаи, включить такой-то режим. И приложен скрин сторонней программы с подписью, что мол для вкл режима выставить такие значения. На скрине адрес 0x02020000, внизу введено смещение и ниже данные. 

Автор: magesi 2.8.2012, 20:37
Цитата(batex @  2.8.2012,  18:06 Найти цитируемый пост)
при таком-то случаи, включить такой-то режим.

ну, не при каком-то, а там есть триггер перехода в различные режимы

Цитата(batex @  2.8.2012,  18:06 Найти цитируемый пост)
 И приложен скрин 

выложите в тему пожалуйста скрин и описание , быстрее же Вам поможем

Автор: batex 3.8.2012, 11:29
Сегодня стало немного понятнее. 0x02020000 + 0x4a это физический адрес, следовательно, необходимо перейти в привилегированный режим. Пока что не могу найти как это сделать

Автор: batex 3.8.2012, 13:29
Попробовал через функцию MmMapIoSpace.

Код

PHYSICAL_ADDRESS PhyAddr;
PhyAddr.HighPart = 0x02020000+0x4a;
PhyAddr.LowPart = 0;
LPDWORD mMem = (LPDWORD) MmMapIoSpace(PhyAdde,16374,false);
*mMem = 0x1;


вылетает эксепшн 0xDFFF0123. 

Интересно вот что. Если посмотреть архитектуру адресного пространства, то системное адресное пространство начинается с 0х80000000 и выше. Системное ап отображается линейно на физические? Т.е. физический 0х02020000 это системный 0х82020000? или нет?

Автор: bsa 3.8.2012, 13:58
нет. скорее всего в этой области адресов находится какое-то внешнее оборудование (считай запись в порт).

Автор: korian 3.8.2012, 14:04
Цитата(batex @  3.8.2012,  12:29 Найти цитируемый пост)
Попробовал через функцию MmMapIoSpace.

на сколько я понимаю значение надо писать в PhyAddr.LowPart
т.е. что-то типа такого:
int64 address = some_value;
PhyAddr.HighPart = address >> 32;
PhyAddr.LowPart = address & 0xFFFFFFFF;

В вашем случае будет достаточно
PhyAddr.HighPart = 0;
PhyAddr.LowPart = 0x02020000+0x4a;


Цитата(batex @  3.8.2012,  12:29 Найти цитируемый пост)
Интересно вот что. Если посмотреть архитектуру адресного пространства, то системное адресное пространство начинается с 0х80000000 и выше. Системное ап отображается линейно на физические? Т.е. физический 0х02020000 это системный 0х82020000? или нет?

Опять же, на сколько я понимаю, физический адрес мапится на виртуальный для текущего процесса, в результате указатель mMem может быть любым, зависит от того, что делает операционка. Предполагаю, если виртуальный адрес 0х82020000 не занят - замапит туда, если занят, то куда-нить еще.

Автор: bems 3.8.2012, 15:11
Цитата(batex @  3.8.2012,  13:29 Найти цитируемый пост)
системное адресное пространство начинается с 0х80000000 и выше

ну оно не выгружаемое, это да. А касательно соответствия физическому, то насколько я понимаю не даже гарантии что две страницы идущие подряд в системном будут идти подряд в физическом.
Короч маппинг может быть более сложным

Автор: batex 3.8.2012, 18:42
Ну в общем, с помощью MmMapIoSpace все заработало. Всем спасибо. Тему можно закрывать

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)