Mar 132017
 

puTTY logoAnyone who has logged in to a UNIX or Linux machine remotely coming from a Windows box probably knows puTTY, which is practically “the” SSH and telnet client for Windows. In conjunction with a small X11 server like Xming you can even do Remote X. To my surprise, a new version has been released just last month, as a colleague told me! So there is version 0.68 now, and it comes in both a 32-bit and a 64-bit flavor.

Of course I had to try the 64-bit version on XP x64, and it did fail to execute:

64-bit puTTY failure on XP x64

A classic: 64-bit puTTY failure on XP x64, because it’s “not a valid Win32 application”

Out of curiosity, I fetched the puTTY source code from [here], because I thought I could just compile & link it myself. Building for 32-bit proved to be relatively easy; Just load the corresponding solution file into Microsoft Visual Studio 2010, build the whole project, done. But I wanted 64-bit! So I created a x64 build target and gave it a shot, but it couldn’t find the _addcarry_u64 intrinsic.

After a bit of searching on the web, it became clear that the intrinsics header of Visual Studio didn’t provide it. It’s too old, you need Visual Studio 2013 or newer for that. Funny part is, puTTY only comes with project files for 2010 and 2012, how are they building their x64 version? No idea. Maybe they’re linking against a different library version or something.

One attempt that I was going to make (build it with VS2013, linking against an older platform SDK) isn’t done yet, because I need to prepare my Windows 7 VM for it. I did manage to compile and run puTTY as 64-bit code on XP x64 by hacking up their program though! In the unpacked source tree, open sshbn.h and take a look at line #70:

expand/collapse source code
  1. #elif defined _MSC_VER && defined _M_AMD64
  2.  
  3.   /*
  4.    * 64-bit BignumInt, using Visual Studio x86-64 compiler intrinsics.
  5.    *
  6.    * 64-bit Visual Studio doesn't provide very much in the way of help
  7.    * here: there's no int128 type, and also no inline assembler giving
  8.    * us direct access to the x86-64 MUL or ADC instructions. However,
  9.    * there are compiler intrinsics giving us that access, so we can
  10.    * use those - though it turns out we have to be a little careful,
  11.    * since they seem to generate wrong code if their pointer-typed
  12.    * output parameters alias their inputs. Hence all the internal temp
  13.    * variables inside the macros.
  14.    */
  15.  
  16.   #include 
  17.   typedef unsigned char BignumCarry; /* the type _addcarry_u64 likes to use */
  18.   typedef unsigned __int64 BignumInt;
  19.   #define BIGNUM_INT_BITS 64
  20.   #define BignumADC(ret, retc, a, b, c) do                \
  21.       {                                                   \
  22.           BignumInt ADC_tmp;                              \
  23.           (retc) = _addcarry_u64(c, a, b, &ADC_tmp);      \
  24.           (ret) = ADC_tmp;                                \
  25.       } while (0)
  26.   #define BignumMUL(rh, rl, a, b) do              \
  27.       {                                           \
  28.           BignumInt MULADD_hi;                    \
  29.           (rl) = _umul128(a, b, &MULADD_hi);      \
  30.           (rh) = MULADD_hi;                       \
  31.       } while (0)
  32.   #define BignumMULADD(rh, rl, a, b, addend) do                           \
  33.       {                                                                   \
  34.           BignumInt MULADD_lo, MULADD_hi;                                 \
  35.           MULADD_lo = _umul128(a, b, &MULADD_hi);                         \
  36.           MULADD_hi += _addcarry_u64(0, MULADD_lo, (addend), &(rl));     \
  37.           (rh) = MULADD_hi;                                               \
  38.       } while (0)
  39.   #define BignumMULADD2(rh, rl, a, b, addend1, addend2) do                \
  40.       {                                                                   \
  41.           BignumInt MULADD_lo1, MULADD_lo2, MULADD_hi;                    \
  42.           MULADD_lo1 = _umul128(a, b, &MULADD_hi);                        \
  43.           MULADD_hi += _addcarry_u64(0, MULADD_lo1, (addend1), &MULADD_lo2); \
  44.           MULADD_hi += _addcarry_u64(0, MULADD_lo2, (addend2), &(rl));    \
  45.           (rh) = MULADD_hi;                                               \
  46.       } while (0)

