存取的方式有很多種,我就列幾種比較常看到的方式:
1. WinIo -有開放原始碼,有興趣的可以研究一下,透過Driver層下去做
2. 呼叫NTDll.dll內的函數 - 這是原本我在XP的做法如下!
wchar_t strPath[30]=L"\\device\\physicalmemory";
LoadLibrary("ntdll.dll");
然後使用下列函數:
ZwOpenSection
ZwMapViewOfSection
ZwUnmapViewOfSection
這些函數可以對實體記憶體映射,不過這個方式在Vista下會無法使用,看樣子VISTA基於安全性考量已經這些功能拿掉了!
3.而在Vista下我目前是直接寫IO Driver,然後AP去Call我自己寫的Driver來讀,作法其實是如同WinIO.. ,只是我把我要的功能抽取出來而已,這個方式就是我用來撰寫DumpBIOS這個工具的作法,原本是用方式2,但是Vista不支援因此才改成方式3,你可能會問我為什麼不用方式1 ?
沒為什麼,就是想自己寫個IO Driver而已~~
Reference
Microsoft
Google
14 則留言:
大大你好
想請問一下利用WINIO怎樣透過底層DRIVER存取Memory,可以說的仔細一點ㄇ,
另外IO Driver,網路上有沒有類似的source code 可以參考,不好意思,對Driver這部份比較弱一點,可以指教一下ㄇ,謝謝
你下載WinIO Source code後裡面會有範例程式,我貼一部份給你看:
void main()
{
// Call InitializeWinIo to initialize the WinIo library.
bResult = InitializeWinIo();
if (bResult)
{
GetPortVal(0x378, &dwPortVal, 4);
SetPortVal(0x378, 10, 4);
GetPhysLong((PBYTE)0xA0000, &dwMemVal);
SetPhysLong((PBYTE)0xA0000, 10);
ShutdownWinIo();
}
}
而WinIO也是一個IO Driver,它裡面也是透過Windows API的方式去存取實體記憶體位址,下面是他負責存取記憶體內容的函數宣告:
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,
ULONG PhysMemSizeInBytes,
PVOID *ppPhysMemLin,
HANDLE *pPhysicalMemoryHandle)
在視窗底下,我目前都是使用SE.EXE 來看IO或是記憶體的值,那請教一下SE.EXE是用哪種方式呢?可以寫的跟他一樣短小精幹嗎!
SE.exe...你可能要問一下原作者!
不過我猜他也是用IO Driver方式啦!
因為在Windows 底下IO Driver最簡單!
我猜他是直接把IO Driver包在執行檔內[Note1],然後在載入執行檔的過程中去分割出IO Driver,然後在透過此IO Driver去存取需要的硬體資訊.而讓OS載入IO Driver的這個做法就是透過SCM的方式啦[Note2]!
Note1: 包在執行檔後面的方式可透過Copy /b方式.
Note2:OS提供的SCM Services可以動態載入驅動程式
大大,你說需要改driver,然後從下面的code下手,但study winio一段時間,可以access memory到0xFFFFF,但access 4G memory還是沒有頭緒,driver要動很多地方ㄇ,可以多點提示ㄇ,只需要改driver就好,那DLL有需要修改ㄇ,謝謝
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,
ULONG PhysMemSizeInBytes,
PVOID *ppPhysMemLin,
HANDLE *pPhysicalMemoryHandle)
PVOID MmMapIoSpace(
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberOfBytes,
IN MEMORY_CACHING_TYPE CacheType
);
F.Y.I
harrison您好
我是使用網路上的WinIO.dll
目地是想要對某一個port做IO access
在Windows 2000, XP, 2003,下都可以使用
不過現在環境換到 Windows2008 64bit下就無法InitializeWinIO
不曉得您了不了解這樣的狀況原因為何
我在很多地方發問仍舊找不到解決方法
只知道問題應該是出在32bit和64bit下應該是會造成這樣的影響
如果您有任何想法或是意見的話
還請不吝賜教
謝謝
jonyjo0915@yahoo.com.tw
Edward
harrison您好
我是使用網路上的WinIO.dll
目地是想要對某一個port做IO access
在Windows 2000, XP, 2003,下都可以使用
不過現在環境換到 Windows2008 64bit下就無法InitializeWinIO
不曉得您了不了解這樣的狀況原因為何
我在很多地方發問仍舊找不到解決方法
只知道問題應該是出在32bit和64bit下應該是會造成這樣的影響
如果您有任何想法或是意見的話
還請不吝賜教
謝謝
jonyjo0915@yahoo.com.tw
Edward
PVOID MmMapIoSpace(
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberOfBytes,
IN MEMORY_CACHING_TYPE CacheType
);
F.Y.I
请问具体怎么做啊,能不能给一个例子....
How to Access I/O Ports in WindowsNT/2K/X
http://mach.debagua.com/archives/2004/0721_000163.html
I/O 埠讀寫的實現
http://win.chinaunix.net/bbs/frame.php?frameon=yes&referer=http%3A//win.chinaunix.net/bbs/thread-11201-1-1.html
你好:
因為我目前需在XP下存取Memory, 無論我用WinIO的GetPhysLong或是ZwMapViewOfSection等方法對於較後段的位置讀取都有錯誤, EX: 0xEFFC0000; 不知道是否能請你協助教導更直接的辦法, 例如你說的方法3, 若可以提供Sample Code就更感謝了! 謝謝!
抱歉, 補上我的e-Mail:
raymond700429@gmail.com
你好,在網路上看到你的部落格,想向你討教一下,如果我在windows底下,用AP設陣列(例:A[10]),,然後讀取位置,再去實際的記憶體位地抓內容,發現裡面所存在的值不是我要的,是不是我們設定出來的陣列,所存在的記憶體位址是虛擬的?如果要去抓此陣列實際所存的記憶體位址要如何讀取呢?是有一定的公式做轉換嗎?謝謝(E-mail:chennick2001@hotmail.com)
張貼留言