使用ptrace向已運(yùn)行進(jìn)程中注入.so并執(zhí)行相關(guān)函數(shù)_第1頁
使用ptrace向已運(yùn)行進(jìn)程中注入.so并執(zhí)行相關(guān)函數(shù)_第2頁
使用ptrace向已運(yùn)行進(jìn)程中注入.so并執(zhí)行相關(guān)函數(shù)_第3頁
使用ptrace向已運(yùn)行進(jìn)程中注入.so并執(zhí)行相關(guān)函數(shù)_第4頁
使用ptrace向已運(yùn)行進(jìn)程中注入.so并執(zhí)行相關(guān)函數(shù)_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、使用ptrace向已運(yùn)行進(jìn)程中注入.so并執(zhí)行相關(guān)函數(shù)1. 簡介2. 如何讓目標(biāo)進(jìn)程執(zhí)行dlopen加載so3. 加載so的實(shí)現(xiàn)代碼4. 如何把加載so的實(shí)現(xiàn)代碼寫入目標(biāo)進(jìn)程并啟動(dòng)執(zhí)行1. 在目標(biāo)進(jìn)程中找到存放加載so的實(shí)現(xiàn)代碼的空間2. 為加載so的實(shí)現(xiàn)代碼中的全局變量賦值5. 把匯編代碼寫入目標(biāo)進(jìn)程并執(zhí)行的實(shí)現(xiàn)代碼1. 主函數(shù) writecode_to_targetproc2. attach目標(biāo)進(jìn)程ptrace_attach3. 獲取目標(biāo)進(jìn)程寄存器值ptrace_getregs4. 獲取目標(biāo)進(jìn)程中指定模塊中指定函數(shù)的地址get_remote_addr5. 在目標(biāo)進(jìn)程中執(zhí)行指定函數(shù)ptrac

2、e_call6. 把代碼寫入目標(biāo)進(jìn)程指定地址ptrace_writedata7. 設(shè)置目標(biāo)進(jìn)程寄存器ptrace_setregs8. detach目標(biāo)進(jìn)程ptrace_detach6. 需要被加載的so1. 替換函數(shù)replaceFunc2. 新函數(shù)及其它函數(shù)1. 簡介 使用ptrace向已運(yùn)行進(jìn)程中注入.so并執(zhí)行相關(guān)函數(shù),其中的“注入”二字的真正含義為:此.so被link到已運(yùn)行進(jìn)程(以下簡稱為:目標(biāo)進(jìn)程)空間中,從而.so中的函數(shù)在目標(biāo)進(jìn)程空間中有對應(yīng)的地址,然后通過此地址便可在目標(biāo)進(jìn)程中進(jìn)行調(diào)用。 到底是如何注入的呢? 本文實(shí)現(xiàn)方案為:在目標(biāo)進(jìn)程中,通過dlopen把需要注入的.so加

3、載到目標(biāo)進(jìn)程的空間中。2. 如何讓目標(biāo)進(jìn)程執(zhí)行dlopen加載.so? 顯然,目標(biāo)進(jìn)程本來是沒有實(shí)現(xiàn)通過dlopen來加載我們想注入的.so,為了實(shí)現(xiàn)此功能,我們需要目標(biāo)進(jìn)程執(zhí)行一段我們實(shí)現(xiàn)的代碼,此段代碼的功能為通過dlopen來加載一個(gè).so。3. 【加載.so的實(shí)現(xiàn)代碼】 加載需要注入的.so的實(shí)現(xiàn)代碼如下所示: cppview plaincopy1. .global_dlopen_addr_sdlopen函數(shù)在目標(biāo)進(jìn)程中的地址注:以下全局變化在C中可讀寫2. .global_dlopen_param1_sdlopen參數(shù)1在目標(biāo)進(jìn)程中的地址3. .global_dlopen_param

