2016-01-27 70 views
-1

我試圖檢測使用C/C++編寫的每個訪問程序在運行時正在進行的操作,特別是動態分配的內存。另外,我想了解一些有關訪問權限的信息。訪問的函數名稱就是我正在尋找的。檢測每個由C/C++程序進行的內存訪問

例如,對於下面的代碼:

void MemoryAccess(int* my_vector) { 
    int x = my_vector[0]; // Read access from 0xFFFF0000. 
    my_vector[0] = x + 1; // Write access to 0XFFFF0000. 
} 

int main(void) { 
    // Assume that the address returned by malloc is 0xFFFF0000. 
    int* vec = malloc(VEC_SIZE * sizeof(int)); 
    if (!vec) { 
     return MEMORY_ALLOCATION_FAIL; 
    } 
    MemoryAccess(vec); 

    int second_elem = vec[1]; // Read access from 0xFFFF0004. 
    v[1] = 10; // Write access to 0xFFFF0004. 

    return 0; 
} 

我想記錄一個日誌文件,包含以下內容:地址已被訪問,即取得了訪問函數名。對於上面的例子,我的日誌應該是這個樣子:

{Read} {MemoryAccess} {0xFFFF0000} 
{Write} {MemoryAccess} {0xFFFF0000} 
{Read} {main}   {0xFFFF0004} 
{Write} {main}   {0xFFFF0004} 

我已經能夠使用異常過濾器做在Windows這樣的事情,並修改監視內存塊的頁面保護。我無法獲得訪問該函數的名稱,只有在引發異常時才提供指令指針值,並且我無法知道如何使用它來獲取函數名稱。

注意:我的目標是監視基於Linux的系統(主要是Debian/Ubuntu)上的內存訪問,而不是Windows。

+0

valgrind能幫助你嗎? – Angew

+1

請提供該「C/C++」語言規範的鏈接。直到那時只有兩種不同的**語言C和C++。這不是C++。這兩種語言的問題都有不同的解決方案。 – Olaf

+0

@Angew:我不認爲Valgrind會監控**每個**訪問。 – Olaf

回答

2

(我專注於Linux的)

你想要做什麼將是很慢和需要不可移植的代碼如果做天真。我想你想要一個通用的解決方案(在許多C++程序上工作,而不是在某個特定的一個上)。

你可以修補一些模擬器,àla Qemu。

也許你只是想用valgrindGCC debugging options如地址消毒劑(搜索-fsanitize=address)。或使用gdb觀察點。請注意,最近的GDB在Python或Guile中是可腳本化的。

也許你可以從valgrind的技巧中獲得靈感。

看還成ptrace(2)

如果你不想災難性的性能(即,天真地解釋每個機器指令和/或處理每一個內存訪問的SIGSEGV,請參見this更多),你需要很棘手。

您可以考慮自定義GCC編譯器(例如使用MELT),以便某些(相關)加載存儲在編譯器內部進行插裝。

如果你採取一種天真的方法(解釋每一個機器指令和/或粗略的SIGSEGV處理),你可能會減慢你的程序超過一千倍,而「半天真」的方法仍然需要幾個月的工作。你會遇到Heisenbugs

如果你想有一個嚴肅的態度,你就需要修改GCC編譯器(例如用MELT),使一些儀器代碼是另外編譯器發出,重新編譯要儀表程序(和所有的圖書館它使用),並且可能會帶你至少一年(除非你已經熟練使用GCC內部)。

如果你是認真的,學習更多的計算機科學(computer architecture,operating systems, compilers),並讓你的博士工作。你需要幾年的努力。