Сейчас на форуме: jinoweb (+5 невидимых)

 eXeL@B —› Программирование —› CreateThreadEx и ExitCode из него
Посл.ответ Сообщение

Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 09 октября 2015 20:08
· Личное сообщение · #1

Вообщем создаю обычный удаленный трэд в чужом процессе - x64 (Win7):
Code:
  1. Create_Thread_handle = CreateRemoteThreadEx(Target_Process,NULL,NULL, (LPTHREAD_START_ROUTINE)Start_Thread_Addr,NULL,NULL,NULL, &Thread_ID);


Любой трэд начинает стартовать с недр, и так далее с потрохов ntdll.dll[2B810] |
".text":0000000076F9B810 <RtlUserThreadStart>:

Code:
  1. SUB RSP,48
  2. MOV R9,RCX
  3. MOV RAX,QWORD PTR DS:[<&BaseThreadInitThunk>]
  4. TEST RAX,RAX
  5. JE ntdll.76FD3E8C
  6. MOV R8,RDX
  7. MOV RDX,RCX
  8. XOR ECX,ECX
  9. CALL RAX //<<<<<<<<<<<<<<
  10. JMP ntdll.76F9B833
  11. ADD RSP,48
  12. RET

В случае с обычной загрузкой такого же обычного exe - BaseThreadInitThunk предварительно вызывает эту обвертку-функу, которая на автомате завершит главный трэд:
Code:
  1. CALL RDX // ntdll вызывает EntryPoint. EP ответьте ntdll, приём!
  2. MOV ECX,EAX
  3. CALL QWORD PTR DS:[<&RtlExitUserThread>]


В случае же создания удаленного потока, стартуем оттуда-же с RtlUserThreadStart, однако: BaseThreadInitThunk = (LPTHREAD_START_ROUTINE)Start_Thread_Addr; Отсюда следует, что поток нужно завершать своими силами

Очевидный вопрос: а нельзя ли в случае удаленного трэда как-то хитро положить на плечи системы "разгребание этого говна" (ExitThread), когда последний RET отправит RIP обратно в кишки ntdll




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 09 октября 2015 22:42
· Личное сообщение · #2

Во-первых, почему CreateRemoteThreadEx, а не CreateRemoteThread?
Во-вторых, достаточно вернуть из Start_Thread_Addr значение, оно и будет ExitCode.

| Сообщение посчитали полезным: ajax

Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 10 октября 2015 08:46
· Личное сообщение · #3

Archer пишет:
Во-первых, почему CreateRemoteThreadEx, а не CreateRemoteThread?
Во-вторых, достаточно вернуть из Start_Thread_Addr значение, оно и будет ExitCode.

не-не-не! Вы меня не поняли.
В другом процессе - создаю удаленный поток. Его ведь нужно завершить потом - надо вызвать ExitProcess. Но, теоретически, завершить за меня его может и система (как в случае порождения main трэда системой)?
ExitCode - эт я лишнее написал, типа нечаяно



Ранг: 53.9 (постоянный), 33thx
Активность: 0.050
Статус: Участник

Создано: 10 октября 2015 10:25
· Личное сообщение · #4

ELF_7719116 пишет:
В другом процессе - создаю удаленный поток. Его ведь нужно завершить потом - надо вызвать ExitProcess. Но, теоретически, завершить за меня его может и система (как в случае порождения main трэда системой)?
ExitCode - эт я лишнее написал, типа нечаяно

Наверное не ExitProcess а ExitThread?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 10 октября 2015 10:26
· Личное сообщение · #5

ELF_7719116 пишет:
Его ведь нужно завершить потом

Завершить ЕГО-это процесс или поток? Если процесс, то при завершении main thread ничего не случится, он не отличается от других потоков, и процесс помрёт, когда последний поток завершится. Если про поток, то верни управление из Start_Thread_Addr, он и помрёт.



Ранг: 419.0 (мудрец), 647thx
Активность: 0.460.51
Статус: Участник
"Тибериумный реверсинг"

Создано: 10 октября 2015 15:36
· Личное сообщение · #6

ExitThread. Поток. Всё танцует вокруг удаленного потока.

Пытаюсь обьяснить, просто не совсем удачно написал (ExitCode и вызод из процесса не при делах): возвращаю управление из Start_Thread_Addr, оказываюсь в RtlUserThreadStart тут:

Code:
  1. ...
  2. CALL RAX //RAX == Start_Thread_Addr. Его вызвала система 
  3. JMP ntdll.76F9B833
  4. ADD RSP,48
  5. RET //а RET в стеке указывает в 0

а RET в RtlUserThreadStart ведёт вникуда! Там ноль в стеке по адресу возврата. т.е. в ring-3 тупо выполнился RtlUserThreadStart и всё. На этом поток, ес-но, рушится c ACCESS_VIOLATION

Добавлено спустя 1 час 42 минуты
Всё, я наконец-то понял, почему писал весь этот бред
Да, действительно для всех потоков сначала: ntdll.RtlExitUserThread -> потом kernel32.BaseThreadInitThunk

СТУПОР НАСТУПИЛ ВОТ ИЗ-ЗА ЧЕГО:
CreateRemoteThreadEx выполняет следующий банальный код:
Code:
  1. MOV RCX, lib_addr_offset
  2. CALL QWORD PTR DS:[LoadLibraryW]
  3. RET

по аналогии с x86, я думал, что RCX - как один агрумент, и пихать в стек ничего не надо! ... и, вконце концов, понял, что LoadLibraryW затирает мой kernel32.BaseThreadInitThunk, в результате я вижу только в стеке оставшейся ntdll.RtlExitUserThread. Я сначала, ОХФИГЕЛ!!! Какого хера ВООБЩЕ, WinAPI что-то затирает в стеке?! WTF???
Code:
  1. ...
  2. 000007FEFD31AD7B | TEST BL,1                                                 |
  3. 000007FEFD31AD7E | MOV EAX,2                                                 |
  4. 000007FEFD31AD83 | CMOVNE EDI,EAX                                            |
  5. 000007FEFD31AD86 | MOV DWORD PTR SS:[RSP+70],EDI                             | -- затирало ТУТ!!

вообщем, перенес всё внимание в WinAPI и понял, что ей нужна выше адреса возврата еще какая-то структура (0x60?). Вследствие чего, код дополнился двумя командами и стал стабильно-рабочим без всяких фокусов:
Code:
  1. MOV RCX, lib_addr_offset
  2. SUB RSP, 0x60
  3. CALL QWORD PTR DS:[LoadLibraryW]
  4. ADD RSP, 0x60
  5. RET


Как эт понять?? Капитан очевидность в замешательстве!




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 10 октября 2015 17:30
· Личное сообщение · #7

Почитать мсдн/любой другой ресурс по поводу конвенции о вызове функций в х64.

| Сообщение посчитали полезным: Hellspawn
 eXeL@B —› Программирование —› CreateThreadEx и ExitCode из него
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати