Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Почему дескриптор удалённого потока не отображается при перечислении потоков процеса?

465
30 марта 2012 года
QWERYTY
595 / / 25.03.2012
Вот так я создаю удалённый поток:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
LibPathLen: DWORD;
begin
   LibPathLen := Length(NewDllPath)*2;
   HProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, PId);
   RemotePMem := VirtualAllocEx(HProcess, 0, LibPathLen, MEM_COMMIT, PAGE_READWRITE);
   StartAddress := GetProcAddress(GetModuleHandle('kernel32.dll'), PAnsiChar('LoadLibraryW'));
   WriteProcessMemory(HProcess, RemotePMem, PWideChar(NewDllPath), LibPathLen, RealWrite);
   HThread := CreateRemoteThread(HProcess, 0, 0, StartAddress, RemotePMem, 0, MyTId);
   Edit4.Text := IntToStr(MyTId);
end;
Библиотека моя подгружается, тут всё норм. Получаю дескриптор созданного потока, а вот при перечислении я его не вижу.
Вижу только в поле редактирования куда вывожу его при создании удалённого потока
Вот так я перечисляю дескрипторы потоков в процессе:



Код:
procedure TForm1.Timer2Timer(Sender: TObject);
var
    SnapHandle: CARDINAL;
    ThreadEntry: ThreadEntry32;
    NumThreads: BYTE;
    NextProc: BOOL;
begin
   Memo1.Clear;
   NumThreads := 0;
   SnapHandle := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, PId);
   ThreadEntry.dwSize := SizeOf(ThreadEntry);
   NextProc := Thread32First(SnapHandle, ThreadEntry);//получаем первый поток
   while NextProc do
   begin
     if ThreadEntry.th32OwnerProcessID = PID then //проверка на принадлежность к процессу
     begin
         NumThreads := NumThreads + 1;
         Memo1.Lines.Add(IntToStr(ThreadEntry.th32ThreadID));
     end;
     NextProc := Thread32Next(SnapHandle, ThreadEntry);     //получаем следующий поток
  end;
    CloseHandle(SnapHandle);     //освобождаем хендл
    Edit3.Text := IntToStr(NumThreads);
end;

Длл которую я загружаю ничего не делает, т.е у неё пусто между бегин и енд.
Может ли быть такое что поток уничтожается, если ему нечего делать, а у меня остаются в переменных его дескриптор и хендл(уже никому не нужные)? Или поток должен быть завершён явно?
Количество потоков я получаю верное. проверенно всякими прогами которые способны выводить информацию о процессах, ну например: ArtMoney, Procmon, API Monitor ну и еще другие которые дают понять что происходит в процессе.
Когда срабатывыает мой код который создаёт удалённый поток то проги про которые я писал выше показывают что моя длл загруженна в адресное пространство "жертвы".
78K
30 марта 2012 года
drfaust
20 / / 19.03.2012
CreateRemoteThread создаёт потов в адресном пространстве другого (не только своего а указанного) процесса.
СreateToolhelp32Snapshot показывает потоки, кучу и загр. модули текущего процесса, но не чужого. (Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.)
78K
30 марта 2012 года
drfaust
20 / / 19.03.2012
Сорри ошибся в переводе. СreateToolhelp32Snapshot работает для указанного pID. Если не кажет может быть указаны разные pid`ы?
465
31 марта 2012 года
QWERYTY
595 / / 25.03.2012
Цитата: drfaust
Сорри ошибся в переводе. СreateToolhelp32Snapshot работает для указанного pID. Если не кажет может быть указаны разные pid`ы?



Да читая эти мануалы при помощи переводчиков не сложно ошибиться. Иногда очень трудно уловить смысл описываемого параметра. Плюс ко всему описания не очень подробные И если не знаешь конкретно нормальное поведение функции то бывает очень сложно бороться с багами

Насчёт разных пидов очень сомневаюсь.
Во первых у меня во всей программе одна глобальная переменная PId.
Во вторых почему тот же самый код перечисляет остальные потоки кроме моего верно, и длл грузится куда надо

