wopr decompiled

This post is a follow up to my Persistence post, and only of interest to people that really want to compare my decompiled C with the disassembled wopr binary.

Here follows the disassembled wopr executable, with my decompiling comments interspersed.

I glossed over error handling; wopr’s handling of failures (such as failure to open sockets) is completely ignored; only a best case-scenario is examined.

root@kali:~/persistence# objdump -s -j .rodata wopr

wopr:     file format elf32-i386

Contents of section .rodata:
 8048c08 03000000 01000200 00000000 5b2b5d20  ............[+]
 8048c18 79656168 2c204920 646f6e27 74207468  yeah, I don't th
 8048c28 696e6b20 736f0a00 736f636b 65740073  ink so..socket.s
 8048c38 6574736f 636b6f70 74006269 6e64005b  etsockopt.bind.[
 8048c48 2b5d2062 696e6420 636f6d70 6c657465  +] bind complete
 8048c58 006c6973 74656e00 2f746d70 2f6c6f67  .listen./tmp/log
 8048c68 00544d50 4c4f4700 5b2b5d20 77616974  .TMPLOG.[+] wait
 8048c78 696e6720 666f7220 636f6e6e 65637469  ing for connecti
 8048c88 6f6e7300 5b2b5d20 6c6f6767 696e6720  ons.[+] logging
 8048c98 71756572 69657320 746f2024 544d504c  queries to $TMPL
 8048ca8 4f470061 63636570 74005b2b 5d20676f  OG.accept.[+] go
 8048cb8 74206120 636f6e6e 65637469 6f6e0000  t a connection..
 8048cc8 5b2b5d20 68656c6c 6f2c206d 79206e61  [+] hello, my na
 8048cd8 6d652069 73207370 6c6f6974 61626c65  me is sploitable
 8048ce8 0a000000 5b2b5d20 776f756c 6420796f  ....[+] would yo
 8048cf8 75206c69 6b652074 6f20706c 61792061  u like to play a
 8048d08 2067616d 653f0a00 3e20005b 2b5d2062   game?..> .[+] b
 8048d18 7965210a 00                          ye!..

root@kali:~/persistence# objdump -M intel -d wopr

wopr:     file format elf32-i386

<snip />

08048774 <get_reply>:
:FUNCTION PROLOGUE
 8048774:    55                       push   ebp
 8048775:    89 e5                    mov    ebp,esp
 8048777:    83 ec 3c                 sub    esp,0x3c

:ARGUMENTS get_reply(char* request, int length, int filehandle)
 804877a:    8b 45 08                 mov    eax,DWORD PTR [ebp+0x8]
 804877d:    89 45 d8                 mov    DWORD PTR [ebp-0x28],eax
 8048780:    8b 45 0c                 mov    eax,DWORD PTR [ebp+0xc]
 8048783:    89 45 d4                 mov    DWORD PTR [ebp-0x2c],eax
 8048786:    8b 45 10                 mov    eax,DWORD PTR [ebp+0x10]
 8048789:    89 45 d0                 mov    DWORD PTR [ebp-0x30],eax

:CANARY A canary at EBP-0x4 gets set to a doubleword from gs:0x14
 804878c:    65 a1 14 00 00 00        mov    eax,gs:0x14
 8048792:    89 45 fc                 mov    DWORD PTR [ebp-0x4],eax

 8048795:    31 c0                    xor    eax,eax

:SYSTEM CALL. Here memcpy is called, and *request is copied to a local variable; let's call it dest:
char[30] dest;
memcpy(dest, filehandle, length);
 8048797:    8b 45 d4                 mov    eax,DWORD PTR [ebp-0x2c]
 804879a:    89 44 24 08              mov    DWORD PTR [esp+0x8],eax
 804879e:    8b 45 d8                 mov    eax,DWORD PTR [ebp-0x28]
 80487a1:    89 44 24 04              mov    DWORD PTR [esp+0x4],eax
 80487a5:    8d 45 de                 lea    eax,[ebp-0x22]
 80487a8:    89 04 24                 mov    DWORD PTR [esp],eax
 80487ab:    e8 6c fe ff ff           call   804861c <memcpy@plt>

