Сейчас на форуме: asfa, Rio (+6 невидимых)

 eXeL@B —› Вопросы новичков —› Подскажите Asm
Посл.ответ Сообщение

Ранг: 8.3 (гость), 1thx
Активность: 0.020
Статус: Участник

Создано: 12 октября 2013 22:03
· Личное сообщение · #1

sub esp,64h \\ Освобождаем память в стеке для переменных или чего либо еще.
mov al,40
push ebx \ Толкаем стек Ebx
push ebp \Толкаем стек Ebp
push esi Толкаем стек Esi
push edi Толкаем стек Edi

mov [esp+74h+var_64],al \ в переменную var_64 загружается значение в al. Верно? Или в переменную по адресу esp+74h+var_64 мы заносим al. Как правильно спасибо!



Ранг: 42.2 (посетитель), 42thx
Активность: 0.040
Статус: Участник

Создано: 12 октября 2013 22:09
· Личное сообщение · #2

[esp+74h+var_64] - по этому указателю записывается байт из AL



Ранг: 49.7 (посетитель), 19thx
Активность: 0.050
Статус: Участник

Создано: 12 октября 2013 22:17 · Поправил: sivorog
· Личное сообщение · #3

в ячейку памяти, адрес которой равен
текущее значение esp+74h+ текущее зн. var_64,
кладем al

kid опередил




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 12 октября 2013 22:18 · Поправил: reversecode
· Личное сообщение · #4

правильно это выганять таких студентов
смахивает на комментарии к лабе

dosprog при модификации комментарии к каждой строке не нужны



Ранг: 431.7 (мудрец), 391thx
Активность: 0.730.32
Статус: Участник

Создано: 12 октября 2013 22:48 · Поправил: dosprog
· Личное сообщение · #5

sivorog,
> + текущее зн. var_64
-- var_64 не переменная, а константа, несмотря на то, что IDA её объявил как "var_64=byte ptr -64h" для индексации регистра EBP (или ESP, как в данном случае).
А вот уже [var_64] - переменная.
Просто так ИГ было удобнее, чем через "EQU" (и серьёзно экономится потом "пространство имён" при реассемблировании).
Но задание констат через "=" - грубый приём в ассемблере, он влечёт за собой труднообнаружимые ошибки при случайном переопределении этой константы. А вот "EQU" не позволит случайно переопределить константу.
ТС просто пытается модифицировать дизассемблерный листинг, и он наделает делОв с таким подходом.
А вообще, всё это описано в любом учебнике по ассемблеру. Начинать нужно с программирования, а не с дизассемблирования, я так считаю.


P.S. - reversecode, уточню, - "sub esp,64h" и следом "var_64" - это явно после IDA. Нужно понимать, как связаны между собой эти строчки, иначе будут подобные вопросы. Лучше начинать с простого.




Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 13 октября 2013 14:23
· Личное сообщение · #6

Dimarik5

В квадратных скобках адрес задаётся, точнее смещение в сегменте(так как сегмент имеет нулевую базу, то смещение совпадает с линейным адресом). Исключение составляет инструкция LEA.

[esp+74h+var_64] вообще бредовая запись. var_* обычно для bp-based, тоесть получается [esp + N + (ebp + M)]. Что это значит можно только гадать.



Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 13 октября 2013 15:38 · Поправил: Модератор
· Личное сообщение · #7

Dr0p пишет:
[esp+74h+var_64] вообще бредовая запись. var_* обычно для bp-based, тоесть получается [esp + N + (ebp + M)]. Что это значит можно только гадать.

ebp используется, чтобы иметь фиксированный адрес фрейма, тогда к стековой переменной из любой точки функции можно обращаться как ebp-varOffset. Если же обращаемся через esp, то последний сначала корректируется на начало фрейма, а потом от него также отсчитывается смещение переменной в фрейме: esp+(startESP-currentESP)-varOffset




Ранг: 324.3 (мудрец), 221thx
Активность: 0.480.37
Статус: Участник

Создано: 13 октября 2013 16:01
· Личное сообщение · #8

Dr0p пишет:
[esp+74h+var_64] вообще бредовая запись

74h - Так в иде указывается текущий указатель стека в месте инструкции, если в качестве базы esp. Для ebp не указывается

-----
IZ.RU




Ранг: 431.7 (мудрец), 391thx
Активность: 0.730.32
Статус: Участник

Создано: 13 октября 2013 16:29 · Поправил: dosprog
· Личное сообщение · #9

Уточню для внесения полной ясности. Два (основных) способа организации локальных переменных.


1) Один - стандартный. Этот генерируется большинством компиляторов:

- - - - - - - - - - -- - - - - - - - -- - - - - - - >8
push ebp
mov ebp,esp
sub esp, LOCAL_VARIABLES_SIZE

- - - - - - - - - - -- - - - - - - - --- - - - - - >8

-- тогда значение var_* для локальных переменных - отрицательное и минимальное значение имеет {-LOCAL_VARIABLES_SIZE} с базированием по EBP (он так и называется - "base pointer"). Для аргументов процедуры тогда - var_* всегда положительные.


2) А такой способ удобен при ручном программировании (и я видел такое после какого-то диковинного старинного компилятора 80-х годов):

- - - - - - - - - - -- - - - - - - - -- - - - - - - >8
push ebp
sub esp, LOCAL_VARIABLES_SIZE
mov ebp,esp

- - - - - - - - - - -- - - - - - - - --- - - - - - >8

-- тогда var_* - всегда положительные и для локальных переменных и для аргументов функции.
Недостаток - заначение (*) для первого аргумента будет зависеть от (LOCAL_VARIABLES_SIZE+4*2).
Достоинство - локальные переменные удобно описывать как STRUC.

Это всё для FLAT модели, где все вызовы NEAR. При USE16 всё осложняется тем, что вызовы могут быть и FAR.

В этих обоих способах область переменных задаётся регистром EBP как постоянное смещение в сегменте стека (с базой=0).
И в том и в другом случае регистр EBP в процедуре изменяться не должен.
Тогда IDA назначает корректные осмысленные имена для var_* и проблем нет.


Такой способ организации стека, как в заголовке темы (третий способ), - извращение. Может применяться для обфускации ассемблерного текста. Адресация с переменной (esp) базой, зависящей от текущей наполненности стека.
В данном конкретном случае [esp+74h+var_64] - это ячейка, в которой записан адрес возврата из процедуры ,это если всё-же принять, что var_64=-64h (иначе - да - это указатель в никуда). В младший байт этого адреса записывается 40.
Но IDA такого не сгенерировал бы (я так думаю, не проверял). Интересующиеся могут провести эксперименты.

--------------------------add-----------------------------
P.S. - DenCoder в предыдущем посте как раз и осветил ошибочность моего последнего предположения.
P.P.S - а также ClockMan в последующем.




Ранг: 568.2 (!), 464thx
Активность: 0.550.57
Статус: Участник
оптимист

Создано: 13 октября 2013 16:41
· Личное сообщение · #10

dosprog пишет:
Такой способ организации стека, как в заголовке темы, - извращение. Может применяться для обфускации ассемблерного текста.

Файло из этой темы --> Link <--
Смотрим функцию по адресу 00473E00
Asm
Code:
  1. /*473E00*/  PUSH EBX
  2. /*473E01*/  PUSH ESI
  3. /*473E02*/  PUSH EDI
  4. /*473E03*/  PUSH EBP
  5. /*473E04*/  ADD ESP,-0C
  6. /*473E07*/  MOV [ESP+4],ECX
  7. /*473E0B*/  MOV [ESP],DX
  8. /*473E0F*/  MOV ESI,EAX
  9. /*473E11*/  XOR EBX,EBX
  10. /*473E13*/  MOV BYTE PTR [ESP+8],1
  11. /*473E18*/  MOV EAX,[4C1BCC]
  12. /*473E1D*/  MOV EDI,[EAX+68]
  13. /*473E20*/  TEST EDI,EDI

IDA
Code:
  1. CODE:00473E00 var_1C          = dword ptr -1Ch
  2. CODE:00473E00 lParam          = dword ptr -18h
  3. CODE:00473E00 var_14          = byte ptr -14h
  4. CODE:00473E00
  5. CODE:00473E00                 push    ebx
  6. CODE:00473E01                 push    esi
  7. CODE:00473E02                 push    edi
  8. CODE:00473E03                 push    ebp
  9. CODE:00473E04                 add     esp, 0FFFFFFF4h
  10. CODE:00473E07                 mov     [esp+1Ch+lParam], ecx
  11. CODE:00473E0B                 mov     word ptr [esp+1Ch+var_1C], dx
  12. CODE:00473E0F                 mov     esi, eax
  13. CODE:00473E11                 xor     ebx, ebx
  14. CODE:00473E13                 mov     [esp+1Ch+var_14], 1




-----
Чтобы правильно задать вопрос, нужно знать большую часть ответа. Р.Шекли.




Ранг: 431.7 (мудрец), 391thx
Активность: 0.730.32
Статус: Участник

Создано: 13 октября 2013 16:45 · Поправил: dosprog
· Личное сообщение · #11

ClockMan,
признал. C IDA я не очень, всё больше с самодельными и с HIEW...

Это "детали реализации" компилятора.

Полная ясность.




Ранг: 324.3 (мудрец), 221thx
Активность: 0.480.37
Статус: Участник

Создано: 13 октября 2013 16:59
· Личное сообщение · #12

dosprog пишет:
P.S. - DenCoder в предыдущем посте как раз и осветил последнее предположение

Как бы это не предположение
В настройках иды на вкладке Disassembly в груп-боксе Display disassembly line parts по умолчанию убран чек на Stack Pointer. Если поставить, то каждую строку с инструкцией будет предварять текущее относительное начала функции положение указателя стека. Оно сходится с тем же числом, что в инструкциях адресации локальных переменных в не ebp-based функциях

-----
IZ.RU





Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 13 октября 2013 22:36
· Личное сообщение · #13

rmn

> ebp используется, чтобы

Ответ исчерпывающий, но напрасный

Зачем сразу ebp и esp юзать то ?

Или это кривые дизасмы иды



Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 13 октября 2013 23:03
· Личное сообщение · #14

Dr0p пишет:
Ответ исчерпывающий, но напрасный

модеры убрали самое вкусное

Dr0p пишет:
Зачем сразу ebp и esp юзать то ?

а где они там одновременно юзаются? в прологе видно же, что ebp сохраняется, т.к. будет использоваться внутри функции.



Ранг: 431.7 (мудрец), 391thx
Активность: 0.730.32
Статус: Участник

Создано: 13 октября 2013 23:18 · Поправил: dosprog
· Личное сообщение · #15

rmn,
насчёт вкусного - если с чем-то не согласны, напишите с чем. Увидели неточность - поправьте (если есть охота). А наезды взаимные неуместны.

Dr0p,
тут, по-моему, не в кривости IDA дело, а в том, что код писался вручную и намеренно не вполне аккуратно. А IDA-то справляется адекватно - ведь оттранслируется всё верно.



Ранг: 8.3 (гость), 1thx
Активность: 0.020
Статус: Участник

Создано: 15 октября 2013 11:40
· Личное сообщение · #16

Спасибо за ответы теперь понял что к чему.





Ранг: 72.3 (постоянный), 133thx
Активность: 0.380
Статус: Участник

Создано: 15 октября 2013 16:19
· Личное сообщение · #17

dosprog

> не в кривости IDA дело

Именно в ней. Ида это шедевр, такого кривого дизасма нет нигде.

| Сообщение посчитали полезным: Abraham

Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 15 октября 2013 17:23
· Личное сообщение · #18

dosprog, Dr0p
так а в чем кривость то? где вы там увидели обращение к локальным переменным и через esp и через ebp одновременно? Если компилятору регистров не хватило, он использует ebp как general purpose register и адресацию переменных через esp.
Одновременное использование обоих регистров для адресации переменных возможно в случае, когда код пишет упоротый кодер на асме или дельфовый компилер такое может сгенерить: ebp указывает на общий фрейм top-level функции, а esp используется для адресации во фреймах вложенных функций.

| Сообщение посчитали полезным: dosprog
 eXeL@B —› Вопросы новичков —› Подскажите Asm
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати