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

 eXeL@B —› Программирование —› Подменить TEB для потока
Посл.ответ Сообщение

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

Создано: 14 октября 2011 17:40
· Личное сообщение · #1

Это вообще возможно?Если да - то возможно ли без системных привелегий?




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

Создано: 14 октября 2011 17:56
· Личное сообщение · #2

Вообще было бы неплохо написать, зачем это нужно. Возможно, задачу решить можно и по-другому.



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

Создано: 14 октября 2011 19:42
· Личное сообщение · #3

Archer пишет:
Вообще было бы неплохо написать, зачем это нужно. Возможно, задачу решить можно и по-другому.

Пытаюсь получить доступ к полностью инициализированному TEB потока,до того как поток начал выполняться.На уровне ZwResumeThread к сожалению всякие там PVOID ведут во всякие места со свойствами страниц PAGE_NOACCESS




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 15 октября 2011 12:46
· Личное сообщение · #4

Yotsi
Если поток юзермодный, и был создан вполне стандартно (вызовом CreateThread), то (для ХР) NtCreateThread создаёт этот поток с флагом CREATE_SUSPENDED:
Code:
  1. push    edi
  2. lea     ecx, [ebp+var_3E0]
  3. push    ecx
  4. lea     ecx, [ebp+var_3A8]
  5. push    ecx
  6. lea     ecx, [ebp+var_3C4]
  7. push    ecx
  8. mov     esi, [ebp+var_3BC]
  9. push    esi
  10. push    eax
  11. push    THREAD_ALL_ACCESS
  12. lea     eax, [ebp+var_3B0]
  13. push    eax
  14. call    ds:__imp__NtCreateThread@32 ; NtCreateThread(x,x,x,x,x,x,x,x)


где чуть выше:

Code:
  1. xor     edi, edi
  2. inc     edi


Чуть дальше выполняется NtResumeThread, которая и стартует поток. Она принимает аж целых два параметра, и среди них нет ничего, ведущего в ТEB.

Code:
  1. NTSYSAPI 
  2. NTSTATUS
  3. NTAPI
  4.  
  5. NtResumeThread(
  6.  
  7.  
  8.   IN HANDLE               ThreadHandle,
  9.   OUT PULONG              SuspendCount OPTIONAL );


О каких PVOID вы говорите?

-----
Stuck to the plan, always think that we would stand up, never ran.





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

Создано: 15 октября 2011 16:58
· Личное сообщение · #5

Видимо, его смущает незаполненный ТЕБ с пвойдами внутри, ведущими вникуда. Но как подмена поможет, мне не совсем понятно. Или ТС желает сам заполнить его вместо винды, типа ему виднее?




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 15 октября 2011 17:28
· Личное сообщение · #6

Видимо о тех, что внутри TEB/PEB, правда как это связано с доступом к TEB мне непонятно

-----
Yann Tiersen best and do not fuck




Ранг: 0.0 (гость), 1thx
Активность: 0=0
Статус: Участник

Создано: 15 октября 2011 23:38 · Поправил: thoufrou
· Личное сообщение · #7

Что такое теб - это сегмент. Соответственно он адресуется селектором Fs. Далее что такое подменить - установить новый сегмент или изменить данные в текущем. Он R/W. Изменить адрес можно поменяв его в обьекте(ETHREAD). Либо создав новый сегмент, селектор для него в LDT и установить барьеры в виде нотификаций, которые будут загружать необходимый селектор в Fs. Вот только зачем это нужно ?

> Пытаюсь получить доступ к полностью инициализированному TEB потока,до того как поток начал выполняться.
Это вырожение само себе противоречит. Инициализация закончится, когда поток покинет загрузчик. До этого времени инициализация выполняется(LdrpInLdrInit = TRUE).

ТС криптор кодит:
> Сплайсинг RtlCreateUserThread
> Функции из ntdll для настройки статического TLS.Есть вопросы.
> Отрезать секцию релоков PE файла

Нотифи на треды ставится следующими путями:

1. Dll-нотификация("DLLMain").
2. Синхронизация на куках, кс(LdrpLoaderLock) etc.
3. IDP.

ARCHANGEL
> xor edi, edi
> inc edi

Хороший, годный ресерч



Ранг: 500.5 (!), 8thx
Активность: 0.230
Статус: Участник

Создано: 16 октября 2011 17:29 · Поправил: Smon
· Личное сообщение · #8

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

-----
"Пусть видят, что мы не шутим. Стволы для понта, ножи для дела" Lock, Stock & Two Smoking Barrels




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

Создано: 16 октября 2011 18:22
· Личное сообщение · #9

Спасибо что подсказали что это ложный путь.Теперь вопрос - если в NtCreateThreadEx передаются адрес ф-ции потока,и адрес передоваемой в неё переменной.То где эти адреса искать в случае с NtCreateThread ?
ЗЫ: Если в случае сплайсинга NtCreateThreadEx ,не вызвать оригинал ф-ции а юзнуть CreateThread ,записать в ThreadHandle то что вернет CreateThread,и вернуть 0.То такой поток будет для системы полноценным?Или нарушится какая то важная цепочка в инициализации потока?



Ранг: 145.8 (ветеран), 191thx
Активность: 0.140.36
Статус: Участник

Создано: 16 октября 2011 19:20
· Личное сообщение · #10

Yotsi пишет:
Если в случае сплайсинга NtCreateThreadEx ,не вызвать оригинал ф-ции а юзнуть CreateThread


И получишь рекурсию.

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

Ранг: 0.0 (гость), 1thx
Активность: 0=0
Статус: Участник

Создано: 16 октября 2011 19:55 · Поправил: thoufrou
· Личное сообщение · #11

Yotsi
Вы бы огласили весь спи.. задачу лучше. Ато както уже глаза протёрлись на этом CreateThread..




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 16 октября 2011 22:41
· Личное сообщение · #12

Yotsi пишет:
Теперь вопрос - если в NtCreateThreadEx передаются адрес ф-ции потока,и адрес передоваемой в неё переменной.То где эти адреса искать в случае с NtCreateThread ?

Вообще нихрена не хотите дизассемблировать, да?

thoufrou
Что, не могли не делю подождать, пока из бана выйдете?

-----
Stuck to the plan, always think that we would stand up, never ran.




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

Создано: 26 октября 2011 16:27 · Поправил: Yotsi
· Личное сообщение · #13

Вот такая вот схема

typedef DWORD(WINAPI *TrhRoutine)(LPVOID lParam);
TrhRoutine PreFunc;
DWORD WINAPI ThrStub(LPVOID lParam)
{
DWORD stat=0;
TEB *thrteb=(TEB*)GetCurrentTeb();
DWORD oldtls=(DWORD)thrteb->ThreadLocalStoragePointer;
ProcessTls(base,thrteb);
PreFunc(lParam);
thrteb->ThreadLocalStoragePointer=(PVOID)oldtls;
return(stat);
}
HANDLE HOOK(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId)
{
HANDLE stat=0;
PreFunc=(TrhRoutine)lpStartAddress;
UnsetSplicingHook((void*)funcadr,oldadr);
stat=CreateThread(lpThreadAttributes,dwStackSize,/*lpStartAddress*/ThrStub,lpParameter,dwCreationFlags,lpThreadId);
SetSplicingHook((void*)funcadr,HOOK,oldadr);
return(stat);
}

нормально работает для потока созданного через CreateThread.Что в принципе и неудивительно.Но вот с CRT обертками непонятная для меня проблема.Ведь если _beginthread и _beginthreadex внутри себя всеравно используют CreateThread,то получаетсчя что при правильно прототипе ф-ции все должно быть ОК.Но при typedef void (WINAPI *TrhRoutine)(LPVOID lParam); поточная ф-ция _beginthread после завершения своей работы вызывает исключение - на тему того что какой то адрес памяти нельзя прочитать.Неужели это проблема из за CRT ??



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

Создано: 27 октября 2011 12:55
· Личное сообщение · #14