:SYSTEM CALL.
write(filehandle, "[+] yeah, I don't think son", 27);
 80487b0:    c7 44 24 08 1b 00 00     mov    DWORD PTR [esp+0x8],0x1b
 80487b7:    00
 80487b8:    c7 44 24 04 14 8c 04     mov    DWORD PTR [esp+0x4],0x8048c14
 80487bf:    08
 80487c0:    8b 45 d0                 mov    eax,DWORD PTR [ebp-0x30]
 80487c3:    89 04 24                 mov    DWORD PTR [esp],eax
 80487c6:    e8 c1 fd ff ff           call   804858c <write@plt>

:CANARY TEST. If the canary value in EBP-0x4 has changed, then call __stack_chk_fail.
 80487cb:    8b 45 fc                 mov    eax,DWORD PTR [ebp-0x4]
 80487ce:    65 33 05 14 00 00 00     xor    eax,DWORD PTR gs:0x14
 80487d5:    74 05                    je     80487dc <get_reply+0x68>
 80487d7:    e8 80 fe ff ff           call   804865c <__stack_chk_fail@plt>
:ELSE exit the function as normal.
 80487dc:    c9                       leave
 80487dd:    c3                       ret

080487de <main>:
:FUNCTION PROLOGUE
 80487de:    55                       push   ebp
 80487df:    89 e5                    mov    ebp,esp
 80487e1:    81 ec 58 02 00 00        sub    esp,0x258

:ARGUMENTS main(int argc, char* argv[])
 80487e7:    8b 45 08                 mov    eax,DWORD PTR [ebp+0x8]
 80487ea:    89 85 c4 fd ff ff        mov    DWORD PTR [ebp-0x23c],eax
 80487f0:    8b 45 0c                 mov    eax,DWORD PTR [ebp+0xc]
 80487f3:    89 85 c0 fd ff ff        mov    DWORD PTR [ebp-0x240],eax
 80487f9:    8b 45 10                 mov    eax,DWORD PTR [ebp+0x10]
 80487fc:    89 85 bc fd ff ff        mov    DWORD PTR [ebp-0x244],eax

:CANARY A canary at EBP-0x4 gets set to a doubleword from gs:0x14
 8048802:    65 a1 14 00 00 00        mov    eax,gs:0x14
 8048808:    89 45 fc                 mov    DWORD PTR [ebp-0x4],eax

 804880b:    31 c0                    xor    eax,eax

:VARIABLE int optval = 1;
 804880d:    c7 85 d0 fd ff ff 01     mov    DWORD PTR [ebp-0x230],0x1
 8048814:    00 00 00

:SYSTEM CALL int s = socket(PF_UNIX, SOCK_STREAM, 0);
 8048817:    c7 85 cc fd ff ff 10     mov    DWORD PTR [ebp-0x234],0x10
 804881e:    00 00 00
 8048821:    c7 44 24 08 00 00 00     mov    DWORD PTR [esp+0x8],0x0
 8048828:    00
 8048829:    c7 44 24 04 01 00 00     mov    DWORD PTR [esp+0x4],0x1
 8048830:    00
 8048831:    c7 04 24 02 00 00 00     mov    DWORD PTR [esp],0x2
 8048838:    e8 cf fd ff ff           call   804860c <socket@plt>
 804883d:    89 85 d8 fd ff ff        mov    DWORD PTR [ebp-0x228],eax
 8048843:    83 bd d8 fd ff ff 00     cmp    DWORD PTR [ebp-0x228],0x0
 804884a:    79 1b                    jns    8048867 <main+0x89>
 804884c:    c7 04 24 30 8c 04 08     mov    DWORD PTR [esp],0x8048c30
 8048853:    e8 94 fd ff ff           call   80485ec <perror@plt>
 8048858:    e8 0f fd ff ff           call   804856c <__errno_location@plt>
 804885d:    8b 00                    mov    eax,DWORD PTR [eax]
 804885f:    89 04 24                 mov    DWORD PTR [esp],eax
 8048862:    e8 45 fe ff ff           call   80486ac <exit@plt>

