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

 eXeL@B —› Программирование —› Вопрос по особенности расчета эффективного адреса в 64-битном режиме
Посл.ответ Сообщение

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

Создано: 28 февраля 2010 16:00
· Личное сообщение · #1

Подскажите плиз!
Я разрабатываю специализированный отладчик под 64-битную Windows Seven.
Мне нужно получить адрес TEB для текущего потока, но не могу расчитать эффективный адрес для следующей инструкции:

mov rax, gs:[0].

В 32-битной ОС это делалось следующим образом:
1) GetThreadContextEx(hThread, &context), и получали селектор fs (в 64-битной ОС стал gs).
2) GetThreadSelectorEntry(hThread, context.SegFs, &ldr_entry);
3) Base = (ldr_entry.BaseLow) | (ldr_entry.HighWord.Bytes.BaseHi << 24) | (ldr_entry.HighWord.Bytes.BaseMid << 16);

Base - содержит фактически базовый адрес сегмента.

Теперь о 64-битном режиме, fs заменили на gs.
А функция GetThreadSelectorEntry не отрабатывает.
В чем проблема???




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

Создано: 28 февраля 2010 16:39
· Личное сообщение · #2

Проблема в том, что ты мсдн не читаешь.
GetThreadSelectorEntry is only functional on x86-based systems. For systems that are not x86-based, the function returns FALSE.



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

Создано: 28 февраля 2010 17:29
· Личное сообщение · #3

Проблема в том, что я мсдн читаю,
мало того могу сказать, что

функция GetThreadSelectorEntry в 64-битном режиме работает, но в самом конце при
любом условии выполняет xor rax, rax

В своем 1-м сообщении я привел просто пример как можно расчитать эффективный адрес для 32-битной ОС.

А как в 64-битном я просто не знаю.



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

Создано: 28 февраля 2010 18:10
· Личное сообщение · #4

В x64 сервис NtSetLdtEntries, Nt[Query]SetInformationProcess(ProcessLdtInformation и ProcessLdtSize) и NtQueryInformationThread(ThreadDescriptorTableEntry) сводятся к вызову xKdSetupPciDeviceForDebugging(), которая вляется заглушкой возвращающей STATUS_NOT_IMPLEMENTED.
Определяйте TEB из ThreadBasicInformation.



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

Создано: 28 февраля 2010 18:25
· Личное сообщение · #5

Спасибо ща попробую



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

Создано: 28 февраля 2010 18:41
· Личное сообщение · #6

Вы безусловно правы насчет функции NtQueryInformationThread,
но получение адреса TEB - это одна из задач связанных с расчетом полного эффективного адреса (с учетом базы сегмента).

Все же задача полного расчета эффективного адреса в юзер моде не раскрыта.

Как все же в Vista64 и Seven64 получить базу сегмента из юзер моде?



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

Создано: 28 февраля 2010 18:43
· Личное сообщение · #7

Mag_3d
Как все же в Vista64 и Seven64 получить базу сегмента из юзер мода ?
Никак. К дескрипторным таблицам доступ нужен. Из ядра читайте.



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

Создано: 28 февраля 2010 18:49
· Личное сообщение · #8

По-любому, есть решение в юзер моде, остальные отладчики же корректно работают (Microsoft VC например), или я ошибаюсь? С отладчиками в юзер моде в 64-битном режиме работал мало.




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

Создано: 28 февраля 2010 21:14
· Личное сообщение · #9

fdbg.x86asm.net/download.html

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

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




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

Создано: 28 февраля 2010 22:17
· Личное сообщение · #10

mak спасибо за ссылку,
посмотрел исходники, забавненько ....

В них я нашел вот какую интересную вещь:
ThreadLocalBase=GS_segment_register

Далее размышления на основе документации AMD:

In 64-bit mode, segmentation is disabled.
In 64-bit mode, the FS and GS segment-base registers (unlike the DS, ES, and SS segmentbase
registers) can be used as non-zero data-segment base registers for address calculations.
...
data-segment registers (DS, ES, and SS) have a base address of 0.
...