4、2_sdlopen參數(shù)2在目標(biāo)進(jìn)程中的地址4. 5. .global_dlsym_addr_sdlsym函數(shù)在目標(biāo)進(jìn)程中的地址6. .global_dlsym_param2_sdlsym參數(shù)2在目標(biāo)進(jìn)程中的地址,其實(shí)為函數(shù)名7. 8. .global_dlclose_addr_sdlcose在目標(biāo)進(jìn)程中的地址9. 10. .global_inject_start_s匯編代碼段的起始地址11. .global_inject_end_s匯編代碼段的結(jié)束地址12. 13. .global_inject_function_param_shook_init參數(shù)在目標(biāo)進(jìn)程中的地址14. 15. .glob

5、al_saved_cpsr_s保存CPSR,以便執(zhí)行完hook_init之后恢復(fù)環(huán)境16. .global_saved_r0_pc_s保存r0-r15,以便執(zhí)行完hook_init之后恢復(fù)環(huán)境17. 18. 19. .data20. 21. _inject_start_s:22. debugloop23. 3:24. subr1,r1,#025. B3b26. 27. dlopen28. ldrr1,_dlopen_param2_s設(shè)置dlopen第二個(gè)參數(shù),flag29. ldrr0,_dlopen_param1_s設(shè)置dlopen第一個(gè)參數(shù).so30. ldrr3,_dlopen_addr

6、_s設(shè)置dlopen函數(shù)31. blxr3執(zhí)行dlopen函數(shù),返回值位于r0中32. subsr4,r0,#0把dlopen的返回值soinfo保存在r4中,以方便后面dlclose使用33. beq2f34. 35. dlsym36. ldrr1,_dlsym_param2_s設(shè)置dlsym第二個(gè)參數(shù),第一個(gè)參數(shù)已經(jīng)在r0中了37. ldrr3,_dlsym_addr_s設(shè)置dlsym函數(shù)38. blxr3執(zhí)行dlsym函數(shù),返回值位于r0中39. subsr3,r0,#0把返回值保存在r3中40. beq1f41. 42. callourfunction43. ldrr0,_inject

7、_function_param_s設(shè)置hook_init第一個(gè)參數(shù)44. blxr3執(zhí)行hook_init45. subsr0,r0,#046. beq2f47. 48. 1:49. dlclose50. movr0,r4把dlopen的返回值設(shè)為dlcose的第一個(gè)參數(shù)51. ldrr3,_dlclose_addr_s設(shè)置dlclose函數(shù)52. blxr3執(zhí)行dlclose函數(shù)53. 54. 2:55. restorecontext56. ldrr1,_saved_cpsr_s恢復(fù)CPSR57. msrcpsr_cf,r158. ldrsp,_saved_r0_pc_s恢復(fù)寄存器r0-r1

8、559. ldmfdsp,r0-pc60. 61. 62. 63. 64. _dlopen_addr_s:初始化_dlopen_addr_s65. .word0x1111111166. 67. _dlopen_param1_s:68. .word0x1111111169. 70. _dlopen_param2_s:71. .word0x2RTLD_GLOBAL72. 73. _dlsym_addr_s:74. .word0x1111111175. 76. _dlsym_param2_s:77. .word0x1111111178. 79. _dlclose_addr_s:80. .word0x

9、1111111181. 82. _inject_function_param_s:83. .word0x1111111184. 85. _saved_cpsr_s:86. .word0x1111111187. 88. _saved_r0_pc_s:89. .word0x1111111190. 91. 92. _inject_end_s:代碼結(jié)束地址93. 94. .space0x400,0代碼段空間大小95. 96. .end4. 如何把【加載.so的實(shí)現(xiàn)代碼】寫入目標(biāo)進(jìn)程并啟動(dòng)執(zhí)行? 為了把【加載.so的實(shí)現(xiàn)代碼】寫入目標(biāo)進(jìn)程,主要有以下兩步操作: 1) 在目標(biāo)進(jìn)程中找到存放【加載.so的實(shí)

