И еще раз инжект. Некоторые приложения иногда падают.

Тема в разделе "WASM.BEGINNERS", создана пользователем l_inc, 20 ноя 2007.

  1. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    По теме первичных и не первичных потоков. Может подойдёт GetThreadTimes(ZwQueryInformationThread)? Она возвращает время создания потока. Счётчик там имеет разрешение 100 наносекунд(если верить докам), вполне достаточно, чтобы дифференцировать даже два, созданных подряд, потока.
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    W4FhLF
    Хороший вариант в качестве подтверждения последовательности получения TID'ов с помощью toolhelp-функций. Но проблемы на случай, когда первичный поток уже уничтожен, не решает.
     
  3. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    l_inc
    Почему не решает? Там есть поле exittime.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    W4FhLF
    Я, наверное, ошибаюсь, но разве можно получить все эти времена, если поток был уничтожен, и к нему не осталось открытых хэндлов? Т.е. речь идет о том, что в середине работы процесса нужно проверить, существует ли еще на данный момент первичный поток этого процесса. Если нет, то все, что мы с помощью GetThreadTimes сможем сделать, - это получить самый старый поток, но определить первичный он или нет, нельзя. Или я гоню?
     
  5. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    l_inc

    Ты прав, если нет открытых хэндлов, то уже не может.

    Дословно, Руссинович:

    "Завершаясь (после возврата из основной процедуры и вызова ExitThread или из-за уничтожения вызовом TerminateThread), поток переходит в состояние Terminated. Если в этот момент ни один описатель его объекта "поток" не открыт, поток удаляется из списка потоков процесса, и соответствующие структуры данных освобождаются."

    Т.е. если после завершения потока программа не вызовет CloseHandle(hThread), то ты можешь получить всю информацию о потоке. Тут нужен ресеарч конкретного приложения.
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    W4FhLF
    Вообще в 2к и ХР на эту тему совершенно разные подходы.
    Вин2к не держит открытых хендлов сама, поэтому после завершения потока и закрытии всех хендлов на него объект благополучно уходит.
    В >=XP всегда остается открытый хендл на поток (видимо), ибо завершенные потоки и процессы можно всегда обнаружить в списке - сам проверял..
    Достаточно дизассемблировать код NtQurySystemInformation чтобы увидеть появившуюся в XP дополнительную проверку флагов на Process->State.Terminated == 1. с потоками там вроде аналогично. в 2к такого не было..
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Great
    Может не все, а только случайно забытые закрыть? Ну там csrss себе хэндл процесса оставил... Или какой-нибудь процесс открыл хэндл потока, а после его завершения не закрыл?
     
  8. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    l_inc, код до сих пор не работает у тебя ?
    я как понял, ты поток не создаешь в процессе, а внедряешся в открытый.. Так вопрос, "какого" ExitThread вызывать ? :)
     
  9. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    wertyman
    Такого, что я в рабочем потоке создаю новый. Оригинальному коду рабочего потока возвращаю управление, а в новом потоке вызываю ExitThread.
    И если бы я рабочий поток завершал, то тема не называлась бы "Некоторые приложения иногда падают". Она называлась бы "Некоторые приложения иногда выживают".
     
  10. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Ааа :) Ну, извини.. Был невнимательным..
    Сегодня целый день копался с этими контекстами, под конец вообще валилось на LoadLibrary и долго не мог допереть, что в дллке прописал FreeLibraryAndExitThread сразу же после аттача :) Смеялся...

    А ты не показывал как меняешь контекст сам, может там проблема ? У тебя загрузчик куда возвращает управление то ? eip же уже переписан, а перехода на старое место, я не вижу, или опять невнимателен ;)
     
  11. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    wertyman
    Вот это есть начало кода, на которое попадает управление после инжекта:
    Код (Text):
    1. CALL loaderProc
    2. JMP NEAR 0                       ;[b][u]this will be initialized by injecting process[/u][/b]
    loaderProc выполняет все, что нужно, а код прыжка (это тот самый переход, которого Вы не видите, на старое место) инициализируется внедряющим процессом на VB (потому и выкладывать не стал).
    И опять-таки, если бы переход был неверным, ну или вообще какая-то часть контекста не сохранялась, то тема имела бы вышеуказанное альтернативное название.
    На самом деле было решено (мной :) ), что код не виноват, а виноват кто-то другой... Санта Клаус, например, т.к. падала только опера и только на моей системе. Да и методику внедрения я все равно слегка поменял. Так что тема в принципе уже давно закрыта, хоть ее и поднимают периодически.
     
  12. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Какая интересная ниточка.
    Но, раз она
    то можно отойти от темы и прояснить то, что обсуждалось уже полторы сотни раз.

    Код (Text):
    1. DWORD WINAPI ThreadProc(LPVOID)
    2. {
    3.     MessageBox(NULL, _T("I am here"), _T("Attention!"), MB_ICONINFORMATION);
    4.     return +1;
    5. }
    6.  
    7. int main()
    8. {
    9.     HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, NULL, 0, NULL);
    10.     CloseHandle(hThread);
    11.     return 0;
    12. }
    Нет мессаджбокса.

    Было подумано, что подобное поведение нелогично. Проверил на MS VC++ 2008 - и, однако ж, действительно нет МессаджБокса. Попробовал _beginthreadex вместо CreateThread - то же самое.
    Если выставить в опциях линкера EP = main(), то всё как и должно быть - поток создаётся, МессаджБокс отображается.


    Мы не увидим МессаджБокс только из-за того, что это в CRT такая фича - вызывать ExitProcess после возврата из основного треда?
    Хм, не должно быть такого поведения, разве нет?