hex.pp.ua

Получение текста сообщения по номеру ошибки

Использование Native API для получения текста сообщения по номеру ошибки




Приведённая пара функций позволяет получать текст ошибки не только для «родных» кодов ошибок (обычно их обозначают как NTSTATUS и их список есть в ntstatus.h в DDK), но и обычные ошибки (например 5 из kernel32.dll — Access Denied), и ошибки NetApi, и любые другие, лишь бы соответствующий модуль был загружен в процесс. Требование загруженности модуля вполне логичное, ибо генерирует номера ошибок всё-таки он. По хорошему перечисление потоков надо оборачивать в захват и освобождение критической секции Peb->LoaderLock, она должна захватываться при любой модификации структур данных загрузчика, что оставляю в качестве домашнего задания.

Функция GetMsg ищет сообщение по значению ns, если сообщение найдено, для него выделяется память в *p.

 NTSTATUS NTAPI GetMsg(IN HANDLE hModule, IN NTSTATUS ns, OUT PWSTR *p)
 {
     PRTL_MESSAGE_RESOURCE_ENTRY pmsg;
     if ((RtlFindMessage(hModule, 0x0B, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
          ns, &pmsg)) == STATUS_SUCCESS)
     {
         if (*p = (PWSTR)malloc((pmsg->Length+2)))
         {
             swprintf(*p,(pmsg->Flags & MESSAGE_RESOURCE_UNICODE)
              ? L"%s" : L"%S", pmsg->Text);
             return STATUS_SUCCESS;
         }

         return STATUS_NO_MEMORY;
     }
     return STATUS_OBJECT_NAME_NOT_FOUND;
 }

Функция FindMsg ищет сообщение по значению ns во всех модулях, загруженных в процесс.

 NTSTATUS NTAPI FindMsg(IN NTSTATUS ns, OUT PWSTR *p)
 {
     PLIST_ENTRY f = &(pPeb->ProcessModuleInfo->ModuleHeader.InLoadOrderModuleList);
     PLIST_ENTRY cur = f;

     for (;;)
     {
         if (GetMsg(((PLDR_MODULE)cur)->BaseAddress,ns,p) == STATUS_SUCCESS)
         return STATUS_SUCCESS;

         cur = cur->Flink;

         if (cur == f)
         return STATUS_OBJECT_NAME_NOT_FOUND;
     }
 }


Автор: Сергей Васкецов
Дата: 29.01.2003


При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт. По поводу рекламы обращайтесь на почту [email protected]