Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> адресная арифметика, 0x00346810 + 0x0048 = 0x00346ed0 ?! 
V
    Опции темы
Logree
Дата 17.9.2010, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



в общем имеется такой код:


Код

BYTE *buffer;

...............

    NR_ATTR_HEADER *attr = (NR_ATTR_HEADER*)(buffer + file_record->attr_offset);
    while (attr->type != 0xFFFF) {                                                                                              // break point
        attr = attr +  attr->length;

    }

отладочная информация перед входом в цикл
Код

attr: 0x00346810
attr->length: 0x0048

после первого прохода:
Код

attr: 0x00346ed0


почему так? ведь должно плучиться 0x00346858?!
может так нельзя?


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
vnf
Дата 17.9.2010, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 9.2.2008

Репутация: нет
Всего: 1



attr = attr +  attr->length; замени  на 
attr = attr +  attr->length/siizeof(attr)
PM MAIL   Вверх
Logree
Дата 17.9.2010, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



результат 0x003469c0, а что это даст? ведь размер по-любому 4 байта.

ps вообще-то NR_ATTR_HEADER - структура.

Это сообщение отредактировал(а) Logree - 17.9.2010, 20:22


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
ilyagoo
Дата 17.9.2010, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 2.5.2010
Где: Санкт-Петербург

Репутация: нет
Всего: нет



у вас есть указатель на какой-нибудь тип.
например:
Код

     struct SomeStruct ptr[10];


делая инкремент ptr, вы получаете адрес следующего элемента
Код

    if ( *(++ptr) == ptr[ 1 ] )
        YouAreHere();


в адресной арифметике это выглядит примерно так:
указатель на тип + число = адрес памяти + число * размер типа

доходчиво?
PM MAIL   Вверх
Logree
Дата 17.9.2010, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



нет не понял, покажите пожалуйста на моём примере как нужно smile


вот так работает:
Код

attr = attr +  (attr->length)/sizeof(NR_ATTR_HEADER);

правда после 3 итерации опять адреса начинают ехать...

кто нибудь может внятно и просто(с примером) объяснить - почему?

Это сообщение отредактировал(а) Logree - 17.9.2010, 21:31


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
ilyagoo
Дата 17.9.2010, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 2.5.2010
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Код

buffer + some_offset


это то же самое, что и
Код

buffer[ some_offset ]


смещение у вас должно быть единицами NR_ATTR_HEADER, а не адресом.

а так?

Это сообщение отредактировал(а) ilyagoo - 17.9.2010, 22:04
PM MAIL   Вверх
Logree
Дата 17.9.2010, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



Все, до меня дошло smile я не знал что attr->length автоматически умножается на sizeof(NR_ATTR_HEADER)
Но почему со временем адреса едут? из-за погрешности деления?


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
ilyagoo
Дата 17.9.2010, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 2.5.2010
Где: Санкт-Петербург

Репутация: нет
Всего: нет



какие погрешности? деление у вас там целочисленное. 13 / 5 = 2 ))
вообще по коду совершенно не понятно, что он мог бы делать. а раз так - то он НЕВЕРЕН. перепишите, не поленИтесь.

и лучше не использовать адресную арифметику, уж больно она платформо-зависима. пишите attr[ index ].
PM MAIL   Вверх
Logree
Дата 17.9.2010, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



Цитата

какие погрешности? деление у вас там целочисленное. 13 / 5 = 2

это смотря в какую сторону округлять)

Цитата

вообще по коду совершенно не понятно, что он мог бы делать

я последовательно "перемещаю" структуру по области памяти.



Вот к примеру на протяжение 3 шагов смотрю в отладчик:

0:
Код

attr: 0x00346810
attr->length: 0x0048

1:
Код

attr: 0x00346858                 // 0x00346810+ 0x0048 верно
attr->length: 0x0060

2:
Код

attr: 0x003468b8                 //0x00346858  + 0x0060 верно
attr->length: 0x0028

3:
Код

attr: 0x003468d0                 //0x003468b8 + 0x0028 не верно
attr->length: мусор


ведь первые 2 раза складывает верно, а других операций там нет, с чем может бытть связано?

Это сообщение отредактировал(а) Logree - 17.9.2010, 23:56


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
bsa
Дата 18.9.2010, 00:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(ilyagoo @  17.9.2010,  23:40 Найти цитируемый пост)
и лучше не использовать адресную арифметику, уж больно она платформо-зависима. пишите attr[ index ]. 

attr[index] - это тоже самое, что *(attr + index). А адресная арифметика четко прописана в стандарте и она гарантируется точное позиционирование на нужный элемент.
PM   Вверх
ilyagoo
Дата 18.9.2010, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 2.5.2010
Где: Санкт-Петербург

Репутация: нет
Всего: нет



мало ли что и где написано, все зависит от реализации.
мне, например неочевидно что содержится в attr->length и что такое 0xFFFF.
PM MAIL   Вверх
semibug
Дата 18.9.2010, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



ilyagoo, точно платформо-независимая, язык гарантирует это.
Другое дело, что *(attr + index)  может выглядеть сложнее attr[ index ].
Но по количеству проблем они абсолютно идентичны, ни в первом ни во втором случае никаких проверок индекса не производиться.
Поэтому если нет специальных показаний (по быстродействию), использовать в чистом виде такие варианты доступа к данным не желательно.



PM   Вверх
Logree
Дата 18.9.2010, 01:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



Цитата

мне, например неочевидно что содержится в attr->length и что такое 0xFFFF.


данный кусок кода перебирает атрибуты файловой записи таблицы MFT, для NTFS, в buffer содержиться сама файловая запись, атрибуты располагаются друг за другом, так что для того чтобы перейти к следующему атрибуту нужно к текущему смещению атрибута прибавить его длинну и чтобы не копировать каждый раз данные я просто перемещаю структуру как маску куда мне нужно, список атрибутов заканчивается терминатором 0xFFFFFFFF, но пока что сойдёт и 0xFFFF.

однако, все это ни как не относится к проблеме, но если поможет её решить - буду рад smile



Это сообщение отредактировал(а) Logree - 18.9.2010, 02:01


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
vnf
Дата 18.9.2010, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 9.2.2008

Репутация: нет
Всего: 1



1. выравнивание? структуры точно лежат подряд  без пустых байтов между ними?
2. Там только  структуры NR_ATTR_HEADER или могут лежать другие, у которых первым элементом является NR_ATTR_HEADER? судя по отладке именно этот случай.



Это сообщение отредактировал(а) vnf - 18.9.2010, 10:47
PM MAIL   Вверх
Logree
Дата 18.9.2010, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



1. Друг за другом,вплотную, поле length по сути является смещением следующего атрибута.
2. нет там только структуры NR_ATTR_HEADER, они закончаться когда type == FFFF

если не правильное значение 0x003468d0 заменить на то что и должно было получиться - 0x003468e0 то всё становится на свои места.
я не понимаю, 2 раза он проделывает  ОПЕРАЦИЮ СЛОЖЕНИЯ верно а в  раз - нет!


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
Logree
Дата 18.9.2010, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



Сделал так:

Код

    BYTE * tmp = (buffer + file_record->attr_offset);
    NR_ATTR_HEADER *attr =(NR_ATTR_HEADER *)tmp;

    while (attr->type != 0xFFFFFFFF) {            
        tmp = tmp + attr->length;
        attr = (NR_ATTR_HEADER *)tmp;
    }

работает, но почему как в предыдущем варианте не прошло?


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
bsa
Дата 19.9.2010, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Logree, а почитать инструкцию к языку программирования не пробовал?

Вот смотри, у тебя на столе лежат в ряд 10 апельсинов. При этом ты знаешь, что диаметр апельсина 100 мм. Чтобы дотянуться до следующего апельсина тебе нужно дать команду руке на позиционирование руку на 100 мм или на 1 апельсин? Конечно на 1 апельсин, так как мозг такую фигню легко и без тебя разруливает. Так и компилятор, когда у тебя есть типизированный указатель, то прибавление/вычитание целого числа приведет к смещению этого указателя на указанное число элементов (т.е. в данном случае предполагается, что указатель ссылается на массив однотипных объектов).
В своем первом коде, ты давал команду сдвинуться не на 1, а на 100. Вот только компилятору ты не сказал, что тебе нужно не 100 "апельсинов", а 100 "миллиметров". А для него по умолчанию это значит именно "апельсины". Чтобы твой код работал правильно, нужно делать так:
Код
    NR_ATTR_HEADER *attr =(NR_ATTR_HEADER *)(buffer + file_record->attr_offset);
    while (attr->type != 0xFFFFFFFF)
        attr = (NR_ATTR_HEADER *)((BYTE*)attr + attr->length);
Но у меня работало и так:
Код
    NR_ATTR_HEADER *attr =(void*)buffer + file_record->attr_offset;
    while (attr->type != 0xFFFFFFFF)
        attr = (void*)attr + attr->length;


Это сообщение отредактировал(а) bsa - 19.9.2010, 19:16
PM   Вверх
Logree
Дата 19.9.2010, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2



я не так часто пишу на Си, так что каждый раз приходиться все вспоминать заново smile

спасибо всем.


--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
Estranged
Дата 20.9.2010, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



А смещение length - это в байтах или в структрурах NR_ATTR_HEADER? Таки скорее всего первое, поэтому attr = (NR_ATTR_HEADER *) ((LPBYTE)attr +  attr->length); ?
PM MAIL   Вверх
Logree
Дата 20.9.2010, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 331
Регистрация: 22.11.2006
Где: Самара

Репутация: нет
Всего: 2





--------------------
Самый распространенный способ дебага пятиста строк ассемблерного кода - очень долгий, очень пристальный и очень задумчивый взгляд.
PM MAIL ICQ   Вверх
Estranged
Дата 21.9.2010, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 30.8.2010

Репутация: нет
Всего: 3



Откройте ассемблерный листинг в отладке и сравните код с LPBYTE и с BYTE*.
mov eax,dword ptr [ebp-18h] ; attr
mov ecx,dword ptr [ebp-18h] ; attr
add ecx,dword ptr [eax+8] ; attr->length
mov  dword ptr [ebp-18h],ecx ; сумма
PM MAIL   Вверх
xvr
Дата 21.9.2010, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(Logree @  20.9.2010,  17:39 Найти цитируемый пост)
(BYTE *) !=== (LPBYTE)?
Равен он, равен  smile 


PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0657 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.