我想在Android 4.0.3。上始终将共享库加载到相同的地址。

我似乎无法使用以下方式禁用ASLR:

echo 0 > /proc/sys/kernel/randomize_va_space


正在运行

cat /proc/sys/kernel/randomize_va_space


确实显示为0,但是在启动应用程序后,共享库始终(仍)加载到其他地址。 >
编辑:

启动使用命令加载共享对象的活动时出现上述行为

尝试使用C语言编写的小型本机进程,通过

am start -n <activity>




echo 0 > /proc/sys/kernel/randomize_va_space


我已经使用android-ndk-r7c工具链arm-linux-androideabi-4.4.3编译了应用程序,没有任何特殊的编译器开关(例如-fPIE或-pie)。 >
我也尝试过类似此处所述的操作,但是共享库仍会加载到其他地址-我猜p er-process ASLR无法在Android上禁用。

由于缺少SYS_personality,我无法从util-linux交叉编译setarch.c。

EDIT2:

进一步的调查取得了部分成功。这就是我所做的,结果是,通过“ am start -n”启动的应用程序在大多数两个不同的地址上加载共享库:


使用其中一种方法,
杀死“ / system / bin / servicemanager”进程(杀死-9 PID)-这也应降低合子和完整的UI,
等待servicemanager,合子和UI重新启动-init.rc处理此问题,
尝试启动/杀死/启动我的应用程序

20次以上的启动和终止序列后,我的应用程序始终将共享库加载到一个或另一个内存地址上。怎么来的?不知道!

但是,这应该可以极大地帮助调试共享库,因为共享库通常连续几次在一个地址上加载,然后在接下来的两次加载在另一个地址上,并晒到第一个地址。

评论

您是否尝试过:sysctl -w kernel.randomize_va_space = 0?

@perror:这实际上与问题中给出的回显线相同。

不完全是因为永久禁用了ASLR。但是,我同意。效果应该相同。

@perror是的,我有。效果是相同的-cat / proc / sys / kernel / randomize_va_space显示为sysctl kernel.randomize_va_space显示值为0,但共享库仍加载在其他地址。

乔恩·奥伯海德(Jon Oberheide)的“ Android Ice Cream Sandwich 4.0”中的ASLR或许会有所帮助。

#1 楼

实际上,ASLR是依赖于体系结构的。我没有设法从Android那里获得资源,但是我研究了Linux内核的各种ARM实现。

在ARM64中,我发现了ASLR的一个完全有效的实现(在arch/arm64/kernel/process.c中):似乎根本不会触发ASLR,除了:

unsigned long arch_align_stack(unsigned long sp)
{
  if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
     sp -= get_random_int() & ~PAGE_MASK;
  return sp & ~0xf;
}

static unsigned long randomize_base(unsigned long base)
{
  unsigned long range_end = base + (STACK_RND_MASK << PAGE_SHIFT) + 1;
  return randomize_range(base, range_end, 0) ? : base;
}

unsigned long arch_randomize_brk(struct mm_struct *mm)
{
  return randomize_base(mm->brk);
}

unsigned long randomize_et_dyn(unsigned long base)
{
  return randomize_base(base);
}


此ARM版本的Linux似乎没有考虑arch/arm/kernel/process.c的触发来控制ASLR。

代替它的唯一的控制方法似乎是过程个性标记(在过程范围内而不是系统范围内):

unsigned long arch_randomize_brk(struct mm_struct *mm)
{
   unsigned long range_end = mm->brk + 0x02000000;
   return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
}


如果可以掌握Android内核源代码,我也许还能说更多。

评论


在我的设备上,uname -m返回“ armv7l”,并且我在板载的基于busybox v1.21.0的setarch中只能识别linux32和linux64个性。同样,它甚至无法识别-R开关AFAIK。我将尝试使用真正的setarch,而不是使用busybox来查看是否有帮助。我的内核版本为3.0.8。感谢您的研究工作!

– Hinko Kocevar
2014年2月12日在22:57

@perror-“我没有设法从Android获取源...”-对于Android,请参阅fs / binfmt_elf.c。另请参阅在Android Ice Cream Sandwich 4.0中的ASLR外观。

– jww
2014年6月14日在22:49