Вернуться   RDot > Технические аспекты > Программирование/Programming > Software development

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.09.2013, 13:29   #1
<Gh0St>
 
Аватар для <Gh0St>
 
Регистрация: 22.03.2012
Сообщений: 75
Репутация: 19
Question Получить начальное значение ESP / Проблема смещения в секции данных

Всем привет!
Дело в следующем, есть Сишная программка (консольная), нужно получить значение ESP в начале работы программы.
Делаю так:
Код:
int main(int argc, char *argv[]) {
	DWORD dwEsp;
	_asm {
		mov dwEsp, esp
		add dwEsp, 0x40
	}
       ...
}
Число 0х40 было получено опытным путём. Получаю значение ESP. Проблема в том, что нужно получить значение ESP без каких-либо заранее вычисленных цифр.

Пролог функции main:
Код:
PUSH EBP
MOV EBP,ESP
SUB ESP,38
В начале работы программы, ESP указывает сюда 0012FF8C. После выполнения пролога, сюда 0012FF50.
Нужно как-то получить начальное значение ESP через асм вставку.
Подскажите, как это сделать?
Благодарю.
__________________
- Про опыт говорят: "Мы так свои ошибки называем"

Последний раз редактировалось SynQ; 03.10.2013 в 10:24.. Причина: объединил схожие темы
<Gh0St> вне форума   Ответить с цитированием
Старый 18.09.2013, 14:43   #2
DrakonHaSh
 
Регистрация: 05.07.2010
Сообщений: 244
Репутация: 106
По умолчанию

EBP+8

к стековым переменным на с ~всегда идет обращение через ebp. ebp остается неизменным во всем теле процедуры, кроме пролога и эпилога процедуры. [ можешь, при желании для лучшего понимания, посмотреть описание операторов asm enter / leave ]

Последний раз редактировалось DrakonHaSh; 18.09.2013 в 14:51..
DrakonHaSh вне форума   Ответить с цитированием
Старый 21.09.2013, 17:04   #3
<Gh0St>
 
Аватар для <Gh0St>
 
Регистрация: 22.03.2012
Сообщений: 75
Репутация: 19
По умолчанию

Чтобы не создавать новую тему, спрошу здесь.
Возникла проблемка, значение ESP требуется для балансировки стека перед передачей управления.
После передачи управления есть такая инструкция:
MOV ESI,DWORD PTR DS:[405504] в регистр esi помещаем данные из регистра данных по адресу 405504. Это находится в секции данных (.data).

Если убрать выравнивание стека, то нужные данные будут находиться по нужному адресу (пропустим первые нулевые байты):
00405503 00B0 48270000 ADD BYTE PTR DS:[EAX+2748],DH

Если вернуть смещение, эти данные переместятся сюда:
0040551B 00B0 1D000001 ADD BYTE PTR DS:[EAX+100001D],DH

Разница в адресах такая:
0040551B - 00405503 = 18h или 24d (или 6 dword'ов)

Т.е. из-за выравнивания стека происходит смещение в секции данных.
Подскажите, почему так происходит? В чём заключается проблема?
Благодарю.
__________________
- Про опыт говорят: "Мы так свои ошибки называем"
<Gh0St> вне форума   Ответить с цитированием
Старый 23.09.2013, 15:00   #4
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

Не очень понятно, что происходит и что требуется...
Зачем ты показываешь дизасм по этим 2м адресам?

http://stackoverflow.com/questions/3...hat-does-it-do
SynQ вне форума   Ответить с цитированием
Старый 23.09.2013, 18:16   #5
<Gh0St>
 
Аватар для <Gh0St>
 
Регистрация: 22.03.2012
Сообщений: 75
Репутация: 19
По умолчанию

Цитата:
Сообщение от SynQ Посмотреть сообщение
Не очень понятно, что происходит и что требуется...
Запускается программа, что-то делает, вызывает какие-то функции, затем передаёт выполнение на код, который находится в другой области памяти, этого же процесса. Например, код выполняется по базовому адресу 0х00400000, а потом программа выполняет код по адресу 0х01000000.

Перед передачей управления на адрес 0х01000000, программа выполняет выравнивание стека, т.е. восстанавливает первоначальное значение ESP. В самом начале работы сохраняем значение ESP, а перед передачей управления, восстанавливаем это сохранённое значение.

В коде по адресу 0х01000000, есть инструкция MOV ESI,DWORD PTR DS:[405504], при выполнении которой программа падает, т.к. DS:[405504] указывает на ноль. Но это при включённом выравнивании стека. Если выравнивание отключить (не восстанавливать ESP), то тут DS:[405504] будут корректные данные (ASCII-строка) и программа успешно выполнится.

Эта строка находится в секции данных (.data), и, каким-то образом из-за выравнивания сетка (восстановления первоначального значения ESP), в этой секции происходит смещение, и в следствии которого получаем нули.

Не понятно, почему так происходит.
__________________
- Про опыт говорят: "Мы так свои ошибки называем"
<Gh0St> вне форума   Ответить с цитированием
Старый 24.09.2013, 10:30   #6
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

И мне не понятно, почему... Какими инструкциями происходит выравнивание стэка?

И вотпо первому посту, тут же по идее должно быть одно и тоже, а по факту разные значения?
00405503 00B0 48270000 ADD BYTE PTR DS:[EAX+2748],DH
0040551B 00B0 1D000001 ADD BYTE PTR DS:[EAX+100001D],DH
SynQ вне форума   Ответить с цитированием
Старый 24.09.2013, 12:16   #7
DrakonHaSh
 
Регистрация: 05.07.2010
Сообщений: 244
Репутация: 106
По умолчанию

отладчиком надо смотреть в чем разница.
может там еще другой поток.
может esp по какой-то хитрой причине указывает на секцию данных.
ручками в отладчик !
DrakonHaSh вне форума   Ответить с цитированием
Старый 24.09.2013, 15:29   #8
<Gh0St>
 
Аватар для <Gh0St>
 
Регистрация: 22.03.2012
Сообщений: 75
Репутация: 19
По умолчанию

Цитата:
Какими инструкциями происходит выравнивание стэка?
В начале работы программы сохраняем исходное значение ESP
Код:
int main(int argc, char *argv[]) {
	// store ESP
	DWORD dwEsp;
	_asm {
		mov dwEsp, ebp
	}
        dwEsp += sizeof(DWORD);
Перед передачей управления (jmp) на код из нового участка памяти, восстанавливаем ESP
Код:
	__asm {
		mov esp, dwEsp
		jmp addr;
	}
Цитата:
И вотпо первому посту, тут же по идее должно быть одно и тоже, а по факту разные значения?
00405503 00B0 48270000 ADD BYTE PTR DS:[EAX+2748],DH
0040551B 00B0 1D000001 ADD BYTE PTR DS:[EAX+100001D],DH
Да, получаются разные значения, нужные данные сдвигаются из адреса 00405503 на такой адрес 0040551B.
А по нужному адресу (00405503) при включённом выравнивании оказываются нули.

Цитата:
отладчиком надо смотреть в чем разница.
может там еще другой поток.
может esp по какой-то хитрой причине указывает на секцию данных.
Так отладчиком и смотрю. Поток только один, а каким образом ESP может указывать на секцию данных? Ведь никак.
__________________
- Про опыт говорят: "Мы так свои ошибки называем"
<Gh0St> вне форума   Ответить с цитированием
Старый 24.09.2013, 17:28   #9
DrakonHaSh
 
Регистрация: 05.07.2010
Сообщений: 244
Репутация: 106
По умолчанию

отладчиком нужно смотреть чистый asm + step by step по *asm инструкциям*. и еще полезно загрузить файл в ida чтобы точно смотреть как там и что работает на низком уровне.

mov esp, dwEsp
dwEsp - это не просто абстрактная переменная, а локальная переменная которая хранится в стеке.

лучше, по мне, делать не 2 вставками, а одной в конце примерно так:
_asm {
mov edx, ebp
add edx,8
mov esp,edx
jmp addr;
}

или

_asm {
leave
jmp addr;
}

Последний раз редактировалось DrakonHaSh; 24.09.2013 в 17:31..
DrakonHaSh вне форума   Ответить с цитированием
Старый 25.09.2013, 13:56   #10
<Gh0St>
 
Аватар для <Gh0St>
 
Регистрация: 22.03.2012
Сообщений: 75
Репутация: 19
По умолчанию

Спасибо за совет!
Сделал в конце вот такую вставку:
Код:
	__asm {
		push addr
		pop eax
		leave
		jmp eax
	}
Программа работает, кадр стека выталкивается, значения регистров восстанавливаются, всё, как положено, но вот проблема с этим местом так и осталась
Код:
MOV ESI,DWORD PTR DS:[405504]
По прежнему получаю нули. В секции данных такое же смещение.
Фууух, замучался уже с этим. Уже не знаю, что и делать...
__________________
- Про опыт говорят: "Мы так свои ошибки называем"
<Gh0St> вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot