日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

[转帖]虚拟内存探究 -- 第二篇:Python 字节

發(fā)布時(shí)間:2024/10/12 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转帖]虚拟内存探究 -- 第二篇:Python 字节 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

虛擬內(nèi)存探究 -- 第二篇:Python 字節(jié)

http://blog.coderhuo.tech/2017/10/15/Virtual_Memory_python_bytes/是真看不懂哦

  

?翻譯 ?虛擬內(nèi)存??翻譯

這是虛擬內(nèi)存系列文章的第二篇。
這次我們要做的事情和《虛擬內(nèi)存探究 – 第一篇:C strings & /proc》類似,不同的是我們將訪問(wèn)Python 3 腳本的虛擬內(nèi)存。這會(huì)比較費(fèi)勁, 所以我們需要了解Pyhton3 內(nèi)部的一些機(jī)制。

一、預(yù)備知識(shí)

本文基于上一篇文章《虛擬內(nèi)存探究 – 第一篇:C strings & /proc》中所講的知識(shí), 所以,在繼續(xù)閱讀本文前,請(qǐng)確保閱讀并理解上一篇文章。

為了方便理解本文,你需要具備以下知識(shí):

  • C語(yǔ)言基礎(chǔ)
  • 些許Python知識(shí)
  • 了解Linux的文件系統(tǒng)和shell命令
  • /proc文件系統(tǒng)的基本知識(shí)(可參閱《虛擬內(nèi)存探究 – 第一篇:C strings & /proc》中的相關(guān)介紹)

二、實(shí)驗(yàn)環(huán)境

所有的腳本和程序都在下面的環(huán)境中測(cè)試過(guò):

  • Ubuntu 14.04 LTS
    • Linux ubuntu 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
  • gcc
    • gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
  • Python 3
    • Python 3.4.3 (default, Nov 17 2016, 01:08:31)
    • [GCC 4.8.4] on linux

三、剖析一個(gè)簡(jiǎn)單的Python腳本

下面是我們將要使用的Python腳本(main.py)。我們將嘗試修改運(yùn)行該腳本的進(jìn)程虛擬內(nèi)存中的“字符串”?Holberton。

#!/usr/bin/env python3 ''' Prints a b"string" (bytes object), reads a char from stdin and prints the same (or not :)) string again '''import syss = b"Holberton" print(s) sys.stdin.read(1) print(s)

Python中的字節(jié)對(duì)象(bytes object)

字節(jié)和字符串(bytes vs str)

譯者注:bytes在這里翻譯成字節(jié), 并非指單個(gè)字符。

如上面代碼所示,我們使用一個(gè)字節(jié)對(duì)象(字符串Holberton前面的b說(shuō)明這是個(gè)字節(jié)對(duì)象)來(lái)存儲(chǔ)字符串Holberton。字節(jié)對(duì)象會(huì)把字符串中的字符以字節(jié)的形式(相對(duì)于每個(gè)字符占多個(gè)字節(jié)的字符串編碼方式而言,也就是寬字符編碼,具體可參閱unicodeobject.h)存下來(lái)。這樣可以保證字符串在虛擬內(nèi)存中是連續(xù)的ASCII碼。

從技術(shù)上來(lái)講, 上面代碼中的s并不是一個(gè)Python字符串。如下所示, 它是一個(gè)字節(jié)對(duì)象(不過(guò)沒(méi)關(guān)系, 這不影響我們的后續(xù)討論):

julien@holberton:~/holberton/w/hackthevm1$ python3 Python 3.4.3 (default, Nov 17 2016, 01:08:31) [GCC 4.8.4] on linux Type "help", "copyright", "credits" or "license" for more information. >>> s = "Betty" >>> type(s) <class 'str'> >>> s = b"Betty" >>> type(s) <class 'bytes'> >>> quit()

一切都是對(duì)象

Pyhton中的整數(shù)、字符串、字節(jié)、函數(shù)等等, 都是對(duì)象。所以, 語(yǔ)句s = b"Holberton"將創(chuàng)建一個(gè)字節(jié)對(duì)象,并將字符串存在內(nèi)存中某處。字符串Holberton很可能在堆上,因?yàn)镻ython必須為字節(jié)對(duì)象s以及s指向的字符串分配內(nèi)存(字符串可能直接存在對(duì)象s中,也可能s只維護(hù)了一個(gè)指向字符串的索引,目前我們并不確定具體的實(shí)現(xiàn))。

對(duì)python腳本執(zhí)行read_write_heap.py腳本

提示:read_write_heap.py是《虛擬內(nèi)存探究 – 第一篇:C strings & /proc》中的腳本,用來(lái)查找并替換內(nèi)存中的字符串。

我們首先執(zhí)行前面的腳本main.py:

julien@holberton:~/holberton/w/hackthevm1$ ./main.py b'Holberton'

這時(shí)main.py阻塞在語(yǔ)句sys.stdin.read(1)上,一直在等待用戶輸入。

接下來(lái)我們用管理員權(quán)限執(zhí)行腳本read_write_heap.py:

