· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.RESEARCH —› Стековые переменные в листинге IDA

Посл.отвђт Сообщенiе


Дата: Авг 13, 2004 11:14:30 · Поправил: Безпощадный даос

Вот что нагенерила IDA:
.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


А вот стековые переменные
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).

Теперь
push ebp

и в стеке новая переменная
(pSource Device), адрес которой - адрес младшего байта,
т.е (sp0 - 4). При этом esp = (sp0 - 4)

Далее
sub esp, 0Ch ; esp = (sp0 - 10h)
push ebx     ; создаётся новая стековая переменная
             ;  её адрес (sp0-14h)
push edi     ; создаётся новая стековая переменная
             ;  её адрес (sp0-18h)


Т.е. сегмент стека должен выглядеть примерно
FFFFFFE8 edi_save        dd ?
FFFFFFEC ebx_save        dd ?
FFFFFFFC pSourceDevice   dd ?                    ; offset 
...


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

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


Дата: Авг 13, 2004 11:42:52

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)

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


Дата: Авг 13, 2004 11:59:45

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


Дата: Авг 13, 2004 12:43:57 · Поправил: letopisec

Спасибо конечно, но чего-то я не очень понял, можно поподробней

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

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

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

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

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

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


Дата: Авг 13, 2004 13:10:03

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 (смотри калькуляцию), а вот смещение к переменной относительно сп меняется при его изменении.

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

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

Успехов!


Дата: Авг 13, 2004 13:31:32

в иде - options->general->disasm->stack pointer включи, поймешь что происходит с sp и откуда берутся числа n


Дата: Авг 13, 2004 14:12:20 · Поправил: letopisec

Как-то не допонял. Вот пример с включенным options->general->disasm->stack pointer:
.text:00010DC5 014                 push    edi

здесь esp = sp0-14
как узнать в какую стековую переменную произошла запись?

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

Заранее спасибо


Дата: Авг 13, 2004 14:46:54

если у нее нет символьного имени - значит к єтому значению не віявлено обращений (просто сохранение еди)

 .. стек вызвавшей процедуры
 .. аргументы для этой процедуры
 04 адрес возврата
 00 ebp
 .. локальные переменные этой процедуры
-10 ebx (sp-0Ch)
-14 edi



Дата: Авг 13, 2004 14:58:23

вот даже точнее ;)

 .. стек вызвавшей процедуры
 0c pPhysicalDeviceObject ->- аргументы ф-и
 08 pDriverObject         /
 04 адрес возврата
 00 ebp
-08 pSourceDevice \
-0c 4 байта      -->- локальные переменные этой ф
-10 ebx (sp-0Ch)
-14 edi



Дата: Авг 13, 2004 20:22:04

Если в IDA на любой строчке внутри функции нажать ALT+K, то она покажет, на сколько, по ее мнению, выполнение этой строки изменит ESP. Если ты уверен, что она неправа, можешь тут же это значение изменить :)

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


Дата: Авг 14, 2004 13:40:52 · Поправил: letopisec

Всем спасибо. Понял что цифири слева действително не адреса, а смещения. Но НЕ относительно текущего указателя стека, а относительно указателя который используется в выражении.
Поясняю на примере:
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 - всё было бы прозрачно.


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.043