-2

これは学術的な使用のみを目的としています。ソフトウェアセキュリティコース. 先生は、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;
    }
}
4

1 に答える 1

3

配列添え字演算子a[b]は と同等です*((a)+(b))

ポインターと整数の間の加算では、まず整数にポインターが指す型のサイズを乗算し、次に乗算された値とポインターが加算されます。

そのため、(0xbffff534 - 0x804a0d4) / sizeof(fptr) ( 771675416if sizeof(fptr)is 4) の 10 進値が機能するはずです。

私が正しければ、その値を使用すると、のアドレスはのアドレスであるptrs[s]必要があり、関数p1 を使用すると呼び出されます。tmp()f1

于 2015-11-01T03:05:41.460 に答える