标签归档:android

关于内核系统调用的hooks问题

关于内核系统调用的hooks问题
转载请注明出处 [ By selinux.com]SELinux+
代码地址:https://github.com/qfong/mkm
截获系统调用的常用的方法通过sys_call_table的方法,如:
注册hooks函数:

unhooks函数

注册hooks函数,但系统必须导出sys_call_table内核符合,但在2.6内核和部分2.4的内核系统中,sys_call_table不再导出,但可以在内存中找到它。

下面给出的方法是基于通过搜索代码块指针为SYS_CLOSE,寻找一个特定的内存模式,用于发现sys_call_table的指针地址,然后依靠的地址表的前6个字到该地址。这是在x86系统以及一招,但一向被认为是不稳定和不太可靠。如下面的代码:

但也有一些依靠sys_call的中断处理程序地址中断描述符表,中断陷入点为0×80。然后一个搜索sys_call_table指针地址的处理程序,用于查找需要跳转到的确切sys_call中断处理。

ARM Linux上的系统,没有IDT(Interrupt Descriptor Table),而是软件中断(SWI)处理程序所在LDR指向的地址0×00000008,或在0xFFFF0008或高向量实现(high-vector implementations)如Android。按照地址,查找并加载其系统调用表。

下面是一些其他获得调用表的方法:
X86平台上

X86_64平台上

ia32平台

ARM

关于写保护
由于内核的页标记为只读,尝试用函数去写这个区域的内存,会产生一个内核oops。这种保护可以很简单的被规避,但通过设置cr0寄存器的WP位为0,禁止写保护CPU上。控制寄存器维基百科的文章 证实了这一点属性:

位 名称 全名 说明
16 WP 写保护 确定CPU是否可以写入页面标记为只读
WP位将需要在代码中的多个点的设置和重置,所以它使抽象的操作纲领性意义。下面的代码来源于PAX项目(http://pax.grsecurity.net/),专门从native_pax_open_kernel()和native_pax_close_kernel()例程。采取格外谨慎,以防止潜在的竞争条件引起由倒霉的调度在SMP系统,由丹•罗森伯格在一篇博客文章中(http://vulnfactory.org/blog/2011/08/12/wp-safe-or-not/)解释:
As described in the Intel Manuals (Volume 3A, Section 2.5):

Code如下:

也可以通过以下代码来实现

在一些ARM中,WP位的概念不存在,必须采取特殊照顾,而在ARM中引入了指令缓存架构来处理数据。虽然数据和指令高速缓存的概念也存在x86和x86_64硬件架构的,这样的功能没有在发展过程中构成障碍。在Android里面,可以不需要对内存保护机制进行考虑。

实现代码地址:https://github.com/qfong/mkm
附文档: 丹•罗森伯格在一篇博客文章
WP: Safe or Not?

During the course of kernel exploitation (or some other form of runtime kernel modification), it is frequently desirable to be able to modify the contents of read-only memory. On x86, a classic trick is to leverage the WP (write-protect) bit in the CR0 register.

As described in the Intel Manuals (Volume 3A, Section 2.5):

WP Write Protect (bit 16 of CR0) – When set, inhibits supervisor-level proce-
dures from writing into read-only pages; when clear, allows supervisor-level
procedures to write into read-only pages (regardless of the U/S bit setting;
see Section 4.1.3 and Section 4.6). This flag facilitates implementation of the
copy-on-write method of creating a new process (forking) used by operating
systems such as UNIX.
In an exploit where code execution has been achieved and the attacker wishes to, for example, install hooks in a read-only data structure, a simple solution is to toggle this bit to 0, perform the write, and toggle it back. This technique has been well-known for years, and is not only used in rootkits but also in commercial anti-virus products (is there a difference?).

In practice, this approach works nearly all of the time. But there are some caveats to be aware of when using this trick in exploit development.

Scheduling Race

On SMP systems, there is a scheduling race that must be dealt with. In extremely unlucky circumstances, it’s possible that the current thread disables the WP bit, is scheduled out at a precise moment, is re-scheduled onto a CPU that still has the WP bit enabled, and faults when attempting to perform a write to read-only memory. Even though I’ve never seen this happen in practice, it’s easy enough to contend with. If this is being done via some mechanism where you have the capability to compile against the current kernel (e.g. a module), one correct way of addressing this is to disable preemption of the current thread while performing writes to read-only pages, as the PaX project does:

static inline unsigned long native_pax_open_kernel(void)
{
unsigned long cr0;

preempt_disable();
barrier();
cr0 = read_cr0() ^ X86_CR0_WP;
BUG_ON(unlikely(cr0 & X86_CR0_WP));
write_cr0(cr0);
return cr0 ^ X86_CR0_WP;
}

static inline unsigned long native_pax_close_kernel(void)
{
unsigned long cr0;

cr0 = read_cr0() ^ X86_CR0_WP;
BUG_ON(unlikely(!(cr0 & X86_CR0_WP)));
write_cr0(cr0);
barrier();
preempt_enable_no_resched();
return cr0 ^ X86_CR0_WP;
}
These two functions, pax_open_kernel() and pax_close_kernel(), are used to modify structures such as the IDT when the PAX_KERNEXEC feature is enabled.

If you’re performing these modifications in an exploit, a simpler solution is to leverage the cli (clear interrupt flag) and sti (set interrupt flag) instructions to disable interrupts entirely during the course of the writes, which prevents re-scheduling as a side effect:

.macro disable_wp
cli
mov eax,cr0
and eax,0xfffeffff
mov cr0,eax
.endm

.macro enable_wp
mov eax,cr0
or eax,0×10000
mov cr0,eax
sti
.endm
Xen

The scheduling issue can easily be worked around, but twiz mentioned to me that there may be problems doing this on Xen. When not using HAP (hardware-assisted paging), Xen handles paging by creating shadow page tables, mapping the guest’s page tables read-only, and relying on WP to cause writes to guest page tables to trap and be handled properly by the hypervisor. As a result, CR0.WP was forcibly enabled in the past. This did not apply when using HAP, where the guest has always been able to freely access CR0.

However, in 2007, Xen added support for emulating the behavior of CR0.WP in order to support software that relies on WP modification (e.g. anti-virus). When the guest faults on a non-user write to a resident page while CR0.WP=0, the faulting instruction is then emulated to allow the write to succeed. This feature is limited by the completeness of the x86 emulator, but everything except the most esoteric instructions should be emulated properly. As a result, leveraging the WP bit to write to read-only memory on Xen should not pose any problems for exploit developers.

Thanks

Thanks to twiz for suggesting looking at Xen, and Keir Fraser for helpful information.

samsung smdk4412 kernel 编译

01, Getting the kernel source android-kernel-samsung-dev.tar.gz

转载请注明出处[By SELinux+]

We can find arm-gcc in framework /prebuilt/linux-x86/toolchain/arm-eabi-*

02, extract kernel source and arm-gcc

03, Set environment:

04, goto kernel source folder:

05, When done, you can find kernel “zImage” in ./arch/arm/boot

[root@fc16 smdk4412]# make mrproper

编译时候注意CROSS_COMPILE版本问题