ВинХР Про, 32 бита. Как поменять регистр ГС

У меня есть код в OllyDBG:

MOV DWORD PTR GS:[396FF4],EBX

Но OllyDBG показывает:

EBX=00000B07
GS:[00396FF4]=???

Так как же вычисляется конечный адрес, на который будет записан EBX? У меня есть свободная память по адресу $004B0000. Что я должен поместить в код вместо $ 396FF4, чтобы EBX был написан, например. по адресу $004B0000.


person testnameC04    schedule 04.05.2015    source источник
comment
Это просто GS + 0x00396FF4. GS будет меняться, поэтому маловероятно, что вы сможете использовать его осмысленно для своих целей. Вы пытаетесь взломать какое-то программное обеспечение?   -  person Luaan    schedule 04.05.2015
comment
Я просто вижу, как работают команды ассемблера. Когда GS=0, я могу редактировать код операции, например MOV DWORD PTR GS:[004B0000],EBX. Но во время шага по коду операции я получаю нарушение прав доступа при чтении [FFFFFFFF] - используйте Shift+F7/F8/F9, чтобы передать исключение программе. Раздел 004B0000 имеет права на запись. Почему я получаю AV?   -  person testnameC04    schedule 04.05.2015
comment
Вы используете Windows Vista+? Что делает приложение верификатор говорите? Кроме того, как вы выделили эту 004B0000 память? И вы используете 32-битное приложение в 64-битной системе?   -  person Luaan    schedule 04.05.2015
comment
У меня 32-разрядная версия Windows XP (см. заголовок). Приложение также 32-битное. Но я просто загружаю фиктивное приложение в OllyDBG и записываю несколько кодов операций ассемблера в точку входа для обучения. Память $004B0000 — это раздел .data фиктивного приложения.   -  person testnameC04    schedule 04.05.2015
comment
О, мой плохой. Я путаю себя и вас. В Windows GS на самом деле является локальным сегментом потока. Вы находитесь в защищенной системе, поэтому вы не можете просто обращаться к памяти напрямую, вы всегда работаете с виртуальной памятью. Я серьезно путаю вещи, которые не применимы, что-то из реального режима старой школы, что-то из защищенного режима старой школы, что-то из смешанной системы пейджинга-сегмента Windows... Я не делал этого довольно давно. в то время как, и кажется, что я забыл большую часть материала :) Насколько мне известно, вы не можете выйти из сегмента GS - он всегда будет указывать на локальное хранилище потока.   -  person Luaan    schedule 04.05.2015
comment
Что насчет режима ядра? GS может быть использован водителем?   -  person testnameC04    schedule 04.05.2015
comment
Как вы понимаете, используется водителем? Он также используется пользовательскими приложениями, иначе вы не могли бы работать с локальным хранилищем потока (и другой информацией о потоке), но это действительно защищенный сегмент памяти, а не один из поддельных сегментов, охватывающих все адресное пространство. И, конечно же, каждый поток имеет свой собственный GS (поэтому он локальный для потока). Или вы имеете в виду что-то вроде манипулирования самой информацией о сегменте?   -  person Luaan    schedule 04.05.2015
comment
› Как вы понимаете, используется драйвером? Если такой код MOV DWORD PTR GS:[396FF4],EBX является кодом водителя, что это значит? Драйвер может напрямую обращаться к памяти.   -  person testnameC04    schedule 04.05.2015
comment
Обратите внимание, что ранее я дезинформировал о том, как работает перевод сегментов — на самом деле он намного сложнее, с таблицей дескрипторов сегментов и тому подобным. фактический базовый адрес — это не GS, а базовый адрес, указанный в таблице дескрипторов сегмента для данного сегмента.   -  person Luaan    schedule 04.05.2015
comment
Ах, это одна из вещей, которую я неправильно объяснил ранее. GS:[396FF4] — идеальный адрес, если (текущий) сегмент GS достаточно велик. Исходный код, очевидно, использовал его - я предполагаю, что это может быть сегмент стека потока (он довольно близок к 4 МБ, что является размером стека по умолчанию для основного потока; 4B0000 превышает 4 МБ, что объясняет доступ нарушение). Однако в обоих случаях он не имеет никакого отношения к физической памяти, в которой он расположен — это по-прежнему выгружаемая память.   -  person Luaan    schedule 04.05.2015
comment
Поэтому, когда вы меняете GS на 0, это на самом деле совершенно нормально — он просто указывает на дескриптор с нулевым сегментом. Но на самом деле вы не можете использовать это для адресации - тогда вы получаете segfault (или, может быть, GP или что-то в этом роде, я не уверен). Чтобы получить предполагаемое поведение, вам нужно было бы указать на дескриптор сегмента, который имеет 0 в качестве базового адреса и достаточную длину.   -  person Luaan    schedule 04.05.2015


Ответы (1)


Извините за путаницу. Реальный ответ выглядит следующим образом:

В Windows (и других современных ОС) модель сегментации больше не используется так, как в старых приложениях реального и защищенного режимов. Вместо этого модель памяти в основном «плоская» (не сегментированная) с подкачкой для упрощения управления и защиты. На самом деле, x86-64 в 64-битном режиме уже даже не позволяет использовать сегменты любым из старых способов.

Исключением являются сегменты FS и GS, предназначенные для внутреннего использования ОС. В Windows сегмент GS относится к локальному хранилищу потока. Насколько я знаю, вырваться из сегмента нельзя - это (аппаратно) защищенная память.

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

MOV DWORD PTR DS:[4B0000], EBX должно работать нормально, как и полное удаление сегментного регистра (MOV DWORD PTR [4B0000], EBX).

person Luaan    schedule 04.05.2015
comment
Я помещаю в память $004B0000 следующие байты: 30 00 4B 00. Это адрес $004B0030. Но MOV DWORD PTR GS:[4B0000],EBX все равно дает AV. Обратите внимание, что MOV DWORD PTR DS:[4B0030],EBX работает нормально и записывает EBX в $4B0030. Почему? - person testnameC04; 04.05.2015