:SYSTEM CALL setsockopt(s, 1, SO_REUSEADDR, *optval, 4);
 8048867:    c7 44 24 10 04 00 00     mov    DWORD PTR [esp+0x10],0x4
 804886e:    00
 804886f:    8d 85 d0 fd ff ff        lea    eax,[ebp-0x230]
 8048875:    89 44 24 0c              mov    DWORD PTR [esp+0xc],eax
 8048879:    c7 44 24 08 02 00 00     mov    DWORD PTR [esp+0x8],0x2
 8048880:    00
 8048881:    c7 44 24 04 01 00 00     mov    DWORD PTR [esp+0x4],0x1
 8048888:    00
 8048889:    8b 85 d8 fd ff ff        mov    eax,DWORD PTR [ebp-0x228]
 804888f:    89 04 24                 mov    DWORD PTR [esp],eax
 8048892:    e8 f5 fd ff ff           call   804868c <setsockopt@plt>
 8048897:    85 c0                    test   eax,eax
 8048899:    79 1b                    jns    80488b6 <main+0xd8>
 804889b:    c7 04 24 37 8c 04 08     mov    DWORD PTR [esp],0x8048c37
 80488a2:    e8 45 fd ff ff           call   80485ec <perror@plt>
 80488a7:    e8 c0 fc ff ff           call   804856c <__errno_location@plt>
 80488ac:    8b 00                    mov    eax,DWORD PTR [eax]
 80488ae:    89 04 24                 mov    DWORD PTR [esp],eax
 80488b1:    e8 f6 fd ff ff           call   80486ac <exit@plt>

:VARIABLE struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(3333);
address.sin_addr = 0;
:SYSTEM CALL memset(*sockaddr_in+8, 0x00, 8); // i.e. fill last 8 bytes of struct with zeros.
 80488b6:    66 c7 85 dc fd ff ff     mov    WORD PTR [ebp-0x224],0x2
 80488bd:    02 00
 80488bf:    c7 04 24 05 0d 00 00     mov    DWORD PTR [esp],0xd05
 80488c6:    e8 01 fd ff ff           call   80485cc <htons@plt>
 80488cb:    66 89 85 de fd ff ff     mov    WORD PTR [ebp-0x222],ax
 80488d2:    c7 85 e0 fd ff ff 00     mov    DWORD PTR [ebp-0x220],0x0
 80488d9:    00 00 00
 80488dc:    c7 44 24 08 08 00 00     mov    DWORD PTR [esp+0x8],0x8
 80488e3:    00
 80488e4:    c7 44 24 04 00 00 00     mov    DWORD PTR [esp+0x4],0x0
 80488eb:    00
 80488ec:    8d 85 dc fd ff ff        lea    eax,[ebp-0x224]
 80488f2:    83 c0 08                 add    eax,0x8
 80488f5:    89 04 24                 mov    DWORD PTR [esp],eax
 80488f8:    e8 af fc ff ff           call   80485ac <memset@plt>

