By 飘云/P.Y.G http://bbs.chinapyg.com http://www.dllhook.com 先写一段函数: int addFunction(int a, int b) { int ret = a + b; return ret; } /* __text:00002078 EXPORT _addFunction __text:00002078 _addFunction ; CODE XREF: _main+24p __text:00002078 __text:00002078 var_C = -0xC __text:00002078 var_8 = -8 __text:00002078 var_4 = -4 __text:00002078 __text:00002078 STMFD SP!, {R7,LR} __text:0000207C __text:0000207C loc_207C ; DATA XREF: __text:off_2074o __text:0000207C ADD R7, SP, #0 __text:00002080 SUB SP, SP, #0xC __text:00002084 STR R0, [SP,#0xC+var_8] ; 将R0保存到栈 [SP+0x0] = R0 __text:00002088 STR R1, [SP,#0xC+var_C] ; 将R1保存到栈 [SP+0x4] = R1 __text:0000208C LDR R2, [SP,#0xC+var_8] ; R2 = [SP+0x0] = R0 __text:00002090 LDR R3, [SP,#0xC+var_C] ; R3 = [SP+0x4] = R1 __text:00002094 ADD R3, R2, R3 ; R3 = R2 + R3 __text:00002098 STR R3, [SP,#0xC+var_4] ; 保存到变量var_4 --- [SP+0x8] __text:0000209C LDR R3, [SP,#0xC+var_4] ; 又从变量传回到R3 --- 这玩意反正是成对使用,慢慢习惯就好了,不要问为什么 __text:000020A0 MOV R0, R3 ; 最后把结果存到R0 __text:000020A4 SUB SP, R7, #0 __text:000020A8 LDMFD SP!, {R7,PC} __text:000020A8 ; End of function _addFunction */ 调用: int c = addFunction(0x11, 0x22); /* __text:000020C8 MOV R0, #0x11 __text:000020CC MOV R1, #0x22 __text:000020D0 BL _addFunction */ 结论:调用函数不是用CALL 而是BL 第一个参数放在R0,第二个参数放在R1 从右到左 然后再写一段4个参数的 int addFunction2(int a, int b, int c, int d) { int ret = a + b + c + d; return ret; } /* __text:000020AC EXPORT _addFunction2 __text:000020AC _addFunction2 ; CODE XREF: _main+54p __text:000020AC __text:000020AC var_14 = -0x14 __text:000020AC var_10 = -0x10 __text:000020AC var_C = -0xC __text:000020AC var_8 = -8 __text:000020AC var_4 = -4 __text:000020AC __text:000020AC STMFD SP!, {R7,LR} __text:000020B0 ADD R7, SP, #0 __text:000020B4 SUB SP, SP, #0x14 __text:000020B8 STR R0, [SP,#0x14+var_8] __text:000020BC STR R1, [SP,#0x14+var_C] __text:000020C0 STR R2, [SP,#0x14+var_10] __text:000020C4 STR R3, [SP,#0x14+var_14] __text:000020C8 LDR R2, [SP,#0x14+var_8] __text:000020CC LDR R3, [SP,#0x14+var_C] __text:000020D0 ADD R2, R2, R3 __text:000020D4 LDR R3, [SP,#0x14+var_10] __text:000020D8 ADD R2, R2, R3 __text:000020DC LDR R3, [SP,#0x14+var_14] __text:000020E0 ADD R3, R2, R3 __text:000020E4 STR R3, [SP,#0x14+var_4] __text:000020E8 LDR R3, [SP,#0x14+var_4] __text:000020EC MOV R0, R3 // 返回值到R0 __text:000020F0 SUB SP, R7, #0 __text:000020F4 LDMFD SP!, {R7,PC} __text:000020F4 ; End of function _addFunction2 */ addFunction2(0x11, 0x22, 0x33, 0x44); /* __text:0000213C MOV R0, #0x11 __text:00002140 MOV R1, #0x22 __text:00002144 MOV R2, #0x33 __text:00002148 MOV R3, #0x44 __text:0000214C BL _addFunction2 */ 结论:调用函数不是用CALL 而是BL 第一个参数放在R0,第二个参数放在R1 第三个参数放在R2 第四个参数放在R3 从右到左 继续写一段8个参数的函数测试: int addFunction3(int a, int b, int c, int d, int e, int f, int g, int h) { int ret = a + b + c + d + e + f + g + h; return ret; } /* __text:000020F8 EXPORT _addFunction3 __text:000020F8 _addFunction3 ; CODE XREF: _main+A4p __text:000020F8 __text:000020F8 var_14 = -0x14 __text:000020F8 var_10 = -0x10 __text:000020F8 var_C = -0xC __text:000020F8 var_8 = -8 __text:000020F8 var_4 = -4 __text:000020F8 arg_0 = 8 __text:000020F8 arg_4 = 0xC __text:000020F8 arg_8 = 0x10 __text:000020F8 arg_C = 0x14 __text:000020F8 __text:000020F8 STMFD SP!, {R7,LR} __text:000020FC ADD R7, SP, #0 __text:00002100 SUB SP, SP, #0x14 __text:00002104 STR R0, [SP,#0x14+var_8] __text:00002108 STR R1, [SP,#0x14+var_C] __text:0000210C STR R2, [SP,#0x14+var_10] __text:00002110 STR R3, [SP,#0x14+var_14] __text:00002114 LDR R2, [SP,#0x14+var_8] __text:00002118 LDR R3, [SP,#0x14+var_C] __text:0000211C ADD R2, R2, R3 __text:00002120 LDR R3, [SP,#0x14+var_10] __text:00002124 ADD R2, R2, R3 __text:00002128 LDR R3, [SP,#0x14+var_14] __text:0000212C ADD R2, R2, R3 __text:00002130 LDR R3, [SP,#0x14+arg_0] __text:00002134 ADD R2, R2, R3 __text:00002138 LDR R3, [SP,#0x14+arg_4] __text:0000213C ADD R2, R2, R3 __text:00002140 LDR R3, [SP,#0x14+arg_8] __text:00002144 ADD R2, R2, R3 __text:00002148 LDR R3, [SP,#0x14+arg_C] __text:0000214C ADD R3, R2, R3 __text:00002150 STR R3, [SP,#0x14+var_4] __text:00002154 LDR R3, [SP,#0x14+var_4] __text:00002158 MOV R0, R3 // 返回值到R0 __text:0000215C SUB SP, R7, #0 __text:00002160 LDMFD SP!, {R7,PC} __text:00002160 ; End of function _addFunction3 */ ret = addFunction3(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88); /* __text:00002164 var_14 = -0x14 __text:00002164 var_10 = -0x10 __text:00002164 var_C = -0xC __text:00002164 var_8 = -8 __text:00002164 var_4 = -4 . . . . . . __text:000021D8 MOV R3, #0x55 __text:000021DC STR R3, [SP,#0x14+var_14] ; 0x0 __text:000021E0 MOV R3, #0x66 __text:000021E4 STR R3, [SP,#0x14+var_10] ; 0x4 __text:000021E8 MOV R3, #0x77 __text:000021EC STR R3, [SP,#0x14+var_C] ; 0x8 __text:000021F0 MOV R3, #0x88 __text:000021F4 STR R3, [SP,#0x14+var_8] ; 0xC __text:000021F8 MOV R0, #0x11 __text:000021FC MOV R1, #0x22 __text:00002200 MOV R2, #0x33 __text:00002204 MOV R3, #0x44 __text:00002208 BL _addFunction3 */ 结论:调用函数不是用CALL 而是BL 第一个参数放在R0,第二个参数放在R1 第三个参数放在R2 第四个参数放在R3 后面开始用栈传递 printf("result=%d\n", ret); /* __text:00002208 BL _addFunction3 __text:0000220C MOV R3, R0 ; 返回到R0 --- R3 = R0 __text:00002210 STR R3, [SP,#0x14+var_4] ; 保存R3到变量 var_4 __text:00002214 LDR R3, =(aResultD - 0x2220) ; 载入格式化字符串“result=%d\n”地址到R3 __text:00002218 ADD R3, PC, R3 ; "result=%d\n" __text:0000221C MOV R0, R3 ; char * __text:00002220 LDR R1, [SP,#0x14+var_4] ; 载入变量var_4 __text:00002224 BL _printf ; 调用printf函数 */
发表评论