Установка точки останова в API CreateFile() в WinDbg

Я настроил WinDbg для гибридной отладки (от пользовательского режима к режиму ядра).

В приложении пользовательского режима я вызываю CreateFile() с определёнными параметрами. Я хочу прервать вызов CreateFile() в контексте процесса пользовательского режима и оттуда проследить его выполнение.

Я попробовал найти символ CreateFile с помощью команды x. Проблема в том, что x nt!*CreateFile* не может найти соответствующий символ. Из множества символов, перечисленных в нем, ближайшим, что я смог найти, был nt!NtCreateFile, который, похоже, имеет другую подпись и, предположительно, внутренний API.

Почему в WinDbg отсутствует символ CreateFile()?

Потому что нет такого символа. Существуют CreateFileW и CreateFileA . И он экспортируется с помощью kernel32.dll и kernelbase.dll. Не автор: ntoskrnl

RbMm 27.08.2024 01:06

@RbMm, который следует опубликовать как ответ, а не как комментарий.

Remy Lebeau 27.08.2024 06:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Имена функций в Windows

Вы можете искать функции Microsoft Windows API, используя условия поиска «MSDN <функция>». Если вы это сделаете, это приведет вас к CreateFileA(). На этом веб-сайте сообщается, что функция определена в fileapi.h.

Загляните внутрь fileapi.h (найдите его на своем локальном компьютере, например, используя Все), вы найдете эти строки:

#ifdef UNICODE
#define CreateFile  CreateFileW
#else
#define CreateFile  CreateFileA
#endif // !UNICODE

Итак, CreateFile() — это просто псевдоним для CreateFileA() или CreateFileW(), в зависимости от того, компилируете ли вы для ANSI или Unicode.

Вы найдете множество функций, которые перенаправляются таким образом и имеют соглашения об именах ...A() и ...W(). Это описано MS в Unicode в Windows API , и они объясняют соглашения на другом примере.

Отладка

На том же сайте есть раздел Требования, в котором написано

Header     fileapi.h (include Windows.h)
Library    Kernel32.lib
DLL        Kernel32.dll

Таким образом, точки останова могут быть установлены с помощью

0:001> bp kernel32!CreateFileA
0:001> bp kernel32!CreateFileW

Но ваш подход x также работает, если вы выполняете поиск по всем модулям, например

0:001> x *!CreateFileA
00007ff8`23dc1320 KERNELBASE!CreateFileA (void)
00007ff8`25fa4e90 KERNEL32!CreateFileA (CreateFileA)

Если установлены обе точки останова (A и W), вы должны найти функцию:

0:001> g
Breakpoint 1 hit
KERNEL32!CreateFileW:
00007ff8`25fa4ea0 ff251af40500    jmp     qword ptr [KERNEL32!_imp_CreateFileW (00007ff8`260042c0)] ds:00007ff8`260042c0 = {KERNELBASE!CreateFileW (00007ff8`23dc1410)}

Почему один и тот же символ экспортируется дважды — как из Kernel32, так и из Kernelbase?

Tracy McDowell 27.08.2024 18:00

Kernel32 - это заглушка, которая перенаправляет на kernelbase, реализация которой смотрит на дизассемблирование kernel32 в ответе, который просто перескакивает

blabb 27.08.2024 18:03

Происходит что-то странное. Когда я вчера запустил x *!CreateFileA, он вернул эти два символа. Когда я сегодня выполняю ту же команду, она ничего не возвращает. Если я снимаю x KERNEL32!*, там написано Couldn't resolve 'x kernel32'. Есть идеи?

Tracy McDowell 28.08.2024 06:51

@TracyMcDowell: Что говорит lm m kernel?

Thomas Weller 28.08.2024 07:10

Из lm, насколько я вижу, kernel32/kernelbase не загружено. Я вижу там win32k/win32kfull/win32kbase/nt среди других. lm m kernel возвращает пустой список

Tracy McDowell 28.08.2024 07:41

kernel32 и kernelbase — это модули, которые загружаются еще до начальной точки останова, поэтому они должны быть там. Исключения редки, могу себе представить вирусы. См. попытку Павла Иосифовича удалить зависимость от ядра32. Не могли бы вы поделиться дампом?

Thomas Weller 28.08.2024 07:49

Вирусы исключены. Это тестовая программа, которую я написал и сейчас отлаживаю. Клянусь x *!CreateFileA работал раньше, выпустил точно такой же результат, как у тебя. Я думаю, не «сломан» ли WinDbg каким-то образом. Кроме того, kernel32.dll указан в выводе dumpbin /imports.

Tracy McDowell 28.08.2024 07:58

Другие вопросы по теме