[Galaxy Note 4 Developer Discussion (Devs., Only)] ZPaul2Fresh8:
Let's get this rolling.

So from a de-compile of libui.so we can see that the function we need to focus our exploit on is located between 0x5cf8 - 0x5e04. It's called 'GraphicBuffer::unflatten'.

Within this function we can cause an integer over flow. Now I'm not an exploit specialist but I'm going to list the Code in both Pseudo and Assembly and maybe we can compare the two and get a good idea of where to throw our hook into.

The Assembly View of the function GraphicBuffer::flatten

; function: android__GraphicBuffer__unflatten at 0x5cf8 -- 0x5e04
0x5cf8: e9 2d 4f f0	stmdb sp0x1 , 0xff0 0x1
0x5cfc: 46 1f	mov r7, r3
0x5cfe: 68 13	ldr r3, [ r2, #0x0 ]
0x5d00: b0 85	sub sp, sp, #0x5
0x5d02: 46 04	mov r4, r0
0x5d04: 46 8a	mov sl, r1
0x5d06: 2b 1f	cmp r3, #0x1f
0x5d08: 46 90	mov r8, r2
0x5d0a: d9 6d	bls 0x5de8 <android__GraphicBuffer__unflatten+0xf0>
0x5d0c: 68 0e	ldr r6, [ r1, #0x0 ]
0x5d0e: 49 39	ldr r1, [ pc, #0x39 ]
0x5d10: 68 32	ldr r2, [ r6, #0x0 ]
0x5d12: 42 8a	cmp r2, r1
0x5d14: d1 66	bne 0x5de4 <android__GraphicBuffer__unflatten+0xec>
0x5d16: f8 d6 b0 1c	ldr.w fp, [ r6, #0x1c ]
0x5d1a: 69 b5	ldr r5, [ r6, #0x6 ]
0x5d1c: f1 0b 02 08	add.w r2, fp, #0x8
0x5d20: ea 4f 09 82	lsl.w r9, r2, #0x2
0x5d24: 45 4b	cmp r3, r9
0x5d26: d3 5f	bcc 0x5de8 <android__GraphicBuffer__unflatten+0xf0>
0x5d28: 6c 43	ldr r3, [ r0, #0x11 ]
0x5d2a: b1 0b	cbz 0x5d30 <android__GraphicBuffer__unflatten+0x38>, 0x5d30 <android__GraphicBuffer__unflatten+0x38>
0x5d2c: f7 ff ff c4	bl 0x5cb8 <android__GraphicBuffer__free_handle>
0x5d30: b9 15	cbnz 0x5d38 <android__GraphicBuffer__unflatten+0x40>, 0x5d38 <android__GraphicBuffer__unflatten+0x40>
0x5d32: f1 bb 0f 00	cmp.w fp, #0x0
0x5d36: d0 22	beq 0x5d7e <android__GraphicBuffer__unflatten+0x86>
0x5d38: 68 70	ldr r0, [ r6, #0x1 ]
0x5d3a: 62 a0	str r0, [ r4, #0xa ]
0x5d3c: 68 b1	ldr r1, [ r6, #0x2 ]
0x5d3e: 62 e1	str r1, [ r4, #0xb ]
0x5d40: 46 59	mov r1, fp
0x5d42: 68 f2	ldr r2, [ r6, #0x3 ]
0x5d44: 63 22	str r2, [ r4, #0xc ]
0x5d46: 69 33	ldr r3, [ r6, #0x4 ]
0x5d48: 63 63	str r3, [ r4, #0xd ]
0x5d4a: 69 70	ldr r0, [ r6, #0x5 ]
0x5d4c: 63 a0	str r0, [ r4, #0xe ]
0x5d4e: 46 28	mov r0, r5
0x5d50: f7 fe ef a4	blx 0x4c9c <native_handle_create>
0x5d54: 68 39	ldr r1, [ r7, #0x0 ]
0x5d56: 00 aa	lsl r2, r5, #0x2
0x5d58: 46 03	mov r3, r0
0x5d5a: f1 00 00 0c	add.w r0, r0, #0xc
0x5d5e: 93 03	str r3, [ sp, #0x3 ]
0x5d60: f7 fe ef 8a	blx 0x4c78 <memcpy>
0x5d64: 99 03	ldr r1, [ sp, #0x3 ]
0x5d66: ea 4f 02 8b	lsl.w r2, fp, #0x2
0x5d6a: eb 01 00 85	add.w r0, r1, r5, lsl #0x2
0x5d6e: f1 06 01 20	add.w r1, r6, #0x20
0x5d72: 30 0c	add r0, #0xc
0x5d74: f7 fe ef 80	blx 0x4c78 <memcpy>
0x5d78: 9a 03	ldr r2, [ sp, #0x3 ]
0x5d7a: 64 62	str r2, [ r4, #0x11 ]
0x5d7c: e0 05	b 0x5d8a <android__GraphicBuffer__unflatten+0x92>
0x5d7e: 63 a5	str r5, [ r4, #0xe ]
0x5d80: 63 65	str r5, [ r4, #0xd ]
0x5d82: 63 25	str r5, [ r4, #0xc ]
0x5d84: 62 e5	str r5, [ r4, #0xb ]
0x5d86: 62 a5	str r5, [ r4, #0xa ]
0x5d88: 64 65	str r5, [ r4, #0x11 ]
0x5d8a: 6c 61	ldr r1, [ r4, #0x11 ]
0x5d8c: 20 01	mov r0, #0x1
0x5d8e: f8 84 00 68	strb .w r0, [ r4, #0x68 ]
0x5d92: b1 89	cbz 0x5db8 <android__GraphicBuffer__unflatten+0xc0>, 0x5db8 <android__GraphicBuffer__unflatten+0xc0>
0x5d94: 6e e0	ldr r0, [ r4, #0x1b ]
0x5d96: f0 00 fc cf	bl 0x6738 <android__GraphicBufferMapper__registerBuffer>
0x5d9a: 46 04	mov r4, r0
0x5d9c: b1 60	cbz 0x5db8 <android__GraphicBuffer__unflatten+0xc0>, 0x5db8 <android__GraphicBuffer__unflatten+0xc0>
0x5d9e: 42 40	rsb r0, r0
0x5da0: f7 fe ee e0	blx 0x4b64 <strerror>
0x5da4: 49 15	ldr r1, [ pc, #0x15 ]
0x5da6: 4a 16	ldr r2, [ pc, #0x16 ]
0x5da8: 94 00	str r4, [ sp, #0x0 ]
0x5daa: 44 79	add r1, pc
0x5dac: 44 7a	add r2, pc
0x5dae: 46 03	mov r3, r0
0x5db0: 20 06	mov r0, #0x6
0x5db2: f7 fe ee d2	blx 0x4b5a <__android_log_print>
0x5db6: e0 19	b 0x5dec <android__GraphicBuffer__unflatten+0xf4>
0x5db8: f8 da 40 00	ldr.w r4, [ sl, #0x0 ]
0x5dbc: eb 04 03 89	add.w r3, r4, r9, lsl #0x2
0x5dc0: f8 ca 30 00	str .w r3, [ sl, #0x0 ]
0x5dc4: f8 d8 10 00	ldr.w r1, [ r8, #0x0 ]
0x5dc8: eb c9 02 01	rsb.w r2, r9, r1, lsl #0x0
0x5dcc: 99 0e	ldr r1, [ sp, #0xe ]
0x5dce: f8 c8 20 00	str .w r2, [ r8, #0x0 ]
0x5dd2: 68 38	ldr r0, [ r7, #0x0 ]
0x5dd4: eb 00 04 85	add.w r4, r0, r5, lsl #0x2
0x5dd8: 60 3c	str r4, [ r7, #0x0 ]
0x5dda: 68 0b	ldr r3, [ r1, #0x0 ]
0x5ddc: 24 00	mov r4, #0x0
0x5dde: 1b 5d	sub r5, r3, r5
0x5de0: 60 0d	str r5, [ r1, #0x0 ]
0x5de2: e0 03	b 0x5dec <android__GraphicBuffer__unflatten+0xf4>
0x5de4: 4c 04	ldr r4, [ pc, #0x4 ]
0x5de6: e0 01	b 0x5dec <android__GraphicBuffer__unflatten+0xf4>
0x5de8: f0 6f 04 0b	mvn.w r4, #0xb
0x5dec: 46 20	mov r0, r4
0x5dee: b0 05	add sp, sp, #0x5
0x5df0: e8 bd 8f f0	ldm.w sp0x1 , 0xff0 0x0 0x1
0x5df4: 46 52	mov r2, sl
0x5df6: 47 42
0x5df8: 00 01	lsl r1, r0, #0x0
0x5dfa: 80 00	strh r0, [ r0, #0x0 ]
0x5dfc: 27 ae	mov r7, #0xae
0x5dfe: 00 00	lsl r0, r0, #0x0
0x5e00: 27 f6	mov r7, #0xf6
0x5e02: 00 00	lsl r0, r0, #0x0

Pseudo version (Edited to reflect the exploitable pre-patched version) of GraphicBuffer::flatten

status_t GraphicBuffer::unflatten(
void const*& buffer, size_t& size, int const*& fds, size_t& count) {
if (size < 8*sizeof(int)) return NO_MEMORY;
int const* buf = static_cast<int const*>(buffer);
if (buf[0] != 'GBFR') return BAD_TYPE;
const size_t numFds = buf[8];
const size_t numInts = buf[9];
const size_t sizeNeeded = (10 + numInts) * sizeof(int);

if (size < sizeNeeded) return NO_MEMORY;
- size_t fdCountNeeded = 0;
if (count < fdCountNeeded) return NO_MEMORY;
if (handle) {
// free previous handle if any
free_handle();
}
if (numFds || numInts) {
width = buf[1];
height = buf[2];
stride = buf[3];
format = buf[4];
usage = buf[5];
native_handle* h = native_handle_create(numFds, numInts);

memcpy(h->data, fds, numFds*sizeof(int));
memcpy(h->data + numFds, &buf[10], numInts*sizeof(int));
handle = h;
} else {
width = height = stride = format = usage = 0;
handle = NULL;
}
mId = static_cast<uint64_t>(buf[6]) << 32;
mId |= static_cast<uint32_t>(buf[7]);
mOwner = ownHandle;
if (handle != 0) {
status_t err = mBufferMapper.registerBuffer(handle);
if (err != NO_ERROR) {
width = height = stride = format = usage = 0;
handle = NULL;
ALOGE("unflatten: registerBuffer failed: %s (%d)",
strerror(-err), err);
return err;
}
}
buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded);
size -= sizeNeeded;
fds += numFds;
count -= numFds;
return NO_ERROR;
}
// ---------------------------------------------------------------------------
}; // namespace android

I'm using this as learning experience so if anyone sees a mistake please let me know and maybe others can benefit. Possibly next is how-to trigger this Integer overflow via APK to corrupt memory. Is there a way to 'sticky' replies in ONE thread rather than having to sift through all the non-sense?