Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>(edit: If by "physical address", you mean the level of "in which RAM module are my bits stored", then the following answer is inappropriate.)</p> <p>You don't need root privileges to do this. What you need instead is a debugger. And here we go (using a Linux system on x86_64):</p> <p>First we need a little program to play with. This one accesses a global variable and prints it two times in a row. It has two global variables, which we find in the memory later.</p> <pre> #include &lt;stdio.h> int a, b = 0; int main(void) { printf("a: "); if (fscanf("%d", &a) &lt; 1) return 0; printf("a = %d\n", myglobal); printf("b: "); if (fscanf("%d", &b) &lt; 1) return 0; printf("a = %d, b = %d\n", a, b); return 0; } </pre> <p>Step 1: Compile the program and strip all debug information from it, so we don't get any hints from the debugger that we wouldn't get in a real life situation.</p> <pre> $ gcc -s -W -Wall -Os -o ab ab.c </pre> <p>Step 2: Run the program and input one of the two numbers.</p> <pre> $ ./ab a: 123 a = 123 b: _ </pre> <p>Step 3: Find the process.</p> <pre> $ ps aux | grep ab roland 21601 0.0 0.0 3648 456 pts/11 S+ 15:17 0:00 ./ab roland 21665 0.0 0.0 5132 672 pts/12 S+ 15:18 0:00 grep ab </pre> <p>Step 4: Attach a debugger to the process (21601).</p> <pre> $ gdb ... (gdb) attach 21601 ... (gdb) where #0 0x00007fdecfdd2970 in read () from /lib/libc.so.6 #1 0x00007fdecfd80b40 in _IO_file_underflow () from /lib/libc.so.6 #2 0x00007fdecfd8230e in _IO_default_uflow () from /lib/libc.so.6 #3 0x00007fdecfd66903 in _IO_vfscanf () from /lib/libc.so.6 #4 0x00007fdecfd7245c in scanf () from /lib/libc.so.6 #5 0x0000000000400570 in ?? () #6 0x00007fdecfd2f1a6 in __libc_start_main () from /lib/libc.so.6 #7 0x0000000000400459 in ?? () #8 0x00007fffd827da48 in ?? () #9 0x000000000000001c in ?? () #10 0x0000000000000001 in ?? () #11 0x00007fffd827f9a2 in ?? () #12 0x0000000000000000 in ?? () </pre> <p>The interesting frame is number 5, since it is between some code calling the <code>main</code> function and the <code>scanf</code> function, so it must be our <code>main</code> function. Continuing the debugging session:</p> <pre> (gdb) frame 5 ... (gdb) disassemble $pc $pc+50 ... 0x0000000000400570 : test %eax,%eax 0x0000000000400572 : jle 0x40058c &lt;scanf@plt+372> 0x0000000000400574 : mov 0x2003fe(%rip),%edx # 0x600978 &lt;scanf@plt+2098528> 0x000000000040057a : mov 0x2003fc(%rip),%esi # 0x60097c &lt;scanf@plt+2098532> 0x0000000000400580 : mov $0x40068f,%edi 0x0000000000400585 : xor %eax,%eax 0x0000000000400587 : callq 0x4003f8 &lt;printf@plt> ... </pre> <p>Now we know that the function <code>printf</code> will get three parameters, and two of there are only four bytes away from each other. That's a good sign that these two are our variables <code>a</code> and <code>b</code>. So the address of <code>a</code> is either 0x600978 or 0x60097c. Let's find out by trying:</p> <pre> (gdb) x/w 0x60097c 0x60097c &lt;scanf@plt+2098532>: 0x0000007b (gdb) x/w 0x600978 0x600978 &lt;scanf@plt+2098528>: 0x00000000 </pre> <p>So <code>a</code>, the variable that is read in first, is at address 0x60097c (because 0x0000007b is the hexadecimal representation for 123, which we entered), and <code>b</code> is at 0x600978.</p> <p>Still in the debugger, we can modify the variable <code>a</code> now and then continue the program.</p> <pre> (gdb) set *(int *)0x60097c = 1234567 (gdb) continue </pre> <p>Back in the program that asked us to enter two numbers:</p> <pre> $ ./ab a: 123 a = 123 b: 5 a = 1234567, b = 5 $ </pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload