C++程序怎麼在鏈接期間確保一塊內存空間?
我有一個非常反人類的DLL,要求使用進程中一塊固定地址和大小的內存(例如0x200000-0x300000),我的EXE要確保這塊內存可用,才能載入那個DLL。
我試過設定EXE的固定基址,然後建立一個巨大的全局變數來佔用這段空間,但隨著EXE里的代碼增加,這個全局變數終於被其它文件里的變數「擠」出了那個範圍,導致那個DLL內部出錯。
問1:怎麼確保這塊內存?
我的編程環境是:Windows,VS2017,32位EXE
PS:那個DLL沒有源碼,也不再維護,但我必須使用它。
需要操作固定內存空間的dll,怕不是dos時代的東西了吧
windows從很早就(一定)不把dll載入到pe頭裡面指定的基地址了
補充VirtualAlloc可以
#include &
#include &
int main()
{
std::cout &<&< VirtualAlloc((void*)0x200000,0x100000,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE) &<&< std::endl;
std::cout &<&< GetLastError() &<&< std::endl;
}
或許VirtualAllocEx能解決你的問題,不過我覺得你應該逆向了這個dll自己再重新開發一個替換掉他,否則肯定會被坑死。
題主在評論里說了這個反人類DLL沒有重定位表,那麼我下面的方法可能是唯一可行的。因為0x200000這個地址實在是太低了,以至於EXE稍微載入幾個導入表裡的DLL就會把這裡分配掉(沒錯,我說的就是user32.dll)。
另外寫一個EXE作為launcher(自己啟動自己也行),CreateProcess帶CREATE_SUSPEND參數啟動你這個反人類EXE,然後VirtualAllocEx 0x200000-0x300000這塊空間,這個時候進程里只有EXE和NTDLL,所以肯定能申請成功。
然後ResumeThread讓你的反人類EXE開始執行。在EXE中VirtualFree掉父進程申請的這塊空間,然後立即調用LoadLibrary載入你的反人類DLL。@vczh
真是反人類啊……
如果是我的話我就在DLL裡面封裝一個Mapping,然後把任意VirtualAlloc一塊內存之後把入口地址Maping為0x20000000,然後把指針封裝起來操作避免直接動裸指針就好了
很簡單…改了呢個dll就行…
沒開玩笑,自己veh去接管了它的異常,跑一遍
在所有觸發異常的地方做個記錄
然後隨便找個啥反彙編工具,反彙編了呢個地方的代碼
之後自己寫個DllLoader
先分配一塊內存,把DLL載入進去
之後把所有之前標記好的地方patch掉
然後處理好導入表導出表
peb裡面的雙鏈表插好數據,讓api知道有這個東西的存在
……………………分割線…………………
昨玩這些你就對pe loader的reloc有了深刻的認識(滑稽把這個DLL放到一個簡單的EXE裡面,只提供進程間通訊的介面. 其他代碼用進程間通訊的方式調用.
首先load DLL,再申請一塊內存,將DLL 0x20000000常數修改為你申請的內存地址不就行了? 又穩定,又省事。
謝邀,具體參考http://github.com/nagist/metahook不過可能會遇到DEP問題,慎用。
VirtualAllocEx 可以指定分配空間的起始地址,lpAddress參數設置成指定的值即可,但是如果你要的空間已被分配了,那估計就是失敗。你可以試一下。
推薦閱讀:
※怎麼看待做手游cocos前端開發,lua用的多,c++用的少面試會被鄙視?
※若要向C++之父 Bjarne Stroustrup 請教10個技術Topics,有什麼好的建議么?
※將一個double類型的指針自增一次,前後的地址差是否一定為sizeof(double)?