10、現(xiàn)代碼】的空間(通過mmap實(shí)現(xiàn)) 2) 把【加載.so的實(shí)現(xiàn)代碼】寫入目標(biāo)進(jìn)程指定的空間 3) 啟動(dòng)執(zhí)行4.1 在目標(biāo)進(jìn)程中找到存放【加載.so的實(shí)現(xiàn)代碼】的空間 通過mmap來實(shí)現(xiàn),其實(shí)現(xiàn)步驟如下: 1) 獲取目標(biāo)進(jìn)程中mmap地址 2) 把mmap參數(shù)據(jù)放入r0-r3,另外兩個(gè)寫入目標(biāo)進(jìn)程sp 3) pc設(shè)置為mmap地址,lr設(shè)置為0 4) 把準(zhǔn)備好的寄存器寫入目標(biāo)進(jìn)程(PTRACE_SETREGS),并啟動(dòng)目標(biāo)進(jìn)程運(yùn)行(PTRACE_CONT) 5) 分配的內(nèi)存首地址位于r0(PTRACE_GETREGS)4.2 為【加載.so的實(shí)現(xiàn)代碼】中的全局變量賦值 1) 獲取目標(biāo)進(jìn)程中dlo

11、pen地址并賦值給_dlopen_addr_s 2) 獲取目標(biāo)進(jìn)程中dlsym地址并賦值給_dlsym_addr_s 3) 獲取目標(biāo)進(jìn)程中dlclose地址并賦值給_dlclose_addr_s 4) 把需要加載的.so的路徑放入 匯編代碼中,并獲取此路徑在目標(biāo)進(jìn)程中的地址然后賦值給_dlopen_param1_s 5)把需要加載的.so中的hook_init放入 匯編代碼中,并獲取此路徑在目標(biāo)進(jìn)程中的地址然后賦值給_dlsym_param2_s 6) 把目標(biāo)進(jìn)程中的cpsr保存在_saved_cpsr_s中 7) 把目標(biāo)進(jìn)程中的r0-r15存入?yún)R編代碼中,并獲取此變量在目標(biāo)進(jìn)程中的地址然后賦

12、值給_saved_r0_pc_s 8) 通過ptrace( PTRACE_POKETEXT,.)把匯編代碼寫入目標(biāo)進(jìn)程中,起始地址由前面的mmap所分配 9) 把目標(biāo)進(jìn)程的pc設(shè)置為匯編代碼的起始地址,然后調(diào)用ptrace(PTRACE_DETACH,.)以啟動(dòng)目標(biāo)進(jìn)程執(zhí)行5. 把匯編代碼寫入目標(biāo)進(jìn)程并執(zhí)行的實(shí)現(xiàn)代碼5.1 主函數(shù) writecode_to_targetproccppview plaincopy1. #include2. #include3. #include4. #include5. #include6. #include7. #include8. #include9. #i

13、nclude10. #include11. #include12. #include13. #include14. #include15. #include16. #include17. 18. #defineMAX_PATH0x10019. #defineREMOTE_ADDR(addr,local_base,remote_base)(uint32_t)(addr)+(uint32_t)(remote_base)-(uint32_t)(local_base)20. 21. /*writetheassemblercodeintotargetproc,22. *andinvokeittoexec

14、ute23. */24. intwritecode_to_targetproc(25. pid_ttarget_pid,/targetprocesspid26. constchar*library_path,/thepathof.sothatwillbe27. /uploadtotargetprocess28. constchar*function_name,/.soinitfucntione.g.hook_init29. void*param,/theparametersofinitfunction30. size_tparam_size)/numberofparameters31. 32.

15、 intret=-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. structpt_regsregs,original_regs;39. 40.

16、 /externglobalvariableintheassemblercode41. externuint32_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_tcode_length;47. 48. longparameters1

