日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
【博文推薦】如何獲得C語言函數(shù)起始地址和返回地址
 本博文出自博客gmxydm 博主,有任何問題請(qǐng)進(jìn)入博主頁面互動(dòng)討論!
博文地址:http://5412097.blog./5402097/1641374
 

在反外掛系統(tǒng)中,經(jīng)常會(huì)檢測函數(shù)的返回地址,確認(rèn)函數(shù)的返回地址在規(guī)定的范圍之內(nèi),從而保證,游戲程序中的函數(shù),不被外掛所調(diào)用。這種檢查方式就涉及到一個(gè)基本的技術(shù)問題,如何獲得函數(shù)的返回地址?

10年積累的成都做網(wǎng)站、網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站策劃后付款的網(wǎng)站建設(shè)流程,更有茂名免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

例如下面的***段代碼:

 
 
  1. #include 
  2. int main() 
  3. getchar(); 
  4. return 0; 

非常簡單的一段程序,那么我們?nèi)绾潍@得該函數(shù)的起始地址和返回地址呢?起始地址獲取非常容易,如下:

 
 
  1. #include 
  2. int main() 
  3. printf("%0x\n",main); 
  4. getchar(); 
  5. return 0; 

那么如何獲得函數(shù)的返回地址呢?這個(gè)就相對(duì)來說比較困難。我們先看***段代碼反匯編后的結(jié)果:

 
 
  1. #include 
  2. intmain() 
  3. 009919E0 push ebp 
  4. 009919E1 mov ebp,esp 
  5. 009919E3 sub esp,0C0h 
  6. 009919E9 push ebx 
  7. 009919EA push esi 
  8. 009919EB push edi 
  9. 009919EC lea edi,[ebp-0C0h] 
  10. 009919F2 mov ecx,30h 
  11. 009919F7 mov eax,0CCCCCCCCh 
  12. 009919FC rep stos dword ptr es:[edi] 
  13. getchar(); 
  14. 009919FE mov esi,esp 
  15. 00991A00 call dword ptr [__imp__getchar (9982B0h)] 
  16. 00991A06 cmp esi,esp 
  17. 00991A08 call @ILT+295(__RTC_CheckEsp) (99112Ch) 
  18. return 0; 
  19. 00991A0D xor eax,eax 
  20. 00991A0F pop edi 
  21. 00991A10 pop esi 
  22. 00991A11 pop ebx 
  23. 00991A12 add esp,0C0h 
  24. 00991A18 cmp ebp,esp 
  25. 00991A1A call @ILT+295(__RTC_CheckEsp) (99112Ch) 
  26. 00991A1F mov esp,ebp 
  27. 00991A21 pop ebp 
  28. 00991A22 ret

代碼開始部分,先保存ebp的內(nèi)容,然后將ESP的內(nèi)容寫入EBP:

 
 
  1. 009919E0 push ebp 
  2.  
  3. 009919E1 mov ebp,esp 

匯編指令call會(huì)做兩件事情,其一,將call指令后面的一條指令的地址壓入棧中,無條件跳轉(zhuǎn)到call指令的調(diào)用地指處,開始執(zhí)行子程序。

和call指令對(duì)應(yīng)的ret指令,則開始執(zhí)行call指令后面的一條指令。

那么,ret指令如何知道call指令后面一條指令的地址呢?因?yàn)閏all指令已經(jīng)將這條指令壓入到了棧中,所以ret指令可以找到call指令后的一條指令的地址。

既然ret指令可以找到call的返回地址,也就是call的下一條指令的地址,那么我們也可以找到!??!

main函數(shù)在執(zhí)行前以及執(zhí)行過程中,棧的分布如下:

通過以上幾張圖,我們可以清楚的看到,main函數(shù)的返回地址在[EBP+4]處。所以,獲得main函數(shù)的返回地址的代碼如下:

 
 
  1. #include 
  2. int main() 
  3. int re_addr; 
  4. __asm 
  5. mov eax,dword ptr [ebp+4] 
  6. mov re_addr,eax 
  7. printf("%0X\n",re_addr); 
  8. getchar(); 
  9. return 0; 

其中__tmainCRTStartup()函數(shù)調(diào)用了main函數(shù),調(diào)用的匯編代碼如下:

mainret = main(argc, argv, envp);

00B81926  mov        eax,dword ptr [envp (0B87140h)] 

00B8192B  push       eax 

00B8192C  mov        ecx,dword ptr [argv (0B87144h)] 

00B81932  push       ecx 

00B81933  mov        edx,dword ptr [argc (0B8713Ch)] 

00B81939  push       edx 

00B8193A call        @ILT+300(_main)(0B81131h) 

00B8193F  add        esp,0Ch 

00B81942  mov        dword ptr [mainret (0B87154h)],eax

可以看出,call main指令后的一條指令的地址為:00B8193F,而我們獲得的main的返回地址如下:

B8193F

說明我們獲得的結(jié)果正確。

對(duì)于其他函數(shù)的情況類似,下面筆者就把獲得某個(gè)函數(shù)的返回值得功能,做成一個(gè)函數(shù),提供給大家,如下:

 
 
  1. #include 
  2.  
  3. int Get_return_addr() 
  4. int re_addr; 
  5. __asm 
  6. mov eax,dword ptr [ebp] 
  7. mov ebx,dword ptr [eax+4] 
  8. mov re_addr,ebx 
  9. returnre_addr; 
  10.  
  11.  
  12. int main() 
  13. intre_addr=Get_return_addr(); 
  14. printf("%0X\n",re_addr); 
  15. getchar(); 
  16. return 0; 

Get_return_add函數(shù)中,為什么會(huì)多幾條匯編指令呢?大家可以自行思考。


分享題目:【博文推薦】如何獲得C語言函數(shù)起始地址和返回地址
網(wǎng)站地址:http://www.5511xx.com/article/ccodpep.html