Обманываем программу на С, вводя адрес указателя

Это только для академического использования. Курс безопасности программного обеспечения. Учитель хочет, чтобы я обманул программу, введя что-то, по-моему, адрес монтера, чтобы запустить функцию, отличную от f2 или f3. Я могу видеть все адреса памяти, используя GDB. Что я должен войти, чтобы запустить f1?

Спасибо за помощь.

void f1 (void) {...} // f1 address 0x8048559
void f2 (void) {...} // f2 address 0x804857e
void f3 (void) {...} // f3 adrress 0x8048627

fptr ptrs[2] = {NULL, f2, f3}; // ptrs adress 0x804a0d4

int main(int argc, char *argv[]) {
    char  buf[1024] = {0}; // buf address 0xbffff130
    int r; // r address 0xbffff530
    fptr p1 = f1; // p1 address 0xbffff534

    r = read(0, buf, sizeof(buf)-sizeof(char));

    if(r > 0) {
        buf[r] = '\0';
        int s = atoi(buf);
        fptr tmp = ptrs[s];
        tmp();
    } else {
        break;
    }
}

1 ответ

Оператор индекса массива a[b] эквивалентно *((a)+(b)),

Сложение между указателем и целым числом сначала умножит целое число на размер типа, на который указывает указатель, затем умноженное значение и указатель добавляются.

По этой причине десятичное значение (0xbffff534 - 0x804a0d4) / sizeof(fptr)(771675416 если sizeof(fptr) 4) должно работать.

Если я прав, используя это значение, адрес ptrs[s] должен быть адрес p1и используя tmp() функция f1 будет называться.

Другие вопросы по тегам