這就是之前我所說到的,memcpy的乙個函式漏洞,他庫函式本身就不能避免這個漏洞,所以在進行模仿的時候雖然發現了這個問題但是還是沒有將這個問題彌補,因為有讓你彌補的地方,那就是來模仿這個
memmove
函式。
再給大家來說一下memcpy函式的漏洞是哪個,就是上圖這樣,如果你開始將原始區域的內容複製到目標區域的時候,會將你後半部分的原始區域的資料進行覆蓋,造成你原始資料的丟失,所以,你在模仿
memmove
函式的時候就需要對你操作的兩個空間進行判斷,看你所要操作的兩個資料區域是不是上圖的重合情況,如果是的話那你就需要進行特殊的操作。
那特殊的操作是什麼呢?期初我是想將原始區域後半部分的資料提前儲存起來,之後再對其進行使用,後來我才發現了乙個更好的辦法就是將你發的複製操作變成從後開始複製,而不是我們正常的從前往後複製。
下邊就來寫乙個這個模擬庫函式的**:
#include
#include
#include
void *my_memmove(void *det, const
void *src, int
n)void *ret = det;
if ((char*)det
<= (char *)src || (char *)det >= (char *)src + n)
while (n--)
*(char *)det = *(char *)src;
det = (char *)det + 1;
src = (char *)src + 1;
else
det = (char *)det + n - 1;
src = (char *)src + n - 1;
while (n--)
*(char *)det = *(char *)src;
det = (char *)det -1;
src = (char *)src - 1;
return ret;
int main()
char arr[10] = "abcd";
my_memmove(arr + 2, arr, 4);
printf("記憶體覆蓋:%s\n", arr + 2);
system("pause");
return 0;
很多人納悶為什麼在你的函式開頭要將
*(char *)det = *(char *)src;
det = (char *)det + 1;
src = (char *)src + 1;
這些資料都強制轉化成乙個char*型別,並不是說你操作的物件是字串,是因為你操作的單位是乙個字元,因為
char
型別的占用的記憶體大小就是乙個字元,所以這裡需要將你的內容變成乙個
char*
型別以對字元進行操作。
這裡再進入函式的時候你就需要對這兩個操作空間進行乙個簡單的判斷,判斷是不是出現了之前所說的那種情況。如果出現了就要對這個資料拷貝進行反向拷貝
所以上述程式中即使兩個操作區域進行了覆蓋依然可以進行正常的拷貝操作。對一些庫函式的模仿暫時就這些了,之後如果還有那些經典的值得大家來模仿一下深究的庫函式,我會繼續更新給大家。
模擬實現memmove函式
memmove函式也是從源src 拷貝n個位元組到目的 dst 中。與memcpy不同的是,memmove會考慮記憶體重疊問題,會對兩記憶體的位置進行判斷,從而考慮是從前往後拷貝或是從後往前拷貝。記憶體中的位置關係可以分為以下四種,而前三種又能統一劃分到一組,因為在這種情況下,從前往後拷貝時,拷貝過...
模擬實現memmove函式
int arr 6 將陣列前4個元素複製到後4個元素上,即將陣列變為 將陣列還原為初始在將後四個元素複製到三個元素上,即為 void my memcpy void dest,void src,size t count return ret int main memcpy arr 2,arr,16 將...
c 模擬實現memmove
memmove 是乙個記憶體操作函式,不是字串操作函式,它可以處理多種型別的資料。它的原型是 void memmove void dest,const void src,size t count 注意 1 它的返回值是void 引數型別也是void 這樣它才可以處理不同型別的資料。2 目標dest不...