Natuurlijk mag een applicatie wel registers wijzigen. Ook de program counter dus. Je krijgt pas een foutmelding wanneer je probeert de program counter in een ongeldige page te plaatsen.
Helaas zijn C# en C++ beiden erg ongeschikt voor het manipuleren van hardware op registernivo. Je zal hoe dan ook assembly moeten gebruiken. Zoek eens naar de Microsoft Macro Assembler (MASM), bijvoorbeeld. Ik zou in jou specifieke geval aanraden om de profiling code in assembly te schrijven en te linken tegen een C++/C# executable, want GUI's bouwen in assembly is een hel.
Ik denk trouwens dat het ophalen van de programcounter niet zo nuttig is. Op het moment dat je die opvraagt met een stukje code, weet je al waar die naar wijst: naar de code die de programcounter opvraagt! Wat je wil lijkt me daarom niet zo haalbaar, maar daar kom je zelf wel achter. Handiger is waarschijnlijk om op kritische punten in je programma tellers te installeren, zodat je kunt zien hoe vaak bepaalde routines worden aangeroepen e.d.