Сейчас на форуме: tyns777, zds, JustLife (+4 невидимых)

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

Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 09 марта 2010 22:16
· Личное сообщение · #1

Всем доброго времени суток!
У меня такая проблема пишу инжектор который подгружает длл с помощью функции CreateRemoteThread, но программа использует длл в точке входа которой исполняется код. А моя точка входа в моей длл стартует уже после ее вызова. Как исполнить код в другом процессе чтобы он стартовал раньне него?
Code:
  1. invoke   CreateProcess,NULL,[szFileName],NULL,NULL,FALSE,\
  2.                  CREATE_SUSPENDED,NULL,NULL,[lpStartInfo],[lpProcessInfo]
  3.                         
  4. ; вставляем патч
  5. mov           ecx,[lpProcessInfo]
  6. assume   ecx:PROCESS_INFORMATION
  7. invoke   VirtualAllocEx,[ecx.hProcess],0,sizeinjector,$1000,$4
  8. push     eax
  9. mov           ecx,[lpProcessInfo]
  10. invoke   PatchProcessEx,[ecx.hProcess],eax,sizeinjector,[Injector]
  11. pop           eax
  12. lea           ebx,[lpThreadId]
  13. mov           ecx,[lpProcessInfo]
  14. invoke   CreateRemoteThread,[ecx.hProcess],0,0,eax,1,0,ebx
  15. invoke   WaitForSingleObject,eax,INFINITE
  16.  
  17. ; main inject code, is copy and run in injected process
  18. proc     _Injector uses ebx ecx edx esi edi ,istest
  19.          int3
  20.          ret
  21. endp
  22. sizeinjector=$-Injector




Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 09 марта 2010 22:38 · Поправил: HiEndsoft
· Личное сообщение · #2

флаг CREATE_SUSPENDED - ничего не значит, т.к. загрузчик заранее подгружает все либы к процессу и лишь замораживает осн поток. Проблема может быть как мне кажется решена только в нативе или на уровне дрова.

-----
продавец резиновых утёнков





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

Создано: 09 марта 2010 22:41
· Личное сообщение · #3

Ты не прав. К моменту окончания загрузки только основные либы загружены (нтдлл, кернел). Основные либы грузятся после создания ремотпроцесса.
Видимо, связано с очередью сообщений, но могу и ошибаться.



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

Создано: 09 марта 2010 22:42 · Поправил: vptrlx
· Личное сообщение · #4

если действительно
флаг CREATE_SUSPENDED - ничего не значит
то загружать файл вручную / инжектиться в лоадер / если есть возможность просто временно убрать из файла iat, а потом вручную подгрузить только импорт



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 09 марта 2010 22:45 · Поправил: HiEndsoft
· Личное сообщение · #5

Archer
бывает, после праздников
тогда наверное вопрос неясно задан/понят, т.к. такого быть не должно.
Очевидно это только случай статический.
Единственный (безгеморный) вариант - использовать свой или один из готовых исходников лоадеров, весь гемор будет с совместимостью.

-----
продавец резиновых утёнков





Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 09 марта 2010 23:00 · Поправил: DillerInc
· Личное сообщение · #6

У меня тоже есть такая проблема.Например,в GeTaOEP - либы, защищённые каким-нибудь протом ловятся обычно без проблем, а простые(незащищённые) - проскакивают мимо, т.е. они подгружаются быстрее, чем мой удалённый поток получит управление.И решения в usermode похоже нет(разве только использовать loader для либы).

-----
the Power of Reversing team




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 10 марта 2010 00:12
· Личное сообщение · #7

DillerInc
Нет возможности изменить стартупапк, но можно перенаправить её на диспетчер исключений взведя TF. Это единственное эффективное решение.
Neo32
Не понятно что вам нужно.




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 10 марта 2010 00:26
· Личное сообщение · #8

Имеется ввиду вот так ?


Если да то вот тут все есть www.codeproject.com/KB/threads/completeinject.aspx

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube





Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 10 марта 2010 01:16
· Личное сообщение · #9

