Reputation: 313
Still a novice to C and the different things I am finding online as to how this is done are confusing me.
I have an address converted to an unsigned long value in order to verify that something is at that address in /proc/self/maps.
Once verified, I want to print the byte that is at that address.
From what I am gathering, the address itself is simply a pointer to that byte, so I need to dereference the memory address to get the byte.
So if I wanted to print that byte as a hex number, it would simply be:
printf("%02x", *address)
Any input would be appreciated. Thanks!
Upvotes: 1
Views: 1576
Reputation: 67546
#define UCPTR(addr) (volatile unsigned char*)(addr)
printf("0x%02hhx", *UCPTR(address));
To prevent question why volatile
?
#define UCPTR(addr) (volatile unsigned char*)(addr)
#define NVUCPTR(addr) (unsigned char*)(addr)
void foo()
{
while(*NVUCPTR(0x4564));
}
void bar()
{
while(*UCPTR(0x4564));
}
and the resulting code:
foo:
cmp BYTE PTR ds:17764, 0
je .L1
.L3:
jmp .L3
.L1:
ret
bar:
.L6:
movzx eax, BYTE PTR ds:17764
test al, al
jne .L6
ret
I think that the code is self explanatory
Can it be archived other way? Yes, but not portable, for example:
void foo()
{
while(*NVUCPTR(0x4564)) asm("":::"memory");
}
Upvotes: 1
Reputation: 60067
printf("%02x", (unsigned)*(unsigned char*)the_address_as_an_integer_or_pointer);
Explanation:
If you want to fetch a value from an address, it needs a pointer type. So you cast to a pointer to a char
. (Strict aliasing permits fetching any value through a pointer to a character type, other pointer types are more limited). Casting to signed char *
would lead to sign-extension (undesirable if you want to print the value as an unsigned
) so you cast to *unsigned char
. Then you dereference (*
).
Such a *(unsigned char*)address
has type unsigned char
, which gets promoted to int
when passed through the ...
of printf
. That usually works with "%x"
, but to fully satisfy the standard, "%x"
requires an unsigned
and thence the final cast to unsigned
.
Upvotes: 2