Ошибка при выполнее примера из книги Неббета

Тема в разделе "WASM.BEGINNERS", создана пользователем lomomike, 12 мар 2008.

  1. lomomike

    lomomike New Member

    Публикаций:
    0
    Регистрация:
    7 фев 2008
    Сообщения:
    29
    Доброго всем времени суток. Я решил написать пример из книги Неббета. Пример 1.2, который должен выводить список дескрипторов указанного процесса.
    Собственно вот текст программы

    Код (Text):
    1. // head.cpp : Defines the entry point for the console application.
    2. //
    3.  
    4. #include "stdafx.h"
    5.  
    6. #include "ntdll.h"
    7. //#include "memory.cpp"
    8.  
    9. #include <stdlib.h>
    10. #include <stdio.h>
    11. #include <vector>
    12. #include <map>
    13. #include <conio.h>
    14.  
    15. #define  WIN32_LEAN_AND_MEAN
    16.  
    17. #pragma comment( lib, "ntdll" )
    18.  
    19. #pragma warning(disable:4786)
    20.  
    21. struct OBJECTS_AND_TYPES{
    22.     std::map<ULONG, NT::PSYSTEM_OBJECT_TYPE_INFORMATION, std::less<ULONG> > types;
    23.     std::map<PVOID, NT::PSYSTEM_OBJECT_INFORMATION, std::less<PVOID> > objects;
    24. };
    25.  
    26. std::vector<NT::SYSTEM_HANDLE_INFORMATION> GetHandles()
    27. {
    28.     ULONG n;
    29.     PULONG p = new ULONG[n = 0x100];
    30.  
    31.     while( NT::ZwQuerySystemInformation(NT::SystemHandleInformation,
    32.                                         p,
    33.                                         n * sizeof *p,
    34.                                         0) == STATUS_INFO_LENGTH_MISMATCH)
    35.                                 delete []p, p = new ULONG[n *= 2];
    36.  
    37.     NT::PSYSTEM_HANDLE_INFORMATION h = NT::PSYSTEM_HANDLE_INFORMATION(p+1);
    38.  
    39.     return std::vector<NT::SYSTEM_HANDLE_INFORMATION>(h, h + *p);
    40. }
    41.  
    42. OBJECTS_AND_TYPES GetObjectsAndTypes()
    43. {
    44.     ULONG n;
    45.     PCHAR p = new CHAR[n = 0x1000];
    46.  
    47.     while(NT::ZwQuerySystemInformation(NT::SystemObjectInformation,
    48.                                        p,
    49.                                        n * sizeof *p,
    50.                                        0) == STATUS_INFO_LENGTH_MISMATCH)
    51.     {
    52.         delete []p;
    53.         p = new CHAR[n *= 2];
    54.     }
    55.  
    56.     OBJECTS_AND_TYPES oats;
    57.  
    58.     for(NT::PSYSTEM_OBJECT_TYPE_INFORMATION t = NT::PSYSTEM_OBJECT_TYPE_INFORMATION(p);
    59.         ;
    60.         t = NT::PSYSTEM_OBJECT_TYPE_INFORMATION(p + t->NextEntryOffset))
    61.     {
    62.         oats.types[t->TypeNumber] = t;
    63.  
    64.         for(NT::PSYSTEM_OBJECT_INFORMATION o = NT::PSYSTEM_OBJECT_INFORMATION(PCHAR(t->Name.Buffer) + t->Name.MaximumLength);
    65.             ;
    66.             o = NT::PSYSTEM_OBJECT_INFORMATION(p + o->NextEntryOffset))
    67.         {
    68.             oats.objects[o->Object] = o;// !!!! CRASH !!!! здесь происходит сбой
    69.  
    70.             if(o->NextEntryOffset == 0) break;
    71.         }
    72.         if(t->NextEntryOffset == 0) break;
    73.     }
    74.  
    75.     delete []p;
    76.     return oats;
    77. }
    78.  
    79.  
    80. int _tmain(int argc, _TCHAR* argv[])
    81. {
    82.     //if(argc == 1) return 0;
    83.  
    84.     //ULONG pid = strtoul(argv[1], 0, 0);
    85.     ULONG pid = 344;// == DEBUG ==
    86.  
    87.     std::vector<NT::SYSTEM_HANDLE_INFORMATION> handles = GetHandles();
    88.    
    89.     OBJECTS_AND_TYPES oats = GetObjectsAndTypes();
    90.  
    91.    
    92.  
    93.     NT::SYSTEM_OBJECT_INFORMATION defobj = {0};
    94.  
    95.     printf("Object Hnd Access F1 Atr #H #P Type Name \n");
    96.  
    97.     for(std::vector<NT::SYSTEM_HANDLE_INFORMATION>::iterator h = handles.begin();
    98.         h != handles.end();
    99.         h++)
    100.     {
    101.         if(h->ProcessId == pid)
    102.         {
    103.             NT::PSYSTEM_OBJECT_TYPE_INFORMATION t = oats.types[h->ObjectTypeNumber];
    104.             NT::PSYSTEM_OBJECT_INFORMATION o = oats.objects[h->Object];
    105.  
    106.             if(o == 0) o = &defobj;
    107.             printf("%p %04hx %61x %2x %3hx %3ld %4ld %-14.*S %.*S \n",
    108.                    h->Object,
    109.                    h->Handle,
    110.                    h->GrantedAccess,
    111.                    int(h->Flags),
    112.                    o->Flags,
    113.                    o->HandleCount,
    114.                    t->Name.Length,
    115.                    t->Name.Buffer,
    116.                    o->Name.Length,
    117.                    o->Name.Buffer);
    118.         }
    119.     }
    120.  
    121.     _getch();
    122.     return 0;
    123. }
    При выполнении программы в отладочной сборке выдается ошибка
    Unhandled exception at 0x00416b39 in tratata.exe: 0xC0000005: Access violation reading location 0xcdce9b9e.
    и я попадаю в тело процедуры GetObjectsAndTypes() на строку
    Код (Text):
    1. oats.objects[o->Object] = o;
    При выполнении программы в релизной сборке выпадает ошибка

    Инструкция по адресу "0x00402961" обратилась к памяти по адресу "0x00000004". Память не может быть "read".

    Собственно, как я это понимаю, происходит обращение к указателю на невыделенную память.
    Прогоняя программу в отладчике, я увидел что в процедуре GetObjectsAndTypes() цикл
    Код (Text):
    1. while(NT::ZwQuerySystemInformation(NT::SystemObjectInformation,
    2.                                        p,
    3.                                        n * sizeof *p,
    4.                                        0) == STATUS_INFO_LENGTH_MISMATCH)
    5.     {
    6.         delete []p;
    7.         p = new CHAR[n *= 2];
    8.     }
    не выполняется ни разу, то есть не выделяется нужное количество памяти.

    ДЕло в том что программа полностью списана с книги.
    Может ли кто-нибудь объяснить, почему происходит такая ошибка и почему не выполняется цикл выделения памяти, хотя в процедуре GetHandles() такойже цикл выполняется.

    Заранее большое спасибо.
     
  2. ant_man

    ant_man New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2004
    Сообщения:
    23
    Цикл не выполняется если памяти достаточно с первой попытки или произошла ошибка отличная от STATUS_INFO_LENGTH_MISMATCH
     
  3. lomomike

    lomomike New Member

    Публикаций:
    0
    Регистрация:
    7 фев 2008
    Сообщения:
    29
    Я это понимаю.
    Дополнительная проверка показывает, что ZwQuerySystemInformation возвращает
    значение STATUS_UNSUCCESSFUL (0xc0000001L).
    Почему такое может возникать?
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    У тебя касперский работает ?
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    NtGlobalFlags проверь. афаир для перечиесления объектов один из флагов должен быть установлен.
     
  6. lomomike

    lomomike New Member

    Публикаций:
    0
    Регистрация:
    7 фев 2008
    Сообщения:
    29
    Clerk
    Нет, у меня антивируса вообще на том компьютере не стоит

    n0name

    Точно. Должен быть установлен флаг FLG_MAINTAIN_OBJECT_TYPELIST

    Я в процедуру добавил следующий код
    Код (Text):
    1. ULONG k = 1;
    2. NTSTATUS status;
    3.     NT::PSYSTEM_GLOBAL_FLAG sgf = new NT::SYSTEM_GLOBAL_FLAG[k];
    4.     while((status = NT::ZwQuerySystemInformation(NT::SystemGlobalFlag, sgf, k * sizeof *sgf, 0) )
    5.          == STATUS_INFO_LENGTH_MISMATCH)
    6.     {
    7.         delete []sgf;
    8.         sgf = new NT::SYSTEM_GLOBAL_FLAG[k *= 2];
    9.     }
    10.    
    11.  
    12.     if((sgf->GlobalFlag & NT::FLG_MAINTAIN_OBJECT_TYPELIST) == NT::FLG_MAINTAIN_OBJECT_TYPELIST)
    13.         MessageBox(0,"GlobalFlags are OK","",0);
    14.     else
    15.     {
    16.         sgf->GlobalFlag |=  NT::FLG_MAINTAIN_OBJECT_TYPELIST;
    17.         status = NT::ZwSetSystemInformation(NT::SystemGlobalFlag, sgf, k * sizeof *sgf);
    18.         //delete []p;
    19.         if(status != STATUS_SUCCESS)
    20.         {
    21.             delete []sgf;
    22.             delete []p;
    23.             MessageBox(0,"Error in set global flags","",0);
    24.             exit(1);
    25.         }
    26.  
    27.    
    28.     }
    Код выполняется корректно (возвращает STATUSS_SUCCESS), но все равно на том же самом месте падает.
    Ничего не понимаю.

    PS. Пытался установить этот флаг через прогу Global Flags, но он почему-то не усновился. Никто не знает почему?
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    У меня установлен касперский. Установив в реестре в GlobalFlags бит FLG_MAINTAIN_OBJECT_TYPELIST и перезагрузившись, в ntos!NtGlobalFlag этот бит сброшен, в PEB.NtGlobalFlags также бит сброшен, твой инфокласс возвращает STATUS_UNSUCCESSFUL. Если налету установить ntos!NtGlobalFlag это ничего не меняет, также возвращается ошибка.
     
  8. lomomike

    lomomike New Member

    Публикаций:
    0
    Регистрация:
    7 фев 2008
    Сообщения:
    29
    Clerk
    А каким образом тогда можно установить этот флаг, чтобы все заработало?
     
  9. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    юзай гугл.
     
  10. lomomike

    lomomike New Member

    Публикаций:
    0
    Регистрация:
    7 фев 2008
    Сообщения:
    29
    Все нашел, всем спасибо =)