转自:http://bbs.byr.cn/article/MobileTerminalAT/4278
最近找工作非常心烦,很有“不存在感”,都不知道怎么办了...
貌似有些轻度失眠,最近晚上不到4点完全睡不着,于是乎趁着睡不着,起来学习一直都梦寐以求的LBE,感觉还是那么遥不可及的技术啊,不过看看总是有收获的。感觉这两个晚上还是没白看,虽然还是那么遥不可及。
首先LBE就不介绍了,Android下面一个安全软件,不过做得的确很出色,主要就是那一套主动防御的技术。LBE号称叫做业界最早实现HOOK技术的人,又是Linux,又是ARM...我去,人生是不能洗点的,就这两点其实就废掉了,找不到工作也是该的。
安装完了LBE什么发短信,读手机卡之类的操作会被拦截下来,这点做得确实霸道。不过结合一下Windows HOOK,还是能够理解原因的。HOOK嘛,首先要注入,然后就是注入后的事。由于现在出的版本都是很新很新的了,在SO中好多调试链接信息都被无情地strip鸟,要逆向真的非常头大。我估摸着老版本没有问题,于是在网上找了个可以说是第一版的软件,但是功能还是足够的,最为重要的是调试信息,拖到IDA里面就感叹其意义。
安装完毕之后里面有两个BIN,可能版本不同情况也不同,反正作为最老版是这样:一个叫libloader.so,一个叫libservice.so。相信SO大家都编过,但是这两个SO,其实不是传统书上教的那种,因为连个什么对JAVA接口都没有。不过我还是相信用法嘛,可能是什么System.loadLibrary之类,但是不是...
由AndroidManifest.xml可以知道哪里是入口点,反正就那么找,然后逆向JAVA代码之后发现了下面这种情况:
package com.lbe.security.service.loader;
...
String str2 = Integer.toString(Process.myUid());
arrayOfString[1] = str2;
Cursor localCursor = localContentResolver.query(localUri, null, null, arrayOfString, null);
...
package com.lbe.security.service.loader;
public Cursor query(...)
{
try
{
Runtime localRuntime1 = Runtime.getRuntime();
String str3 = "/system/bin/chmod 755 " + str1 + "/libloader.so";
java.lang.Process localProcess1 = localRuntime1.exec(str3);
try
{
Runtime localRuntime2 = Runtime.getRuntime();
String str4 = String.valueOf(str1);
String str5 = str4 + "/libloader.so " + str2;
java.lang.Process localProcess2 = localRuntime2.exec(str5);
l = 4000L;
......
}
那就是说,其实这个libloader.so就不是真正的SO而是一个BIN,于是乎一测试就发现了:
# ./libloader.so
./libloader.so
Usage: ./libloader.so euid#
至于Usage嘛,那应该是后面接个UID就是了(注意:Process.myUid())。
好吧,那么这个loader真是名副其实的loader,而且也不是属于那种constructor来混淆你的SO而是真正的BIN。记得Windows注入就是一个EXE一个DLL,那么说另外一个SO就是所谓的“HOOK DLL(SO)”。
还是继续从loader下手,它HOOK了那些程序?其实从IDA里面的Strings可以看到一堆,不过还有个函数即使在main附近的一个叫find_pid_of,那个里面有个结构体(猜的),里面讲到了三个注入过程:
1、inject_svcmgr(HOOK实际对象是/system/bin/servicemanage),感觉和短信有关
2、inject_server(HOOK为system_server中的/system/lib/libandroid_runtime.so中的导入表sendmsg),据LBE自己说拦截网络和那个iptables无关,不过sendmsg似乎是UDP的啊,其它情况呢?
3、inject_phonemgr(HOOK为com.android.phone),打电话
不过怎么HOOK都是后话,我觉得第一步还是怎么注入是关键。arm汇编着实让人头大,不过大致的流程还是能够看到,在loader中有一个叫inject_remote_process的函数,其就是主要负责注入滴,而另外三个注入过程的函数(inject_svcmgr、inject_server、inject_phonemgr)都路过调用了它,其中传入的参数有要注入的进程pid以及一个字符串解析值,不过那个解析值直到看libservice.so才明白(有的注释自己加的):
libloader.so inject_phonemgr CODE:
.text:00008FA4 inject_phonemgr
.text:00008FA4 STMFD SP!, {R4-R10,LR}
.text:00008FA8 LDR R4, =(_GLOBAL_OFFSET_TABLE_ - 0x8FBC)
.text:00008FAC LDR R6, =0x104
.text:00008FB0 SUB SP, SP, #0x210
.text:00008FB4 ADD R4, PC, R4
.text:00008FB8 LDR R2, [R4,R6]
.text:00008FBC ADD R5, SP, #0x10C
.text:00008FC0 MOV R10, R0
.text:00008FC4 LDR R3, [R2]
.text:00008FC8 MOV R7, R1
.text:00008FCC MOV R0, R5
.text:00008FD0 MOV R1, #0x100
.text:00008FD4 STR R3, [SP,#0x20C]
.text:00008FD8 BL getcwd
.text:00008FDC MOV R0, R5
.text:00008FE0 BL strlen
.text:00008FE4 LDR R1, =0xFFFFF7E8 ; "/libservice.so"
.text:00008FE8 MOV R2, #0xF
.text:00008FEC ADD R0, R5, R0
.text:00008FF0 ADD R1, R4, R1
.text:00008FF4 BL memcpy
.text:00008FF8 MOV R0, R5
.text:00008FFC MOV R1, #0
.text:00009000 BL access
.text:00009004 CMP R0, #0
.text:00009008 BNE loc_9094
.text:0000900C MOV R0, R7
.text:00009010 BL get_thread_list
.text:00009014 MOV R9, R0
.text:00009018 BL getpid
.text:0000901C LDR R1, =0xFFFFF830 ; "func=%d,sec_uid=%d,sec_pid=%d"
.text:00009020 ADD R8, SP, #0xC
.text:00009024 STR R0, [SP]
.text:00009028 ADD R1, R4, R1
.text:0000902C MOV R3, R10
.text:00009030 MOV R2, #3
.text:00009034 MOV R0, R8
.text:00009038 BL sprintf
.text:0000903C LDR R12, =0xFFFFF850 ; "hook_entry"
.text:00009040 MOV R0, R7
.text:00009044 MOV R1, R5
.text:00009048 ADD R2, R4, R12
.text:0000904C MOV R3, R8
.text:00009050 BL inject_remote_process
.text:00009054 CMP R0, #0
.text:00009058 BNE loc_9084
libservice.so hook_entry CODE:
.text:00010560 EXPORT hook_entry
.text:00010560 hook_entry
.text:00010560
.text:00010560 var_20 = -0x20
.text:00010560 var_14 = -0x14
.text:00010560 var_10 = -0x10
.text:00010560 var_C = -0xC
.text:00010560 var_4 = -4
.text:00010560
.text:00010560 STR LR, [SP,#var_4]!
.text:00010564 LDR R12, =($_GLOBAL_OFFSET_TABLE_ - 0x10578)
.text:00010568 LDR R1, =(aFuncDSec_uidDS - 0x1DF20)
.text:0001056C SUB SP, SP, #0x1C
.text:00010570 ADD R12, PC, R12
.text:00010574 ADD R3, SP, #0x20+var_10
.text:00010578 ADD LR, SP, #0x20+var_14
.text:0001057C ADD R1, R12, R1 ; "func=%d,sec_uid=%d,sec_pid=%d"
.text:00010580 ADD R2, SP, #0x20+var_C
.text:00010584 STR LR, [SP,#0x20+var_20]
.text:00010588 BL sscanf
.text:0001058C LDR R3, [SP,#0x20+var_C]
.text:00010590 CMP R3, #2 ;2号 hook_server
.text:00010594 BEQ loc_105D4
.text:00010598 CMP R3, #3 ;3号 hook_phonemgr
.text:0001059C BEQ loc_105C4
.text:000105A0 CMP R3, #1 ;1号 hook_svcmgr
就是注入进去之后然后调用的hook_entry代码了,至于这个传入的"func=%d,sec_uid=%d,sec_pid=%d"被sscanf解析了,func ID不说了,sec_uid应该是来自JAVA代码的myUid,而pid就是进程吧。
inject_remote_process是亮点啊,我是完全对Linux不懂,而且ARM也不懂,真麻烦。其大致的过程是:
1、首先ATTACH(附加进程)
2、然后GETREGS(读那个进程寄存器,这里是ARM汇编,不是X86):
#ifndef __ASSEMBLY__
struct pt_regs {
long uregs[18];
};
#define ARM_cpsr uregs[16]
#define ARM_pc uregs[15]
#define ARM_lr uregs[14]
#define ARM_sp uregs[13]
#define ARM_ip uregs[12]
#define ARM_fp uregs[11]
#define ARM_r10 uregs[10]
#define ARM_r9 uregs[9]
#define ARM_r8 uregs[8]
#define ARM_r7 uregs[7]
#define ARM_r6 uregs[6]
#define ARM_r5 uregs[5]
#define ARM_r4 uregs[4]
#define ARM_r3 uregs[3]
#define ARM_r2 uregs[2]
#define ARM_r1 uregs[1]
#define ARM_r0 uregs[0]
#define ARM_ORIG_r0 uregs[17]
3、注入代码POKETEXT(dlopen dlsym dlclose)
4、设置寄存器SETREGS(这里有结构体,由于不熟悉ARM,但是粗略猜测这里可能是ARM_lr,因为BX LR嘛)
5、运行CONT
嗯,也就说就目前这种写法上看,我需要在自己写的测试so里面有个hook_entry供调用才行,并且函数格式还得对。不过如果不考虑这些,就用它自己提供的两个SO,在不启动LBE主进程的情况下,进行测试,对象为/system/bin/servermanager...
这是servermanager没有运行loader之前的情况(查看maps文件):
00008000-0000a000 r-xp 00000000 1f:00 564 /system/bin/servicemanager
0000a000-0000b000 rwxp 00002000 1f:00 564 /system/bin/servicemanager
0000b000-0000c000 rwxp 0000b000 00:00 0 [heap]
40000000-40008000 r-xs 00000000 00:07 188 /dev/ashmem/system_properties (deleted)
40008000-40028000 r-xp 00000000 00:0a 53 /dev/binder
40028000-40029000 r-xp 40028000 00:00 0
afa00000-afa03000 r-xp 00000000 1f:00 364 /system/lib/liblog.so
afa03000-afa04000 rwxp 00003000 1f:00 364 /system/lib/liblog.so
afb00000-afb20000 r-xp 00000000 1f:00 419 /system/lib/libm.so
afb20000-afb21000 rwxp 00020000 1f:00 419 /system/lib/libm.so
afc00000-afc01000 r-xp 00000000 1f:00 356 /system/lib/libstdc++.so
afc01000-afc02000 rwxp 00001000 1f:00 356 /system/lib/libstdc++.so
afd00000-afd3f000 r-xp 00000000 1f:00 368 /system/lib/libc.so
afd3f000-afd42000 rwxp 0003f000 1f:00 368 /system/lib/libc.so
afd42000-afd4d000 rwxp afd42000 00:00 0
b0001000-b000c000 r-xp 00001000 1f:00 615 /system/bin/linker
b000c000-b000d000 rwxp 0000c000 1f:00 615 /system/bin/linker
b000d000-b0016000 rwxp b000d000 00:00 0
beb4c000-beb61000 rwxp befeb000 00:00 0 [stack]
这是运行之后的情况:
00008000-0000a000 r-xp 00000000 1f:00 564 /system/bin/servicemanager
0000a000-0000b000 rwxp 00002000 1f:00 564 /system/bin/servicemanager
0000b000-00011000 rwxp 0000b000 00:00 0 [heap]
40000000-40008000 r-xs 00000000 00:07 188 /dev/ashmem/system_properties (deleted)
40008000-40028000 r-xp 00000000 00:0a 53 /dev/binder
40028000-40029000 r-xp 40028000 00:00 0
40029000-4002d000 rwxp 40029000 00:00 0
80000000-8001b000 r-xp 00000000 1f:01 484 /data/data/com.lbe.security/lib/libservice.so
8001b000-8001f000 rwxp 0001b000 1f:01 484 /data/data/com.lbe.security/lib/libservice.so
a8100000-a8124000 r-xp 00000000 1f:00 373 /system/lib/libutils.so
a8124000-a8125000 rwxp 00024000 1f:00 373 /system/lib/libutils.so
a8200000-a821f000 r-xp 00000000 1f:00 442 /system/lib/libbinder.so
a821f000-a8225000 rwxp 0001f000 1f:00 442 /system/lib/libbinder.so
af700000-af713000 r-xp 00000000 1f:00 395 /system/lib/libz.so
af713000-af714000 rwxp 00013000 1f:00 395 /system/lib/libz.so
af900000-af90e000 r-xp 00000000 1f:00 372 /system/lib/libcutils.so
af90e000-af90f000 rwxp 0000e000 1f:00 372 /system/lib/libcutils.so
af90f000-af91e000 rwxp af90f000 00:00 0
afa00000-afa03000 r-xp 00000000 1f:00 364 /system/lib/liblog.so
afa03000-afa04000 rwxp 00003000 1f:00 364 /system/lib/liblog.so
afb00000-afb20000 r-xp 00000000 1f:00 419 /system/lib/libm.so
afb20000-afb21000 rwxp 00020000 1f:00 419 /system/lib/libm.so
afc00000-afc01000 r-xp 00000000 1f:00 356 /system/lib/libstdc++.so
afc01000-afc02000 rwxp 00001000 1f:00 356 /system/lib/libstdc++.so
afd00000-afd3f000 r-xp 00000000 1f:00 368 /system/lib/libc.so
afd3f000-afd42000 rwxp 0003f000 1f:00 368 /system/lib/libc.so
afd42000-afd4d000 rwxp afd42000 00:00 0
b0001000-b000c000 r-xp 00001000 1f:00 615 /system/bin/linker
b000c000-b000d000 rwxp 0000c000 1f:00 615 /system/bin/linker
b000d000-b0016000 rwxp b000d000 00:00 0
beb4c000-beb61000 rwxp befeb000 00:00 0 [stack]
哎,就到这里吧,晚上笔试中兴完了继续学习吧...主要就是把inject_remote_process实现出来差不多了。
--