Clerk, правильно ли я понял, что это альтернатива удалённому потоку?Перехватываем диспетчер исключений,генерируем исключение SINGLE_STEP и в обработчике перехвата грузим свою либу.Так ли?

-----
the Power of Reversing team




Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 10 марта 2010 07:59 · Поправил: Neo32
· Личное сообщение · #10

Clerk
Не понятно что вам нужно.

ситуация такая же:
У меня тоже есть такая проблема.Например,в GeTaOEP - либы, защищённые каким-нибудь протом ловятся обычно без проблем, а простые(незащищённые) - проскакивают мимо, т.е. они подгружаются быстрее, чем мой удалённый поток получит управление.И решения в usermode похоже нет(разве только использовать loader для либы).

и тут еще проскакивал пост про отключение иат, думаю стоит попробовать... Создаешь процесс с CREATE_SUSPENDED , обнуляешь директорию импорта, запускаешь CreateRemoteThread,[ProcessInfo.hProcess],0,0,[LoadLibraryA],eax,0,ebx а потом возвращаешь директорию иат и вручную подгружаешь модули... возможно такое?

просто CreateRemoteThread подгружает все модули из иат после своего выполнения и причем моя либа отрабатывает не первой



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 10 марта 2010 08:02
· Личное сообщение · #11

DillerInc
Я в блоге описывал это:
Запуск пользовательского потока в обход перехвата диспетчера APC(R3).
o Восстанавливаем RtlpCalloutEntryList, для исключения глобальных VEH.
o Создаём удалённый поток.
o Формируем SEH-фрейм.
o Взводим TF в контексте.
(Без закрытия списка RtlpCalloutEntryList, там не сложно):
Code:
  1. SEH_FRAME struct
  2. pLink       PVOID ?
  3. pSeh         PVOID ?
  4. pSafe       PVOID ?
  5. rEbp         PVOID ?
  6. SEH_FRAME ends
  7. PSEH_FRAME typedef ptr SEH_FRAME
  8.  
  9. STACK_FRAME struct
  10. Seh           SEH_FRAME <>
  11. pRet         PVOID ?
  12. Data         PVOID ?
  13. STACK_FRAME ends
  14. PSTACK_FRAME typedef ptr STACK_FRAME
  15.  
  16. REMOTE_SEH macro
  17.          assume fs:nothing
  18.          mov esp,dword ptr [esp + 2*4]      ; ExceptionList.
  19.          mov fs:[TEB.Tib.ExceptionList],NULL
  20.          push STACK_FRAME.Seh.pSafe[esp]
  21.          xor ebp,ebp
  22.          ret sizeof(SEH_FRAME)
  23. endm
  24.  
  25. SEH4 proc C
  26.          REMOTE_SEH
  27. SEH4 endp
  28.  
  29. .code
  30. CreateHiddenThread proc ProcessHandle:HANDLE, ExceptionHandler:PVOID, StartupRoutine:PVOID, StartupParameter:PVOID
  31. Local Buffer:STACK_FRAME
  32. Local ThreadInformation:THREAD_BASIC_INFORMATION
  33. Local ThreadHandle:HANDLE, ClientId:CLIENT_ID
  34. Local Context:CONTEXT
  35.          invoke RtlCreateUserThread, ProcessHandle, NULL, TRUE, 0, 0, PAGE_SIZE*2, 0, 0, addr ThreadHandle, addr ClientId
  36.          test eax,eax
  37.          jnz Exit
  38.          invoke ZwQueryInformationThread, ThreadHandle, ThreadBasicInformation, addr ThreadInformation, sizeof(THREAD_BASIC_INFORMATION), NULL
  39.          test eax,eax
  40.          mov Context.ContextFlags,CONTEXT_CONTROL
  41.          jnz Kill
  42.          invoke ZwGetContextThread, ThreadHandle, addr Context
  43.          test eax,eax
  44.          mov ecx,ExceptionHandler
  45.          mov edx,StartupRoutine
  46.          jnz Kill
  47.          mov Buffer.Seh.pLink,-1
  48.          sub Context.regEsp,sizeof(SEH_FRAME)
  49.          mov Buffer.Seh.pSeh,ecx
  50.          mov Buffer.Seh.pSafe,edx
  51.          mov ecx,StartupParameter
  52.          mov Buffer.Seh.rEbp,eax
  53.          mov Buffer.pRet,eax
  54.          mov Buffer.Data,ecx
  55.          invoke ZwWriteVirtualMemory, ProcessHandle, ThreadInformation.TebBaseAddress, addr Context.regEsp, 4, NULL ; TEB.Tib.ExceptionList
  56.          test eax,eax
  57.          jnz Kill
  58.          invoke ZwWriteVirtualMemory, ProcessHandle, Context.regEsp, addr Buffer, sizeof(STACK_FRAME), NULL
  59.          test eax,eax
  60.          jnz Kill
  61.          or Context.regEFlags,EFLAGS_TF
  62.          invoke ZwSetContextThread, ThreadHandle, addr Context
  63.          test eax,eax
  64.          jnz Kill
  65.          invoke ZwResumeThread, ThreadHandle, NULL
  66.          test eax,eax
  67.          jz Exit
  68. Kill:
  69.          push eax
  70.          invoke ZwTerminateThread, ThreadHandle, Eax
  71. ; invoke RtlFreeUserThreadStack, ProcessHandle, ThreadHandle ; or TEB.FreeStackOnTermination
  72.          pop eax
  73. Exit:
  74.          ret
  75. CreateHiddenThread endp




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 10 марта 2010 08:05
· Личное сообщение · #12

