使用ptrace向已运行进程中注入so并执行相关函数讲解.docx
- 文档编号:8938654
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:22
- 大小:23.81KB
使用ptrace向已运行进程中注入so并执行相关函数讲解.docx
《使用ptrace向已运行进程中注入so并执行相关函数讲解.docx》由会员分享,可在线阅读,更多相关《使用ptrace向已运行进程中注入so并执行相关函数讲解.docx(22页珍藏版)》请在冰豆网上搜索。
使用ptrace向已运行进程中注入so并执行相关函数讲解
使用ptrace向已运行进程中注入.so并执行相关函数
1.简介
2.如何让目标进程执行dlopen加载so
3.加载so的实现代码
4.如何把加载so的实现代码写入目标进程并启动执行
1.在目标进程中找到存放加载so的实现代码的空间
2.为加载so的实现代码中的全局变量赋值
5.把汇编代码写入目标进程并执行的实现代码
1.主函数writecode_to_targetproc
2.attach目标进程ptrace_attach
3.获取目标进程寄存器值ptrace_getregs
4.获取目标进程中指定模块中指定函数的地址get_remote_addr
5.在目标进程中执行指定函数ptrace_call
6.把代码写入目标进程指定地址ptrace_writedata
7.设置目标进程寄存器ptrace_setregs
8.detach目标进程ptrace_detach
6.需要被加载的so
1.替换函数replaceFunc
2.新函数及其它函数
1.简介
使用ptrace向已运行进程中注入.so并执行相关函数,其中的“注入”二字的真正含义为:
此.so被link到已运行进程(以下简称为:
目标进程)空间中,从而.so中的函数在目标进程空间中有对应的地址,然后通过此地址便可在目标进程中进行调用。
到底是如何注入的呢?
本文实现方案为:
在目标进程中,通过dlopen把需要注入的.so加载到目标进程的空间中。
2.如何让目标进程执行dlopen加载.so?
显然,目标进程本来是没有实现通过dlopen来加载我们想注入的.so,为了实现此功能,我们需要目标进程执行一段我们实现的代码,此段代码的功能为通过dlopen来加载一个.so。
3.【加载.so的实现代码】
加载需要注入的.so的实现代码如下所示:
[cpp] viewplaincopy
1..global _dlopen_addr_s @dlopen函数在目标进程中的地址 注:
以下全局变化在C中可读写
2..global _dlopen_param1_s @dlopen参数1<.so>在目标进程中的地址
3..global _dlopen_param2_s @dlopen参数2在目标进程中的地址
4.
5..global _dlsym_addr_s @dlsym函数在目标进程中的地址
6..global _dlsym_param2_s @dlsym参数2在目标进程中的地址,其实为函数名
7.
8..global _dlclose_addr_s @dlcose在目标进程中的地址
9.
10..global _inject_start_s @汇编代码段的起始地址
11..global _inject_end_s @汇编代码段的结束地址
12.
13..global _inject_function_param_s @hook_init参数在目标进程中的地址
14.
15..global _saved_cpsr_s @保存CPSR,以便执行完hook_init之后恢复环境
16..global _saved_r0_pc_s @保存r0-r15,以便执行完hook_init之后恢复环境
17.
18.
19..data
20.
21._inject_start_s:
22. @ debug loop
23.3:
24. @sub r1, r1, #0
25. @B 3b
26.
27. @ dlopen
28. ldr r1, _dlopen_param2_s @设置dlopen第二个参数, flag
29. ldr r0, _dlopen_param1_s @设置dlopen第一个参数 .so
30. ldr r3, _dlopen_addr_s @设置dlopen函数
31. blx r3 @执行dlopen函数,返回值位于r0中
32. subs r4, r0, #0 @把dlopen的返回值soinfo保存在r4中,以方便后面dlclose使用
33. beq 2f
34.
35. @dlsym
36. ldr r1, _dlsym_param2_s @设置dlsym第二个参数,第一个参数已经在r0中了
37. ldr r3, _dlsym_addr_s @设置dlsym函数
38. blx r3 @执行dlsym函数,返回值位于r0中
39. subs r3, r0, #0 @把返回值
40. beq 1f
41.
42. @call our function
43. ldr r0, _inject_function_param_s @设置hook_init第一个参数
44. blx r3 @执行hook_init
45. subs r0, r0, #0
46. beq 2f
47.
48.1:
49. @dlclose
50. mov r0, r4 @把dlopen的返回值设为dlcose的第一个参数
51. ldr r3, _dlclose_addr_s @设置dlclose函数
52. blx r3 @执行dlclose函数
53.
54.2:
55. @restore context
56. ldr r1, _saved_cpsr_s @恢复CPSR
57. msr cpsr_cf, r1
58. ldr sp, _saved_r0_pc_s @恢复寄存器r0-r15
59. ldmfd sp, {r0-pc}
60.
61.
62.
63.
64._dlopen_addr_s:
@初始化_dlopen_addr_s
65..word 0x11111111
66.
67._dlopen_param1_s:
68..word 0x11111111
69.
70._dlopen_param2_s:
71..word 0x2 @RTLD_GLOBAL
72.
73._dlsym_addr_s:
74..word 0x11111111
75.
76._dlsym_param2_s:
77..word 0x11111111
78.
79._dlclose_addr_s:
80..word 0x11111111
81.
82._inject_function_param_s:
83..word 0x11111111
84.
85._saved_cpsr_s:
86..word 0x11111111
87.
88._saved_r0_pc_s:
89..word 0x11111111
90.
91.
92._inject_end_s:
@代码结束地址
93.
94..space 0x400, 0 @代码段空间大小
95.
96..end
4.如何把【加载.so的实现代码】写入目标进程并启动执行?
为了把【加载.so的实现代码】写入目标进程,主要有以下两步操作:
1)在目标进程中找到存放【加载.so的实现代码】的空间(通过mmap实现)
2)把【加载.so的实现代码】写入目标进程指定的空间
3)启动执行
4.1在目标进程中找到存放【加载.so的实现代码】的空间
通过mmap来实现,其实现步骤如下:
1)获取目标进程中mmap地址
2)把mmap参数据放入r0-r3,另外两个写入目标进程sp
3)pc设置为mmap地址,lr设置为0
4)把准备好的寄存器写入目标进程(PTRACE_SETREGS),并启动目标进程运行(PTRACE_CONT)
5)分配的内存首地址位于r0 (PTRACE_GETREGS)
4.2为【加载.so的实现代码】中的全局变量赋值
1)获取目标进程中dlopen地址并赋值给_dlopen_addr_s
2)获取目标进程中dlsym地址并赋值给_dlsym_addr_s
3)获取目标进程中dlclose地址并赋值给_dlclose_addr_s
4)把需要加载的.so的路径放入汇编代码中,并获取此路径在目标进程中的地址然后赋值给_dlopen_param1_s
5) 把需要加载的.so中的hook_init放入汇编代码中,并获取此路径在目标进程中的地址然后赋值给_dlsym_param2_s
6)把目标进程中的cpsr保存在_saved_cpsr_s中
7)把目标进程中的r0-r15存入汇编代码中,并获取此变量在目标进程中的地址然后赋值给_saved_r0_pc_s
8)通过ptrace(PTRACE_POKETEXT,...)把汇编代码写入目标进程中,起始地址由前面的mmap所分配
9)把目标进程的pc设置为汇编代码的起始地址,然后调用ptrace(PTRACE_DETACH,...)以启动目标进程执行
5.把汇编代码写入目标进程并执行的实现代码
5.1主函数writecode_to_targetproc
[cpp] viewplaincopy
1.#include
2.#include
3.#include
4.#include
5.#include
6.#include
7.#include
8.#include
9.#include
10.#include
11.#include
12.#include
13.#include
14.#include
15.#include
16.#include
17.
18.#define MAX_PATH 0x100
19.#define REMOTE_ADDR( addr, local_base, remote_base ) ( (uint32_t)(addr) + (uint32_t)(remote_base) - (uint32_t)(local_base) )
20.
21./* write the assembler code into target proc,
22. * and invoke it to execute
23. */
24.int writecode_to_targetproc(
25. pid_t target_pid, // target process pid
26. const char *library_path, // the path of .so that will be
27. // upload to target process
28. const char *function_name, // .so init fucntion e.g. hook_init
29. void *param, // the parameters of init function
30. size_t param_size ) // number of parameters
31.{
32. int ret = -1;
33. void *mmap_addr, *dlopen_addr, *dlsym_addr, *dlclose_addr;
34. void *local_handle, *remote_handle, *dlhandle;
35. uint8_t *map_base;
36. uint8_t *dlopen_param1_ptr, *dlsym_param2_ptr, *saved_r0_pc_ptr, *inject_param_ptr, *remote_code_ptr, *local_code_ptr;
37.
38. struct pt_regs regs, original_regs;
39.
40. // extern global variable in the assembler code
41. extern uint32_t _dlopen_addr_s, _dlopen_param1_s, _dlopen_param2_s, \
42. _dlsym_addr_s, _dlsym_param2_s, _dlclose_addr_s, \
43. _inject_start_s, _inject_end_s, _inject_function_param_s, \
44. _saved_cpsr_s, _saved_r0_pc_s;
45.
46. uint32_t code_length;
47.
48. long parameters[10];
49.
50. // make target_pid as its child process and stop
51. if ( ptrace_attach( target_pid ) == -1 )
52. return -1;
53.
54. // get the values of 18 registers from target_pid
55. if ( ptrace_getregs( target_pid, ®s ) == -1 )
56. goto exit;
57.
58. // save original registers
59. memcpy( &original_regs, ®s, sizeof(regs) );
60.
61. // get mmap address from target_pid
62. // the mmap is the address of mmap in the cur process
63. mmap_addr = get_remote_addr( target_pid, "/system/lib/libc.so", (void *)mmap );
64.
65. // set mmap parameters
66. parameters[0] = 0; // addr
67. parameters[1] = 0x4000; // size
68. parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot
69. parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags
70. parameters[4] = 0; //fd
71. parameters[5] = 0; //offset
72.
73. // execute the mmap in target_pid
74. if ( ptrace_call( target_pid, (uint32_t)mmap_addr, parameters, 6, ®s ) == -1 )
75. goto exit;
76.
77. // get the return values of mmap
78. if ( ptrace_getregs( target_pid, ®s ) == -1 )
79. goto exit;
80.
81. // get the start address for assembler code
82. map_base = (uint8_t *)regs.ARM_r0;
83.
84. // get the address of dlopen, dlsym and dlclose in target process
85. dlopen_addr = get_remote_addr( target_pid, "/system/bin/linker", (void *)dlopen );
86. dlsym_addr = get_remote_addr( target_pid, "/system/bin/linker", (void *)dlsym );
87. dlclose_addr = get_remote_addr( target_pid, "/system/bin/linker", (void *)dlclose );
88.
89. // set the start address for assembler code in target process
90. remote_code_ptr = map_base + 0x3C00;
91.
92. // set the start address for assembler code in cur process
93. local_code_ptr = (uint8_t *)&_inject_start_s;
94.
95. // set global variable of assembler code
96. // and these address is in the target process
97. _dlopen_addr_s = (uint32_t)dlopen_addr;
98. _dlsym_addr_s = (uint32_t)dlsym_addr;
99. _dlclose_addr_s = (uint32_t)dlclose_addr;
100.
101. code_length = (uint32_t)&_inject_end_s - (uint32_t)&_inject_start_s;
102.
103. dlopen_param1_ptr = local_code_ptr + code_length + 0x20;
104. dlsym_param2_ptr = dlopen_param1_ptr + MAX_PATH;
105. saved_r0_pc_ptr = dlsym_param2_ptr + MAX_PATH;
106. inject_param_ptr = saved_r0_pc_ptr + MAX_PATH;
107.
108.
109. // save library path to assembler code global variable
110. strcpy( dlopen_param1_ptr, library_path );
111. _dlopen_param1_s = REMOTE_ADDR( dlopen_param1_ptr, local_code_ptr, remote_code_ptr );
112.
113.
114. // save function name to assembler code global variable
115. strcpy( dlsym_param2_ptr, function_name );
116. _dlsym_param2_s = REMOTE_ADDR( dlsym_param2_ptr, local_code_ptr, remote_code_ptr );
117.
118. // save cpsr to assembler code global variable
119. _saved_cpsr_s = original_regs.ARM_cpsr;
120.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 ptrace 运行 进程 注入 so 执行 相关 函数 讲解