Share via


Array Indexing Errors

Array indexing errors are much less commonly exploited than buffer overruns, but these represent just an array of characters, and arrays of other types could also be used to write to arbitrary memory locations.

Following is sample code that demonstrates how an array indexing error can be used to write memory in arbitrary locations:

/*
    ArrayIndexError.cpp
*/

#include <stdio.h>
#include <stdlib.h>

int* IntVector;

void bar(void)
{
    printf("You have been hacked!\n");
}

void InsertInt(unsigned long index, unsigned long value)
{
    printf("Writing memory at %p\n", &(IntVector[index]));

    IntVector[index] = value;
}

bool InitVector(int size)
{
    IntVector = (int*)malloc(sizeof(int)*size);
    printf("Address of IntVector is %p\n", IntVector);

    if(IntVector == NULL)
        return false;
    else
        return true;
}

int main(int argc, char* argv[])
{
    unsigned long index, value;

    if(argc != 3)
    {
        printf("Usage is %s [index] [value]\n");
        return -1;
    }

printf("Address of bar is %p\n", bar);

    //Initialize the vector - 64 KB should be enough for 
    //anyone <g>.
    if(!InitVector(0xffff))
    {
        printf("Cannot initialize vector!\n");
        return -1;
    }

    index = atol(argv[1]);
    value = atol(argv[2]);

    InsertInt(index, value);
    return 0;
}

A typical way to be attacked with this sort of error occurs when a user tells you how many elements to expect, and is then allowed to randomly access the array after it is created because you have failed to enforce bounds checking.

The array in our example starts at 0x00510048, and the value the attacker would like to write is the return value on the stack, which is located at 0x0012FF84. The following equation describes how the address of a single array element is determined by the base of the array, the index, and the size of the array elements:

Address of array element = base of array + index * sizeof(element)

Substituting the values into the equation produces:

0x10012FF84 = 0x00510048 + index * 4

Note that 0x10012FF84 is used in the equation instead of 0x0012FF84. A little quick work with Calc.exe shows that index is 0x3FF07FCF, or 1072725967, and that the address of bar (0x00401000) is 4198400 in decimal. Here are the program results:

[d:\]ArrayIndexError.exe 1072725967 4198400
Address of bar is 00401000
Address of IntVector is 00510048
Writing memory at 0012FF84
You have been hacked!

As you can see, this sort of error is trivial to exploit if the attacker has access to a debugger.

Copyright © 2005 Microsoft Corporation.
All rights reserved.