вызов функций из DLL

Тема в разделе "LANGS.C", создана пользователем seiko, 6 дек 2007.

  1. seiko

    seiko New Member

    Публикаций:
    0
    Регистрация:
    9 ноя 2007
    Сообщения:
    98
    как мне вызвать функцию из ntdll в Visual C++ в win32 Application

    В дельфе достаточно написать external + 'имя длл'
    но как это сделать в сишнике если нужно импортировать из ntdll

    Пробовал явно вызвать (процедурные типы), но
    getModuleHandle и Loadlibrary возвращают нули
    def файлы я решительно не понял, да и не в них, я думаю, решение

    Подскажите незнающему
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    seiko
    getModuleHandle и Loadlibrary возвращают нули
    покажи код
     
  3. Rascalspb

    Rascalspb New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    46
    Адрес:
    СПб
    нада подключить ntdll.lib
    вроде все.
     
  4. seiko

    seiko New Member

    Публикаций:
    0
    Регистрация:
    9 ноя 2007
    Сообщения:
    98
    Вот объявление глобальных типов и переменных этих двух типов
    Код (Text):
    1. typedef WINUSERAPI DWORD WINAPI (ShutdownProc)(DWORD);
    2. typedef WINUSERAPI WORD WINAPI (GetPrivilege)(DWORD,BOOL,int,PDWORD);
    3. ....
    4. GetPrivilege* RtlAdjustPrivilege;
    5. ShutdownProc* NtShutdownSystem;
    Вот кусок _tWinMain

    Код (Text):
    1. HMODULE hModule = GetModuleHandle(LPCWSTR("ntdll.dll")); ///В hModule записываеться 0
    2.  
    3. RtlAdjustPrivilege = (GetPrivilege*)GetProcAddress(hModule,LPCSTR("RtlAdjustPrivilege"));
    4. NtShutdownSystem = (ShutdownProc*)GetProcAddress(hModule,LPCSTR("NtShutdownSystem"));
    5.  
    6. hook = SetWindowsHookEx(WH_KEYBOARD_LL,HookProc,hInstance,0); ///Думаю тут всё понятно
    Вот уже код внутри ловушки на нажатие WIN + P
    Код (Text):
    1. if (keyP)
    2. {
    3.        (*RtlAdjustPrivilege)(19,1,0,0);
    4. ////Если не делать проверок ещё на hModule то вылетает здесь с нулевым адресом
    5.        (*NtShutdownSystem)(0);
    6. }
     
  5. Rascalspb

    Rascalspb New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    46
    Адрес:
    СПб
    HMODULE hModule = GetModuleHandle(LPCWSTR("ntdll.dll")); ///В hModule записываеться 0

    GetModuleHandleW писать нада. у тебя видимо анси стоит флаг,а не юникод
     
  6. seiko

    seiko New Member

    Публикаций:
    0
    Регистрация:
    9 ноя 2007
    Сообщения:
    98
    Нет определён юникод, потому что
    Во-первых иначе бы не скомпилился

    Во-вторых используется W версия
    Код (Text):
    1. #define GetModuleHandle GetModuleHandleW
    Вопрос для меня в том почему такие приколы и как подгрузить ntdll.lib?
    Я вообще не догоняю на хер её нужно специально подключать если она и так во все процессы грузиться
    (нельзя было придумать что-то вроде
    Код (Text):
    1. external 'ntdll.dll'
    как в дельфи или хотя бы DllImport[...] как в С#)?
     
  7. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    тебе надо не GetModuleHandle, а LoadLibrary вызывать.
     
  8. Rascalspb

    Rascalspb New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    46
    Адрес:
    СПб
    ntdll всегда загружена, не надо вызывать LoadLibrary

    вставить #pragma comment(lib, "ntdll.lib") в начало cpp с main, после всех инклюдов
    скачать файлик, скинуть в папку c:\program...\microsoft visual studio 2xxxx\vc7\lib

    учим мат часть...
     
  9. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    ну да, ну да...

    еще вместо LPCWSTR попробуй _T("ntdll.dll");
     
  10. Rascalspb

    Rascalspb New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    46
    Адрес:
    СПб
    Код (Text):
    1. HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
    если так уж хочется использовать юникод
     
  11. seiko

    seiko New Member

    Публикаций:
    0
    Регистрация:
    9 ноя 2007
    Сообщения:
    98
    Дело не в том хочется или не хочется использовать мне юникод, если уж определён юникод, так зачем что-то менять, в данном случае аналогичные проблемы всё равно возникают и с Ansi кодировкой, мне кто-нить может объяснить в чём причина подобных ненахождений адреса
     
  12. LLInuoH

    LLInuoH New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2006
    Сообщения:
    15
    Код (Text):
    1. PVOID QSIptr = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwQuerySystemInformation");
    у меня это прекрасно работает...
     
  13. Rascalspb

    Rascalspb New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    46
    Адрес:
    СПб
    ну начнем с того, что искать адрес с нулевым хэндлом модуля мягко говоря аморально. если не находит хэндл модуля, значит кривость в вызове апи, ибо у меня все находит. специально для этого есть апи GetLastError, кто мешает вызвать. Или прописатьв окне watch студии строку err,hr и смотреть, какую ошибку вернула система.
    А ваще может стоит почитать мсдн или рихтера? а то немного удивляет настойчивость поиска адреса с нулевым хэндлом... Да и приведение к типу LPCWSTR тоже неверно, ибо это не заставит студию конвертировать строку в юникодную, а просто позволит обойти сообщение об ошибке компилера, правда я не знаю, если стоит флаг юникода, не конвертируются ли строки автоматически...

    ADDED:
    Код (Text):
    1. FARPROC GetProcAddress(
    2.   HMODULE hModule,
    3.   LPCSTR lpProcName
    4. );
    зачем приводить к типу юникода имя функции?
     
  14. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Когда компилятор видит эту строчку, он делает следующее: создаёт строку "ntdll.dll" где-то в данных, причём в ANSI-представлении; берёт на неё указатель, он оказывается типа const char*; мысленно пожимая плечами, делает вид, что этот же самый указатель имеет тип const wchar_t*. В результате нет ошибок компиляции, но фактически-то API-функции GetModuleHandleW передаётся ANSI-строка! Естественно, она с такого фигеет.
    Чтобы создать UNICODE-строку, использовать надо L"ntdll.dll". Есть ещё макрос _T("ntdll.dll"), который раскрывается в "ntdll.dll" в ANSI-окружении и L"ntdll.dll" в UNICODE-окружении.
     
  15. seiko

    seiko New Member

    Публикаций:
    0
    Регистрация:
    9 ноя 2007
    Сообщения:
    98
    Поверьте все подобные советы уже были использованы и с L в том числе, дело не в этом
    Из-за азиатского рынка высоких технологий я даже толком не могу ничего сделать, как хотя бы ошибку отформатировать и вывести это на экран по человечески?
     
  16. Rascalspb

    Rascalspb New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    46
    Адрес:
    СПб
    короч почитай рихтера. все вопросы, которые здесь задаешь, у него разжеваны и есть примеры кодеса. апи FormatMessage вроде. лень лезть искать, ибо сам сможешь найти
     
  17. seiko

    seiko New Member

    Публикаций:
    0
    Регистрация:
    9 ноя 2007
    Сообщения:
    98
    забавно смотрю переменные,
    hModule == 0x7c900000
    NtShutdownSystem == 0x7c929e8c
    RtlAdjustPrivilege == 0x7c90e7e6
    Но при вызове
    вылетает acess violation с текстом

    Unhandled exception at 0x7c929f1e in klav.exe: 0xC0000005: Access violation writing location 0x00000000.

    То же место
    Код (Text):
    1. (*RtlAdjustPrivilege)(19,1,0,0);
    2. (*NtShutdownSystem)(0);
    насколько я понимаю нарушение происходит внутри процедуры?
     
  18. roman_pro

    roman_pro New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    291
    Код (Text):
    1. HMODULE hLib=LoadLibrary(_T("ntdll.dll"));
    2.     if (hLib)
    3.     {
    4.         BOOL (WINAPI* pRtlAdjustPrivilege)(int v1, BOOL v2, BOOL v3, BOOL* v4)=(BOOL (WINAPI *)(int, BOOL, BOOL, BOOL*))GetProcAddress(hLib, "RtlAdjustPrivilege");
    5.         BOOL (WINAPI* pZwShutdownSystem)(int v1)=(BOOL (WINAPI *)(int))GetProcAddress(hLib, "ZwShutdownSystem");
    6.         BOOL f;
    7.         if (pRtlAdjustPrivilege && pZwShutdownSystem)
    8.         {
    9.             pRtlAdjustPrivilege(19, TRUE, FALSE, &f);
    10.             pZwShutdownSystem(2);
    11.         }
    12.         FreeLibrary(hLib);
    13.     }
     
  19. seiko

    seiko New Member

    Публикаций:
    0
    Регистрация:
    9 ноя 2007
    Сообщения:
    98
    видимо у меня были не те параметры для RtlAdjustPrivilege, и в ней косяки были, короче привилегии получил на третьем кольце традиционным способом, а вот на Rtl вариант забил и все нормально работает
    Вопрос насчёт параметров Nt(Zw)ShutdownSystem в чём разница между 0 или 2, я помню что это способы выключения, но чем они отличаются не помню
    (сорри за вопрос не по теме)
     
  20. roman_pro

    roman_pro New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2007
    Сообщения:
    291
    Ага, последний параметр должен быть указателем. Если же передавать 0, то естественно и вываливается с обращением по адресу 0.

    Насчёт параметров Nt(Zw)ShutdownSystem, если ничего не путаю, 2 - выключение компа, а 0 - или логофф или перезагрузка (что именно - проверять некогда :)).