Wo ist das Problem? Mach die Verbindung doch andersherum. Also programmiere deine Software in eine Reverse Connection um.
Also so, dass der Server eben nicht hinter der Firewall ist, bzw. wo Port Forwarding möglich ist. Der Client braucht ja kein Port Forwarding.
Es gibt nur einen Unterschied. Normalerweise läuft der Server ständig und der Client verbindet zu bestimmten Zeitpunkten.
Baut man die Software zu einer Reverse Connection um (getautschte Rollen), dann muss der Client eben periodisch versuchen die Verbindung zum Server selbstgesteuert aufzunehmen, bis dieser startet und auf seinem Port lauscht.
Sind jedoch sowohl Client und Server hinter einer Firewall bzw. hinter einer NAT, wo Ports geforwardet werden müssen, dann muss man zu anderen Mitteln greifen.
Zu empfehlen wären NAT Traversal Verfahren, wie STUN, TURN oder ICE, wie sie auch für VOIP-Dienste genutzt werden.
Der Nachteil: Man benötigt einen dritten Vermittlungsserver. Es gibt aber auch beispielsweise öffentliche STUN Server [1].
Ganz ohne dritte Vermittlungsinstanz geht es mit pwnnat [2], wo ICMP Echo Antworten zu einer fix gewählten nichtexistenten IP blind zu dem Server hinter der NAT beantwortet werden und somit der Server die IP kennenlernt.
Sind sich beide bekannt, tauschen danach beide gegenseitg den öffentlichen UDP Port voneinander aus mittels
UDP Hole Punching [3].
Zwar werden solche Techniken regelmäßig für VOIP und von anderer Peer2Peer Software benutzt, aber ich sah bisher noch keinen
ach so elitären Trojaner, der so etwas kann.

Oder kennt jemand einen? (Außer lame Reverse Connection)
[1]
STUN - voip-info.org
[2]
pwnat - NAT to NAT client-server communication
[3]
UDP hole punching - Wikipedia, the free encyclopedia