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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Драйвер. Чтение физической памяти. Проблемы  (Прочитано 19590 раз)
0 Пользователей и 1 Гость смотрят эту тему.
miyka
Гость
« : 05-07-2010 19:17 » 

Здравствуйте. Меня спросили: смогу ли я написать простейший динамический драйвер для чтения физической памяти? Я, имея некий опыт писания на С/С++, естественно ответил да. Потребовалось некоторое кол-во времени, чтобы осознать, что и как надо делать.
Я изучил теорию, почитал некоторую литературу по этой теме и решил перейти к практике. На практике все оказалось на много сложнее. А теперь по порядку:

Во-первых относительно написания самого драйвера, без всяких свистелок переделок.
За основу сначала я взял статью "Драйвер с нуля", потом книгу П. И. Рудаков, К. Г. Финогенов "Язык ассемблера: уроки программирования". Код был "адаптирован" под Вин7* и в обоих случаях драйвер в WDK 7.6 не копмилится, пишет 5 ворнингов и 2 еррора, что делать не знаю. Хелп?

И собственно первый вопрос, обязательно прописывать строки, в частности последнюю, или хватит только первой или второй.
Код:
#define NT_DEVICE_NAME L"\\Device\\DrvrPro"
#define WIN32_DEVICE_NAME L"\\??\\DrvrPro"
#define DOS_DEVICE_NAME L"\DosDevices\DrvrPro"
Ну и следовательно надо ли везде таскать структуры для кажого типа устройства:
Код:
UNICODE_STRING unitNtName;
RtlInitUnicodeString(&unitNtName, NT_DEVICE_NAME);
UNICODE_STRING unitWinName;
RtlInitUnicodeString(&unitWinName, WIN32_DEVICE_NAME);
            // И делать следующее действие, связывая их
IoCreateSimbolicLink(&unitWinName, &unitNtName);

Так же меня очень удивляет то, что в разных источниках авторы пишут одинаковые по содержанию функции xxxOpen и xxxClose, но разные по назначению, почему так?

      * Хотел бы узнать, сильно ли отличается программирование драйверов на Вин7 от ХР, потому как я знаю, что в Висте и в 7 драйвера находятся не на нулевом уровне привилегий и помешает ли мне это сделать чтение памяти? Конечно же я могу ошибаться.

Во-вторых конечно меня интересует чтение, хотя бы чтение физической памяти, причем любого участка, хотя опять же, прошу вас не зацикливаться на "любого участка"...
В этом вопросе я хотел бы определиться, какие функции надо использовать для достижения поставнной цели, потому что везде пишут разное. У меня в данный момент написано следующее:

Код:
NTSTATUS CtlDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION pIrpStack;
PULONG pIOBuffer;
UNICODE_STRING uniMemoryName;
OBJECT_ATTRIBUTES ObjectAttributes;

HANDLE SectionHandle; //Дескрипктор секции памяти
PHYSICAL_ADDRESS PhysicalAddress;
PHYSICAL_ADDRESS SectionBase;

ULONG Length;

PVOID VertialAddress = NULL;

pIrpStack = IoGetCurrentIrpStackLocation(Irp);
pIOBuffer = Irp->AssociatedIrp.SystemBuffer;

switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_ADD:
*pIOBuffer = (ULONG)CtlDispatch; //Адрес процедуры
Irp->IoStatus.Information = 4; // Число переслылаемых байтов
break;

case IOCTL_MAP:
PhysicalAddress.LowPart = *pIOBuffer++;
PhysicalAddress.HighPart = 0;

Length = *pIOBuffer--;

RtlInitUnicodeString(&unitMemoryName, L"\\Devise\\PhysicalMemory");
InitializeObjectAttributes(&ObjectAttributes, &uniMemoryName, OBJ_CASE_INSENSITIVE, NULL, NULL);

ZwOpenSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes);
SectionBase = PhysicalAddress;
ZwMapViewOfSectoin(SectoinHandle, (HANDLE)-1, &VirtualAddress, 0L, Length, &SectionBase, &Length, ViewShare, 0, PAGE_READWRITE|PAGE_NOCACHE);

(ULONG)VirtualAddress += PhysicalAddress.LowPrat - SectionBase.LowPart;
*pIOBuffer = (ULONG)VirtualAddress;
Irp->IoStatus.Information = 4;

break;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

Собственно когда драйвер получает команду IOCTL_MAP он должен вернуть адрес физического участка памяти и передать его в программу (USER MODE?). Это теоретически, а на практике это как(так)?
Тут использованы команды ZwXXX, описание которых если "пояндексить/гуглить" не найти или найти там где я их взял, и то описанием это сложно называть. Может есть другие функции или подобное что могло бы мне помочь решить задачу? И вообще рад услышать совет в этой области. Опять же повторюсь, мне надо чтение физической памяти, по заданному отрезку.

В третьих, билдер от WDK это не возможно, что можете посоветовать как замену?

Короче помогите, чем можете. Заранее спасибо.

