builtin_expect

2012/05/11 19:17


malloc.c 를 살펴보던 중, 도배되어 있는 __builtin_expect() 를 보았다.


gcc 에는 __builtin_expect() 라는 기능이 있다.

찾아보니까 branch prediction 에 대한 힌트를 주는 키워드였다.


vmware@ubuntu:~$ cat test.c

#include <stdio.h>


int main(int argc, char * argv[])

{


//    if (__builtin_expect(argc == 2, 0))

    if (argc == 2)

    {

        puts("argc = 2");

    }


    puts("oh");

    return 0;

}



Reading symbols from /home/vmware/aa...(no debugging symbols found)...done.

(gdb) disassemble main

Dump of assembler code for function main:

   0x080483d4 <+0>:     push   ebp

   0x080483d5 <+1>:     mov    ebp,esp

   0x080483d7 <+3>:     and    esp,0xfffffff0

   0x080483da <+6>:     sub    esp,0x10

   0x080483dd <+9>:     cmp    DWORD PTR [ebp+0x8],0x2

   0x080483e1 <+13>:    jne    0x80483ef <main+27>

   0x080483e3 <+15>:    mov    DWORD PTR [esp],0x80484e0

   0x080483ea <+22>:    call   0x80482f0 <puts@plt>

   0x080483ef <+27>:    mov    DWORD PTR [esp],0x80484e9

   0x080483f6 <+34>:    call   0x80482f0 <puts@plt>

   0x080483fb <+39>:    mov    eax,0x0

   0x08048400 <+44>:    leave

   0x08048401 <+45>:    ret

End of assembler dump.

(gdb) q

vmware@ubuntu:~$ gdb ./a.out -q

Reading symbols from /home/vmware/a.out...(no debugging symbols found)...done.

(gdb) disassemble main

Dump of assembler code for function main:

   0x080483d4 <+0>:     push   ebp

   0x080483d5 <+1>:     mov    ebp,esp

   0x080483d7 <+3>:     and    esp,0xfffffff0

   0x080483da <+6>:     sub    esp,0x10

   0x080483dd <+9>:     cmp    DWORD PTR [ebp+0x8],0x2

   0x080483e1 <+13>:    sete   al

   0x080483e4 <+16>:    movzx  eax,al

   0x080483e7 <+19>:    test   eax,eax

   0x080483e9 <+21>:    je     0x80483f7 <main+35>

   0x080483eb <+23>:    mov    DWORD PTR [esp],0x80484e0

   0x080483f2 <+30>:    call   0x80482f0 <puts@plt>

   0x080483f7 <+35>:    mov    DWORD PTR [esp],0x80484e9

   0x080483fe <+42>:    call   0x80482f0 <puts@plt>

   0x08048403 <+47>:    mov    eax,0x0

   0x08048408 <+52>:    leave

   0x08048409 <+53>:    ret

End of assembler dump.


밑에꺼 ./a.out 이 __builtin_expect() 를 집어넣고 컴파일 한 바이너리인데, 거의 비슷하다.
다만 jne 가 je 로 바뀌었다.

jne 를 je 로 바꾸기 위해 sete al; movzx eax, al; test eax, eax; 를 수행하는데,
branch prediction 이 삑사리 나는 것보다 명령어 3개를 실행하는게 더 이득인건가??
그냥 내가 만든 test.c 가 너무 조그만한 프로그램이라 그런건가...? ㅋㅋ

아 .. malloc() 이라면 시도때도 없이 불리니까.. 더 이득일것 같다능...

각설하고, free(bad); 에서 코드실행을 하고 싶은데 못하겠다.
익스플로잇을 하려고 모든 assert 를 통과하게 만들었더니, 우아하게 free() 가 종료하였다.. ㅋㅋ

"Never underestimate what you can accomplish when you believe in yourself"

Posted by 츠피
◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [118] : NEXT ▶

BLOG main image
기왕 달릴꺼면 Ring-0 에서 달려보자!!! by 츠피

공지사항

카테고리

분류 전체보기 (118)
Profile (0)
Concept (26)
Windows Kernel (6)
Hunting (11)
Keyboard Internals (22)
Fun~! (46)
Link (0)

글 보관함

달력

«   2012/05   »
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Total : 67,418
Today : 7 Yesterday : 22