能力值:
( LV3,RANK:30 )
|
-
-
2 楼
Intel网站上有最全的文档:
Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 Instruction Set Reference
|
能力值:
( LV5,RANK:70 )
|
-
-
3 楼
又折腾了一天,发现x86是可以跳绝对地址的,而arm只能去跳相对地址。
x86上我只要执行“\x55\x89\xe5\xb8\x84\x06\x40\x00\xff\xd0\x5d\xc3”这个二进制代码就能跳转到相应的函数
arm是现在试来试去,不是Illegal instruction就是Segmentation fault,哎,不知道是指令的问题,还是地址计算的问题
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
这个你查查shellcode分析吧,贴一个连接
http://www.linuxidc.com/Linux/2011-10/44766.htm
|
能力值:
( LV5,RANK:70 )
|
-
-
5 楼
嗯,很好的参考。谢谢
现在我有一个疑问,我先写c代码调用一个函数:
void test2()
{
}
void test()
{
test2();
}
看test函数的汇编:
00008474 <test2>:
8474: 4770 bx lr
00008476 <test>:
8476: b508 push {r3, lr}
8478: f7ff fffc bl 8474 <test2>
847c: bd08 pop {r3, pc}
因此,我直接将上面test函数的汇编的二进制代码作为shellcode:
\x08\xb5\xff\xf7\xfc\xff\x08\xbd
(考虑到字节序的问题,我也尝试过\xb5\x08之类的,而且里面的地址我也是算了相对偏移地址的,结果都一样)
再来执行或反汇编时发现,是无法解析:
<UNDEFINED> instruction: 0xf7ffb508
它为什么总是把4个字节当作一个指令来解析?为什么不先解析b5 08?
|
能力值:
( LV3,RANK:20 )
|
-
-
7 楼
主要意思就是 ARM
STMFD SP!, {R11, LR}
BL 0x11111111
LDMFD SP!, {R11,PC}
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
很厉害的样子
|
能力值:
( LV5,RANK:70 )
|
-
-
9 楼
谢谢解答,看起来是这样的。因为我要写shellcode,所以要翻成二进制码。我用c写了函数,然后看它的二进制代码,copy过来用发现总是有问题。
另外,我看反汇编代码,它里面用的助记符也是push和pop,好像通常arm是用你写的STMFD/LDMFD这样的啊。这是怎么回事呢?
|
能力值:
( LV5,RANK:70 )
|
-
-
10 楼
说一下我现在的情况,c++代码:
void test2()
{
printf("test2\n");
}
int main()
{
char* base = (char*)mmap((void*)MMAP_BASE, 1024, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
if(base == MAP_FAILED) {
perror("mmap");
return 1;
}
char jump[] = "\x08\xb5\x11\x11\x11\x11\x08\xbd";
//char jump[] = "x11\x11\x11\x11\x08\xbd";
int offset = (int)test2 - (int)(base);
*((unsigned int*)(jump+2)) = offset / 4 - 3;
jump[5] = 0xeb; // bl
memcpy(base, code, 1024);
(*(void(*)())base();
return 0;
}
如果jump前面加上\x08\xb5,不能正确地跳到test2,在执行base前的寄存器状态为:
r0 0xa 10
r1 0xc008 49160
r2 0x6d 109
r3 0x889 2185
r4 0x9d09 40201
r5 0x24 36
r6 0x1000 4096
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0xbefabb3c -1090864324
r12 0xffffff24 -220
sp 0xbefab6d8 0xbefab6d8
lr 0x400f3cfb 1074740475
pc 0x86f8 0x86f8 <main()+220>
cpsr 0x60000030 1610612784
执行之后,提示Segmentation fault,0x00002000 in ?? (),寄存器变成:
r0 0xa 10
r1 0xc008 49160
r2 0x6d 109
r3 0x889 2185
r4 0x9d09 40201
r5 0x24 36
r6 0x1000 4096
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0xbefabb3c -1090864324
r12 0xffffff24 -220
sp 0xbefab6d8 0xbefab6d8
lr 0x86fb 34555
pc 0x2000 0x2000
cpsr 0x60000010 1610612752
pc变成0x2000了,不知道怎么变过来的
如果jump前面不加\x08\xb5,直接就是BL指令,那么可以正确跳转到test2函数,但接下来的执行却会出错。执行前的寄存器:
r0 0xa 10
r1 0xc008 49160
r2 0x6d 109
r3 0x889 2185
r4 0x9d0a 40202
r5 0x24 36
r6 0x1000 4096
r7 0xbe9f26f0 -1096866064
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0xbe9f2b3c -1096864964
r12 0xffffff24 -220
sp 0xbe9f26d0 0xbe9f26d0
lr 0x4003ecfb 1073999099
pc 0x86f0 0x86f0 <main()+212>
cpsr 0x60000030 1610612784
执行后,提示Illegal instruction,寄存器为:
r0 0xa 10
r1 0x2 2
r2 0x6d 109
r3 0x889 2185
r4 0x9d0a 40202
r5 0x24 36
r6 0x1000 4096
r7 0xbe9f26f0 -1096866064
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0xbe9f2b3c -1096864964
r12 0xffffff24 -220
sp 0xbe9f26d0 0xbe9f26d0
lr 0x1004 4100
pc 0x8610 0x8610 <test2()+4>
cpsr 0x60000010 1610612752
pc已经到了test2+4,这个是c++代码,其汇编代码为:
0x0000860c <+0>: push {r3, lr}
0x0000860e <+2>: ldr r0, [pc, #8] ; (0x8618 <test2()+12>)
0x00008610 <+4>: add r0, pc
0x00008612 <+6>: blx 0x84dc
0x00008616 <+10>: pop {r3, pc}
0x00008618 <+12>: ; <UNDEFINED> instruction: 0x000016b5
我是绝对新手,现在项目需要没有时间从头开始学了,求大神指导。
|
能力值:
( LV5,RANK:70 )
|
-
-
11 楼
终于搞清楚了。我之前犯的错误是没有搞清楚arm和thumb的区别。ndk编译的代码缺省使用了thumb指令,在调用我的shellcode时,它使用BLX指令,这要求我的shellcode必须用arm指令来写,而不能是thumb指令。因此,改成arm指令后就OK啦。
|
能力值:
( LV5,RANK:70 )
|
-
-
12 楼
|
|
|