I just commented out the entire codeblock using that modern _addcarry_u64 intrinsic, and replaced it with the code being used for the 32-bit version:

  1. #elif defined _MSC_VER && defined _M_AMD64
  2.  
  3.   /* 32-bit BignumInt, using Visual Studio __int64 as BignumDblInt 
  4.    * This is compatible with VS2010 & VS2012 for building a x86_64
  5.    * version of puTTY (no __int128 with those compilers).
  6.    */
  7.  
  8.   typedef unsigned int BignumInt;
  9.   #define BIGNUM_INT_BITS  32
  10.   #define DEFINE_BIGNUMDBLINT typedef unsigned __int64 BignumDblInt

I built that and it works, even though I keep thinking I should be using a wide 128-bit data type here (just like the original x64 code), but then we don’t have __int128 in MSVC before 2013, and I’m on 2010. And I don’t know how to use SSE registers in that context with things like __m128, which is why I left it alone. Looking good anyway:

puTTY 64-bit XP x64 version logged in to Windows 2000

puTTY 64-bit XP x64 version logged in to Windows 2000 using a modern SSH server (click to enlarge)

And:

puTTY 64-bit XP x64 version logged in to FreeBSD 10.3 UNIX

puTTY 64-bit XP x64 version logged in to FreeBSD 10.3 UNIX (click to enlarge)

In any case, here is a complete 64-bit build of puTTY that works on NT5.2 operating systems like Windows XP Professional x64 Edition or Windows Server 2003 x64:

  • [puTTY 0.68][1] (x64 version for NT5.2, portable without installer)

Maybe I’ll try to build a version with VS2013 on Windows 7 for the same platform target, we’ll see. But at least this works!

Oh and… No, I don’t really think anyone actually needs a 64-bit version of puTTY ;). Plus the 32-bit one works just fine on XP x64 / Server 2003 out-of-the-box anyway. But hey… You know… :roll:

[1] puTTY is © 1997-2017 Simon Tatham and is licensed under the MIT license

