I am aware that there is a little information regarding the pagemap file here. But nobody seems to indicate how to reference entries in the file. Is it offset by virtual address? Can I take a virtual address VA and simply lseek to offset VA? Or is it by page? If so, how do I retrieve the page number, as maps simply lists them in order. I am trying to translate between virtual and physical addresses, and lseek'ing with the virtual address as the offset always returns the same number, no matter where I seek to.
Thanks
#leeduhem: Yes I have. Here's the relevant part:
3. Open /proc/pid/pagemap and seek to the pages you would like to examine.
4. Read a u64 for each page from pagemap.
That doesn't help me. It wants me to seek to the page, but how do I know where the entry for the page is?
There is a tool that will help you to get information you need from the pagemap file.
http://fivelinesofcode.blogspot.com/2014/03/how-to-translate-virtual-to-physical.html
You divide the virtual address by the pagesize (normally 0x1000 or 4096) and use that to index in /proc/self/pagemap. After the division, that's known as the PFN, or page frame number.
Larry
Related
I am writing to inquire the feasibility of tracing the page table access (in terms of "index" of each page table access) of a common Linux user application. Basically, what I am doing is to re-produce the exploitation mentioned in this research article (https://www.ieee-security.org/TC/SP2015/papers-archived/6949a640.pdf). In particular, the data-page accesses need to be recorded for usage and inference of program secrets.
I understand the on Linux system, 64-bit x86 architecture, the page table size is 4K. And i have used pin (https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool) to log a trace of addresses for all virtual memory access. So can I simply calculate the "index" of each data page table access, with the following translation rule?
index = address >> 15
Since 4KB = 2 ^ 15. Is it correct? Thank you in advance for any suggestions or comments.
Also, I think one thing I want to point out is that conceptually, I don't need a "precise" identifier of each data page table ID, but just a number ("index") to distinguish the access of different data pages. This shall provide conceptually identical amount of information compared with their attacks.
Ok, so you don't really need an "index", but just some unique identifier to distinguish different pages in the virtual address of a process.
In such case, then you can just do address >> PAGE_SHIFT. In x86 with 4KB pages PAGE_SHIFT is 12, so you can do:
page_id = address >> 12
Then if address1 and address2 correspond to the same page the page_id will be the same for both addresses.
Alternatively, to achieve the same result, you could do address & PAGE_MASK, where PAGE_MASK is just 0xfffffffffffff000 (that is ~((1UL << PAGE_SHIFT) - 1)).
I am reading a book about linux.It says the address 0x7c00 is about 31K.I want to know how to get the 31K according to address.The code is:mov ax,#BOOTSEG.Which #BOOTSEG is 0x07c0.I have already search from internet.
I am told that I can find the physical address corresponding to a virtual address using /proc/[pid]/pagemap.
I read that this pagemap file is an array of 64-bit entries, with bits 0-54 corresponding to the page frame number. I don't know how to make the leap from this to translating virtual to physical. Partially, I don't know how to find the entry I want in this file; nobody seems to specify how they are indexed.
Also, I don't know if the PFN is virtual or physical. And I don't know what to do with the PFN, regardless. How can I proceed?
Thanks
Divide the VA by the page size (4096 normally), use that as an offset into /proc/self/pagemap. Then take that number (the page), multiply by the pagesize (4096), and offset that by your VA%4094.
Larry
From LDD3/ Ch. 15/ sections "Using remap_pfn_range" and "A Simple Implementation", pfn has been equated to the vm_pgoff field. I am confused by this. How can that be so?
Note that vm_pgoff is described as:
The offset of the area in the file, in pages. When a file or device is
mapped, this is the file position of the first page mapped in this
area.
Thus if the first page mapped corresponds to the first page of the file as well (which, I think would be quite common), vm_pgoff would be 0. correct? If so, this doesn't seem to be the correct value for the pfn parameter of remap_pfn_range( ). What am I missing here? What is the correct value? For ease of reference, I am reproducing the relevant code from LDD3 below (Page no. 426)
static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma)
{
if (remap_pfn_range(vma, vma->vm_start, vm->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
...
}
The specific example you've provided is implementing a character device file that allows one to map physical memory, very similar to /dev/mem. By specifying the offset of the file you specify the physical memory address. Hence the calculation that takes the offset and divide in the page size to find the PFN.
For a "real" device driver, you would normally have the physical address of the device memory mapped registers or RAM hard coded from the device specification, and use that to derive the PFN (by dividing by the page size).
What is the difference between a relative virtual address and an offset from the base of a file??
The RVA is the relative-virtual address, that is, the distance from the preferred base address. The preferred base address is stated in the PE header, and is the (preferred) virtual address of the start of the image in memory for when the executable be loaded in memory.
And the file offset is the number of bytes you have to read from the beginning of the PE file to arrive somewhere in the file. So, if you have a section, you will find both things in the section header: the RVA of the section and its offset in the file; you will also find two sizes, one for how much virtual memory the section will get once loaded and one that merely indicates the size of the section data in the PE file.
Many references inside a PE are given as RVAs. In such cases, you need to check in all the section headers (or have some sort of map) to get the offset in the PE file of the reference.