78K
31 марта 2012 года
drfaust
20 / / 19.03.2012
Цитата: QWERYTY
[..
Во первых у меня во всей программе одна глобальная переменная PId....


И всё-таки стоит проверить (запись в stderr значений pid и просмотр отладчиком), и пусть они будут одинаковыми. Тогда легче искать траблу будет.

465
31 марта 2012 года
QWERYTY
595 / / 25.03.2012
Да, если бы это было просто. Слова асемблер и отладчик для меня пока слишком возвышенные. Я не программист, это моё так сказать хобби.
Изначально была задача перехватывать кое какие события в одной програмке. С начала я ставил хук на создание окна этой программой, но там был баг с которым не смог справиться. Когда дочернее окно порождало диалог с классом #32770 то прога "жертва" зависала.
Теперь пытаюсь перехватывать вызов CreateWindowExA из user32.dll.
Нижняя часть кода по сути не очень важна, это я хотел видеть(не залазя в разные проги) что после нажатия кнопки стало например не 7 потоков а 8
78K
31 марта 2012 года
drfaust
20 / / 19.03.2012
Ох. не помню я паскаль.
на С/С++ просто:
cerr<<"PID: "<<Pid;
или
fprintf(stderr,"PID: %li",PiD);
Просмотр - это в самой
78K
31 марта 2012 года
drfaust
20 / / 19.03.2012
Delphi среде.

З.Ы. Сорри, Ентер случайно нажал.
465
01 апреля 2012 года
QWERYTY
595 / / 25.03.2012
Не посоветуете какую нибудь книженцию по теме процессов, потоков. Тут нужно разобраться посерьёзней.
Дело в том что первое что пришло в голову поймать созданный мной поток. Для этого был модифицирован код в таймере:

NextProc := Thread32First(SnapHandle, ThreadEntry); //получаем первый поток
while NextProc do
begin
if ThreadEntry.th32OwnerProcessID = PID then //проверка на принадлежность к процессу
begin

if MyTId = ThreadEntry.th32ThreadID then ShowMessage('Попался поток, СУЧАРА!'); // MyTId тоже глобальная и после создания не меняется

NumThreads := NumThreads + 1;
Memo1.Lines.Add(IntToStr(ThreadEntry.th32ThreadID));
end;

И срабатывание таймера было установленно в 1/1000 секунды.
Начало появляться сообщение, но после нажатия ОК оно не появляется. Таймер продолжает работать, я вижу как мигает мемо.
Похоже что поток завершается, а вот по чему и нужно разобраться
Спасибо заранее..
73K
01 апреля 2012 года
bolt7
33 / / 20.02.2012
когда завершается функция потока завершается и сам поток, если хочешь его поймать в теле функции напиши sleep или цикл какой то. не хочу много писать, так что скажу об очень хорошей книге, где это хорошо описывается "windows via c/c++", не смотри на то что написано си, там описывается сама система просто примеры на сях. там есть главы посвященные процессам и потокам. у меня сейчас на руках издание 2009 года, там на странице 176 раздел Завершение потока, где описывается как и почему. если не ясно что то конкретно, пиши суда.
465
12 апреля 2012 года
QWERYTY
595 / / 25.03.2012
Я с этой темой уже разобрался, но за книгу всё равно спасибо. То что там си написано меня не смущает, постоянно приходится в мсдн лазить, исходники на си читать. Хотел както недавно на си++ перейти, начал с ним знакомиться, но больно он мне показался муторным. Ну например работа со строками немного подутомила. И еще мне не понравилось когда грузишь свою библиотеку грузятся ещё две в догонку. Пытался с этим бороться, читал в интернете статьи как настраивать компилятор чтоб этого не происходило, компилил проекты в релиз моде, но левые библы как дамоклов меч(ничто их не брало). В делфи таких чудес не наблюдалось, и в 7 и ща в 2010 всегда грузится только моя.

И поток я уже поймал.
Я не писал ничего в функции потока, а просто применил сразу после создания потока функцию SuspendThread.
А потом по нажатию кнопки ResumeThread, и вот тогда он исчезал.


Всем спасибо кто отозвался.
7
12 апреля 2012 года
@pixo $oft
3.4K / / 20.09.2006
Отвязка от CRT делается элементарно(если нет зависимости от неё).Я тоже читал и,на удивление,без проблем сделал ☺
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог