Страницы

Поиск по вопросам

четверг, 26 декабря 2019 г.

Передача RtlCreateUserThread параметров

#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 для перехвата системных вызовов процесса.

Комментариев нет:

Отправить комментарий