Что возможно, но, возможно, не совсем полезно в вашем случае, это извлечь текущие и предыдущие указатели фреймов стека (т. Е. Регистр bp) и, используя стандартную структуру фрейма стека, определить, сколько 4 байта (для 32-битного)Прикладные) параметры блоков были переданы в вызов текущей процедуры.Вы не сможете определить, какие единицы являются char, short или long, и если два из них вместе могут быть параметром long long / __ int64.
Я подумал об этом еще немного.Рассмотрим типичный вызов функции «func (a, b)».Вызывающий код, если у вас нет параметров в регистрах (некоторые опции компилятора x86-32 и рекомендуемые intel для x86-64), код будет выглядеть так:
; long *esp,*ebp;
push b ; *(--esp)=b;
push a ; *(--esp)=a;
call func ; *(--esp)=return_address_location;
return_address_location:
add esp,8 ; esp+=2; // free memory allocated for passing parameters
Затем вы переходите к обработке в func
func:
push ebp ; *(--esp)=(long) ebp; // save current ebp <=> current stack frame
mov ebp,esp ; ebp=esp; // create new stack frame in ebp
sub esp,16 ; esp-=4; // reserve space for local variables <=> sizeof(long)*4
(func code ...)
Теперь, когда вы находитесь в func и вам нужен доступ к параметрам, вы обращаетесь к ним с помощью ebp + 2 и ebp + 3 (* ebp содержит предыдущий ebp, ebp + 1 обратный адрес. Когда вам нужен доступ к локальномуПеременные, к которым вы обращаетесь с помощью ebp-4 до ebp-1 (могут быть чрезмерно упрощены, если они не все длинные, и у вас есть набор опций упаковки).
Через некоторое время func сделал свое дело, и вам нужнодля возврата:
mov esp,ebp ; esp=ebp; // unreserve space for local variables
pop ebp ; ebp=*(esp++); // restore previous ebp <=> previous stack frame
ret ; eip=*(esp++); // pop return address into instruction pointer
Из первого фрагмента вы также увидите, как освобождается первое выделение стека (для передачи параметров) сразу после возврата.
Несколько советов:
- Сделайте математику для себя, пошагово (инструкция за инструкцией) через последовательность вызовов / возвратов, и вы получите идеи о том, как решить исходную проблему.dling, который выглядит более или менее одинаково на всех архитектурах и реализациях, поэтому полезно знать
- Представьте неправильно рассчитанный memset / memcpy для локального буфера и как он уничтожит данные в стеке, включая адреса возвратапредыдущие кадры стека и т. д.
- Обратите внимание на значения в ds и ss (селекторы данных и стека), и, если они содержат одно и то же значение, ваше решение может использовать memcpy для копирования параметров из стека в данныепамять для проверки или что-то еще, если это поможет
- Если ds = ss, вы можете использовать &, чтобы найти адрес переданных параметров изнутри func (¶m1, ¶m2)
- Если ds и ssили не равно (как они могут быть в многопоточном приложении) вам понадобится вариант memcpy, который использует «дальнюю адресацию», которая будет обрабатывать ситуацию, когда ds и ss отличаются