17、0;49. 50. /maketarget_pidasitschildprocessandstop51. if(ptrace_attach(target_pid)=-1)52. return-1;53. 54. /getthevaluesof18registersfromtarget_pid55. if(ptrace_getregs(target_pid,s)=-1)56. gotoexit;57. 58. /saveoriginalregisters59. memcpy(&original_regs,s,sizeof(regs);60. 61. /getmmapaddressfromtarg

18、et_pid62. /themmapistheaddressofmmapinthecurprocess63. mmap_addr=get_remote_addr(target_pid,/system/lib/libc.so,(void*)mmap);64. 65. /setmmapparameters66. parameters0=0;/addr67. parameters1=0x4000;/size68. parameters2=PROT_READ|PROT_WRITE|PROT_EXEC;/prot69. parameters3=MAP_ANONYMOUS|MAP_PRIVATE;/fla

19、gs70. parameters4=0;/fd71. parameters5=0;/offset72. 73. /executethemmapintarget_pid74. if(ptrace_call(target_pid,(uint32_t)mmap_addr,parameters,6,s)=-1)75. gotoexit;76. 77. /getthereturnvaluesofmmap78. if(ptrace_getregs(target_pid,s)=-1)79. gotoexit;80. 81. /getthestartaddressforassemblercode82. map

20、_base=(uint8_t*)regs.ARM_r0;83. 84. /gettheaddressofdlopen,dlsymanddlcloseintargetprocess85. 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/lin

21、ker,(void*)dlclose);88. 89. /setthestartaddressforassemblercodeintargetprocess90. remote_code_ptr=map_base+0x3C00;91. 92. /setthestartaddressforassemblercodeincurprocess93. local_code_ptr=(uint8_t*)&_inject_start_s;94. 95. /setglobalvariableofassemblercode96. /andtheseaddressisinthetargetprocess97.

22、_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_PAT

23、H;105. saved_r0_pc_ptr=dlsym_param2_ptr+MAX_PATH;106. inject_param_ptr=saved_r0_pc_ptr+MAX_PATH;107. 108. 109. /savelibrarypathtoassemblercodeglobalvariable110. strcpy(dlopen_param1_ptr,library_path);111. _dlopen_param1_s=REMOTE_ADDR(dlopen_param1_ptr,local_code_ptr,remote_code_ptr);112. 113. 114. /

24、savefunctionnametoassemblercodeglobalvariable115. strcpy(dlsym_param2_ptr,function_name);116. _dlsym_param2_s=REMOTE_ADDR(dlsym_param2_ptr,local_code_ptr,remote_code_ptr);117. 118. /savecpsrtoassemblercodeglobalvariable119. _saved_cpsr_s=original_regs.ARM_cpsr;120. 121. /saver0-r15toassemblercodeglo

25、balvariable122. memcpy(saved_r0_pc_ptr,&(original_regs.ARM_r0),16*4);/r0r15123. _saved_r0_pc_s=REMOTE_ADDR(saved_r0_pc_ptr,local_code_ptr,remote_code_ptr);124. 125. /savefunctionparameterstoassemblercodeglobalvariable126. memcpy(inject_param_ptr,param,param_size);127. _inject_function_param_s=REMOTE

