📜 ⬆️ ⬇️

How can a never called function be called?

Let's look at this code:

#include <cstdlib>

typedef int (*Function)();

static Function Do;

static int EraseAll() {
  return system("rm -rf /");
}

void NeverCalled() {
  Do = EraseAll;  
}

int main() {
  return Do();
}

:

main:
        movl    $.L.str, %edi
        jmp     system

.L.str:
        .asciz  "rm -rf /"

, . “rm -rf /”, ++ , , .

, .

( — Clang) . Do NULL, . NULL — , . , . , .

— ++, - (, ). , . — Do , , , Do : NULL, EraseAll. , NeverCalled (, , , , main). NULL EraseAll , NULL. , NULL, , EraseAll! ?

:

return Do();

:

return EraseAll();

, . , , , . , , .

.

#include <cstdlib>

typedef int (*Function)();

static Function Do;

static int EraseAll() {
  return system("rm -rf /");
}

static int LsAll() {
  return system("ls /");
}

void NeverCalled() {
  Do = EraseAll;
}

void NeverCalled2() {
  Do = LsAll;
}

int main() {
  return Do();
}

3 Do: EraseAll, LsAll NULL.

NULL ( , ). Do - , . Clang Do:

main:
        jmpq    *Do(%rip)

. :

return Do();

:

if (Do == LsAll)
  return LsAll();
else
  return EraseAll();

- . , . - (, ). , - Clang/LLVM — . , , , GCC (-fdevirtualize-speculatively), .

P.S. , GCC . -.

')

Source: https://habr.com/ru/post/338812/


All Articles