Neo32
До перехода потока на пользовательский код он вызывает загрузчик для нотификации модулей, которая последовательно выполняется для модулей из базы данных. Опишите нормально задачу.



Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 10 марта 2010 08:19 · Поправил: Neo32
· Личное сообщение · #13

Clerk
Опишите нормально задачу.

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



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 10 марта 2010 08:30
· Личное сообщение · #14

Neo32
Повторяю, они вызываются при создании потока, есчо до того как он на ваш код выполнять начнёт.



Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 10 марта 2010 08:33
· Личное сообщение · #15

Clerk тогда как исполнить его раньше?



Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 10 марта 2010 09:23 · Поправил: __
· Личное сообщение · #16

DillerInc пишет:
И решения в usermode похоже нет(разве только использовать loader для либы).


для XP+ можно попробовать Debug loader, в котором сначала отловить все длл(через отладочные сообщения) и потом
пустить процесс на волю.



Ранг: 11.1 (новичок)
Активность: 0.010
Статус: Участник

Создано: 10 марта 2010 09:58 · Поправил: Twister
· Личное сообщение · #17

Neo32
Ну если у тебя есть доступ к памяти целевого процесса, то что мешает сделать следующее (я так понимаю тебе необходимо просто скрыть свое присутствие):

1. Заморозить все потоки процесса.
2. Пробежаться по EP всех библиотек загруженных в него и изменить начальные байты так, чтобы эти DllEntry просто возвращали управление, ничего при этом не делая.
3. Провести инжект и запуск потока.
4. Восстановить оригинальные байты во всех DllMain.
5. Запустить ранее замороженные потоки.

?



Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 10 марта 2010 11:24 · Поправил: Neo32
· Личное сообщение · #18

Twister (я так понимаю тебе необходимо просто скрыть свое присутствие):
нет мне не надо скрывать надо запустить раньше любого кода который может выполнить процесс свой код
Twister 2. Пробежаться по EP всех библиотек загруженных в него и изменить начальные байты так, чтобы эти DllEntry просто возвращали управление, ничего при этом не делая.
они обязательно должны свое дело делать

вообщем то я решил сделать так:
1. пропатчить директорию импорта,
2. запустить процесс с флагом CREATE_SUSPENDED
3. внедрить длл,
4. в своем коде забить таблицу импорта, подгружая длл что бы у них отработали точки входа
5. запустить процесс



Ранг: 237.0 (наставник), 20thx
Активность: 0.130
Статус: Участник
sysenter

Создано: 10 марта 2010 11:44 · Поправил: HiEndsoft
· Личное сообщение · #19

