1

I am writing a self-modifying program; already got it working. I found these two functions, but not sure what EXACTLY they do and I like to comment my code proper.

pagesize is got using getpagesize

/*
 * Defining variables:
 * func - function in memory I'm using mprotect on
 * offset - the offset in memory
 * ptr - the pointer to the memory
 */

unsigned int offset = (unsigned int)( ((long)func) & (pagesize-1) );
unsigned char * ptr = (unsigned char *) ((long)func & (~(pagesize-1) ) );

I have found offset's function being used for memory alignment checks. I know vaguely what they do, but not the difference?

Thanks.

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
Thomas
  • 1,401
  • 8
  • 12

2 Answers2

4

Assuming pagesize is the size of a page, they use bit masks to calculate the pointer (ptr) to the start of the page containing func, and the offset (offset) within that page in bytes.

As pagesize will always be a power of two, (pagesize-1) has all ones set. The offset within the page is the last 12 (for instance) bits (12 corresponds with pagesize is 4k=2^12), so the first statement clears all the bits except the last 12 by using & with an all ones bitmask of 12 least significant bits.

The second line calculates the pointer to the page itself by clearing the last 4 bits; by using the logical inverse (~) of the previous bitmask, then an &, it clears all the other bits.

abligh
  • 24,573
  • 4
  • 47
  • 84
  • Ok, why the -1? Any way to explain why the location can be extracted from a pointer? – Thomas Jan 22 '14 at 18:20
  • 2
    Try writing the bits out on paper. Offset 5 (binary 101) would of page 3, (binary 11), would be at location `11 0000 0000 0101`. Binary for 4k is `01 0000 0000 0000`. So 4k-1 is `00 1111 1111 1111`. Now we can use that as a mask to AND with the location to give `00 0000 0000 0101` (i.e. 5, the offset). If we invert it, we get `...(ones)... 1111 0000 0000 0000 0000`, which we can then AND with the location, to get `11 0000 0000 0000`, i.e. a pointer to the page. Not quite sure what you mean by "why the location can be extracted from a pointer". A pointer *is* the location. – abligh Jan 22 '14 at 18:24
0

(I'll assume that "pagesize" is the platform's page size, and it's a power of two - e.g. on x86 it's 0x1000. Also I'll assume the "func" is a pointer to a function, i.e. the code you want to change).

"offset" contains the offset of the page of the code, while "pthr" contains the virtual address at which the memory page containing the code is mapped. My guess is that somewhere in your program a new virtual view (with different access rights, in particular write permission) of the code's page is created. Let's say that this new address is stored in "unsigned char *page2". So, the code may be changed by writing to *(page2 + offset).

Giuseppe Guerrini
  • 4,274
  • 17
  • 32