windowsperlcmdsyswow64

How to launch a x64 shell using x86 perl system on windows


I use perl to call system start that I need to specify the cpu number which I want my program to bind to.

When I use x86 perl, it will launch x86 cmd to run the start command. This x86 start doesn't accept the parameter 0x100000000 as it exceeds 32 bit length. If I use a x64 perl, the whole thing works fine because x64 perl launch x64 cmd which accepts 0x100000000.

So how can I launch a x64 cmd to run the start command when using a 32-bit perl?

Details:

First, I verified that 32bit cmd shell doesn't accept start /affinity 100000000 while 64bit cmd shell does. In 32bit cmd shell, it throws error The system cannot accept the START command parameter 100000000.

Then I tried x64 perl and x86 perl respectively and find x86 perl will get the same error. See commands below.

path/to/x64/perl.exe -e "system qq{start /b /wait /affinity 100000000 my.exe}"
path/to/x86/perl.exe -e "system qq{start /b /wait /affinity 100000000 my.exe}"

Is there any method to launch a x64 shell using x86 perl to excute start?


Solution

  • The File System Redirector of WOW64 emulator redirects file system paths of %SystemRoot%\system32 to %SystemRoot%\SysWOW64 where %SystemRoot% is the a system environment variable which refers to the Windows directory e.g. C:\Windows.

    So normally, the WOW64 processes (32-bit processes running on 64-bit windows) can not access the system32 directory.

    However, starting with windows Vista, the 32-bit processes can refer to and access the files and folder in the sysetm32 directory by replacing system32 with the special alias SysNative in the file path.

    To launch the x64 cmd shell from a x86 perl instance, you need to explicitly specify the path to the 64-bit cmd.exe by %SystemRoot%\SysNative\cmd.exe

    Path_to_x86_perl\perl -e "system $ENV{SystemRoot}.'\sysnative\cmd.exe /x /d /c start /b /wait /affinity 100000000 my.exe'"
    

    Note, however, that this only works on a WOW64 process, So it can not be used as a single one-liner solution for both x86 and x64 versions of perl under Windows. However, you could use the following in a program:

    use Config qw( %Config );
    my $system = $ENV{SystemRoot} . '\\' . ( $Config{ptrsize} == 4 ? 'SysNative' : 'System32' );