Стековые переменные в листинге IDA

Тема в разделе "WASM.RESEARCH", создана пользователем letopisec, 13 авг 2004.

  1. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Вот что нагенерила IDA:
    Код (Text):
    1.  
    2. .text:00010DBE _UMSS_PnPAddDevice@8 proc near          ; DATA XREF: DriverEntry(x,x)+39o
    3.  
    4. .text:00010DBE ebx_save        = dword ptr -0Ch
    5. .text:00010DBE pSourceDevice   = dword ptr -4
    6. .text:00010DBE pDriverObject   = dword ptr  8
    7. .text:00010DBE pPhysicalDeviceObject= dword ptr  0Ch
    8. .text:00010DBE
    9. .text:00010DBE                 push    ebp             ; push pSourceDevice
    10. .text:00010DBF                 mov     ebp, esp
    11. .text:00010DC1                 sub     esp, 0Ch
    12. .text:00010DC4                 push    ebx
    13. .text:00010DC5                 push    edi
    14.  




    А вот стековые переменные


    Код (Text):
    1.  
    2. FFFFFFF4 ebx_save        dd ?
    3. FFFFFFF8                 db ? ; undefined
    4. FFFFFFF9                 db ? ; undefined
    5. FFFFFFFA                 db ? ; undefined
    6. FFFFFFFB                 db ? ; undefined
    7. FFFFFFFC pSourceDevice   dd ?                    ; offset (FFFFFFFF)
    8. 00000000  s              db 4 dup(?)
    9. 00000004  r              db 4 dup(?)
    10. 00000008 pDriverObject   dd ?                    ; offset (FFFFFFFF)
    11. 0000000C pPhysicalDeviceObject dd ?
    12. 00000010
    13. 00000010 ; end of stack variables
    14.  




    Я предполагаю, что при входе в функцию, указатель стека

    как бы равен нулю (далее sp0).



    Теперь
    Код (Text):
    1.  
    2. push ebp
    3.  


    и в стеке новая переменная

    (pSource Device), адрес которой - адрес младшего байта,

    т.е (sp0 - 4). При этом esp = (sp0 - 4)



    Далее
    Код (Text):
    1.  
    2. sub esp, 0Ch ; esp = (sp0 - 10h)
    3. push ebx     ; создаётся новая стековая переменная
    4.              ;  её адрес (sp0-14h)
    5. push edi     ; создаётся новая стековая переменная
    6.              ;  её адрес (sp0-18h)
    7.  




    Т.е. сегмент стека должен выглядеть примерно
    Код (Text):
    1.  
    2. FFFFFFE8 edi_save        dd ?
    3. FFFFFFEC ebx_save        dd ?
    4. FFFFFFFC pSourceDevice   dd ?                    ; offset
    5. ...
    6.  




    А почему IDA изобразила стек по другому?



    Помогите пожалуйста.
     
  2. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    esp=0 ebp=?

    push ebp esp=-4 ebp=?

    mov ebp, esp esp=-4 ebp=-4

    sub esp, 0Ch esp=-10 ebp=-4

    push ebx ebx-->[ss:-10]



    а теперь - ebp+ebx_save = -4 + -c = -10 (отн. ss)



    то есть, ида наверное права, а из какого отладчика брал переменные?
     
  3. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    да, кстати, эти цифири слева - не адрес в памяти, а смещение относительного текущего указателя стека (не скажу что сам ас ;)
     
  4. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Спасибо конечно, но чего-то я не очень понял, можно поподробней



    >а теперь - ebp+ebx_save = -4 + -c = -10 (отн. ss)



    непонятно, я заметил что ида для обращения к стековой перменной val использует выражение типа:

    mov ax,[sp+n+val], где val, это адрес стековой переменной относительно значения sp, при входе в подпрограмму (у меня обозначено sp0), а n - это коррекция, те насколько отличается текущее значение sp от значения sp0.



    >да, кстати, эти цифири слева - не адрес в памяти, а смещение относительного текущего указателя стека (не >скажу что сам ас ;)



    но ведь текущее значение sp - в разных местах подпрограммы - разное. Вобщем ничего не понял :dntknw:



    >то есть, ида наверное права, а из какого отладчика брал переменные?



    имена придумал сам, без отладчика
     
  5. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    1. никто не запрещает программисту закодировать такую команду:

    mov ax,[sp+XX]



    ида только дизассемблирует эту команду, при этом может распознать обращение к стековой переменной и разбить смещение ХХ на УУ+смещение переменной (типа сервис),

    т.е. это не ида использует это выражение, а программист.



    2. да, значение у сп разное, но дело не в этом, меня просто несколько удивили адреса:



    FFFFFFF4 ebx_save dd ?

    FFFFFFF8 db ? ; undefined

    FFFFFFF9 db ? ; undefined

    FFFFFFFA db ? ; undefined

    FFFFFFFB db ? ; undefined

    FFFFFFFC pSourceDevice dd ? ; offset (FFFFFFFF)

    00000000 s db 4 dup(?)

    00000004 r db 4 dup(?)

    00000008 pDriverObject dd ? ; offset (FFFFFFFF)

    0000000C pPhysicalDeviceObject dd ?

    00000010

    00000010 ; end of stack variables



    ведь если бы действительно сп был бы равен нулю при входе в процедуру, то по адресу 0 было бы записано ебп а не s, и от изменения сп оно бы никуда не сместилось, а ебх - по адресу -10 (смотри калькуляцию), а вот смещение к переменной относительно сп меняется при его изменении.



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



    верятно, ты неправильно разместил переменные в стеке вручную (я сейчас ухожу, поэтому некогда расставлять, но я думаю, ты меня понял ;)



    Успехов!
     
  6. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    в иде - options->general->disasm->stack pointer включи, поймешь что происходит с sp и откуда берутся числа n
     
  7. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Как-то не допонял. Вот пример с включенным options->general->disasm->stack pointer:


    Код (Text):
    1.  
    2. .text:00010DC5 014                 push    edi
    3.  


    здесь esp = sp0-14

    как узнать в какую стековую переменную произошла запись?



    это именно та строчка что и в первом посте.



    Заранее спасибо
     
  8. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    если у нее нет символьного имени - значит к єтому значению не віявлено обращений (просто сохранение еди)
    Код (Text):
    1.  
    2.  
    3.  .. стек вызвавшей процедуры
    4.  .. аргументы для этой процедуры
    5.  04 адрес возврата
    6.  00 ebp
    7.  .. локальные переменные этой процедуры
    8. -10 ebx (sp-0Ch)
    9. -14 edi
    10.  
    11.  
     
  9. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    вот даже точнее ;)
    Код (Text):
    1.  
    2.  
    3.  .. стек вызвавшей процедуры
    4.  0c pPhysicalDeviceObject ->- аргументы ф-и
    5.  08 pDriverObject         /
    6.  04 адрес возврата
    7.  00 ebp
    8. -08 pSourceDevice \
    9. -0c 4 байта      -->- локальные переменные этой ф
    10. -10 ebx (sp-0Ch)
    11. -14 edi
    12.  
    13.  
     
  10. RobinFood

    RobinFood New Member

    Публикаций:
    0
    Регистрация:
    6 апр 2004
    Сообщения:
    45
    Адрес:
    Ukraine
    Если в IDA на любой строчке внутри функции нажать ALT+K, то она покажет, на сколько, по ее мнению, выполнение этой строки изменит ESP. Если ты уверен, что она неправа, можешь тут же это значение изменить :)



    А если нажать ALP+P, то там можно изменить и еще кой-какие значения, но я обычно предпочитаю их не трогать, поэтому затрудняюсь сходу сказать, что от этого изменится.
     
  11. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Всем спасибо. Понял что цифири слева действително не адреса, а смещения. Но НЕ относительно текущего указателя стека, а относительно указателя который используется в выражении.

    Поясняю на примере:
    Код (Text):
    1.  
    2. push  ebp              ;esp = sp0 - 4
    3. mov   ebp, esp         ;ebp = sp0 - 4
    4. push  ebx              ;esp = sp0 - 8
    5. mov   ebx, [ebp+pValue] ;
    6.  




    если (адрес value) = sp0 + 4, адрес возврата из процедуры

    лежит по адресу sp0, то pValue будет равно 8, а не 0Сh(если бы отсчёт вёлся от текущего значения указателя стека)



    IMHO, было бы удобнее, если бы стек представлял собой cмещения, относительно sp0 - всё было бы прозрачно.