где можно посмотреть поля этой структуры после portable part ? Например, что находится по смещению +124h ? спасибо.
вот, если кому надо (это от Win2k sp?): Код (Text): typedef struct _GDI_TEB_BATCH { ULONG Offset; ULONG HDC; ULONG Buffer[0x136]; } GDI_TEB_BATCH, *PGDI_TEB_BATCH; typedef struct _TEB { NT_TIB Tib; /* 00h */ PVOID EnvironmentPointer; /* 1Ch */ CLIENT_ID Cid; /* 20h */ PVOID ActiveRpcInfo; /* 28h */ PVOID ThreadLocalStoragePointer; /* 2Ch */ PPEB Peb; /* 30h */ ULONG LastErrorValue; /* 34h */ ULONG CountOfOwnedCriticalSections; /* 38h */ PVOID CsrClientThread; /* 3Ch */ struct _W32THREAD* Win32ThreadInfo; /* 40h */ ULONG Win32ClientInfo[0x1F]; /* 44h */ PVOID WOW32Reserved; /* C0h */ ULONG CurrentLocale; /* C4h */ ULONG FpSoftwareStatusRegister; /* C8h */ PVOID SystemReserved1[0x36]; /* CCh */ PVOID Spare1; /* 1A4h */ LONG ExceptionCode; /* 1A8h */ UCHAR SpareBytes1[0x28]; /* 1ACh */ PVOID SystemReserved2[0xA]; /* 1D4h */ GDI_TEB_BATCH GdiTebBatch; /* 1FCh */ ULONG gdiRgn; /* 6DCh */ ULONG gdiPen; /* 6E0h */ ULONG gdiBrush; /* 6E4h */ CLIENT_ID RealClientId; /* 6E8h */ PVOID GdiCachedProcessHandle; /* 6F0h */ ULONG GdiClientPID; /* 6F4h */ ULONG GdiClientTID; /* 6F8h */ PVOID GdiThreadLocaleInfo; /* 6FCh */ PVOID UserReserved[5]; /* 700h */ PVOID glDispatchTable[0x118]; /* 714h */ ULONG glReserved1[0x1A]; /* B74h */ PVOID glReserved2; /* BDCh */ PVOID glSectionInfo; /* BE0h */ PVOID glSection; /* BE4h */ PVOID glTable; /* BE8h */ PVOID glCurrentRC; /* BECh */ PVOID glContext; /* BF0h */ NTSTATUS LastStatusValue; /* BF4h */ UNICODE_STRING StaticUnicodeString; /* BF8h */ WCHAR StaticUnicodeBuffer[0x105]; /* C00h */ PVOID DeallocationStack; /* E0Ch */ PVOID TlsSlots[0x40]; /* E10h */ LIST_ENTRY TlsLinks; /* F10h */ PVOID Vdm; /* F18h */ PVOID ReservedForNtRpc; /* F1Ch */ PVOID DbgSsReserved[0x2]; /* F20h */ ULONG HardErrorDisabled; /* F28h */ PVOID Instrumentation[0x10]; /* F2Ch */ PVOID WinSockData; /* F6Ch */ ULONG GdiBatchCount; /* F70h */ USHORT Spare2; /* F74h */ BOOLEAN IsFiber; /* F76h */ UCHAR Spare3; /* F77h */ ULONG Spare4; /* F78h */ ULONG Spare5; /* F7Ch */ PVOID ReservedForOle; /* F80h */ ULONG WaitingOnLoaderLock; /* F84h */ ULONG Unknown[11]; /* F88h */ PVOID FlsSlots; /* FB4h */ } TEB, *PTEB; правда, что собственно такое +124h (PVOID), неясно...
Содержимое структуры меняется для каждой оси и даже сервиспаков. Убедись, что работаешь с правильной версией. А статьях о дровах Four-F и в моих вторых упаковщиках это расписано подробнее.
Ребзя, есть две проги, работают в одной и той же среде. У одной после загрузки поле pTLSArray (+2Сh) содержит указатель, а у другой - ноль. Вопрос: почему? (нужно, чтобы вторая прога тоже содержала такой указатель, от чего это зависит?)
от млин, это aspr делает такой указатель. т.е. первая прога запакована и после распаковки на OEP fs:2c содержит указатель, а вторая - уже распакована, и fs:2с на OEP содержит нули. У кого есть идеи как во второй сэмулировать этот указатель? Там наверно функция какая в аспре это все создает, ковырять нет времени, может кто знает?
volodya там как-то странно... смотри, если распаковать стриппером, то секция tls присутствует, fs:2ch содержит указатель. если проехаться caspr-ом, то секции tls нет, но fs:2Ch все равно содержит указатель (т.е. секция не обязталеьно должна tls именоваться?!) у меня же третий вариант - прога распакована caspr-ом и заново собрана masm-ом в DLL - вроде у сегментов не менял называния, но fs:2Ch содержит ноль! что это может быть?
т.е. вопрос даже не в том, а почему если лепить exe, то все ОК, секция tls есть, а в DLL ее нет? в MSDN есть такая фигня - флаг LOAD_LIBRARY_AS_DATAFILE при загрузке DLL через LoadLibraryEx, при этом If this value is used, the system maps the file into the calling process's virtual address space as if it were a data file. Nothing is done to execute or prepare to execute the mapped file. Use this flag when you want to load a DLL only to extract messages or resources from it. т.е. теоретически без этого флага ДОЛЖНА происходить prepare to execute the mapped file, т.е. настройка TIB и др., т.е. tls секция теоретически МОЖЕТ быть в DLL, НО КАК?
хорошо, если подумать - TLS свой для каждого потока. При загрузке DLL в память отдельного потока НЕ создается (ведь так?). Следовательно, у DLL не может быть TLS ??? Блин, а как же тогда...
AFAIK, следует различать виндовую поддержку TLS (ф-ции TlsXXX), и поддержку на уровне компилятора (__declspec(thread)), являющуюся надстройкой над виндовой. В частности, компилятор для этий целей добавляет в бинарник tls-директорию. Использовать "компиляторный" TLS в DLL не рекомендуется, если предполагается динамическая загрузка этой DLL в многопоточный процесс.
Broken Sword всех деталей реализации я не знаю... В общих словах, при загрузке длл в память ОС выделяет для её tls-данных нужное кол. памяти и сохраняет указатель в TLS array (TlsAlloc/TlsSetValue). Затем полученным TLS-индексом иинциализируется спец. DWORD в бинарнике (инфа о его располлжении берется из IMAGE_TLS_DIR). Выделенная память инициализируется из tls-секции длл. доступ к данным выглядит так: mov eax, DWORD PTR __tls_index mov ecx, DWORD PTR fs:__tls_array mov edx, DWORD PTR [ecx+eax*4] mov DWORD PTR tls_var_offset[edx], some_value По моему TIB-поле tls_array может не инициализироваться загрузчиком если в процессе нет модулей имеющих tls directory.
вообщем, все решилось. Может кому пригодиться - в сгенеренном IDA-ой листинге имеется переменная TlsDirectory, вот ее смещение и нужно закидывать по FS:2Ch, в случае DLL делать это лучше в обработчике PROCESS_ATTACH
Broken Sword ты вероятно имел ввиду DLL_THREAD_ATTACH Следует только иметь ввиду, что DLL не получает DLL_THREAD_ATTACH от потоков, которые уже существовали на момент загрузки этой длл.
нет нет, именно DLL_PROCESS_ATTACH, событие генериться при загрузке (LoadLibrary) образа DLL-ли в память грузящим процессом
в таком случае не понимаю, как это будет работать при использовании ДЛЛ потоком, отличным от того, в котором она была загружена...