:SYSTEM CALL bind(s, *address, 16);
 80488fd:    8d 85 dc fd ff ff        lea    eax,[ebp-0x224]
 8048903:    c7 44 24 08 10 00 00     mov    DWORD PTR [esp+0x8],0x10
 804890a:    00
 804890b:    89 44 24 04              mov    DWORD PTR [esp+0x4],eax
 804890f:    8b 85 d8 fd ff ff        mov    eax,DWORD PTR [ebp-0x228]
 8048915:    89 04 24                 mov    DWORD PTR [esp],eax
 8048918:    e8 1f fd ff ff           call   804863c <bind@plt>
 804891d:    85 c0                    test   eax,eax
 804891f:    79 1b                    jns    804893c <main+0x15e>
 8048921:    c7 04 24 42 8c 04 08     mov    DWORD PTR [esp],0x8048c42
 8048928:    e8 bf fc ff ff           call   80485ec <perror@plt>
 804892d:    e8 3a fc ff ff           call   804856c <__errno_location@plt>
 8048932:    8b 00                    mov    eax,DWORD PTR [eax]
 8048934:    89 04 24                 mov    DWORD PTR [esp],eax
 8048937:    e8 70 fd ff ff           call   80486ac <exit@plt>

:SYSTEM CALL puts("[+] bind complete");
 804893c:    c7 04 24 47 8c 04 08     mov    DWORD PTR [esp],0x8048c47
 8048943:    e8 24 fd ff ff           call   804866c <puts@plt>

:SYSTEM CALL listen(socket, 14);
 8048948:    c7 44 24 04 14 00 00     mov    DWORD PTR [esp+0x4],0x14
 804894f:    00
 8048950:    8b 85 d8 fd ff ff        mov    eax,DWORD PTR [ebp-0x228]
 8048956:    89 04 24                 mov    DWORD PTR [esp],eax
 8048959:    e8 3e fc ff ff           call   804859c <listen@plt>
 804895e:    85 c0                    test   eax,eax
 8048960:    79 1b                    jns    804897d <main+0x19f>
 8048962:    c7 04 24 59 8c 04 08     mov    DWORD PTR [esp],0x8048c59
 8048969:    e8 7e fc ff ff           call   80485ec <perror@plt>
 804896e:    e8 f9 fb ff ff           call   804856c <__errno_location@plt>
 8048973:    8b 00                    mov    eax,DWORD PTR [eax]
 8048975:    89 04 24                 mov    DWORD PTR [esp],eax
 8048978:    e8 2f fd ff ff           call   80486ac <exit@plt>

:SYSTEM CALL setenv("TMPLOG", "/tmp/log", 1);
 804897d:    c7 44 24 08 01 00 00     mov    DWORD PTR [esp+0x8],0x1
 8048984:    00
 8048985:    c7 44 24 04 60 8c 04     mov    DWORD PTR [esp+0x4],0x8048c60
 804898c:    08
 804898d:    c7 04 24 69 8c 04 08     mov    DWORD PTR [esp],0x8048c69
 8048994:    e8 03 fd ff ff           call   804869c <setenv@plt>

:SYSTEM CALL puts("[+] waiting for connections");
 8048999:    c7 04 24 70 8c 04 08     mov    DWORD PTR [esp],0x8048c70
 80489a0:    e8 c7 fc ff ff           call   804866c <puts@plt>

:SYSTEM CALL puts("[+] logging queries to $TMPLOG");
 80489a5:    c7 04 24 8c 8c 04 08     mov    DWORD PTR [esp],0x8048c8c
 80489ac:    e8 bb fc ff ff           call   804866c <puts@plt>