Видимо разработчики не стали заморачиваться на полную реализацию функции:
GetThreadSelectorEntry поскольку нужно реально знать только базу gs и этот адрес пишут в
ThreadLocalBase.

Таким образом, получается что
gs - для прямой адресации к teb в 64-битном режиме;
fs - для прямой адресации к teb в 32-битном режиме;

видимо чтобы не путаться самим.

Согласны?



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

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

Mag_3d
> Согласны?
Нет. ASLR не забыли ?
Нет способа в юзермоде извлечь дескриптор без доступа к ядерной памяти(x64). Так как те сервисы не доступны, также нет способа создавать дескрипторы. Изменив селектор, базу сегмента вы не найдёте. Для сегмента, атрибуты которого можно изменять(к TEB не относится) определить его базу можно аппаратно, при возникновении исключения процессор передаёт в ISR линейный адрес к которому произошло обращение(в Cr2), а далее его получает диспетчер исключений.



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

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

> Нет способа в юзермоде извлечь дескриптор без доступа к ядерной памяти(x64).
> Так как те сервисы не доступны, также нет способа создавать дескрипторы. Изменив селектор, базу
> сегмента вы не найдёте. Для сегмента, атрибуты которого можно изменять(к TEB не относится)
> определить его базу можно аппаратно, при возникновении исключения процессор передаёт в ISR
> линейный адрес к которому произошло обращение(в Cr2), а далее его получает диспетчер исключений.

Это все понятно, мы ВЕЛИ РАЗГОВОР в ветке форума лишь О юзер моде и лишь О расчете эффективного адреса.

По поводу "согласен" - я имел введу, что в 32-битном режиме в юзер моде для получения базы сегментов есть функция GetThreadSelectorEntry, а в 64-битном режиме ее нет из-за не целесообразности ее введения как таковой, т.к. fs в 64-битном режиме не используется, а значение базы gs разработчики размещают в ThreadLocalBase, т.е. остальные базы равны 0.

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



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

Создано: 01 марта 2010 09:50
· Личное сообщение · #13

Mag_3d
Cr2 передаётся в пользовательский диспетчер, чтоже ты такой не понятливый



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

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

По-моему я описал более простой способ определения ;)
Без генерации всяких исключений (особенно когда нужно определить все 1 базовый адрес gs, а не несколько ;)

Хотя последнее замечание считаю оправданным (в общем случае определения базы какого либо сегмента).

