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函数
*/

 

你可能感兴趣的文章

评论区

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。