:LOOP BEGINS
while(true) {
:VARIABLE struct sockaddr_in client;
:VARIABLE int session;
:SYSTEM CALL session = accept(s, *client, 16);
 80489b1:    8d 95 cc fd ff ff        lea    edx,[ebp-0x234]
 80489b7:    8d 85 ec fd ff ff        lea    eax,[ebp-0x214]
 80489bd:    89 54 24 08              mov    DWORD PTR [esp+0x8],edx
 80489c1:    89 44 24 04              mov    DWORD PTR [esp+0x4],eax
 80489c5:    8b 85 d8 fd ff ff        mov    eax,DWORD PTR [ebp-0x228]
 80489cb:    89 04 24                 mov    DWORD PTR [esp],eax
 80489ce:    e8 29 fc ff ff           call   80485fc <accept@plt>
 80489d3:    89 85 d4 fd ff ff        mov    DWORD PTR [ebp-0x22c],eax
 80489d9:    83 bd d4 fd ff ff 00     cmp    DWORD PTR [ebp-0x22c],0x0
 80489e0:    79 1b                    jns    80489fd <main+0x21f>
 80489e2:    c7 04 24 ab 8c 04 08     mov    DWORD PTR [esp],0x8048cab
 80489e9:    e8 fe fb ff ff           call   80485ec <perror@plt>
 80489ee:    e8 79 fb ff ff           call   804856c <__errno_location@plt>
 80489f3:    8b 00                    mov    eax,DWORD PTR [eax]
 80489f5:    89 04 24                 mov    DWORD PTR [esp],eax
 80489f8:    e8 af fc ff ff           call   80486ac <exit@plt>

:SYSTEM CALL puts("[+] got a connection");
 80489fd:    c7 04 24 b2 8c 04 08     mov    DWORD PTR [esp],0x8048cb2
 8048a04:    e8 63 fc ff ff           call   804866c <puts@plt>

:SYSTEM CALL Fork the process.
:IF BEGIN? Only perform following batch if PID is zero?
if (!fork()) {
 8048a09:    e8 6e fc ff ff           call   804867c <fork@plt>
 8048a0e:    85 c0                    test   eax,eax
 8048a10:    0f 85 f8 00 00 00        jne    8048b0e <main+0x330>

:SYSTEM CALL write(session, "[+] hello, my name is sploitablen", 33);
 8048a16:    c7 44 24 08 21 00 00     mov    DWORD PTR [esp+0x8],0x21
 8048a1d:    00
 8048a1e:    c7 44 24 04 c8 8c 04     mov    DWORD PTR [esp+0x4],0x8048cc8
 8048a25:    08
 8048a26:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048a2c:    89 04 24                 mov    DWORD PTR [esp],eax
 8048a2f:    e8 58 fb ff ff           call   804858c <write@plt>

:SYSTEM CALL write(session, "[+] would you like to play a game?n", 35);
 8048a34:    c7 44 24 08 23 00 00     mov    DWORD PTR [esp+0x8],0x23
 8048a3b:    00
 8048a3c:    c7 44 24 04 ec 8c 04     mov    DWORD PTR [esp+0x4],0x8048cec
 8048a43:    08
 8048a44:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048a4a:    89 04 24                 mov    DWORD PTR [esp],eax
 8048a4d:    e8 3a fb ff ff           call   804858c <write@plt>

:SYSTEM CALL write(session, "> ", 2);
 8048a52:    c7 44 24 08 02 00 00     mov    DWORD PTR [esp+0x8],0x2
 8048a59:    00
 8048a5a:    c7 44 24 04 10 8d 04     mov    DWORD PTR [esp+0x4],0x8048d10
 8048a61:    08
 8048a62:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048a68:    89 04 24                 mov    DWORD PTR [esp],eax
 8048a6b:    e8 1c fb ff ff           call   804858c <write@plt>

:VARIABLE char[512] readbuffer;
:SYSTEM CALL memset(readbuffer, 0x00, 512); // Zero the buffer.
 8048a70:    c7 44 24 08 00 02 00     mov    DWORD PTR [esp+0x8],0x200
 8048a77:    00
 8048a78:    c7 44 24 04 00 00 00     mov    DWORD PTR [esp+0x4],0x0
 8048a7f:    00
 8048a80:    8d 85 fc fd ff ff        lea    eax,[ebp-0x204]
 8048a86:    89 04 24                 mov    DWORD PTR [esp],eax
 8048a89:    e8 1e fb ff ff           call   80485ac <memset@plt>

:VARIABLE int readlength;
:SYSTEM CALL readlength = read(session, readbuffer, 512);
 8048a8e:    c7 44 24 08 00 02 00     mov    DWORD PTR [esp+0x8],0x200
 8048a95:    00
 8048a96:    8d 85 fc fd ff ff        lea    eax,[ebp-0x204]
 8048a9c:    89 44 24 04              mov    DWORD PTR [esp+0x4],eax
 8048aa0:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048aa6:    89 04 24                 mov    DWORD PTR [esp],eax
 8048aa9:    e8 2e fb ff ff           call   80485dc <read@plt>

:SYSTEM CALL get_reply(readbuffer, readlength, session);
 8048aae:    89 85 c8 fd ff ff        mov    DWORD PTR [ebp-0x238],eax
 8048ab4:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048aba:    89 44 24 08              mov    DWORD PTR [esp+0x8],eax
 8048abe:    8b 85 c8 fd ff ff        mov    eax,DWORD PTR [ebp-0x238]
 8048ac4:    89 44 24 04              mov    DWORD PTR [esp+0x4],eax
 8048ac8:    8d 85 fc fd ff ff        lea    eax,[ebp-0x204]
 8048ace:    89 04 24                 mov    DWORD PTR [esp],eax
 8048ad1:    e8 9e fc ff ff           call   8048774 <get_reply>

:SYSTEM CALL write(session, "[+] bye!n", 9);
 8048ad6:    c7 44 24 08 09 00 00     mov    DWORD PTR [esp+0x8],0x9
 8048add:    00
 8048ade:    c7 44 24 04 13 8d 04     mov    DWORD PTR [esp+0x4],0x8048d13
 8048ae5:    08
 8048ae6:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048aec:    89 04 24                 mov    DWORD PTR [esp],eax
 8048aef:    e8 98 fa ff ff           call   804858c <write@plt>

:SYSTEM CALL close(session);
 8048af4:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048afa:    89 04 24                 mov    DWORD PTR [esp],eax
 8048afd:    e8 4a fb ff ff           call   804864c <close@plt>

:SYSTEM CALL exit(0); // Return zero. Clean exit.
 8048b02:    c7 04 24 00 00 00 00     mov    DWORD PTR [esp],0x0
 8048b09:    e8 9e fb ff ff           call   80486ac <exit@plt>

:IF ENDS }
:SYSTEM CALL close(session);
 8048b0e:    8b 85 d4 fd ff ff        mov    eax,DWORD PTR [ebp-0x22c]
 8048b14:    89 04 24                 mov    DWORD PTR [esp],eax
 8048b17:    e8 30 fb ff ff           call   804864c <close@plt>

:SYSTEM CALL waitpid(0xffffff, 0x0, 0x1); // Not sure about this.
 8048b1c:    c7 44 24 08 01 00 00     mov    DWORD PTR [esp+0x8],0x1
 8048b23:    00
 8048b24:    c7 44 24 04 00 00 00     mov    DWORD PTR [esp+0x4],0x0
 8048b2b:    00
 8048b2c:    c7 04 24 ff ff ff ff     mov    DWORD PTR [esp],0xffffffff
 8048b33:    e8 f4 fa ff ff           call   804862c <waitpid@plt>
 8048b38:    85 c0                    test   eax,eax
 8048b3a:    7f e0                    jg     8048b1c <main+0x33e>

:LOOP ENDS }
 8048b3c:    e9 70 fe ff ff           jmp    80489b1 <main+0x1d3>

 8048b41:    90                       nop
 8048b42:    90                       nop
 8048b43:    90                       nop
 8048b44:    90                       nop
 8048b45:    90                       nop
 8048b46:    90                       nop
 8048b47:    90                       nop
 8048b48:    90                       nop
 8048b49:    90                       nop
 8048b4a:    90                       nop
 8048b4b:    90                       nop
 8048b4c:    90                       nop
 8048b4d:    90                       nop
 8048b4e:    90                       nop
 8048b4f:    90                       nop

<snip />

Leave a Reply

Your e-mail address will not be published. Required fields are marked *