從 csdn 上找到的
原檔案地址:http://topic.csdn.net/t/20021224/14/1295059.html
------------------------
知道一個進程的ID/HANDLE/FileName,怎麼取得它在記憶體中的映像檔案地址?!樓主FIGLAB(無花果)2002-12-24 14:04:54 在 VC/MFC / 進程/線程/DLL 提問
知道一個進程的ID/HANDLE/FileName,怎麼取得它在記憶體中的映像檔案地址?!像
IMAGE_NT_HEADERTF等。
我知道ReadProcessMomey API是可以,但是它裡面有個參數BaseAddress(基址),應該
就是映像檔案的首地址吧?!可是我連它的首址都取不到,那我更加不能用
ReadProcessMomey來取得它了!
請問:怎麼取得它的映像地址呢?!
3 樓fangyan()回複於 2002-12-25 16:32:46 得分
10
這個簡單,呵呵。這個地址就在檔案的OptionalHeader裡,
IMAGE_NT_HEADER ImageNtHeader = GetImageNtHeaderFromFile(FileName);
DWORD BaseAddress = ImageNtHeader.OptionalHeader.ImageBase;
Top
4 樓FIGLAB(無花果)回複於 2002-12-26 13:20:14 得分 0
首先,謝謝各位!
昨天我已經用這樣的方法可以列出所有的在記憶體中進程:
/*
* 這裡只是部分代碼而以
*/
PROCESSENTRY32 pProcessEntry = new PROCESSENTRY32;
MODULEENTRY32 pModuleEntry = new MODULEENTRY32;
char cpProcessFileName[MAX_PATH];
char cpModuleFileName[MAX_PATH];
bool bOK = false;
HANDLE hSnapshot = ::CreateToolhelp32Snapshot(
TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS,
dwProcessID);
for (bool bProcess = ::Process32First(hSnapshot, pProcessEntry),
bProcess,
bProcess = ::Process32Next(hSnapshot, pProcessEntry))
{
HANDLE hS = ::CreateToolhelp32Snapshot(
TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS,
pProcessEntry->dwProcessID);
for (bool bModule = ::Module32First(hSnapshot, pModuleEntry),
bModule,
bModule = ::Module32Next(hSnapshot, pModuleEntry))
{
/* 注意:
* in windows 9x
* cpModuleFileName = pModuleEntry-szExePath
* in windows 2000
* cpModuleFileName = pModuleEntry->szModule
*
* use _strupr in VC
* use strupr in BCB
*/
strcpy(cpProcessFileName, strupr(pProcessEntry->szExePath));
strcpy(cpModuleFileName, strupr(pModuleEntry->szExePath));
if (strcmp(cpProcessFileName, cpModuleFileName) == 0)
{
bOK = true;
break;
}
}
if (!bOK)
continue;
fprintf(stdout,
"%-40s Address:%10x/n",
cpModuleFileName, (DWORD)cpModuleFileName->modBaseAddr);
::CloseHandle(hS);
}
::CloseHandle(hSnapshot);
但是,為什麼列出的每一個使用者級的進程地址都是0x400000呢?!
可是,當前0x400000的地址是當前啟動並執行程式首址,也就是的我的這個程式。
我怎麼才能得到真正的進程地址呢?!
Top
5 樓slwqw(四大名捕之追殺令)回複於 2002-12-27 10:43:41 得分
49
在W9X/2000/NT下面,每一個進程都有自己獨立的線性地址空間,這個線性地址空間範圍從0-4GB,不同的是不同進程的線性地址空間對應的物理地址空間並不一樣。
如果想使用ReadProcessMemory()讀取別的進程的記憶體空間,可以這樣:
1、利用上面你的代碼得到指定進程的ID。
2、使用OpenProcess()開啟進程,得到其控制代碼hProcess。
3、使用DuplicateHandle()複製hProcess為hDupProcess。
4、ReadProcessMemory(hDupHandle,...........)。
=========
上面是讀取進程的內容,但是從你的問題來看,你想讀IMAGE_NT_HEADER這種東西,這個應該讀模組部分。
1、同樣利用Module32First、Module32Next尋找指定進程的模組。
2、下面代碼得到模組的“入口地址”、“基地址”:
//入口地址(摸塊控制代碼)
Item->SubItems->Add(IntToHex((int)ModEntry32.hModule,8));
//基地址,EntryPoint就是模組的進入點,從這個地方開始讀
MODULEINFO mi;
GetModuleInformation(hProcess,ModEntry32.hModule,&mi,sizeof(MODULEINFO));
Item->SubItems->Add(IntToHex((int)mi.EntryPoint,8));
EntryPoint就是進入點(廢話!:)),ReadProcessMemory()從那個地方開始讀就可以了。
特別聲明:我並沒有真正使用上面代碼來讀模數塊的IMAGE_NT_HEADER部分,上面的方法只是建議,無法保證它能正常工作。
Top
11 樓FIGLAB(無花果)回複於 2002-12-31 10:49:56 得分 0
對不起,這兩天忙著去把一個遊戲修改器反組譯碼來研,所以沒有上著來,
也謝謝各位的幫忙!
經過努力終於被做出來了,大家也來分享一下,因為,我沒有發現哪位的回答比較正確,所以,也給大家來研究一下:
// 其實不是很難,真的,就一個參數問題,呵呵
#define PROCESS_BASE_ADDRESS //使用者級程式基地址
DWORD dwP[0x200]; // 讀進來的buffer
// Get Process's Handle with read/write VM
hProcessID = OpenProcess(
PROCESS_VM_READ | PROCESS_VM_WRITE, // 注意啊!就是用這兩個參數
false,
dwProcessID); // 進程的ID
ReadProcessMemory(hProcessID, 0x400000, dwM, sizeof(dwM), NULL);
// 呵呵^_&,就這麼地簡單!!!
// 知道這些你也可以做個遊戲修改器了,哈哈!
// 不過,還有一些進程是讀不出來的,或者說不是讀不出來吧,而是還不
// 知道它的基址,像kernal32.dll這樣一些系統級的進程還不清楚它地基址
// 上面的代碼只支援使用者級的應用程式