Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

int80h vs syscall

Name: Anonymous 2010-05-15 12:28

Why does int 80h only work with certain code on x86_64 Linux?
for example:

section .bss
  arg    resq

section .text
  global _start

_start:
  ; code here to fill arg with argv[1]
  mov rax,1
  mov rdi,2
  mov rsi,[arg]
  mov rdx,[arglen]
  syscall


is fine, but

section .bss
  arg    resq

section .text
  global _start

_start:
  ; code here to fill arg with argv[1]
  mov rax,4
  mov rbx,2
  mov rcx,[arg]
  mov rdx,[arglen]
  int 80h

doesn't work with pointers copied from bss, if that's even relevant
rax is filled with 0xfffffffffffffff2, aka -14.

Name: Anonymous 2010-05-15 12:52

because you touch yourself at night

Name: Anonymous 2010-05-15 13:08

Because those are OS internals subject to change.
In Windows NT, we used to use int 2Eh, but it was later changed to sysenter. Of course, to retain backwards compatibility, each way to do a syscall was exported as a symbol (undocumented) from NTDLL:

7C90EB8B KiFastSystemCall                        8BD4            MOV EDX,ESP
7C90EB8D                                         0F34            SYSENTER
7C90EB8F                                         90              NOP
7C90EB90                                         90              NOP
7C90EB91                                         90              NOP
7C90EB92                                         90              NOP
7C90EB93                                         90              NOP
7C90EB94 KiFastSystemCallRet                     C3              RETN
7C90EB95                                         8DA424 00000000 LEA ESP,DWORD PTR SS:[ESP]
7C90EB9C                                         8D6424 00       LEA ESP,DWORD PTR SS:[ESP]
7C90EBA0                                         90              NOP
7C90EBA1                                         90              NOP
7C90EBA2                                         90              NOP
7C90EBA3                                         90              NOP
7C90EBA4                                         90              NOP
7C90EBA5 KiIntSystemCall                         8D5424 08       LEA EDX,DWORD PTR SS:[ESP+8]
7C90EBA9                                         CD 2E           INT 2E
7C90EBAB                                         C3              RETN


Each actual syscall being performed like:

mov eax, ssdt_vector_index ; syscall number
call [&ntdll.KiFastSystemCall]
retn XX

The old interrupt dispatcher is still supported on NT.

The reason sysenter is recommended instead of int ** is for efficiency reasons. You usually perform a lot of these calls during an application's lifetime and the ring3->ring0->ring3 switches are costly too. sysenter is more lightweight.

While I'm not as familiar with linux's syscall mechanism, maybe they decided not to retain backwards compatibility, or at least backwards compatibility isn't enabled in your linux kernel build?

Name: Anonymous 2010-05-15 18:43

>>1
Because every x86_64 CPU supports SYSCALL, Linux doesn't support int 80h except for compatibility with 32-bit programs (CONFIG_IA32_EMULATION).

Unrelatedly, I came across http://pastebin.com/HkhaA7Z2 while trying to find an authorative source (which only seems exists as code).

Name: Anonymous 2010-05-15 18:50

>>4

that is ultrashit

Name: Anonymous 2010-05-15 18:54

>>5
That's a troll. It sends some random shit to a chosen remote target. It's not even a valid HTTP request. The shellcode is supposed to shut down the remote box, though of course it won't work. Now the confirmation of the troll is that, the first part is a remote exploit, while the second one is a "local exploit", well, confirmation of the troll:



...
#define getshell initshell(r,i,f,n,p,t)
...
#define initshell(a,b,c,d,e,f) e##a##b##d##f##c
...
// You should see that getshell is the same as printf if you know the basics of C macros.

   if(exploit(argv[1], atoi(argv[2])) == 1){
      printf("\n[+] Successfully exploited!\n");
         printf("[+] Spawning shell....\n");
         sleep(2);
         getshell("\x5b\x2b\x5d\x20\x41\x70\x72\x69\x6c\x20\x66\x6f\x6f\x6c\x73\x2c\x20\x6d\x6f\x74\x68\x65\x72\x66\x75\x63\x6b\x65\x72\x2e");
// that's the same as printf("[+] April fools, motherfucker.");
// or YHBT
         printf("\n");
         setgid(0); setuid(0);
         execl("/bin/sh","sh",0);
   }

Name: Anonymous 2010-05-15 22:39

>>3
NOP NOP NOP NOP NPO
Oh god. They're not even aligning anything!

Name: Anonymous 2010-05-15 23:03

>>8
Those nops ar for alignment (mod4), look more carefully.
Notice that there's 2 exports?  KiFastSystemCall and KiFastSystemCallRet. Originally, I was confused about the nops too, but if you think about it, it makes perfect sense:
KiFastSystemCall is what you call from user mode and the kernel-mode handler returns/sets eip to KiFastSystemCallRet upon exiting the handler and returning to user mode. The nops are ther efor alignment, as all functions are aligned mod 4(can be a different value depending on options passed to the cl/link). The nops indicate that it was built in Release mode instead of Debug mode(if it was debug mode, you'd get 0xCC(int3)'s instead of nop(0x90)'s).

Those nops were slightly misleading when I first encountered them, as I used to step over the sysenter in a debugger which made the app continue. What I should have done is set a breakpoint on the return instead, or better yet, step over the call to KiFastSystemCall.

If one views the 2 exports as separate functions that they are, everything makes sense. KiFastSystemCall is a __naked function which probably looks something like:

DWORD __declspec(naked) __stdcall KiFastSystemCall(...)
{
     __asm
     {
          mov edx,esp
          sysenter
     }
}

Name: Anonymous 2010-05-16 12:12

Yeah, that's probably right, I have IA32 emulation in my kernel config. Ty for the help proglodykes.

Now I'm done, I hand this thread over to HMA memesmith and pals, unless anyone can think of interesting asm to discuss.

Name: Anonymous 2010-07-23 11:55

>>9
Mod 4 plus 1, more like. Note that the second string of nops puts the next instruction at 7C90EBA5.

Don't change these.
Name: Email:
Entire Thread Thread List