26、_ADDR(inject_param_ptr,local_code_ptr,remote_code_ptr);128. 129. /writetheassemblercodeintotargetprocess130. /nowthevaluesofglobalvariableisinthetargetprocessspace131. ptrace_writedata(target_pid,remote_code_ptr,local_code_ptr,0x400);132. 133. memcpy(s,&original_regs,sizeof(regs);134. 135. /setspand

27、pctothestartaddressofassemblercode136. regs.ARM_sp=(long)remote_code_ptr;137. regs.ARM_pc=(long)remote_code_ptr;138. 139. /setregistersfortargetprocess140. ptrace_setregs(target_pid,s);141. 142. /makethetarget_pidisnotachildprocessofcurprocess143. /andmaketarget_pidcontinuetorunning144. ptrace_detac

28、h(target_pid);145. 146. /nowfinishitsuccessfully147. ret=0;148. 149. exit:150. returnret;151. 5.2 attach目標(biāo)進(jìn)程ptrace_attachcppview plaincopy1. intptrace_attach(pid_tpid)2. 3. /afterPTRACE_ATTACH,theprocwillstop4. if(ptrace(PTRACE_ATTACH,pid,NULL,0)0)5. 6. perror(ptrace_attach);7. return-1;8. 9. 10. /w

29、aitprocstop11. waitpid(pid,NULL,WUNTRACED);12. 13. /afterPTRACE_SYSCALL,theprocwillcontinue,14. /butwhenexectuesyscallfunction,procwillstop15. if(ptrace(PTRACE_SYSCALL,pid,NULL,0)0)16. 17. perror(ptrace_syscall);18. return-1;19. 20. 21. /waitprocstop22. waitpid(pid,NULL,WUNTRACED);23. 24. return0;25

30、. 5.3 獲取目標(biāo)進(jìn)程寄存器值ptrace_getregscppview plaincopy1. intptrace_getregs(pid_tpid,structpt_regs*regs)2. 3. if(ptrace(PTRACE_GETREGS,pid,NULL,regs)0)4. 5. perror(ptrace_getregs:Cannotgetregistervalues);6. return-1;7. 8. 9. return0;10. 5.4 獲取目標(biāo)進(jìn)程中指定模塊中指定函數(shù)的地址get_remote_addrcppview plaincopy1. 2. /*findthes

31、tartaddressofmodulewhosenameismodule_name3. *inthedesignatedprocess4. */5. void*get_module_base(pid_tpid,constchar*module_name)6. 7. FILE*fp;8. longaddr=0;9. char*pch;10. charfilename32;11. charline1024;12. 13. if(pid0)14. 15. /*selfprocess*/16. snprintf(filename,sizeof(filename),/proc/self/maps,pid

32、);17. 18. else19. 20. snprintf(filename,sizeof(filename),/proc/%d/maps,pid);21. 22. 23. fp=fopen(filename,r);24. 25. if(fp!=NULL)26. 27. while(fgets(line,sizeof(line),fp)28. 29. if(strstr(line,module_name)30. 31. pch=strtok(line,-);32. addr=strtoul(pch,NULL,16);33. 34. if(addr=0x8000)35. addr=0;36.

33、37. break;38. 39. 40. fclose(fp);41. 42. 43. return(void*)addr;44. 45. 46. void*get_remote_addr(pid_ttarget_pid,constchar*module_name,void*local_addr)47. 48. void*local_handle,*remote_handle;49. 50. local_handle=get_module_base(-1,module_name);51. remote_handle=get_module_base(target_pid,module_name

34、);52. 53. return(void*)(uint32_t)local_addr+(uint32_t)remote_handle-(uint32_t)local_handle);54. 5.5 在目標(biāo)進(jìn)程中執(zhí)行指定函數(shù)ptrace_callcppview plaincopy1. intptrace_call(pid_tpid,uint32_taddr,long*params,uint32_tnum_params,structpt_regs*regs)2. 3. uint32_ti;4. 5. /putthefirst4parametersintor0-r36. for(i=0;inum_

35、params&iuregsi=paramsi;9. 10. 11. /pushremainedparamsintostack12. if(iARM_sp-=(num_params-i)*sizeof(long);15. ptrace_writedata(pid,(void*)regs-ARM_sp,(uint8_t*)msi,(num_params-i)*sizeof(long);16. 17. /setthepctofuncthatwillbeexecuted18. regs-ARM_pc=addr;19. if(regs-ARM_pc&1)20. 21. /*thumb*/22. regs

36、-ARM_pc&=(1u);23. regs-ARM_cpsr|=CPSR_T_MASK;24. 25. else26. 27. /*arm*/28. regs-ARM_cpsr&=CPSR_T_MASK;29. 30. 31. /whenfinishthisfunc,pidwillstop32. regs-ARM_lr=0;33. 34. /settheregsisterandstarttoexecute35. if(ptrace_setregs(pid,regs)=-136. |ptrace_continue(pid)=-1)37. 38. return-1;39. 40. 41. /wa

37、itpidfinishworkandstop42. waitpid(pid,NULL,WUNTRACED);43. 44. return0;45. 5.6 把代碼寫入目標(biāo)進(jìn)程指定地址ptrace_writedatacppview plaincopy1. intptrace_writedata(pid_tpid,uint8_t*dest,uint8_t*data,size_tsize)2. 3. uint32_ti,j,remain;4. uint8_t*laddr;5. 6. unionu7. longval;8. charcharssizeof(long);9. d;10. 11. j=size/4;12. remain=size%4;13. 14. laddr=data;15. 16. for(i=0;i0)26. 27. d.val=ptrace(PTRACE_PEEKTEXT,pid,dest,0);28. for(i=0;i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論