Только для особо не понятливых (такого как я) объсните как получить значение записанное в cr2 (если я отладчик и занимаюсь трассеровкой некоторого процесса ???



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

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

Mag_3d
> как получить значение записанное в cr2 (если я отладчик и занимаюсь трассеровкой некоторого процесса ???
Оно передаётся как информация об исключении, вы получите адрес к которому произошло обращение.
> По-моему я описал более простой способ определения ;)
Сказали ведь, ASLR(рандомизация адресного пространства) выполняется. Сегмент плавает и база его не фиксирована. Решение в #4.



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

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

> Сегмент плавает и база его не фиксирована.

База сегмента gs в ThreadLocalBase.
Все остальные базы сегментов равны 0.

База имеджа совсем другое, и ее рендомизация ни как не связана с базой сегмента (базу имеджа определить крайне просто отладчику).



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

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

>> как получить значение записанное в cr2 (если я отладчик и занимаюсь трассеровкой некоторого
>> процесса ???

> Оно передаётся как информация об исключении, вы получите адрес к которому произошло обращение.

Интересно вот мы занимаемся отладкой приложения и как же мне по вашему определить базовый адрес сегмента gs?

Выставляя инт3 или тф мы можем лишь определить адрес базовый cs.



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

Создано: 01 марта 2010 15:48
· Личное сообщение · #18

Mag_3d
> База сегмента gs в ThreadLocalBase.
База сегмента определена в дескрипторе, который находится в дескрипторной таблице(GDT или LDT) и индексируется селектором. Что есть ThreadLocalBase нам не известно. Плавает это значит что для всех процессов адрес TEB и PEB различны lhc645.wordpress.com/2009/11/07/aslr/
Базу TEB в GDT загружает шедулер при свопинге.



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

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

Clerk не читаешь мои сообщения:

mak спасибо за ссылку,
посмотрел исходники, забавненько ....

В них я нашел вот какую интересную вещь:
ThreadLocalBase=GS_segment_register

Далее размышления на основе документации AMD:

In 64-bit mode, segmentation is disabled.
In 64-bit mode, the FS and GS segment-base registers (unlike the DS, ES, and SS segmentbase
registers) can be used as non-zero data-segment base registers for address calculations.
...
data-segment registers (DS, ES, and SS) have a base address of 0.
...


Видимо разработчики не стали заморачиваться на полную реализацию функции:
GetThreadSelectorEntry поскольку нужно реально знать только базу gs и этот адрес пишут в
ThreadLocalBase.

Таким образом, получается что
gs - для прямой адресации к teb в 64-битном режиме;
fs - для прямой адресации к teb в 32-битном режиме;



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

Создано: 02 марта 2010 00:28
· Личное сообщение · #20

Речь идёт о том, что адреса TEB & PEB в разных процессах различны.




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

Создано: 02 марта 2010 01:28
· Личное сообщение · #21

Mag_3d пишет:
Clerk не читаешь мои сообщения:
Да нет, он как раз их читает. Он имеет ввиду (ИМХО), что в gs никак не может находиться сегмент. Там находится селектор, по которому можно определить, к какой из таблиц - LDT или GDT - принадлежит сегмент, описываемый этим селектором.

Базу TEB в GDT загружает шедулер при свопинге.
Планировщик загружает базу TEB в GDT при обращению к файлу подкачки??? Я правильно понял?

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





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

Создано: 02 марта 2010 18:51 · Поправил: Модератор
· Личное сообщение · #22

Какая подкачка, при свопконтексте.



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

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

> Он имеет ввиду (ИМХО), что в gs никак не может находиться сегмент.

Странные вы люди, это и ежику понятно.
Я вел разговор про базу сегмента и опускал всегда момент, что gs - это сегментный регистр.

> Там находится селектор, по которому можно определить, к какой из таблиц - LDT или GDT -
> принадлежит сегмент, описываемый этим селектором.

А по этому поводу все достаточно просто (рассмотрим структуру Segment Selectors - 16 бит):

Bits Mnemonic Description R/W

15-3 SI Selector Index R/W
2 TI Table Indicator R/W
1-0 RPL Requestor Privilege Level R/W

The TI bit indicates which table holds
the descriptor referenced by the selector index. When TI=0 the
GDT is used and when TI=1 the LDT is used.

Таким образом, крайне просто определить принадлежность к таблице LDT или GDT.



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

Создано: 02 марта 2010 19:16
· Личное сообщение · #24

> Базу TEB в GDT загружает шедулер при свопинге.
> Планировщик загружает базу TEB в GDT при обращению к файлу подкачки??? Я правильно понял?

Конечно нет. Загрузчик формирует адресное просторанство процесса.
И при этом и определяет сегменты (для сегментно-страничной адресации).

Доступ к памяти при расчете эффективного адреса производится через сегментные регистры: cs, ds, gs, fs, ss, es (для каждого из них есть дескриптор, где указывается задает база, лимит, ...).

Полный эффективный адрес расчитывается оп формуле: [база сегмента] + base + index*scale + disp8(32).
Для простоты реализации микрософт все адресует через [база сегмента] = 0, за исключением в 32-битном режиме сегмента fs, а в 64-битном режиме - gs.



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

Создано: 02 марта 2010 19:17
· Личное сообщение · #25

Считаю, что ветку надо закрыть, я лично ответ получил и уже проверил.




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

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

Во-первых, автор сам закрыть может, кнопка Закрыть тему под кнопкой Отправить сообщение.
Во-вторых, есть кнопка Правка, выучи её уже наконец.


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