тут два варианта стоит посмотреть
- или из-за неправильного использования конвенций о вызовах трэшится стек
- или нарушается синхронизация




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 27 октября 2011 14:34
· Личное сообщение · #15

Yotsi пишет:
HANDLE HOOK

Тут разве не должно быть HANDLE WINAPI HOOK?

-----
Yann Tiersen best and do not fuck




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

Создано: 27 октября 2011 15:05
· Личное сообщение · #16

очень верно подмечено по умолчанию си компилит в __cdecl



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

Создано: 27 октября 2011 15:26 · Поправил: Yotsi
· Личное сообщение · #17

тестовое приложение простейшее,непонимаю как может произойти проблема с синхронизацией
Code:
  1. __declspec( thread ) int tls_i=1;
  2. __declspec( thread ) char tls_char[25]="Hello World";
  3. __declspec( thread ) char tls_char2[25]="Hello World2";
  4. __declspec( thread ) char tls_char3[25]="Hello World3";
  5. DWORD WINAPI thrFunc(LPVOID lParam)
  6. {
  7.          printf("FROM THREAD:\n");
  8.          printf("adr- %d, %d, %s\n",tls_char,strlen(tls_char),tls_char);
  9.          printf("adr- %d, %d, %s\n",tls_char2,strlen(tls_char2),tls_char2);
  10.          printf("adr- %d, %d, %s\n",tls_char3,strlen(tls_char3),tls_char3);
  11.          printf("and int == %d\n",tls_i);
  12.          /*TEB *teb=GetCurrentTeb();
  13.          printf("%X\n",teb->ThreadLocalStoragePointer);*/
  14.          return 0;
  15. }
  16. void bgThr(void* Params)
  17. {
  18.          printf("FROM THREAD:\n");
  19.          printf("adr- %d, %d, %s\n",tls_char,strlen(tls_char),tls_char);
  20.          printf("adr- %d, %d, %s\n",tls_char2,strlen(tls_char2),tls_char2);
  21.          printf("adr- %d, %d, %s\n",tls_char3,strlen(tls_char3),tls_char3);
  22.          printf("and int == %d\n",tls_i);
  23.          //_endthread();
  24. }
  25. static unsigned __stdcall bgThrEx(void *Params)
  26. {
  27.          printf("FROM THREAD:\n");
  28.          printf("adr- %d, %d, %s\n",tls_char,strlen(tls_char),tls_char);
  29.          printf("adr- %d, %d, %s\n",tls_char2,strlen(tls_char2),tls_char2);
  30.          printf("adr- %d, %d, %s\n",tls_char3,strlen(tls_char3),tls_char3);
  31.          printf("and int == %d\n",tls_i);
  32.          //_endthreadex(0);
  33.          return 0;
  34. }
  35. int _tmain(int argc, _TCHAR* argv[])
  36. {
  37.          //DWORD selfbase=(DWORD)GetModuleHandle(NULL);
  38.          //printf("Base: %X\n",selfbase);
  39.          printf("adr- %d, %d, %s\n",tls_char,strlen(tls_char),tls_char);
  40.          printf("adr- %d, %d, %s\n",tls_char2,strlen(tls_char2),tls_char2);
  41.          printf("adr- %d, %d, %s\n",tls_char3,strlen(tls_char3),tls_char3);
  42.          printf("and int == %d\n",tls_i);
  43.          _beginthread(bgThr,0,0);
  44.          //CreateThread(0,0,thrFunc,0,0,0);
  45.          //_beginthreadex(0,0,bgThrEx,0,0,0);
  46.          getch();
  47.          return 0;
  48. }

Да и соглашение __stdcall ничего неизменило(
ЗЫ:как в ольке можно проверить "правильность" стека?



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

Создано: 28 октября 2011 20:43 · Поправил: Yotsi
· Личное сообщение · #18

Видимо проблема все таки с синхронизацией ,если воткнуть getch в конец поточной функции,то все ОК работает.Только вот что куда неуспевает попасть,никак понять не могу(((
Гм забавно,Sleep и MessageBox недают подобного эффекта.Чего в этом getch такого особенного??


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


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