Twister
Смысла в предложенном вами алгоритме нет абсолютно. Зачем патчить EP если они уже выполнены, т.к. в п 1. вы предлагаете заморозить рабочие потоки (они создаются уже после подгрузки либ и выполнения загрузчиком винды всех своих ф-ций).
Neo32
Как вариант ничего, но патчить файло - не универсальный вариант (хотя процесс можно запустить из промапленного). Надо подождать Clerk'a что-то он не досказал кажись

-----
продавец резиновых утёнков




Ранг: 11.1 (новичок)
Активность: 0.010
Статус: Участник

Создано: 10 марта 2010 11:51 · Поправил: Twister
· Личное сообщение · #20

>> Смысла в предложенном вами алгоритме нет абсолютно. Зачем патчить EP если они уже выполнены

DllMain == EP. Я предложил их пропатчить для того, чтобы библиотека не была уведомлена об аттаче трида. Впрочем, раз автору не скрыться надо, а именно выполниться раньше, то способ, конечно, не поможет. А триды заморозить на всякий, для пущей надежности.

По теме: Вы бы описали конкретную задачу, а не предполагаемый вариант решения. Возможно найдутся другие варианты.



Ранг: 11.1 (новичок)
Активность: 0.010
Статус: Участник

Создано: 10 марта 2010 12:09 · Поправил: Twister
· Личное сообщение · #21

В принципе, можно вот еще какой вариант предложить:

Опять же, заморочимся с DllMain всех модулей (их вызов будет происходить в одном потоке), проставим в начале каждого какую-нибудь инструкцию, которая будет генерировать исключение. Дальше перехватим KiUserExceptionDispatcher и запустим наш поток. Начнется нотификация модулей, первый же модуль сгенерит ошибку, мы ее поймаем и "узнаем". Тут и исполним необходимый нам код, где он будет лежать (в нашей DllMain или еще где) уже дело второе. Потом, конечно, все вернем на место. Я тут не учел VEH-обработчики, но это дело наживное.




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 10 марта 2010 14:35 · Поправил: mak
· Личное сообщение · #22

есть же готовое решение
Let us stop for a moment and consider what we do to inject our DLL into a process in the first place.
По ссылке выше , то что вы и описали

ПС Twister это не вам а нео

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 11.1 (новичок)
Активность: 0.010
Статус: Участник

Создано: 10 марта 2010 15:06
· Личное сообщение · #23

>> то что вы и описали
Эм... Признаюсь честно - по ссылке не ходил.



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 10 марта 2010 16:01 · Поправил: Clerk
· Личное сообщение · #24

Neo32
> тогда как исполнить его раньше?
Вы не можите выполнить код в модуле раньше чем он будет загружен, а это произойдёт когда поток перейдёт на ваш код. В этом случае нужен стаб.
> Заморозить все потоки процесса.
Связка NtSuspendProcess/NtResumeThread не обязательна. К примеру ядро знает про критическую секцию LdrpLoaderLock и при завершении треда может её освобождать. Ничего не мешает сделать это удалённо, тогда потоки обратившиеся к загрузчику будут ждать особождения этой кс.
> Опять же, заморочимся с DllMain всех модулей (их вызов будет происходить в одном потоке), проставим в начале каждого какую-нибудь инструкцию, которая будет генерировать исключение.
Брейк ставить не обязательно, это нужно если вы отладчик. Иначе достаточно манипуляции ссылками - сделать не валидными, что потребует обработки исключений(удалённо VEH поставить нельзя), либо замена ссылки на свой обработчик(выше - стаб).
Тут многие смежные вопросы рассмотрены http://indy-vx.narod.ru/log.txt



Ранг: 19.9 (новичок)
Активность: 0.020
Статус: Участник

Создано: 11 марта 2010 08:01 · Поправил: Neo32
· Личное сообщение · #25

Всем спасибо за ответы! Думаю тема исчерпана, и ответов больше не будет. Закрываю. Буду обрабатывать полученный материал


 eXeL@B —› Программирование —› CreateRemoteThread
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати