取得檔案在記憶體中的位置貼)

來源:互聯網
上載者:User

從 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這樣一些系統級的進程還不清楚它地基址  
  //   上面的代碼只支援使用者級的應用程式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.