CC BY-NC-SA 4.0 A build of 64-bit puTTY that works on XP x64 and Server 2003 x64 by The GAT at XIN.at is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

  12 Responses to “A build of 64-bit puTTY that works on XP x64 and Server 2003 x64”

  1. BTW, Xming is rather old, and new releases are not free any more.
    A replacement is vcxsrv, https://sourceforge.net/projects/vcxsrv/

    • Hm, I hadn’t really paid attention to that, but you’re right. Only issue in my case is that vcxsrv doesn’t support my XP x64 anymore, starting with version 1.14.3.0, which is also quite old. This being a VisualStudio project, I could try to compile it by myself, as long as the build setup gives me a VC project or solution file and as long as the code isn’t really depending on newer Win32 API versions.

      I never EVER managed to find out how to change the platform target / toolset when building stuff on the command line using Microsofts’ nmake. Only way I ever found was to compile directly on XP, but that’s only possible with VS2010. I had to set up a secondary build VM with Win7 because of that, one where I have VS2013, 2015 and 2017 as well.

      If I have the time, I’ll give it a shot next week… But the source code package is huge. I’m having a bad feeling about this…

      • Yep, it’s big, and probably quite ugly.
        However, it doesn’t need the .net lamework. It might also be recently supported for XP, which might give better results than Xming on some newer hosts. Maybe something with that wayland. I don’t know. I don’t have any *nix server running a gui.

        • There are a ton of libraries included (as expected), and while I’ve learned how to handle platform targets even when using nmake in the meantime, that code just won’t build. Don’t remember where it broke and what exactly went wrong, but targeting XP won’t fly for vcxsrv. I haven’t invested more than 1 or 2 days though, if I remember correctly.

          Guess it really was something related to the code itself, not the build tools. I’ll just stay with Xming on older systems, don’t need Wayland for another while anyway.

  2. Recently PuTTY 0.69 was released. Two releases in one year, it’s getting crazy out there! ;-)

    They seem to finally have fixed some rather nasty bug that dropped the connection once in a while. This made me compile virtualbox on the console, with a log to file, rather than in a SSH session.
    What also happened was a virtualbox-ose-nox11 package for FreeBSD so I did not to compile it myself any more.

    • Heyho,

      I’ve encountered rather frequent connection drops as well (like every 10-20 minutes or so?). But still, you might want to take a look at [GNU screen], a virtual terminal emulator. It’s available from FreeBSD packages and ports as well, see [sysutils/screen]

      What I do: I log in via SSH, then run screen, which launches the terminal emulator. Here, I launch my long-running jobs. Then I disconnect from the screen session with <CTRL>+a, d, after which screen says it’s “detached”. You can now terminate your SSH session, as screen and it’s daughter processes keep running in the background. If you wanna look at it at a later time, just log in and run screen -x. If you have multiple screen sessions running, you can list them with screen -ls, and then connect to the one you want with screen -x <PID>. As usual, see [screen(1)] for more.

      It’s reaaally useful to run background jobs on remote, UNIX-style machines. You can also set it up for multi-user operation with read & write permissions for collaborative software development, demonstration or document writing etc. :)

      Btw., I never compiled VBox myself on FreeBSD?! Was there something wrong with the packages? I always just used those…

      • The default package came with a gui, which I don’t use on a server. Lots of dependencies and libraries, well, let’s not do that. Anyway, if I had to do it again now, I would be using Bhyve, since it can now run windows with a VNC console.

        I have looked at screen before, but now I’m just using MTPuTTY, which also old, but just uses a new putty.exe. It works good enough now.

        But your option uses one SSH connection to one host and then connect to other hosts with screen?

        • Huh? I’m using puTTY only on Windows, GUI and all. On Linux and UNIX I just use standard OpenSSH.

          You can think of screen just like a localhost VNC server for terminals. It’s happily running in the background, and whenever you need something from it, you SSH into the box and reconnect to it. Difference being that you need no tunnels / TCP sockets.

          While in the same LAN as all the Linux and UNIX machines, I just login to my target machine with SSH, then execute screen -x <PID>, and I’m in. I actually run ALL my long-running jobs within screen sessions, even locally. Because they survive even X11 server crashes. I can kill the whole X session, bring it back up, launch a terminal, run screen -x <PID>, and I can re-access the VT my process is running on!

          I do that for larger software compilation jobs and media transcoding jobs, which tend to run for days. So I can SSH into a remote box, and launch a job that takes 5 days to complete, with no fear of a SSH connection drop, because all I need to do is to detach myself from the screen, then close puTTY on Windows or my terminal on *NIX, and the process keeps running on the target box.

          When outside of said LAN, I connect to our SSH gateway server, and from there, I hop to any of my target machines using another SSH connection. When on target, I connect to my screen session using local UNIX sockets, no tunnels needed, just launch screen -ls, then screen -x <PID>, done…

  3. You know you can use editbin, right? I would suggest writing _addcarry_u64 using ml64 instead BTW.

    • Hello,

      No, I don’t even know editbin. I get it’s some kind of binary editor, but I’ve never used it, no idea what I would do with it?!

      Also, there is simply no way I could write x86 assembly by myself, I just don’t have the skill. I fooled around with very simple stuff like add, mul, jmp shl/shr etc. in the 90s, but to write the _addcarry_u64 intrinsic by myself? I wouldn’t even know where to start, and my C++ knowledge is basically zero as well.

      As you can see, I am not a developer, I’m just hacking up other peoples’ code to the best of my meager abilities. It’s like stumbling through the dark… So please don’t expect too much! ;)

      • Run it from a command prompt. You will notice a /SUBSYSTEM option. For example, editbin /subsystem:windows,5.2 xxx.exe.

        • Hi again,

          Actually, I found a similar way to make puTTY x64 work on XP x64 and Server 2003 x64 in the meantime, I learned this from Oleg Ovcharenko, the developer of some [XP game patches], like for Stellaris and others. I guess it’s doing essentially the same as editbin…

          I followed his suggestions, and loaded puTTY.exe in NTCores’ [CFF Explorer VIII], then looked at the optional headers of that binary:

          The x64 version of puTTY.exe in CFF Explorer VIII
          x64 puTTY.exe in CFF Explorer VIII, platform/kernel version marked in red (click to enlarge)

          As you can see, the target is major version 6, minor version 0, so Windows NT 6.0, which is the kernel version of Windows Vista. I just changed that to the kernel version of XP x64 / Server 2003 x64, which is 5.2 (like your command line does as well I assume):

          The x64 version of puTTY.exe in CFF Explorer VIII
          Now with a modified header (click to enlarge)

          With that, puTTY just works, thanks to Olegs’ help and that great tool CFF Explorer. Of course, I could have just done what you suggested and I would have reached the same result much quicker, but I kind of forgot about your comment actually (my apologies for that). Well, I guess if the software actually does make use of modern libraries or Kernel API functions, this won’t be enough. But yeah, it works for puTTY!

          Probably better than me messing with their source code (even if both versions do work). :)

          Thank you for your help!

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">

(required)

(required)