#cpp #c #многопоточность #winapi
В процессе создаю поток функцией RtlCreateUserThread RtlCreateUserThread(hProcess, NULL, true, 0, 0, 0, (PVOID)GetProcAddress(hModule, function), NULL, &hThread, &cid); В случае с функциями без параметров, например ExitProcess из kernel32, все работает нормально, но когда пытаюсь передать например MessageBox из user32.dll, не знаю как передать параметры этой функции (3-ий с конца параметр RtlCreateUserThread) такие как родитель, текст, тип и т.д. Как передать параметры (PVOID StartParameter)? Обновление Попробовал сделать так, объявил функцию void message(){ MessageBoxA(NULL, "text", "aption", MB_OK); } И вызвал RtlCreateUserThread(hProcess, NULL, true, 0, 0, 0, &message, NULL, &hThread, &cid); Процесс крашнулся Thread tried write a virtual adress for wich id does not have the appropriate access Обновление 2 Вызов делаю в чужом процессе. Нужна пока что просто для общего развития. Насчёт прав странно, до вызова получаю токен доступа с TOKEN_ALL_ACCESS OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken); Да и процесс открываю с PROCESS_ALL_ACCESS HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
Ответы
Ответ 1
А чем вас не устраивает функция CreateRemoteThread? Ну во-первых, вы можете передать только один параметр, поэтому и у стартуемой функции должен быть только один параметр. И победить это никак не получится. Во-вторых, у функции CreateRemoteThread есть одна тонкость, я уверен что и с RtlCreateUserThread дело обстоит точно так же. Дело в том, что указатель StartAddress должен быть адресом запускаемой функции в пространстве удаленного процесса. То есть вы заранее должны знать по какому адресу размещена стартуемая функция в пространстве удаленного процесса. Вы же при вызове RtlCreateUserThread(hProcess, NULL, true, 0, 0, 0, &message, NULL, &hThread, &cid); указываете адрес message() из пространства вызывающего процесса. Поэтому и происходит падение. По этой же причине бессмысленно предавать указатель на локальную память в качестве параметра. Но почему же тогда не падает в случае ExitProcces? Да потому, что ExitProcses во всех процессах расположена по одному и тому же адресу - так работает загрузчик. При запуске нового процесса он намапывает библиотеку kernel32.dll в адресное пространство самой первой (или одной из первых, не помню) так как без нее системные вызовы работать не будут. Но это поведение загрузчика не специфицировано и нет гарантии что завтра MS не поменяет логику и не начнет мапать kernel32.dll каждый раз по разному. К стати функция CreateRemoteThread используется при реализации замечательной хакерской техники внедрения dll для перехвата системных вызовов процесса.
Комментариев нет:
Отправить комментарий