In the K.N.King book, there’s an example:
viewmemory.c
/* Allows the user to view regions of computer memory */
#include <stdio.h>
#include <ctype.h>
typedef unsigned char BYTE;
int main(void)
{
unsigned int addr;
int i, n;
BYTE *ptr;
printf("Address of main function: %x\n", (unsigned int) main);
printf("Address of addr variable: %x\n", (unsigned int) &addr);
printf("\nEnter a (hex) address: ");
scanf("%x", &addr);
printf("Enter number of bytes to view: ");
scanf("%d", &n);
printf("\n");
printf(" Address Bytes Characters\n");
printf(" ------- ------------------------------- ----------\n");
ptr = (BYTE *) addr;
for (; n > 0; n -= 10) {
printf("%8X ", (unsigned int) ptr);
for (i = 0; i < 10 && i < n; i++)
printf("%.2X ", *(ptr + i));
for (; i < 10; i++)
printf(" ");
printf(" ");
for (i = 0; i < 10 && i < n; i++) {
BYTE ch = *(ptr + i);
if (!isprint(ch))
ch = '.';
printf("%c", ch);
}
printf("\n");
ptr += 10;
}
return 0;
}
For some reason, when I try to enter addr variable address as the parameter, it has a segmentation fault error. However, in the book’s example and the screenshot from this site in Hangul, there’s no such error?
When I try using gdb
to check the issue, here’s what I get:
gdb
$ gdb ./a.out --silent
Reading symbols from ./a.out...
(gdb) run
Starting program: /home/<username>/Desktop/c-programming-a-modern-approach/low-level-programming/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/gnu/store/zvlp3n8iwa1svxmwv4q22pv1pb1c9pjq-glibc-2.39/lib/libthread_db.so.1".
Address of main function: 401166
Address of addr variable: ffffd678
Enter a (hex) address: ffffd678
Enter number of bytes to view: 64
Address Bytes Characters
------- ------------------------------- ----------
Program received signal SIGSEGV, Segmentation fault.
0x000000000040123a in main () at viewmemory.c:31
warning: Source file is more recent than executable.
31 printf ("%.2X ", *(ptr + i));
(gdb)
What is going on? By the way, I am using Guix, if that matters in any way. Here’s the output for ldd
:
ldd
$ ldd ./a.out
linux-vdso.so.1 (0x00007ffecdda9000)
libgcc_s.so.1 => /gnu/store/w0i4fd8ivrpwz91a0wjwz5l0b2ralj16-gcc-11.4.0-lib/lib/libgcc_s.so.1 (0x00007fcd2627a000)
libc.so.6 => /gnu/store/zvlp3n8iwa1svxmwv4q22pv1pb1c9pjq-glibc-2.39/lib/libc.so.6 (0x00007fcd2609c000)
The pointer
addr
is actually undefined, and currently points to some random every time it is executed. Could this be where the memory protection is being triggered, preventing access to other segments?Could be, yeah.
I guess I didn’t read the code well enough, but I was expecting
addr
to point to somewhere on the stack.I guess that’s something to try - declare and assign a variable and then print the address of it, and then use that to take a look at stack memory.