Сейчас на форуме: -Sanchez- (+7 невидимых) |
eXeL@B —› Основной форум —› VS - размещение переменных в памяти |
Посл.ответ | Сообщение |
|
Создано: 14 сентября 2016 10:52 · Личное сообщение · #1 Приветствую...новичок на этом форуме, если что упущу - сильно не пинайте... по ряду причин пришлось заняться реверсом мелкомягкой библиотеки компрессии файлов для WinCE...опыта в реверсе не то, чтобы много, но набираюсь...столкнулся со следующей ситуацией... имеем дизассемблированный IDA кусок функции, назовем ее CompressBlock: Code:
тут мы четко видим, что в стеке переменные v10 и v11 идут друг за другом: [ebp+var_4] и [ebp+var_8]. Т.к. в VS я не нашел, как отображать смещения в стеке, то сравнил по адресам: [ebp+var_8] = 0054EDEC, [ebp+var_4] = 0054EDF0. Разница - 4 байта. В функции LZInitialize метод qmemcpy перемещает 8 байт (8u) с адреса переменной v10 (&v10) по адресу первого аргумента функции. Соответственно перемещаются переменные v10 и v11 (т.к. они оба int и имеют размерность 4 байта). теперь смотрим, как HexRays декомпилировал это место: Code:
в принципе, все нормально...но вот, что происходит, когда этот код компилирует VS: Code:
и вроде все нормально, кроме того, что разница между адресами - [v11] = 0x0029E9A0, [v10] = 0x0029E998 - 8 байт! И когда метод qmemcpy в функции LZInitialize перемещает 8 байт с адреса переменной v10, то перемещается только переменная v10 и пустота за ней... вопрос: как обойти такую ситуацию? почему VS помещает переменные в стек не друг за другом, как описано в коде? можно на это как-то повлиять настройками компилятора? |
|
Создано: 14 сентября 2016 10:58 · Личное сообщение · #2 |
|
Создано: 14 сентября 2016 11:00 · Поправил: OKOB · Личное сообщение · #3 Возможно там была структура и тогда подойдет такой костыль #pragma pack(push, 1) struct Foo { unsigned int v10; unsigned int v11; }; #pragma pack(pop) struct Foo x; x.v10 = 10; x.v11 = 0x1000; v7 = LZInitialize((int)(v6 + 7), &x, sizeof(struct Foo)); ----- 127.0.0.1, sweet 127.0.0.1 | Сообщение посчитали полезным: madlord |
|
Создано: 14 сентября 2016 11:16 · Поправил: dosprog · Личное сообщение · #4 |
|
Создано: 14 сентября 2016 11:25 · Личное сообщение · #5 dosprog пишет: Наверное, можно даже и без этого. Больше сила привычки. Всегда обрамляю определение структур, когда перетягиваю код из АСМ в С. Мало ли что по ходу прийдется добросить в структуры, потом втыкать почему не работает. Если у исходной структуры было другое выравнивание, просто разбавляю char unk1[N1]; и т.п. ----- 127.0.0.1, sweet 127.0.0.1 |
|
Создано: 14 сентября 2016 11:30 · Личное сообщение · #6 |
|
Создано: 14 сентября 2016 11:38 · Поправил: reversecode · Личное сообщение · #7 |
|
Создано: 14 сентября 2016 11:42 · Поправил: dosprog · Личное сообщение · #8 madlord пишет: так можно или лучше всё же структуру?... То же самое. Но структура лучше и ближе к первоначальной логике. А структуры дизассемблер "видит" тогда, когда это явно следует из описаний аргументов стандартных функций, которые используют эти данные. | Сообщение посчитали полезным: madlord |
eXeL@B —› Основной форум —› VS - размещение переменных в памяти |