Фундаментальные основы хакерства



         

Идентификация локальных стековых переменных - часть 6


Легко доказать, если младший бит равен нулю, число – четное. Чтобы быть уверенным, что значение указателя вершины стека делится на два без остатка, достаточно лишь сбросить его младший бит. Сбросив два бита, мы получим значение заведомо кратное четырем, три – восьми и т.д.

Сброс битов в подавляющем большинстве случаев осуществляется инструкцией AND. Например, "AND ESP, FFFFFFF0" дает ESP кратным шестнадцати. Как было получено это значение? Переводим "0xFFFFFFF0" в двоичный вид, получаем – "11111111 11111111 11111111 11110000". Видите четыре нуля на конце? Значит, четыре младших бита любого числа будут маскированы, и оно разделиться без остатка на 24 = 16.

___Как IDA идентифицирует локальные переменные.

Хотя с локальными переменными мы уже неоднократно встречались при изучении прошлых примеров, не помешает это сделать это еще один раз:

#include <stdio.h>

#include <stdlib.h>

int MyFunc(int a, int b)

{

int c;       // Локальная переменная типа int

char x[50]   // Массив (демонстрирует схему размещения массивов в памяти_

c=a+b;                            // Заносим в 'c' сумму аргументов 'a

и 'b'

ltoa(c,&x[0],0x10)  ;            // Переводим сумму 'a' и 'b' в строку

printf("%x == %s == ",c,&x[0]);   // Выводим строку на экран

return c;

}

main()

{

int a=0x666; // Объявляем локальные переменные 'a' и 'b' для того, чтобы

int b=0x777; // продемонстрировать механизм их иницилизации компилятором

int c[1];    // Такие извращения понадобовились для того, чтобы запретит

// отимизирующему компилятору помещать локальную переменную

// в регистр (см. "Идентификация регистровых переменных")

// Т.к. функции printf

передается указатель на 'c', а

// указатель на регистр быть передан не может, компилятор

// вынужен оставить переменную в памяти

c[0]=MyFunc(a,b);

printf("%x\n",&c[0]);




Содержание  Назад  Вперед