Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 561 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to print exact value of the program counter in C

#1
I want to write a C program which would print the contents of the program counter `PC`. Can this be done from user space, or assembly, or some specific kernel routines are used?
Reply

#2
Well I think you can get the information by inserting assembly blocks inside your C code. This will totally depend on your compiler and the register set of your platform.
I did it like this:

int get_counter1()

{

__asm__ ("lea (%rip), %eax ") ;
}

int get_counter2()

{

int x = 0;
__asm__ ("lea (%rip), %eax") ;
}

int main()

{

printf("%x\n",get_counter1());
printf("%x\n",get_counter2());
return 0;
}

4004ce

4004e1
Reply

#3
On ARM, you can use:

static __inline__ void * get_pc(void) {
void *pc;
asm("mov %0, pc" : "=r"(pc));
return pc;
}

Or this one should work as well:

static __inline__ void * get_pc(void) {
register void * pc __asm__("pc");
__asm__("" : "=r"(pc));
return pc;
}

The forced inlining is important here, because that ensures you retrieve `PC` as per the call site.

**Edit:** just remembered, [`__current_pc()` ARM intrinsic][1]. GCC should have this as well.


[1]:

[To see links please register here]

Reply

#4
You should be able to determine the PC by using the [`__current_pc()` intrinsic][1] in the ARM compiler toolchain (the ARM compiler supports many of the same extensions as GCC).<sup>*</sup> This is particular to ARM:

int main () {
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
return 0;
}

> <sub>* Thanks to FrankH. for pointing out the presence of `__current_pc()`</sub>

In general, the PC gets saved as the return address in a function call. On non-ARM [tag:linux] systems with GCC, you can call `__builtin_return_address(0)` to obtain the return address of the current function call context. Obtaining the program counter in this way incurs the penalty of adding a function call, but it avoids inline assembly, so this technique is portable to any system supported by GCC.

__attribute__ ((__noinline__))
void * get_pc () { return __builtin_return_address(0); }

int main () {
printf("%p\n", get_pc());
printf("%p\n", get_pc());
printf("%p\n", get_pc());
return 0;
}

When I run the above program on my `x86` system, it produces the output:

0x8048432
0x8048447
0x804845c

When disassembled in `gdb`:

Dump of assembler code for function main:
0x08048424 <+0>: push %ebp
0x08048425 <+1>: mov %esp,%ebp
0x08048427 <+3>: and $0xfffffff0,%esp
0x0804842a <+6>: sub $0x10,%esp
0x0804842d <+9>: call 0x804841c <get_pc>
0x08048432 <+14>: mov %eax,0x4(%esp)
0x08048436 <+18>: movl $0x8048510,(%esp)
0x0804843d <+25>: call 0x80482f0 <printf@plt>
0x08048442 <+30>: call 0x804841c <get_pc>
0x08048447 <+35>: mov %eax,0x4(%esp)
0x0804844b <+39>: movl $0x8048510,(%esp)
0x08048452 <+46>: call 0x80482f0 <printf@plt>
0x08048457 <+51>: call 0x804841c <get_pc>
0x0804845c <+56>: mov %eax,0x4(%esp)
0x08048460 <+60>: movl $0x8048510,(%esp)
0x08048467 <+67>: call 0x80482f0 <printf@plt>
0x0804846c <+72>: mov $0x0,%eax
0x08048471 <+77>: leave
0x08048472 <+78>: ret
End of assembler dump.

[1]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through