П.С. Видите ли, я не могу скомпилировать драйвер и следовательно проверить его работоспособность, поэтому код драйвера выкладываю во вложении)

Простите, есть странно/не понятно излагаю свой вопрос, но уже шарики за ролики или ролики за шарики заскакивают от этого драйвера.





* TskDrvr.rar (1.66 Кб - загружено 997 раз.)
Записан
Ochkarik
Модератор

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

« Ответ #1 : 05-07-2010 21:54 » 

1. семерка от xp практически мало отличается... и кстати работают они (по крайней мере те, о чем идет речь в ring-0)
первые два куска кода - определение имен. первое используется для определения имен в пространстве имен ОС - фактически имя драйвера как объекта в ОС. второе - дос-имя. используется для доступа к создаваемому объекту через Create|OpenFile из процессов.
подробнее http://msdn.microsoft.com/en-us/library/ff556420(VS.85).aspx

2. вы должны отмапировать физические адреса в адресное пространство приложения. те адреса с которыми работают приложения - виртуальны. физически они могут находится даже на жестком диске. вам необходимо для конкретного вызывающего процесса сопоставить участок его виртуальных адресов - конкретным физическим.(кстати для доступа из драйвера это  тоже необходимо сделать)  либо просто скопировать в выходной буфер данного IOCTL запроса.

 то что вы использовали для этого http://technet.microsoft.com/ru-ru/library/cc787565(WS.10).aspx ... не знаю, сам не пользовался. на http://www.wasm.ru/forum/viewtopic.php?pid=371732  какой то пример его использования есть, уже смотрели?
на погуглить
ZwOpenSection http://msdn.microsoft.com/en-us/library/ff567029(VS.85).aspx
ZwMapViewOfSection http://msdn.microsoft.com/en-us/library/ff566481(VS.85).aspx

 у меня был другой подход, с созданием DMA адаптера (http://msdn.microsoft.com/en-us/library/ff549220(VS.85).aspx) и ручного мапирования памяти. либо что то вроде MmAllocateContiguousMemory/MmMapLockedPages. правда это не совсем ваш случай... в последнем - память выделяется и резервируется а вам этого видимо не надо?

3. первая из прибитых тем. о компиляции драйвера в VS)

PS вопросы заданы вполне понятно и грамотно) время позднее извиняюсь что развернуто ответить уже сил нет)
PPS посмотрите http://support.microsoft.com/kb/189327 это кажется похоже на то что надо
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #2 : 06-07-2010 09:29 » 

Кажется, у Вас не правильная постановка задачи.
Я так понимаю, что в память пишет железяка, и ей нужно знать физадреса. Но если память выделяется приложением, то есть момент. Представим, что происходить исключительная ситуация, и приложение слетает. Память ПРИЛОЖЕНИЯ при этом освобождается. Железка об этом не знает, и продолжает писать. А страницы памяти уже принадлежат другому приложению, или даже ядру. В результате - обычный слёт приложения оборачивается синим экраном в большинстве случаев.
Поэтому память должна выделяться драйвером, и мапироваться им в адреса приложения. То, о чём писал  Ochkarik  в п.2. выше.  Тут Вы можете выделить непрерывный кусок (примерно до 4 МБ без проблем), что очень понравится Вашим железячникам, поскольку выделение в приложении происходит отдельными страницами, скорее всего, идущими не подряд.  В этом случае слёт приложения не оборачивается синим экраном, поскольку память принадлежит драйверу, и никому не отдаётся. Кстати, Вам таки желательно из драйвера засекать слёт приложения, и останавливать плату. Но в этом случае проблем не будет по любому. Тогда как с памятью ПРИЛОЖЕНИЯ не факт, что система не освободит (и переназначит) память до того, как уведомит драйвер про завершения процесса.
« Последнее редактирование: 06-07-2010 09:37 от PredatorAlpha » Записан
Ochkarik
Модератор

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

« Ответ #3 : 06-07-2010 10:19 » 

PredatorAlpha, и так тоже) но я понял задачу буквально как чтение произвольного физ адреса.
miyka, если подразумевается работа с железом - то выбранный вами  подход - не верен.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #4 : 06-07-2010 10:28 » 

Тогда мне
а) не вполне понятно, как "натравить" драйвер на произвольный физический адрес памяти. MDL самому заполнять?
б) не понятно, зачем это вообще надо.
Записан
Ochkarik
Модератор

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

« Ответ #5 : 06-07-2010 12:49 » 

дождемся ответа)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
resource
Молодой специалист

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

« Ответ #6 : 06-07-2010 14:48 » 

а) не вполне понятно, как "натравить" драйвер на произвольный физический адрес памяти. MDL самому заполнять?
б) не понятно, зачем это вообще надо.

а) Ochkarik дал ссылку на wasm. Там это разобрано уже.
б) Ну мы же не osr. Хочет человек, так пусть делает.
Записан
miyka
Гость
« Ответ #7 : 06-07-2010 20:45 » 