julien@holberton:~/holberton/w/hackthevm1$ ps aux | grep main.py | grep -v grep julien 3929 0.0 0.7 31412 7848 pts/0 S+ 15:10 0:00 python3 ./main.py julien@holberton:~/holberton/w/hackthevm1$ sudo ./read_write_heap.py 3929 Holberton "~ Betty ~" [*] maps: /proc/3929/maps [*] mem: /proc/3929/mem [*] Found [heap]:pathname = [heap]addresses = 022dc000-023c6000permisions = rw-poffset = 00000000inode = 0Addr start [22dc000] | end [23c6000] [*] Found 'Holberton' at 8e192 [*] Writing '~ Betty ~' at 236a192 julien@holberton:~/holberton/w/hackthevm1$

不出所料,我們?cè)诙焉险业搅俗址瓾olberton并且將之替換成’~ Betty ~’。
現(xiàn)在我們按下回車鍵讓腳本main.py繼續(xù)執(zhí)行,它應(yīng)該會(huì)輸出b'~ Betty ~':

b'Holberton' julien@holberton:~/holberton/w/hackthevm1$

什么???

我們找到字符串Holberton并且替換了它,但是這不是我們要找的字符串?繼續(xù)深入探究之前,我們需要再確認(rèn)一件事情。我們的腳本read_write_heap.py在目標(biāo)字符串首次出現(xiàn)之后就退出了,如果堆中有多個(gè)字符串Holberton呢?為了避免遺漏,我們將腳本read_write_heap.py執(zhí)行多次。

還是先啟動(dòng)腳本main.py:

julien@holberton:~/holberton/w/hackthevm1$ ./main.py b'Holberton'

然后多次執(zhí)行腳本read_write_heap.py:

julien@holberton:~/holberton/w/hackthevm1$ ps aux | grep main.py | grep -v grep julien 4051 0.1 0.7 31412 7832 pts/0 S+ 15:53 0:00 python3 ./main.py julien@holberton:~/holberton/w/hackthevm1$ sudo ./read_write_heap.py 4051 Holberton "~ Betty ~" [*] maps: /proc/4051/maps [*] mem: /proc/4051/mem [*] Found [heap]:pathname = [heap]addresses = 00bf4000-00cde000permisions = rw-poffset = 00000000inode = 0Addr start [bf4000] | end [cde000] [*] Found 'Holberton' at 8e162 [*] Writing '~ Betty ~' at c82162 julien@holberton:~/holberton/w/hackthevm1$ sudo ./read_write_heap.py 4051 Holberton "~ Betty ~" [*] maps: /proc/4051/maps [*] mem: /proc/4051/mem [*] Found [heap]:pathname = [heap]addresses = 00bf4000-00cde000permisions = rw-poffset = 00000000inode = 0Addr start [bf4000] | end [cde000] Can't find 'Holberton' julien@holberton:~/holberton/w/hackthevm1$

字符串’Holberton’在堆上只出現(xiàn)了一次。那么腳本main.py所使用的字符串’Holberton’到底在哪里呢?Python的字節(jié)對(duì)象又是在內(nèi)存的哪部分呢?有沒(méi)有可能在棧上?我們可以把腳本read_write_heap.py中的[heap]改成[stack]試試看。

提示:文件/proc/[pid]/maps中標(biāo)記為[stack]的部分就是棧, 具體可參閱上一篇文件《虛擬內(nèi)存探究 – 第一篇:C strings & /proc》。

改寫(xiě)棧的腳本read_write_stack.py如下, 它所做的和之前的腳本read_write_heap.py一樣,唯一的不同是它訪問(wèn)進(jìn)程的棧:

#!/usr/bin/env python3 ''' Locates and replaces the first occurrence of a string in the stack of a processUsage: ./read_write_stack.py PID search_string replace_by_string Where: - PID is the pid of the target process - search_string is the ASCII string you are looking to overwrite - replace_by_string is the ASCII string you want to replace search_string with '''import sysdef print_usage_and_exit(): print('Usage: {} pid search write'.format(sys.argv[0])) sys.exit(1) # check usage if len(sys.argv) != 4: print_usage_and_exit() # get the pid from args pid = int(sys.argv[1]) if pid <= 0: print_usage_and_exit() search_string = str(sys.argv[2]) if search_string == "": print_usage_and_exit() write_string = str(sys.argv[3]) if search_string == "": print_usage_and_exit() # open the maps and mem files of the process maps_filename = "/proc/{}/maps".format(pid) print("[*] maps: {}".format(maps_filename)) mem_filename = "/proc/{}/mem".format(pid) print("[*] mem: {}".format(mem_filename)) # try opening the maps file try: maps_file = open('/proc/{}/maps'.format(pid), 'r') except IOError as e: print("[ERROR] Can not open file {}:".format(maps_filename)) print(" I/O error({}): {}".format(e.errno, e.strerror)) sys.exit(1) for line in maps_file: sline = line.split(' ') # check if we found the stack if sline[-1][:-1] != "[stack]": continue print("[*] Found [stack]:") # parse line addr = sline[0] perm = sline[1] offset = sline[2] device = sline[3] inode = sline[4] pathname = sline[-1][:-1

轉(zhuǎn)載于:https://www.cnblogs.com/jinanxiaolaohu/p/10917729.html

總結(jié)

以上是生活随笔為你收集整理的[转帖]虚拟内存探究 -- 第二篇:Python 字节的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。