滴水逆向 RVA與FOA相互轉換

2021-10-23 04:28:52 字數 3395 閱讀 9679

(開始這段別人總結的比較好,我就拿來用了)

1.rva to foa

即我們現在知道記憶體狀態下的偏移,需要找到檔案狀態下的偏移。

步驟如下圖:

step1:記憶體中的位址減去記憶體基址得到偏移,即rva。

step2:迴圈遍歷節表中各個節的資訊,判斷在哪個節中。(需要滿足:記憶體偏移+節資料沒對齊的大小》image_panyi>記憶體偏移)

step3:找出在哪個節後,減去該節在記憶體中的偏移(virturaladdress)得到在該節中的相對偏移。

step4:上一步得到的該節的相對偏移+該節在檔案中的偏移(pointtorawdata),即得到foa

2.foa to rva

現在我們已經知道如何從記憶體中的偏移轉化為檔案中的偏移。現在是它的逆過程

step1:檔案中的位址減去檔案基址,得到在檔案中的偏移,即foa。

step2:迴圈遍歷節表中各個節的資訊,判斷在哪個節中。(檔案對齊+檔案偏移》file_panyi>檔案偏移)

step3:找出在哪個節後,減去該節在檔案中的偏移(virturaladdress)得到在該節中的相對偏移。

step4:上一步得到的該節的相對偏移+該節在記憶體中的偏移(virtualaddress),即得到rva。

3.**實現

#include#include#include#define test 1

dword toloaderpe(lpstr file_path, pvoid* pfilebuffer);

dword foatoimageoffset(pvoid pbuffer, dword dwfoa);

dword rvatofileoffset(pvoid pbuffer, dword dwrva);

char file_path = "c:\\users\\njupt\\desktop\\notepad.exe";

char write_file_path = "d:\\lib\\cp_xx.exe";

//返回pe檔案大小

dword toloaderpe(lpstr file_path, pvoid* pfilebuffer)

fseek(pfile, 0, seek_end);

filesize = ftell(pfile);

printf("filebuffer: %#x\n", filesize);

fseek(pfile, 0, seek_set);

pfilebuffertemp = malloc(filesize);

if (!pfilebuffertemp)

dword n = fread(pfilebuffertemp, filesize, 1, pfile);

if (!n)

*pfilebuffer = pfilebuffertemp;

pfilebuffertemp = null;

fclose(pfile);

return filesize;

}dword rvatofileoffset(pvoid pbuffer, dword dwrva)

if (*((pword)pbuffer) != image_dos_signature)

pdosheader = (pimage_dos_header)pbuffer;

if (*((pdword)((dword)pbuffer + pdosheader->e_lfanew)) != image_nt_signature)

printf("imageoffset: %#x\n", dwrva);

pntheader = (pimage_nt_headers)((dword)pbuffer + pdosheader->e_lfanew);

ppeheader = (pimage_file_header)((dword)pntheader + 4); // 這裡必須強制型別轉換

poptionheader = (pimage_optional_header32)((dword)ppeheader + image_sizeof_file_header);

psectionheader = (pimage_section_header)((dword)poptionheader + ppeheader->sizeofoptionalheader);

pimage_section_header psectiontemp = psectionheader;

if (dwrva <= poptionheader->sizeofheaders)

return (dword)dwrva;

else

}} printf("rvatofoa failed!\n");

return 0;

}dword foatoimageoffset(pvoid pbuffer, dword dwfoa)

if (*((pword)pbuffer) != image_dos_signature)

pdosheader = (pimage_dos_header)pbuffer;

if (*((pdword)((dword)pbuffer + pdosheader->e_lfanew)) != image_nt_signature)

printf("fileoffset: %#x\n", dwfoa);

pntheader = (pimage_nt_headers)((dword)pbuffer + pdosheader->e_lfanew);

ppeheader = (pimage_file_header)((dword)pntheader + 4); // 這裡必須強制型別轉換

poptionheader = (pimage_optional_header32)((dword)ppeheader + image_sizeof_file_header);

psectionheader = (pimage_section_header)((dword)poptionheader + ppeheader->sizeofoptionalheader);

pimage_section_header psectiontemp = psectionheader;

if (dwfoa <= poptionheader->sizeofheaders)

return (dword)dwfoa;

else

}} printf("foatorva failed!\n");

return 0;

}void operate()

int main()

4.結果展示

RVA與FOA的轉換

1.pe程式加載入記憶體後頭的位址與檔案中一致,但對齊方式 偏移 不同 2.結構體 typedef struct image section header misc dword virtualaddress 節區的rva位址 dword sizeofrawdata 在檔案中對齊後的尺寸 dword ...

RVA與FOA的轉換

我們執行程式可以看見相應的值,那麼我們可以是否可以在檔案中直接搜尋對應的值然後修改呢?這種方法沒有毛病,但是檔案中也許會存在很多個0x12345678,你無法準確的知道哪乙個才是全域性變數 那麼,又是否可以通過已經給出的這個位址0x42ba30直接去尋找呢?當然也是不行的,因為在之前章節的學習中我們...

PE檔案學習 RVA與FOA轉換

當我們的pe檔案沒有被裝載到記憶體中的時候,它是以什麼樣的儲存方式在磁碟中儲存呢?當被裝載到記憶體之後,pe檔案的內容又是什麼樣的光景呢?今天我們說的重點就是rva和foa的轉換,之前我們已經知道pe檔案在磁碟檔案中的對齊粒度是0x200,在記憶體中的對齊粒度是0x1000,我們來看一張 windo...