ARM64 hooking: insert a jump in memory - android

I'm trying to hook on a 64 bit ARM Android device the SSL_do_handshake function available in libssl.so, until now I have:
address of libssl.so (found in proc//maps)
offset of SSL_do_handshake(found in libssl.so)
absolute address of SSL_do_handshake (address_of_libssl + offset_of_SSL_do_handshake)
What I'm doing is save the instructions at absolute address of libssl.so (for recovery) and overwrite them with my instructions (for jump):
LDR X9,#8
Br X9
address for jump 7f75a5b890
In detail what I'm saving in memory is 49000058 20011fd6 90b8a5757f if I look in memory after the overwriting I found my instructions and the address. If I try to execute it and call SSL_do_hanshake I have a crash before the jump.
I did the same for ARMv7 using thumb32 with the same approach but different instructions:
ldr pc [pc,#0]
address for jump (f36e240d)
In memory dff800f0 0d246ef3 and it works.
Any idea of what I'm doing wrong?

Related

Why ART need Relocate?

ART relocate the boot.art & boot.oat under /system/framework/arm/ to /data/dalvik-cache/arm/ by default.
Why the art likes to use the cached one rather than the system one?
Why not just use the boot image under /system?
I guess, in Android L & M, the boot.art and boot.oat use the absolute address to load boot.art & boot.oat. But, sometime, ART can't load them at special base address, so, ART load them by another base address. Therefore ART must relocate the address of classes in boot.art.
See the code: ./runtime/gc/space/image_space.cc RelocateImage
std::string base_offset_arg("--base-offset-delta=");
StringAppendF(&base_offset_arg, "%d", hooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, ART_BASE_ADDRESS_MAX_DELTA));
the base-offset-delta is used to calculate the new address of classes in boot.art.

Getting a physical address from an allocated buf in a module without using virt_to_phys macro

I am trying to write a android arm kernel module in which I need to use a virt_to_phys translation of a memory var allocated using _kmalloc.
I do know that I can use the macro virt_to_physc to do this task. However, I dont have the specifically full kernel source, and beacuse virt_to_physc is a macro
I can't get a function address reading kallsyms to use in my module , so I would like to find another way to do this task.
I've been trying to do it using MMU (registers ATS1Cxx and PAR) to perform V=>P as Iam working in an ARMv7 proccessor but I couldnt make it work.
That's my test code...
int hello_init_module(void) {
printk("Virtual MEM:0x%X \n", allocated_buf);
//Trying to get the physc mem
asm("\t mcr p15, 0, %[value], c7, c8, 2\n"
"\t isb\n"
\t mrc p15, 0, %[result], c7, c4, 0\n" : [result]"=r" (pa) : [value]"r" (allocated_buf));
printk("Physical using MMU : %x\n", pa );
//This show the right address, but I wanna do it without calling the macro.
printk("Physical using virt_2_physc: 0x%X",virt_to_phys((int *) allocated_buf);)
}
What Iam actually doing is developing a module that is intended to work in two devices with the same 3.4.10 kernel but different memory arquitectures,
I can make the module works as they have the same VER_MAGIC and functions crc, so the module load perfectly in both devices.
The main problem is that because of diferences in their arquitecture, PAGE_OFFSET and PHYS_OFFSET actually change in both of them.
So, I've wondering if there is a way to make the translation without define this values as constant in my module.That's what I tried using MMU to perform V=>P , but MMU hasnt worked in my case, it always returns 0x1F.
According to cat /proc/cpuinfo . Iam working with a
Processor : ARMv7 Processor rev 0 (v7l)
processor : 0
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls
CPU implementer : 0x51
CPU architecture: 7
If it's not possible to do it using MMU as alternative way of using virt_to_phys.
Does somebody know other way to do it?

Arm Instructions [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i wanted to ask what is happening in arm instruction here. I have knowledge of ASM but i am having hard time understanding ARM. I try to look up the info on the internet that gives the basics but the thing i am looking at is a little different. So here is a code i am trying to understand.. Can you please explain what these instructions are doing. I will mark the ones i dont understand. Its a code from IDA. Can someone please explain the entire function. i will really be grateful. Thanks
LDR R3, =(unk_E9BFB0 - 0x6B1B4C) //This once,i dont get it, is it subtracting?
LDR R8, [R5]
MOV R1, R6
ADD R3, PC, R3
LDR LR, [R4,#0xC] //This instruction
LDR R12, =(aDraw_debug - 0x6B1B68) //This once
MOV R2, R7
STR R8, [R3,#0x30]
MOV R0, R3
STR R4, [R3]
ADD R12, PC, R12 ; "draw_debug" //This once
STR R3, [R5]
STR R12, [R3,#0x2C]
ADD R12, LR, #1
STR R12, [R4,#0xC]
BL __aeabi_atexit
LDR is the instruction on ARM to load a register with a value from memory. The following, however, are the pseudoinstruction form of LDR:
LDR R3, =(unk_E9BFB0 - 0x6B1B4C) //This once,i dont get it, is it subtracting?
LDR R12, =(aDraw_debug - 0x6B1B68) //This once
I believe it is constructing an offset from a code location to pull data out of the .text section. aDraw_debug - 0x6B1B68, for example, is likely taking the address of label aDraw_debug, and subtracting the location of some instruction, 0x6B1B68.
The end result is that this essentially will load the offset of aDraw_debug (from an arbitrary point) into R12. Likewise, the other instruction will load unk_E9BFB0 into R3. That one is probably compiler-generated data because of the mangled name.
The other LDR instruction:
LDR LR, [R4,#0xC] //This instruction
are a straightforward affair. LDR is still being used to load a register from memory, but the addressing is different. In this case, LR, the link register, is being loaded with the data at address R4 + 0xC in memory.
The ADD is straightforward as well, and I'm not sure if your were confused as to what it was doing but:
ADD R12, PC, R12 ; "draw_debug" //This once
this simply adds PC + R12 and stores it in R12 without updating the processor flags. This takes the offset determined earlier and applies it to the current PC.
Overall, it looks like this is code to store values into some sort of struct or class. The compiler chose to do PC-relative addressing, but the offset is likely outside of the usable range for the instruction. PC-relative LDR/STR instructions can only address +/- 4096 from PC.
The ldr reg,=something is a shortcut. The arm is a mostly fixed length instruction set or lets say there are not enough bits to allow for any possible immediate value. Also this shortcut allows you to use labels, load the address of some label into this register. What the assembler does with this is when it generates the machine code it allocates a word location somewhere not too far away that is not in the execution path (after an unconditional branch or bx for example). Then for the ldr reg,= instruction it encodes a pc relative instruction ldr reg,[pc,+offset] to load that value into the register. This allows for any 32 bit value to be loaded, no restrictions. It also allows for labels to be used where the data value (address) is filled in later by the linker. Your example takes that one further and does math on a label, so the assembler or linker will have to resolve the label, do the math, then put that value in the word location.
ARM.COM Arm instruction Set
Info Center of ARM.com - Quick Reference Cards for ARM instruction set
Doc for ARM instruction set
Indexed for each instruction web page
Arm-instructionset
Embedded Systems Architecture: The ARM Instruction Set Architecture by Mark McDermott With help from ourgood friends at ARM

PC and LR in same function in Android Kernel

I am facing a problem in which the PC1 and LR2 both are pointing with in the function cpuacct_charge() in the kernel's sched.c. Are there any scenario's in which this might happen? My analysis shows no recursion in the cpuacct_charge() function. I cannot provide the code. However, any scenario's when this happens would be a big help.
For Clarification : The value of PC and LR points to a different locations in function:
void cpuacct_charge(struct task_struct *tsk, u64 cputime)
Note 1: PC - Program Counter
Note 2: LR - Link Register
When a function returns it basically does a branch to the address in the link register.
So, presumably you've paused the program right after a function return.

No refrence for instructions strneh, lsreq, streqb

I was looking at strcpy.S file in android platform at path libc/arch-arm/bionic, in this file there are many arm instructions which i am not able to understand, i am also referring ARM System Developers Guide.
Here except "tst" and "tstne" i am not able to find any refrence for others in any book or ARM refrence manual.
tst r2, #0xff00
iteet ne
strneh r2, [ip], #2
lsreq r2, r2, #8
r2, [ip]
tstne r2, #0xff
Not only these instructions there are many others in different files also.
Does anyone have any idea what these instructions are ?
The first instructions it the it-instruction from the thumb instructions set.
iteet ne
This instruction marks the next three instructions to be conditional executable. The last three characters of the instruction make a pattern consisting of e (else) or t (then). The operand 'ne' specifies the condition to be evaluated.
The other three instructions are ordinary ARM instructions with conditionals:
strneh r2, [ip], #2 ; store halfword if not equal
lsreq r2, r2, #8 ; logical shift right if equal
tstne r2, #0xff ; test if not equal
These are the three instructions affected by the it-instruction. They come with ne/eq conditional flags as well.
As you can see the conditions of the it-instructions and the conditions of the other three instructions are in conflict to each other. This is a bug in the code. Most likely it hasn't been discovered before because the code-snippet is from the ARM-big-endian code, and I know of no android phone that uses ARM in big endian.
Btw, it's worthwhile to know why the conditions are given in the it-instruction and in the instructions itself. This is part of the unified arm assembly standard. On the ARM you have two modes of operation: Thumb mode (uses It-instruction, less powerful) and ARM-mode (more powerful, uses condition-flags in the instructions itself).
If you limit yourself to the capabilities of the thumb-mode it is possible to write code that would compile in thumb and ARM-mode. This is done here.
If you assemble for Thumb-mode the It-instruction will be used to control the conditions of the next three instruction, and the conditions within the instructions gets ignored. If you assemble to ARM-instruction set the It-instruction gets ignored and the conditions from the instruction itself will become active.
This works well as long as the it-instruction and the conditions in the arm-instructions match. As I said before this is not the case here, so it will either not work in thumb-mode, arm-mode or both :-)
strneh is a store command with some conditional execution/size specifier suffixes. The ARM docs are a good place to start: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/Chdehgih.html
If you google "arm conditional execution", you'll find a number of blogs/articles that may also help: http://blogs.arm.com/software-enablement/258-condition-codes-2-conditional-execution/
As for your *strneh" instruction:
str = store
ne = execute if not equal (Z flag clear)
h = perform a half-word operation

Categories

Resources