как мне вызвать функцию из ntdll в Visual C++ в win32 Application В дельфе достаточно написать external + 'имя длл' но как это сделать в сишнике если нужно импортировать из ntdll Пробовал явно вызвать (процедурные типы), но getModuleHandle и Loadlibrary возвращают нули def файлы я решительно не понял, да и не в них, я думаю, решение Подскажите незнающему
Вот объявление глобальных типов и переменных этих двух типов Код (Text): typedef WINUSERAPI DWORD WINAPI (ShutdownProc)(DWORD); typedef WINUSERAPI WORD WINAPI (GetPrivilege)(DWORD,BOOL,int,PDWORD); .... GetPrivilege* RtlAdjustPrivilege; ShutdownProc* NtShutdownSystem; Вот кусок _tWinMain Код (Text): HMODULE hModule = GetModuleHandle(LPCWSTR("ntdll.dll")); ///В hModule записываеться 0 RtlAdjustPrivilege = (GetPrivilege*)GetProcAddress(hModule,LPCSTR("RtlAdjustPrivilege")); NtShutdownSystem = (ShutdownProc*)GetProcAddress(hModule,LPCSTR("NtShutdownSystem")); hook = SetWindowsHookEx(WH_KEYBOARD_LL,HookProc,hInstance,0); ///Думаю тут всё понятно Вот уже код внутри ловушки на нажатие WIN + P Код (Text): if (keyP) { (*RtlAdjustPrivilege)(19,1,0,0); ////Если не делать проверок ещё на hModule то вылетает здесь с нулевым адресом (*NtShutdownSystem)(0); }
HMODULE hModule = GetModuleHandle(LPCWSTR("ntdll.dll")); ///В hModule записываеться 0 GetModuleHandleW писать нада. у тебя видимо анси стоит флаг,а не юникод
Нет определён юникод, потому что Во-первых иначе бы не скомпилился Во-вторых используется W версия Код (Text): #define GetModuleHandle GetModuleHandleW Вопрос для меня в том почему такие приколы и как подгрузить ntdll.lib? Я вообще не догоняю на хер её нужно специально подключать если она и так во все процессы грузиться (нельзя было придумать что-то вроде Код (Text): external 'ntdll.dll' как в дельфи или хотя бы DllImport[...] как в С#)?
ntdll всегда загружена, не надо вызывать LoadLibrary вставить #pragma comment(lib, "ntdll.lib") в начало cpp с main, после всех инклюдов скачать файлик, скинуть в папку c:\program...\microsoft visual studio 2xxxx\vc7\lib учим мат часть...
Дело не в том хочется или не хочется использовать мне юникод, если уж определён юникод, так зачем что-то менять, в данном случае аналогичные проблемы всё равно возникают и с Ansi кодировкой, мне кто-нить может объяснить в чём причина подобных ненахождений адреса
Код (Text): PVOID QSIptr = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "ZwQuerySystemInformation"); у меня это прекрасно работает...
ну начнем с того, что искать адрес с нулевым хэндлом модуля мягко говоря аморально. если не находит хэндл модуля, значит кривость в вызове апи, ибо у меня все находит. специально для этого есть апи GetLastError, кто мешает вызвать. Или прописатьв окне watch студии строку err,hr и смотреть, какую ошибку вернула система. А ваще может стоит почитать мсдн или рихтера? а то немного удивляет настойчивость поиска адреса с нулевым хэндлом... Да и приведение к типу LPCWSTR тоже неверно, ибо это не заставит студию конвертировать строку в юникодную, а просто позволит обойти сообщение об ошибке компилера, правда я не знаю, если стоит флаг юникода, не конвертируются ли строки автоматически... ADDED: Код (Text): FARPROC GetProcAddress( HMODULE hModule, LPCSTR lpProcName ); зачем приводить к типу юникода имя функции?
Когда компилятор видит эту строчку, он делает следующее: создаёт строку "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-окружении.
Поверьте все подобные советы уже были использованы и с L в том числе, дело не в этом Из-за азиатского рынка высоких технологий я даже толком не могу ничего сделать, как хотя бы ошибку отформатировать и вывести это на экран по человечески?
короч почитай рихтера. все вопросы, которые здесь задаешь, у него разжеваны и есть примеры кодеса. апи FormatMessage вроде. лень лезть искать, ибо сам сможешь найти
забавно смотрю переменные, hModule == 0x7c900000 NtShutdownSystem == 0x7c929e8c RtlAdjustPrivilege == 0x7c90e7e6 Но при вызове вылетает acess violation с текстом Unhandled exception at 0x7c929f1e in klav.exe: 0xC0000005: Access violation writing location 0x00000000. То же место Код (Text): (*RtlAdjustPrivilege)(19,1,0,0); (*NtShutdownSystem)(0); насколько я понимаю нарушение происходит внутри процедуры?
Код (Text): HMODULE hLib=LoadLibrary(_T("ntdll.dll")); if (hLib) { BOOL (WINAPI* pRtlAdjustPrivilege)(int v1, BOOL v2, BOOL v3, BOOL* v4)=(BOOL (WINAPI *)(int, BOOL, BOOL, BOOL*))GetProcAddress(hLib, "RtlAdjustPrivilege"); BOOL (WINAPI* pZwShutdownSystem)(int v1)=(BOOL (WINAPI *)(int))GetProcAddress(hLib, "ZwShutdownSystem"); BOOL f; if (pRtlAdjustPrivilege && pZwShutdownSystem) { pRtlAdjustPrivilege(19, TRUE, FALSE, &f); pZwShutdownSystem(2); } FreeLibrary(hLib); }
видимо у меня были не те параметры для RtlAdjustPrivilege, и в ней косяки были, короче привилегии получил на третьем кольце традиционным способом, а вот на Rtl вариант забил и все нормально работает Вопрос насчёт параметров Nt(Zw)ShutdownSystem в чём разница между 0 или 2, я помню что это способы выключения, но чем они отличаются не помню (сорри за вопрос не по теме)
Ага, последний параметр должен быть указателем. Если же передавать 0, то естественно и вываливается с обращением по адресу 0. Насчёт параметров Nt(Zw)ShutdownSystem, если ничего не путаю, 2 - выключение компа, а 0 - или логофф или перезагрузка (что именно - проверять некогда ).