Большое спасибо за ответы. Из Ваших ответов я понял не которые нюансы.
В задаче нету работы с железом. Суть драйвера заключаться как раз в выделении памяти, просто забраться в ринг0. Мне как раз надо выделать те самый непрерывные 4 метра.

Самое конечно не удачное, но WDk ссылается в buildfre_win7_x86.err на отсутсвие, опять же как я понимаю, *.rc файла (а без него разве нельзя?)  и ... лушче вы сами это увидите.
Код:
1>errors in directory c:\tskdrvr
1>c:\tskdrvr\makefile(1) : error U1052: file 'c:\winddk\7600.16385.1\binmakefile.def' not found
1>nmake.exe /nologo BUILDMSG=Stop. -i BUILD_PASS=PASS2 LINKONLY=1 NOPASS0=1 MAKEDIR_RELATIVE_TO_BASEDIR= failed - rc = 2

Про VS: не хочется делать махинации с настройками, так как нужна она мне и для других вещей.

З.Ы.  "Гугл все же у нас  видимо разный". Черт, что то еще хотел написать, позже вспомню и добавлю. Еще раз спасибо.
Записан
resource
Молодой специалист

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

« Ответ #8 : 06-07-2010 20:59 » 

Суть драйвера заключаться как раз в выделении памяти, просто забраться в ринг0. Мне как раз надо выделать те самый непрерывные 4 метра

Тогда я уже не понимаю. Вам надо выделить или прочитать?

Насчет WDK билда, чего-то явно не то (какой-то элементарный затуп). Лучше посмотреть примеры WDK.
Записан
miyka
Гость
« Ответ #9 : 06-07-2010 21:57 » 

Тьфу, не выделить конечно же, а прочитать. Извиняюсь.
Да вот и я думаю, что затуп.
Записан
resource
Молодой специалист

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

« Ответ #10 : 07-07-2010 04:36 » 

"binmakefile.def" должно выглядеть как "bin\makefile.def". У вас мэйкфайл наверное какой-то свой велосипедный или что-то в этом духе. Надо попробовать скомпилить какой-нибудь простецкий сэмпл из WDK и посмотреть нормально соберется или нет.
Записан
miyka
Гость
« Ответ #11 : 16-07-2010 10:33 » 

И так... Я решил проблему 2 ошибок описанных выше, проблема была в заглавных буквах в названиях файлов makifile и sourse.
Хотелось бы узнать DDK выводит ошибки в коде программы или нет, как это делает VS?
Дело в том, что я не могу перебороть 5 ворнингов. Ведь, по аналогии с VS, ворнинг обычно вылазит когда возможно не правильное приведение типов и тд, а ошибка в свою очередь когда не правильно инициализированный переменная или синтаксическая ошибка. Правильно ли я думаю?
Могу выложить свой код. Спасибо

P.S. Жарища))
 
Записан
Ochkarik
Модератор

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

« Ответ #12 : 16-07-2010 21:42 » 

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

PS бьюсь тут над кодом с++ для  DSP, портированным с x86... к примеру банальное умножение/сложение переменных(a,b,c,d) типа short
"long a  = a*b+c*d;"
дает результат, отличный от явного преобразования:
"long a  = (long)a*b+(long)c*d;"
примерно такого рода варнинги иногда приводят к катастрофам... хотя DSP-шный компилятор нагло не считает это даже варнингом....

PPS ага) душегубка) выкладывайте если сами не сможете разобраться... но лучше попытайтесь сами)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #13 : 04-08-2010 20:05 » 

А под какой DSP пишете ?
Записан
Ochkarik
Модератор

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

« Ответ #14 : 05-08-2010 13:04 » 

теоретически под TMS320с55XX... впрочем сильно в архитектуре не силен.
теперь вот еще трабла: программатор с LPT портом... и переходы PCIe-LPT не катят, номера портов не стандартные... разбираюсь(
где ж я ему такой порт то найду?)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
PredatorAlpha
Помогающий

us
Offline Offline

« Ответ #15 : 07-08-2010 08:10 » 

Я работал с 541х...
Обычно отлаживаются TMS с помощью JTAG-карточки...
Записан
Ochkarik
Модератор

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

« Ответ #16 : 08-08-2010 15:45 » 

так программатор он и есть....  со стороны процессора JTAG... а с другой параллельный порт). плюс заказчик настаивает на CodeComposerStudio v 2.3. тоже программисты аховые, их проект в  CCS v3.3(о v4  молчу) - компилится, но не работает))))
а отладку я на модели проверял... по файлам модели и профайлеру по времени. по идее все долго работать. с включенной оптимизацией должно даже успевать в прерывании.... беда в том, что старая версия компилятора что-то хреново компилит.  одна функция  у меня раза в три медленнее получается, чем в CCS v3.3... ща буду смотреть, что там старый компилятор мне в ассемблере натворил)
PS с ходу что то не получилось либы от новой версии в старый засунуть. ругается на какую то .debug_чего_то_там секцию с каким то неправильным номером 5020 кажется.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines