Вот что нагенерила IDA: Код (Text): .text:00010DBE _UMSS_PnPAddDevice@8 proc near ; DATA XREF: DriverEntry(x,x)+39o .text:00010DBE ebx_save = dword ptr -0Ch .text:00010DBE pSourceDevice = dword ptr -4 .text:00010DBE pDriverObject = dword ptr 8 .text:00010DBE pPhysicalDeviceObject= dword ptr 0Ch .text:00010DBE .text:00010DBE push ebp ; push pSourceDevice .text:00010DBF mov ebp, esp .text:00010DC1 sub esp, 0Ch .text:00010DC4 push ebx .text:00010DC5 push edi А вот стековые переменные Код (Text): 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 Я предполагаю, что при входе в функцию, указатель стека как бы равен нулю (далее sp0). Теперь Код (Text): push ebp и в стеке новая переменная (pSource Device), адрес которой - адрес младшего байта, т.е (sp0 - 4). При этом esp = (sp0 - 4) Далее Код (Text): sub esp, 0Ch ; esp = (sp0 - 10h) push ebx ; создаётся новая стековая переменная ; её адрес (sp0-14h) push edi ; создаётся новая стековая переменная ; её адрес (sp0-18h) Т.е. сегмент стека должен выглядеть примерно Код (Text): FFFFFFE8 edi_save dd ? FFFFFFEC ebx_save dd ? FFFFFFFC pSourceDevice dd ? ; offset ... А почему IDA изобразила стек по другому? Помогите пожалуйста.
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) то есть, ида наверное права, а из какого отладчика брал переменные?
да, кстати, эти цифири слева - не адрес в памяти, а смещение относительного текущего указателя стека (не скажу что сам ас
Спасибо конечно, но чего-то я не очень понял, можно поподробней >а теперь - ebp+ebx_save = -4 + -c = -10 (отн. ss) непонятно, я заметил что ида для обращения к стековой перменной val использует выражение типа: mov ax,[sp+n+val], где val, это адрес стековой переменной относительно значения sp, при входе в подпрограмму (у меня обозначено sp0), а n - это коррекция, те насколько отличается текущее значение sp от значения sp0. >да, кстати, эти цифири слева - не адрес в памяти, а смещение относительного текущего указателя стека (не >скажу что сам ас но ведь текущее значение sp - в разных местах подпрограммы - разное. Вобщем ничего не понял >то есть, ида наверное права, а из какого отладчика брал переменные? имена придумал сам, без отладчика
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 (смотри калькуляцию), а вот смещение к переменной относительно сп меняется при его изменении. а в отладчиках (не стану утверждать - давно не пользовался этим) по-моему содержимое стека можно указывать как в абсолютных адресах, так и относительно текущего значения указателя стека, поэтому я и спросил за отладчик. верятно, ты неправильно разместил переменные в стеке вручную (я сейчас ухожу, поэтому некогда расставлять, но я думаю, ты меня понял Успехов!
в иде - options->general->disasm->stack pointer включи, поймешь что происходит с sp и откуда берутся числа n
Как-то не допонял. Вот пример с включенным options->general->disasm->stack pointer: Код (Text): .text:00010DC5 014 push edi здесь esp = sp0-14 как узнать в какую стековую переменную произошла запись? это именно та строчка что и в первом посте. Заранее спасибо
если у нее нет символьного имени - значит к єтому значению не віявлено обращений (просто сохранение еди) Код (Text): .. стек вызвавшей процедуры .. аргументы для этой процедуры 04 адрес возврата 00 ebp .. локальные переменные этой процедуры -10 ebx (sp-0Ch) -14 edi
вот даже точнее Код (Text): .. стек вызвавшей процедуры 0c pPhysicalDeviceObject ->- аргументы ф-и 08 pDriverObject / 04 адрес возврата 00 ebp -08 pSourceDevice \ -0c 4 байта -->- локальные переменные этой ф -10 ebx (sp-0Ch) -14 edi
Если в IDA на любой строчке внутри функции нажать ALT+K, то она покажет, на сколько, по ее мнению, выполнение этой строки изменит ESP. Если ты уверен, что она неправа, можешь тут же это значение изменить А если нажать ALP+P, то там можно изменить и еще кой-какие значения, но я обычно предпочитаю их не трогать, поэтому затрудняюсь сходу сказать, что от этого изменится.
Всем спасибо. Понял что цифири слева действително не адреса, а смещения. Но НЕ относительно текущего указателя стека, а относительно указателя который используется в выражении. Поясняю на примере: Код (Text): push ebp ;esp = sp0 - 4 mov ebp, esp ;ebp = sp0 - 4 push ebx ;esp = sp0 - 8 mov ebx, [ebp+pValue] ; если (адрес value) = sp0 + 4, адрес возврата из процедуры лежит по адресу sp0, то pValue будет равно 8, а не 0Сh(если бы отсчёт вёлся от текущего значения указателя стека) IMHO, было бы удобнее, если бы стек представлял собой cмещения, относительно sp0 - всё было бы прозрачно.