Monday 26 September 2011

WinDBG remote debugging with SSH port forwarding

When I tried to apply my “tunnel” onto Java remote debugging, I found someone got a better approachSSH port forwarding.

It is very cool, so I’d like to try it on WinDBG.

If the machine with public IP has Linux OS installed, it is very easy to start a SSH daemon. However I got one machine which has windows 2003 installed, so I have to find a Windows version sshd (SSH deamon). I think that freeSSHd is the best one among the free editions.

As the port 22 (default SSH port) on my server is taken by another process, I use 9000 instead, and listen on “All interfaces”. Next, go to the tab “Tunnelling”, check on both “local port forwarding” option and “remote port forwarding”.

We are going to use WinDBG to do the remote debugging, certainly it is done on Windows system, so we need a windows version SSH client. I prefer a CLI version of SSH client, so I choose plink.exe (from the popular putty site).

Which parameters do we need in the SSH client? If you are new to SSH, please have a look of the hyperlinks in this document. However, I believe it is much easier to understand them with an example, so let’s give the instructions first.

On the client machine where the application you want to debug is running on, run debugger server (dbgsrv.exe), specify the port as 1012 (you can use any free one).

dbgsrv –t tcp:port=1012

Check the tab Processes in Task Manager to make sure the debug server is running. Also, open a notepad as the application we are going to debug.

Next, on the same client machine, run

plink –P 9000 -R 9001:localhost:1012 nanoart@sshserver -N

Or, you can run the following command on the relay machine instead.

plink –P 9000 -R 9001:[ip of client machine]:1012 nanoart@sshserver -N

This is very useful when you are debugging GINA or credential provider which prevent you running a user-mode application.

At this stage, we’d better to have some explanations on the plink command.

The parameter -R specifies a remote port forwarding. It asks SSH server to start a listener process on the remote machine (SSH server) with port 9001. Thus the remote machine can accept connections and forwarding them back over SSH back to the machine that started the SSH port forward session, and then from there onto the client machine. Because my SSH sever is not running on the default port 22, I have to specify it with the parameter –P. The last parameter –N means “don't start a shell/command”, this is optional. Of course, you need to provide a SSH login account (“nanoart” in this example).

On developer’s machine, run this command,

plink –P 9000 -L 1012:localhost:9001 nanoart@sshserver –N

The parameter -L means local port forwarding. It results in a process listening on a port (here 1012) on the developer’s machine . This process/port will accept connections and forward them via the remote authenticated SSH (sshd) process to another host:port combination (here it is localhost:9001).

Note: The localhost might appear at first sight a little confusing, but don't forget host:port pair is relative to SSH server in local port forwarding. If localhost is used, it is the SSH server itself. However it is relative to the initiating end of this SSH connection, i.e. the workstation in the case of remote port forwarding.

Now, the route is tunnelled between the developer’s machine and the client’s machine.

On the developer’s machine, we can run

windbg –premote tcp:port=1012, server=localhost

It is worth mentioning that you may need to switch the order of port forwarding (first local port forwarding, then remote port forwarding), otherwise it may not work if you are using the freeSSHd as the SSH server.

In WinDBG, we can see all the processes of the client’s machine at the remote site.

Also, we can attach to the sample process “notepad.exe”.

Bravo, the remote debugging with SSH port forwarding succeeded! Finally I can forget the dbengprx.exe issue.

Please read the full version which has some figures to help you understand it easily.

No comments: