明明是 64 位系统,为什么 sys.platform linux2显示 win 32

64位windows系统怎么安装32位的CAD2008?
作者:佚名
字体:[ ] 来源:互联网 时间:01-26 11:06:15
64位windows系统怎么安装32位的CAD2008?因为工作需要,需安装安装32位的CAD2008电脑又无法安装该怎么办,下面分享windows 64位系统安装32位的CAD2008的方法
64位系统无法安装天河等插件时需要安装安装32位的CAD2008又无法安装可以参考本提议
1、AutoCAD 2008安装包 如果是压缩包或镜像文件的话先解压,如果是光盘先把文件都复制到本地硬盘,得到AutoCAD 2008安装包文件夹下的文件如图:
2、双击打开Orca软件,选择文件&打开,找到你的AutoCAD 2008安装包文件夹下的&acad.msi这个文件(有时acad.msi只显示为acad)点击打开。在左边表栏,点击InstallExecuteSequence项,在右边找到 CheckFor64bitOS和 LaunchConditions这两项。分别在上面点击鼠标右键,选择&删除行&。点击文件-保存-关闭。&
3、用记事本打开根目录下的setup.ini&这是安装配置文件, 找到
#==================== Platform Requirement
OSMAJVER=5
OSMINVER=0
SPMAJVER=3
PLATFORM=NO_WOW_64_PROCESS
把这一段删除后保存。
4、选择acad.msi或setup.exe这个文件右键选择属性&兼容性&以兼容模式运行&确定
5、双击acad.msi或setup.exe就可以正常安装了,选择安装位置时最好在Program Files (x86)的文件夹下,其他与在32位系统下同样安装即可。
大家感兴趣的内容
12345678910
最近更新的内容博客访问: 2272398
博文数量: 844
博客积分: 10134
博客等级: 上将
技术积分: 9505
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Windows平台
http://blog.csdn.net/xieqidong/article/details/2215704
还记得640K内存就足够的好日子吗?那记得是什么时候,它显得捉襟见肘了吗?这是一个日新月异的时代,我们发明了各种方法,以在有限的寻址空间内,映射更多的内存:首先,是“扩充内存”(EMM),起初它只是一张硬件“卡”,以64K或128K HASH(0x80b9d4)为界,切换64K的HASH(0x80b9d4)页到DOS寻址空间内;然后,我们又看到了“扩展内存”(XMS),它使保护模式映射到更多的64K区域成为了可能。而所有这些,都只是给了程序一个权宜之计,我们真正需要的是一个更大的寻址空间,这时,32位寻址就成了大众欢迎的、暂时的“止痛片”。
如果640K对任何人都足够,那么2GB(Windows实际上可寻址到4GB)对大多数应用程序来说都绰绰有余,但是,仍有一些程序要求越来越大的寻址空间,这样,人们又发明了寻址窗口扩展(Address Windowing Extension AWE)和实体地址延伸(Physical Address Extension PAE)等等映射技术。今天,64位处理器和两个新版本的64位Windows来到了我们身边,与16位到32位的变化不同的是,大多数今天我们使用的程序,都没有突破2GB的寻址空间,那么新处理器有什么用呢?我们何必在意它呢。
诚然,在可预见的未来,我们将继续编写32位程序,但不管怎么说,在这两年里,64位CPU进入桌面电脑已成了不争的事实。AMD Athlon64和Opteron处理器随处可见,而主板生产商也推出了相应的主板,价格上与同级别32位主板相近;Intel,一开始掉在了安腾处理器(Itanium)的钱眼里,为了赶上老对手,匆匆于2004年底发布了“32位扩展架构”的至强(Xeon)处理器,技术名称为IA32E或EM64T。由于Intel的安腾处理器缺乏向后兼容,现有的二进制代码运行效率不高,一如当年Win16到Win32的转变,导致OS/2的陨落和Windows在桌面的崛起一样,AMD此时看到了也抓住了这个机会。虽然Intel的处理器可高效运行本地(native)64位代码,但从经验来说,32位程序在AMD64和EM64T架构上效率都不是很高,而Microsoft微软,由于吸取了操作系统源代码兼容性的教训,所以它从现今的Win32源代码从发,构建一个64位版本的系统应该不是件难事。
现在,我们都在平静等待“64位扩展架构”的Windows发布,实际上,许多的电脑厂商已用EM64T或AMD64的芯片搭配32位的Windows,只是你可能没注意到而已,也许这些芯片的最令人吸引之处,就是可以同时运行耗费大量资源的32位程序。你可能此时会想,是不是8TB内存最终对每个人来说都足够了呢?尽管在理论上,64位可达到16000PB的寻址,而实际中,应用程序的寻址空间限制在7至8TB,原因是操作系统的内核,都在地址0x附近映射到每个进程之中。
当然,64位的变化不只在寻址上,现今,我们已经不再追求处理器频率每年翻一番,处理器频率徘徊在3GHz至4GHz之间,所以,有着64位架构的双倍总线带宽处理器(或多核心处理器),在性能上会更好一些。
不可否认,随着越来越多的64位电脑出现,64位的Windows最终也会走入寻常百姓家,现时窘境却是:是把现有程序移植到64位还是继续开发32位程序呢?大约三年前,我们的一个客户要求把Win32平台上的Unix API层移植到基于安腾的64位Windows之上,在移植过程中,发现了一些有趣的问题;本文中,主要围绕从32位移植到64位的一些相关话题,在此与大家分享。
在Windows之上的Windows(Windows on Windows)
相对于当年运行在32位Windows之下的16位程序,WoW32(Windows on Windows 32)从表面上来看,已经表现得非常不错了,关于WoW32的主要问题不是性能,而是兼容性和稳定性。在16位Windows中,由于其运行在DOS之上,所以程序间不得不以共享内存的方式来实现多任务,随着时间推移,程序逐渐运行在一个抢占式多任务环境的系统中,而且有各自的内存空间。在64位Windows中,32位进程被当作了一个在特殊转换层中的64位进程,这个转换层被称作“Win32 on Windows 64”,简写为“Wow64”。
在32位Windows中,总共4GB的寻址空间被划分为操作系统2GB,程序2GB,如果在boot.ini文件中使用了/3GB的启动选项(或者/Userva=3030,但如果系统超出了进程表,将不能登录)和/LARGEADDRESSAWARE链接器标志,可把内核共享系统空间移至1GB,而给应用程序3GB的内存空间。但得到一大块连续的内存空间并不像看起来那么容易,有如下一个简单的测试程序,可显示最大的可用内存块和最高位程序地址,分别用32位和64位编译器编译,并在可执行文件中设置或取消/LARGEADDRESSAWARE位,然后在不同的平台上运行它们,结果如下图所示,具体数字会因Windows版本的不同而有所变化,HKLM/Software/Microsoft/Windows NT/CurrentVersion/Windows/AppInit_DLLs中所加载的DLL对结果也有所影响。估计其最初的设计目的是为了优化页表的大小,并以减小内核可用空间和牺牲性能为代价,调整寻址空间的大小。
#include &stdio.h&
#include &stdlib.h&
#include &windows.h&
#pragma comment(lib, "kernel32.lib")
bool Walk(HANDLE hProcess, SIZE_T &free_bytes, SIZE_T &max_free, SIZE_T &reserved_bytes, void * &system_base)
MEMORY_BASIC_INFORMATION
void *last_
SIZE_T current_region_size = 0;
char *top = (char *) 0 + (SIZE_T) -1;
SYSTEM_INFO
DWORD last_state = 0;
GetSystemInfo(&si);
free_bytes = 0;
max_free = 0;
system_base = (void *) (((char *) si.lpMaximumApplicationAddress) + 1);
reserved_bytes = top - (char *) system_base + 1;
addr = (char *) (last_base = si.lpMinimumApplicationAddress);
while (addr & si.lpMaximumApplicationAddress)
if (0 == VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi)))
#if defined(DEBUG)
char name[MAX_PATH];
name[0] = '/0';
GetModuleFileName((HMODULE) mbi.BaseAddress, name, sizeof(name));
printf("AllocationBase: %x, Base: %x Size: %x, State: %x, Dll: %s/n", mbi.AllocationBase, mbi.BaseAddress, mbi.RegionSize, mbi.State, name);
if (last_state == mbi.State)
current_region_size += mbi.RegionS
if (MEM_FREE == last_state)
if (current_region_size & max_free)
max_free = current_region_
current_region_size = mbi.RegionS
if (MEM_FREE == mbi.State)
free_bytes += mbi.RegionS
last_base = mbi.AllocationB
addr += mbi.RegionS
last_state = mbi.S
int main(int argc, char **argv)
SIZE_T free_
SIZE_T max_
void *system_
if (1 == argc)
ok = Walk(GetCurrentProcess(), free_bytes, max_free, reserved, system_base);
DWORD pid = atoi(argv[1]);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (0 != hProcess)
ok = Walk(hProcess, free_bytes, max_free, reserved, system_base);
CloseHandle(hProcess);
printf("总共可用字节:0x%I64x/n", (long long) free_bytes);
printf("系统保留字节:0x%I64x/n", (long long) reserved);
printf("系统基地址:0x%p/n", system_base);
printf("最大连续可用块:0x%I64x/n", (long long) max_free);
最让人惊奇的事情是,用/LARGEADDRESSAWARE选项编译的32位Windows程序,在x64上,实际可访问4GB内存空间。由此可见,在Windows x64上,只需一小点努力,寻址空间就会翻一倍。
还有一个意料之外的结果,在Windows XP SP2上,最大可用块比其他任何一个平台上的都要小。通过在每个基地址处调用GetModuleFileName(),导出DLL在内存中的位置,最终发现UXTheme.DLL在最大可用块的中间(0x5AD70000)有一个隐含的载入地址,你可能会当它当成一个程序错误,但XP x64似乎没有这个问题(基地址:7DF50000),所以重定位XP SP2中的uxtheme.dll可能是安全的。
对运行在x64之上的32位程序,AWE和PAE也是适用的,但IA64版的Windows,对运行在Wow64中的32位程序,不提供AWE和PAE支持。
Wow64环境还有其他的让人惊喜之处,并且带有一组新的API。通常32位程序对%WINDIR%/System32的请求,会被重定向到%WINDIR%/Syswow64中,而且注册表也被虚拟化了,HKLM/Software现在实质上是HKLM/Wow6432Node,这是与HKCU虚拟化的不同之处。例如,Internet Explorer的设置就同时被32位和64位的Internet Explorer共享。(32位应用程序被默认安装于C:/Program Files (x86))。
有一些新的API,可用于32位程序取消虚拟化时通知64位系统,或者检测是否运行在仿真层中;表2中的API来自最新的Platform SDK,要注意的是,它们只在Windows Server 2003之后的kernel32中实现,“link /delayload:kernel32.dll”此时已是一个必选项,它通过LoadLibrary()和GetProcAddress(),可使二进制代码同时运行在老版本和新版本的Windows上。在包含函数GetSystemWow64Directory()的winbase.h头文件中,也可找到一个GetProcAddress()的函数原型。如下的程序演示了重定向功能:
#define _WIN32_WINNT 0x0501
#include &stdio.h&
#include &windows.h&
#pragma comment(lib, "kernel32.lib")
typedef BOOL (__stdcall *ISWOW64PROCESS)(HANDLE hProcess, PBOOL Wow64Process);
typedef BOOL (__stdcall *WOW64ENABLEWOW64FSREDIRECTION)(BOOL Wow64FsEnableRedirection);
PGET_SYSTEM_WOW64_DIRECTORY_A pGetSystemWow64DirectoryA = 0;
ISWOW64PROCESS pIsWow64Process = 0;
WOW64ENABLEWOW64FSREDIRECTION pWow64EnableWow64FsRedirection = 0;
void ResolveWow64References(void)
HMODULE hKernel32 = GetModuleHandle("kernel32.dll");
if (hKernel32)
pGetSystemWow64DirectoryA = (PGET_SYSTEM_WOW64_DIRECTORY_A) GetProcAddress(hKernel32, GET_SYSTEM_WOW64_DIRECTORY_NAME_A_A);
pIsWow64Process = (ISWOW64PROCESS) GetProcAddress(hKernel32, "IsWow64Process");
pWow64EnableWow64FsRedirection = (WOW64ENABLEWOW64FSREDIRECTION) GetProcAddress(hKernel32, "Wow64EnableWow64FsRedirection");
void WhatIs(const char *cmd)
if (GetBinaryType(cmd, &type))
switch (type)
case SCS_32BIT_BINARY:
printf("%s是一个32位二进制文件/n", cmd);
case SCS_64BIT_BINARY:
printf("%s是一个64位二进制文件/n", cmd);
fprintf(stderr, "%s -未知的二进制类型-%d/n", cmd, type);
{fprintf(stderr, "%s - error %d/n", cmd, GetLastError());}
void main(void)
char windir[MAX_PATH];
char cmd[MAX_PATH];
char syswow64[MAX_PATH];
BOOL bWow64Process = FALSE;
ResolveWow64References();
if (0 == pWow64EnableWow64FsRedirection)
fprintf(stderr, "需运行在支持这些API的平台上/n");
if (pIsWow64Process)
pIsWow64Process(GetCurrentProcess(), &bWow64Process);
printf("这%s是一个Wow64进程/n", (bWow64Process ? "" : "不"));
GetWindowsDirectory(windir, sizeof(windir));
sprintf(cmd, "%s//system32//cmd.exe", windir);
printf("启用重定向Wow64FsRedirection/n");
pWow64EnableWow64FsRedirection(TRUE);
if (pGetSystemWow64DirectoryA)
if (pGetSystemWow64DirectoryA(syswow64, sizeof(syswow64)))
sprintf(cmd, "%s//cmd.exe", syswow64);
WhatIs(cmd);
sprintf(cmd, "%s//system32//cmd.exe", windir);
WhatIs(cmd);
printf("取消重定向Wow64FsRedirection/n");
pWow64EnableWow64FsRedirection(FALSE);
WhatIs(cmd);
先来看一下在Wow64进程当中,是如何包装32位寻址空间的。
在Windows检测到32位二进制代码中的CreateProcess()调用时,会启用一个Wow64进程来接手,这个Wow64进程实际上是一个有着全部64位寻址空间的64位程序,它加载一个64位的ntdll.dll(在所有64位进程中都如此),也会加载几个转换DLL,这些DLL的任务是从32位堆栈中取出信息,重定向32位的函数调用,且使本地64位函数调用转到64位的ntdll.dll中。
wow64cpu.dll
wow64mib.dll
wow64win.dll
除了以上这些DLL,不会有其他的64位DLL加载到Wow64的寻址空间中。一旦这个Wow64程序被加载,会在64位寻址空间中为32位进程设置一个区域——你可能会想,肯定在低位的4GB中——并且加载32位的ntdll.dll,接下来就是32位程序正常加载到内存中运行了。的确,对一个32位进程使用64位调试器(如Windbg),是有先见性的;当跟踪指令到jmp 33:xxxxxxxx处时,32位调试器只会简单地停下来,而64位的调试器就会跳过这一段,从64位ntdll.dll中进入保护模式继续跟踪。
在很大程度上,%WINDIR%/syswow64目录中的32位DLL,与它们在32位Windows上的副本是相同的,两者之间只有一点性能上的差异,例如32位的ntdll.dll,它看起来不只是对32位程序的本地接口层,还设置好相应的转换工作以便转到64位层,并且自身还带有一些Wow64相关的API,这是在64位版本的ntdll.dll中所没有的。在命令行中键入dumpbin -exports | grep Wow64 | grep Nt之后,显示了一个API列表,让我们来看看它们究竟能做什么:
NtWow64GetNativeSystemInformation
NtWow64QueryInformationProcess64
NtWow64QueryVirtualMemory64
NtWow64ReadVirtualMemory64
如果你在Wow64层中运行一个32位程序,并且想访问64位程序中的进程空间,Win32 API ReadProcessMemory()这时可起不了作用,只是读取了寻址空间最开始的4GB。如果你需要的东西是在4GB以外呢?或者想要读取从地址0x7fffffde000开始的进程环境块(PEB)或线程环境块(TEB)呢?
NtQueryInformationProcess()这个函数可返回大多数种类的信息,但返回的数据不能放入一个32位的寻址空间内,转换机制显然会把它替换成零。那么我们怎样收集信息呢?可以创建一些数据结构,并小心地把它们扩展到64位,然后传递给Wow64版本的函数。如下的一个程序演示了如何使用包括GetParentProcessId()和GetCurrentDirectoryExW()在内的这些API。实际上,NtQueryInformationProcess()也可查询到父进程ID,演示程序读取了远程32位或64位进程的进程环境块(PEB),并打印出当前工作目录;由此可看出,一个Wow64进程似乎有一个32位和64位的进程环境块。
nativeinterface.h
#pragma once
#include &windows.h&
#include &string&
class NTProcessInformation
NTProcessInformation(HANDLE hProcess = GetCurrentProcess());
NTProcessInformation(DWORD pid);
bool _declspec(property(get=getok))
__w64 ULONG_PTR __declspec(property(get=getpid))
__w64 ULONG_PTR __declspec(property(get=getppid))
HANDLE __declspec(property(get=gethprocess)) hP
bool __declspec(property(get=getusewow64apis)) UseWow64A
VOID * __ptr64 __declspec(property(get=getpa)) PebBaseA
inline ULONG_PTR getpid(void) {return x_P}
inline ULONG_PTR getppid(void) {return x_PP}
inline VOID * __ptr64 getpa(void) {return x_PebA}
inline bool getok(void) {return x_OK;}
inline bool getusewow64apis(void) {return x_UseWow64A}
inline HANDLE gethprocess(void) {return x_hP}
bool IsWow64Process(HANDLE hProcess = 0);
protected:
void CommonConstruct(void);
__w64 ULONG_PTR x_P
__w64 ULONG_PTR x_PP
DWORD x_ExitS
VOID * __ptr64 x_PebA
HANDLE x_hP
bool x_OK;
bool x_UseWow64A
class NTPEB
NTPEB(HANDLE hProcess = GetCurrentProcess());
NTPEB(DWORD pid);
NTPEB(NTProcessInformation &ntpi);
bool _declspec(property(get=getok))
bool __declspec(property(get=getusewow64apis)) UseWow64A
HANDLE __declspec(property(get=gethprocess)) hP
VOID * __ptr64 __declspec(property(get=getpp)) ProcessP
inline VOID * __ptr64 getpp(void) {return x_ProcessP}
inline bool getok(void) {return x_OK;}
inline bool getusewow64apis(void) {return x_UseWow64A}
inline HANDLE gethprocess(void) {return x_hP}
protected:
void CommonConstruct(NTProcessInformation &ntpi);
VOID * __ptr64 x_ProcessP
bool x_OK;
bool x_UseWow64A
HANDLE x_hP
class NTProcessParameters
NTProcessParameters(HANDLE hProcess = GetCurrentProcess());
NTProcessParameters(DWORD pid);
NTProcessParameters(NTPEB &peb);
bool _declspec(property(get=getok))
std::wstring _declspec(property(get=getcwd))
inline std::wstring getcwd(void) {return x_}
inline bool getok(void) {return x_OK;}
protected:
void CommonConstruct(NTPEB &peb);
std::wstring x_
bool x_OK;
头文件实现文件
nativeinterface.cpp
#include &windows.h&
#include &basetsd.h&
#include "nativeinterface.h"
#include "ntdll_lite.h"
typedef BOOL (__stdcall *ISWOW64PROCESS)(HANDLE hProcess, PBOOL Wow64Process);
typedef NTSTATUS (__stdcall *NTQUERYINFORMATIONPROCESS)(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL);
#if !defined(_WIN64)
typedef NTSTATUS (__stdcall *NTWOW64QUERYINFORMATIONPROCESS64)(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PSIZE_T64 ReturnLength OPTIONAL);
typedef NTSTATUS (__stdcall *NTWOW64READVIRTUALMEMORY64)( IN HANDLE ProcessHandle, IN PVOID64_ BaseAddress, OUT PVOID Buffer, IN SIZE_T64 BufferSize, OUT PSIZE_T64 NumberOfBytesRead OPTIONAL);
ISWOW64PROCESS pIsWow64Process = 0;
NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess = 0;
#if !defined(_WIN64)
NTWOW64QUERYINFORMATIONPROCESS64 pNtWow64QueryInformationProcess64 = 0;
NTWOW64READVIRTUALMEMORY64 pNtWow64ReadVirtualMemory64 = 0;
static BOOL bLoaded = FALSE;
static BOOL LoadDlls(void)
HMODULE hKernel32 = GetModuleHandle("kernel32.dll");
HMODULE hNtDll = GetModuleHandle("ntdll.dll");
if ((0 == hKernel32 ) || (0 == hNtDll))
{return FALSE;}
pIsWow64Process = (ISWOW64PROCESS) GetProcAddress(hKernel32, "IsWow64Process");
pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS) GetProcAddress(hNtDll, "NtQueryInformationProcess");
#if !defined(_WIN64)
pNtWow64QueryInformationProcess64 = (NTWOW64QUERYINFORMATIONPROCESS64) GetProcAddress(hNtDll, "NtWow64QueryInformationProcess64");
pNtWow64ReadVirtualMemory64 = (NTWOW64READVIRTUALMEMORY64) GetProcAddress(hNtDll, "NtWow64ReadVirtualMemory64");
bLoaded = TRUE;
return (0 != pNtQueryInformationProcess);
NTProcessInformation::NTProcessInformation(HANDLE hProcess)
x_PPid(-1)
x_ExitStatus(STILL_ACTIVE)
x_PebAddress(0)
x_hProcess(hProcess)
x_OK(false)
x_UseWow64Apis(false)
CommonConstruct();
NTProcessInformation::NTProcessInformation(DWORD pid)
x_PPid(-1)
x_ExitStatus(STILL_ACTIVE)
x_PebAddress(0)
x_hProcess(0)
x_OK(false)
x_UseWow64Apis(false)
x_hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
CommonConstruct();
void NTProcessInformation::CommonConstruct(void)
if (!bLoaded)
if (!LoadDlls())
PROCESS_BASIC_INFORMATION
if (ERROR_SUCCESS != (err = pNtQueryInformationProcess(x_hProcess, ProcessBasicInformation, (PVOID) &info, sizeof(info), &realsize)))
if (0 == info.PebBaseAddress)
#if defined(_WIN64)
PROCESS_BASIC_INFORMATION64 info64;
SIZE_T64 realsize64;
if (!IsWow64Process(GetCurrentProcess()))
if (0 == pNtWow64QueryInformationProcess64)
if (ERROR_SUCCESS != (err = pNtWow64QueryInformationProcess64(x_hProcess, ProcessBasicInformation, (PVOID) &info64, sizeof(info64), &realsize64)))
x_Pid = (ULONG_PTR) info64.UniqueProcessId;
x_PPid = (ULONG_PTR) info64.InheritedFromUniqueProcessId;
x_ExitStatus = info64.ExitS
x_PebAddress = info64.PebBaseA
x_UseWow64Apis =
x_Pid = info.UniqueProcessId;
x_PPid = info.InheritedFromUniqueProcessId;
x_ExitStatus = info.ExitS
x_PebAddress = info.PebBaseA
bool NTProcessInformation::IsWow64Process(HANDLE hProcess)
if (pIsWow64Process)
BOOL IsWow64 = FALSE;
if (pIsWow64Process(hProcess ? hProcess : x_hProcess, &IsWow64))
{return IsWow64 ? true :}
NTPEB::NTPEB(HANDLE hProcess)
x_ProcessParameters(0)
x_OK(false)
x_UseWow64Apis(false)
x_hProcess(0)
NTProcessInformation info(hProcess);
CommonConstruct(info);
NTPEB::NTPEB(DWORD pid)
x_ProcessParameters(0)
x_OK(false)
x_UseWow64Apis(false)
x_hProcess(0)
NTProcessInformation info(pid);
CommonConstruct(info);
NTPEB::NTPEB(NTProcessInformation &ntpi)
x_ProcessParameters(0)
x_OK(false)
x_UseWow64Apis(false)
x_hProcess(0)
CommonConstruct(ntpi);
void NTPEB::CommonConstruct(NTProcessInformation &ntpi)
if (!bLoaded)
if (!LoadDlls())
x_hProcess = ntpi.hP
if (ntpi.UseWow64Apis)
#if defined(_WIN64)
PEB64 peb64;
SIZE_T64 realsize64;
if (ERROR_SUCCESS != (err = pNtWow64ReadVirtualMemory64(x_hProcess, ntpi.getpa(), &peb64, sizeof(PEB64), &realsize64)))
x_UseWow64Apis =
x_ProcessParameters = peb64.ProcessP
if (FALSE == ReadProcessMemory(x_hProcess, Ptr64ToPtr(ntpi.getpa()), &peb, sizeof(PEB), &realsize))
x_ProcessParameters = peb.ProcessP
NTProcessParameters::NTProcessParameters(HANDLE hProcess)
x_OK(false)
NTPEB peb(hProcess);
CommonConstruct(peb);
NTProcessParameters::NTProcessParameters(DWORD pid)
x_OK(false)
NTPEB peb(pid);
CommonConstruct(peb);
NTProcessParameters::NTProcessParameters(NTPEB &peb)
x_OK(false)
CommonConstruct(peb);
void NTProcessParameters::CommonConstruct(NTPEB &peb)
if (!bLoaded)
if (!LoadDlls())
if (peb.UseWow64Apis)
#if defined(_WIN64)
PROCESS_PARAMETERS64 ProcParams64;
SIZE_T64 realsize64;
if (ERROR_SUCCESS != (err = pNtWow64ReadVirtualMemory64(peb.hProcess, peb.getpp(), &ProcParams64, sizeof(PROCESS_PARAMETERS64), &realsize64)))
SIZE_T64 len = ProcParams64.CurrentDirectory.DosPath.L
wchar_t *buffer = new wchar_t[(SIZE_T) (len+1)];
if (ERROR_SUCCESS != (err = pNtWow64ReadVirtualMemory64(peb.hProcess, ProcParams64.CurrentDirectory.DosPath.Buffer, buffer, len * sizeof(wchar_t), &realsize64)))
buffer[realsize64/2] = '/0';
PROCESS_PARAMETERS ProcP
if (FALSE == ReadProcessMemory(peb.hProcess, Ptr64ToPtr(peb.getpp()), &ProcParams, sizeof(PROCESS_PARAMETERS), &realsize))
SIZE_T len = ProcParams.CurrentDirectory.DosPath.L
wchar_t *buffer = new wchar_t[len+1];
if (FALSE == ReadProcessMemory(peb.hProcess, ProcParams.CurrentDirectory.DosPath.Buffer, buffer, len*sizeof(wchar_t), &realsize))
buffer[realsize/2] = '/0';
相关头文件
ntdll_lite.h
#pragma once
typedef LONG NTSTATUS;
typedef LONG KPRIORITY;
#if (_MSC_VER & 1300)
typedef ULONG *ULONG_PTR;
typedef enum _PROCESSINFOCLASS
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef PVOID PPEB_LDR_DATA;
typedef PVOID PPEB_FREE_BLOCK;
#if !defined(_WIN64)
#if (_MSC_VER & 1300)
typedef unsigned __int64 PCHAR64;
typedef unsigned __int64 HANDLE64;
typedef unsigned __int64 PVOID64_;
typedef char * __ptr64 PCHAR64;
typedef void * __ptr64 HANDLE64;
typedef void * __ptr64 PVOID64_;
typedef PVOID64_ PPEB_LDR_DATA64;
typedef PVOID64_ PPEB_FREE_BLOCK64;
typedef unsigned __int64 SIZE_T64, *PSIZE_T64;
typedef struct _UNICODE_STRING {
USHORT MaximumL
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
#if !defined(_WIN64)
typedef struct _UNICODE_STRING64 {
USHORT MaximumL
} UNICODE_STRING64;
typedef UNICODE_STRING64 *PUNICODE_STRING64;
typedef struct _CURRENT_DIRECTORY {
UNICODE_STRING DosP
} CURRENT_DIRECTORY, *PCURRENT_DIRECTORY;
#if !defined(_WIN64)
typedef struct _CURRENT_DIRECTORY64 {
UNICODE_STRING64 DosP
HANDLE64 H
} CURRENT_DIRECTORY64, *PCURRENT_DIRECTORY64;
typedef struct _PROCESS_PARAMETERS {
ULONG MaximumL
ULONG DebugF
HANDLE ConsoleH
ULONG ConsoleF
HANDLE StandardI
HANDLE StandardO
HANDLE StandardE
CURRENT_DIRECTORY CurrentD
UNICODE_STRING DllP
UNICODE_STRING ImagePathN
UNICODE_STRING CommandL
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillA
ULONG WindowF
ULONG ShowWindowF
UNICODE_STRING WindowT
UNICODE_STRING DesktopI
UNICODE_STRING ShellI
UNICODE_STRING RuntimeD
} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
#if !defined(_WIN64)
typedef struct _PROCESS_PARAMETERS64 {
ULONG MaximumL
ULONG DebugF
HANDLE64 ConsoleH
ULONG ConsoleF
HANDLE64 StandardI
HANDLE64 StandardO
HANDLE64 StandardE
CURRENT_DIRECTORY64 CurrentD
UNICODE_STRING64 DllP
UNICODE_STRING64 ImagePathN
UNICODE_STRING64 CommandL
PVOID64_ E
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillA
ULONG WindowF
ULONG ShowWindowF
UNICODE_STRING64 WindowT
UNICODE_STRING64 DesktopI
UNICODE_STRING64 ShellI
UNICODE_STRING64 RuntimeD
} PROCESS_PARAMETERS64
#if (_MSC_VER & 1300)
typedef unsigned __int64 PPROCESS_PARAMETERS64;
, *PPROCESS_PARAMETERS64;
typedef struct _PEB {
BOOLEAN InheritedAddressS
PVOID ImageBaseA
PPEB_LDR_DATA L
PPROCESS_PARAMETERS ProcessP
PVOID SubSystemD
PVOID ProcessH
PVOID FastPebL
PVOID FastPebLockR
PVOID FastPebUnlockR
PVOID Spare[4];
PPEB_FREE_BLOCK FreeL
ULONG TlsExpansionC
PVOID TlsB
ULONG TlsBitmapBits[2];
PVOID ReadOnlySharedMemoryB
PVOID ReadOnlySharedMemoryH
PVOID *ReadOnlyStaticServerD
PVOID AnsiCodePageD
PVOID OemCodePageD
PVOID UnicodeCaseTableD
LARGE_INTEGER CriticalSectionT
} PEB, *PPEB;
#if !defined(_WIN64)
typedef struct _PEB64 {
BOOLEAN InheritedAddressS
HANDLE64 M
PVOID64_ ImageBaseA
PPEB_LDR_DATA64 L
#if (_MSC_VER & 1300)
PPROCESS_PARAMETERS64 ProcessP
PROCESS_PARAMETERS64 *__ptr64 ProcessP
PVOID64_ SubSystemD
PVOID64_ ProcessH
PVOID64_ FastPebL
PVOID64_ FastPebLockR
PVOID64_ FastPebUnlockR
PVOID64_ Spare[4];
PPEB_FREE_BLOCK64 FreeL
ULONG TlsExpansionC
PVOID64_ TlsB
ULONG TlsBitmapBits[2];
PVOID64_ ReadOnlySharedMemoryB
PVOID64_ ReadOnlySharedMemoryH
PVOID64_ *ReadOnlyStaticServerD
PVOID64_ AnsiCodePageD
PVOID64_ OemCodePageD
PVOID64_ UnicodeCaseTableD
LARGE_INTEGER CriticalSectionT
#if (_MSC_VER & 1300)
typedef unsigned __int64 PPEB64;
, * __ptr64 PPEB64;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitS
PPEB PebBaseA
ULONG_PTR AffinityM
KPRIORITY BaseP
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
#if !defined(_WIN64)
typedef struct _PROCESS_BASIC_INFORMATION64 {
NTSTATUS ExitS
PPEB64 PebBaseA
ULONG64 AffinityM
KPRIORITY BaseP
ULONG64 UniqueProcessId;
ULONG64 InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION64;
typedef PROCESS_BASIC_INFORMATION64 *PPROCESS_BASIC_INFORMATION64;
#include &windows.h&
#include "nativeinterface.h"
#define DEBUG
BOOL GetCurrentDirectoryExW(HANDLE hProcess, wchar_t *buffer, SIZE_T buflen)
NTProcessParameters params(hProcess);
if (!params.ok)
std::wstring result = params.
SIZE_T len = min(buflen-1, result.length());
memcpy(buffer, result.c_str(), sizeof(wchar_t) * len);
buffer[len] = L'/0';
return TRUE;
ULONG_PTR GetParentProcessIdEx(HANDLE hProcess)
NTProcessInformation info(hProcess);
if (!info.ok)
{return -1;}
return info.
BOOL MyIsWow64Process(HANDLE hProcess)
NTProcessInformation info(hProcess);
if (!info.ok)
{return FALSE;}
return info.IsWow64Process() ? TRUE : FALSE;
#if defined(DEBUG)
void main(int argc, char **argv)
if (1 == argc)
{hProcess = GetCurrentProcess();}
DWORD pid = atoi(argv[1]);
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (0 == hProcess)
wchar_t path[4096];
printf("ppid = %d/n", GetParentProcessIdEx(hProcess));
printf("这%s 是一个Wow64进程/n", (MyIsWow64Process(hProcess) ? "" : "不"));
GetCurrentDirectoryExW(hProcess, path, sizeof(path));
printf("当前工作目前 = %ls/n", path);
可读取64位寻址空间——这意味着不但能读取其他64位进程的进程环境块(PEB),而且还能观察到Wow64进程的64位部分。如NtWow64WriteVirtualMemory64()这些分配和修改虚拟内存的函数一样,可加载一个64位DLL到Wow64进程的64位部分。
Wow64程序面对的是虚拟化后的64位文件系统和注册表,但从一个32位系统发起的网络应用,如//server/admin$和ConnectRegistry(),可能面对的是一个真实的64位文件系统和注册表,所以,基于这些原因,copy 1234.dll //server/admin$/system32这行命令可能会达不到预期的目的。
本地64位移植
在Windows平台上,需要多于4GB内存的程序越来越多,这些程序要么在AWE或PAE上苦苦挣扎,要么转而栖身到其他的64位平台,如Solaris。以下列出的一些原因,可能会使你选择重新编译生成本地64位二进制文件。
无论是静态还是动态的32位库,都不能链接到64位的可执行文件,反之亦然,但是如果提供中间件,或者计划部署到64位Windows上,那就需要移植了——最初我们是移植到IA64上,现在是x64。基于COM的DLL在此是个例外,它们在32位的宿主中已经被代理了,即使通过网络连接时也是如此,但最终你会发现由此带来的进程内性能损失得不偿失,最终还是要把组件移植到64位Windows上。
如果你要发布一个Internet Explorer的插件,将会发现,32位版本的插件在64位Internet Explorer上无法使用。64位的Windows同时带有32位和64位的Internet Explorer,并且是按照每个窗口一个进程这样配置的,所以在64位平台上两者都能运行。因此,对64位Windows,必须同时发布32位和64位的插件。
如果有一个16位的Windows程序,因为没有Windows on Windows on Windows (WoWoW?)诸如的方案,所以16位程序不可能运行在x64上(会有诸如提示:映像文件有效,但不适用于此计算机类型)。
设备驱动程序也亦然,32位的设备驱动程序无法工作在64位的Windows上。
也许移植的目标是IA64,但会发现,程序并没有预期中的性能,或者是因为程序使用了AWE和PAE,两者在IA64平台上均不被支持,但看起来似乎本地编译的IA64二进制文件比32位效率要高得多。此现象主要针对第一代安腾处理器,对于第二代安腾处理器,情况要好多了。或许Windows使用的是32位软件二进制仿真器,而不是本地硬件仿真器。
移植到新平台上,工作量非常巨大,一项普通的移植都需要严格的计划和时间上巨大的开销。为了找到问题的范围,无论如何都要挑出一些有代表性的源代码,试编译运行。听起来好像很简单,只是敲入make(或者nmake、devenv /build)就行了,实际上,要做的工作远远不只这些。
那些没有源代码的程序,有库可用吗?在移植中要使用什么平台呢?是使用目标平台还是类似x86的桌面平台?对新平台来说,源代码配置管理系统(SCM)可用吗?从哪可得到编译器和链接器?所有的工具都适合64位开发吗?构建环境是否支持在同一源代码中生成多平台应用,还是需要多做一份拷贝?实际上,敲入make需要更多的前端工作,但最简单的解决方案是,拷贝一份源代码,安装好Microsoft Platform SDK,使用x86 to x64跨平台交叉编译器,而把其他诸如开发环境、生成工具、SCM等等,统统扔在32位Windows中不管。这也许是最大的一个惊喜了,在链接可执行文件前,甚至都不需要一台64位电脑。
正因为不能把32位的静态或动态库,链接到64位程序,所以,如果没有全部库的源代码,或者64位版本的库还不存在,那么移植方案就得暂时搁下。你需要在64位目标平台上找到一些东西,替换掉这些库,要么说服生产商提供这些库,或者干脆不移植。
接下来一个最大的问题是开发环境——包括编译器、链接器、调试器、源代码管理系统、make和集成开发环境(IDE)。
从哪可以得到一个编译器呢?在本文写作时,GNU C/C++还不行。Intel已经发布了商业版本的编译器,分别对应于IA64(本地或跨平台)、IA32E(Intel称其为EM64T x64平台)和IA32;微软也有一对版本号为14.0的编译器(VC.NET 2005),分别对应于x86 to IA64和x64,而通过Platform SDK,提供了跨平台交叉编译功能。实际上在Visual Studio.NET 2005中,微软已经提供了本地x64和IA64编译器。
集成开发环境(IDE)不需要是64位的,你能在32位系统上跨平台交叉编译,或者在64位平台上运行32的IDE。
从哪可以得到一个调试器呢?Windbg有针对以上三个平台的版本,但对普通人来说,它还是有点不太好用,除非是黑客。Visual Studio.NET 2005有一个远程调试器服务端可用于以上两个64位平台。它仍是一个32位程序,所以你能得到一个混合的实现,在当前x86桌面系统上开发,而在64位平台上远程调试。
那配置管理系统呢?也许你的SCM已经支持相应64位平台开发了,如果没有,那只有在32位系统上跨平台交叉编译,或者拷贝源代码到64位平台上。
现在我们可以准备生成程序了,所有为移植做的准备就是为了现在享受胜利的果实,但代码有多具移植性呢?
我们都知道sizeof(short) &= sizeof(int) &= sizeof(long) &= sizeof(long long),但也要准备接受sizeof(long) != sizeof(void *)或者sizeof(int) != sizeof(void *)。大多数64位Unix系统定义sizeof(long) == sizeof(void *),这被称作LP64模型,此时long与指针都是64位的。Windows选择的是LLP64模型,此时对移植32位Windows源代码来说,sizeof(long long) == sizeof(void *)。这意味着,如果代码中把指针赋值给int(这是不可移植的,因为它不严谨且假定sizeof(int) == sizeof(long) == sizeof(void *)),或者把指针赋值给long,那就要在代码移植之前,把它们全部改正过来。记住,程序看起来也许运行得很正常,只要它位于64位寻址空间的低4GB位置,但malloc()和HeapAlloc()返回的值可能会在此之外,MapViewOfFile()也同样。
在很大程度上,编写良好的Win32代码只需稍作改动,便可通过编译。你可能会惊奇地发现,在很多地方,DWORD与PVOID几乎是同一样东西,只要认真遵循前面所提到的方法,源代码通过编译不是件难事,但是,记住在生成64位程序时使用-W3选项,对编译器的警告多加留意。
就以往的经验来说,需要为每一个COM组件生成一个新的GUID,但在Windows x64上,同一个组件的32位和64位版本(如Internet Explorer 工具栏)可以共享一个GUID,并可在同一台电脑上,同时为它们的客户程序提供服务。事实上,COM的实现是高度可伸缩性的,可以允许32位的组件被64位进程使用(反之亦然),或同时注册32位和64位的组件。换句话来说,如果你选择移植组件,可以保留GUID和接口定义;如果不移植(那些充当进程内服务的IE工具栏和插件必须要移植),多数情况下,它们都能正常运行,此时性能可能会受影响。
一些更棘手的问题都是围绕与32位程序共享二进制数据上,也许是通过文件,或者是共享内存、网络等等。在此有很多技术都可以用得上,但微软已经在它的编译器和头文件中内置了一些实用的工具。
微软编译器cl版本13.0或者更高(VS.NET 2003或后续版本),Platform SDK中的14.0版本,这些编译器都支持/Wp64选项。对每个源程序,只需简单地设置/Wp64选项,就可以看到5个(至少到目前为止)有用的警告;参见图1;以下的程序示范了这些警告,并且提供了一些有关移植的解决方法。
#include &windows.h&
#include &stdio.h&
#include &stddef.h&
#include &string.h&
#include &basetsd.h&
#pragma comment(lib, "user32.lib")
void main(void)
void *ptr = 0;
HWND hWnd = GetDesktopWindow();
printf("%x/n", ptr);
printf("%p/n", ptr);
val = (int)
intptr = (intptr_t)
val = strlen("abc");
sizet = strlen("abc");
val = (int) hW
val = HandleToUlong(hWnd);
hWnd = (HWND) UlongToHandle(val);
在头文件BaseTsd.h中,有一些可用的新内联函数和宏,如DWORD32、DWORD64、UINT_PTR、PointerToUlong()、Ptr64ToPtr()等。HWND在64位Windows上已是一个64位的变量,如果你想把它传递给一个32位进程,它的值会被截断,HandleToUlong()此时正好帮得上忙,但需注意的是,尽量不要让截断发生。*__ptr64强制一个指针变量占用64位,哪怕是在32位平台上,void * __ptr64 ptr就可强制在32位和64位平台上得到同样大小的变量,以保证二进制兼容;还有一个相应的__ptr32。显然,在我们发现8TB寻址空间不够用之前,是不会出现__ptr128的。
在把指针赋值给int时,尽量使用intptr_t,而不是int或long long。大多数编译器都提供了一个typedef,以保证对你的目标平台,变量有一个正确的大小。
删除源代码中的内联汇编语句,或者用一些“C”代码代替它,在生成程序时,也不要链接外部的汇编文件,因为__asm在IA64和x64编译器中会产生错误。为了确保二进制的兼容,请明智地决定联合体(Union)中变量的位置,以便结构数据对齐保持一致。参见以下程序:
#include &windows.h&
#include &stdio.h&
#include &stddef.h&
struct abc
void * __ptr32 ThirtyTwoBitP
void * __ptr64 SixtyFourBitP
struct def
void * __ptr32 ThirtyTwoBitP
long long reserved2;
void * __ptr64 SixtyFourBitP
long long reserved3;
void main(void)
printf("%d/n", sizeof(abc));
printf("/tAWindow %p/n", offsetof(abc, AWindow));
printf("/t32bit pointer %p/n", offsetof(abc, ThirtyTwoBitPointer));
printf("/t64bit pointer %p/n", offsetof(abc, SixtyFourBitPointer));
printf("/tAlong %p/n", offsetof(abc, ALong));
printf("%d/n", sizeof(def));
printf("/tAWindow %p/n", offsetof(def, AWindow));
printf("/t32bit pointer %p/n", offsetof(def, ThirtyTwoBitPointer));
printf("/t64bit pointer %p/n", offsetof(def, SixtyFourBitPointer));
printf("/tAlong %p/n", offsetof(def, ALong));
IA64平台,像多数RISC处理器一样,对数据对齐过分吹毛求疵,有以下代码:
unsigned char *
DWORD dword = (DWORD) (*(unsigned long long *) ptr);
此时使用一个memcpy(),也许是比赋值更好的选择。
也许你经常要为32位和64位生成不同代码,为此,微软的64位编译器定义了一个预处理变量_WIN64。微软的编译器同时也提供_M_IX86、_M_IA64、_M_AMD64,以便应付那些需要针对特定处理器生成代码的极端场合。
64位移植中最困难的事,恐怕就是代码生成环境了。如果你之前移植到其他的架构上(如Alpha、MIPS或PowerPC),可能会觉得很容易,平台提供的示例代码中,常含有一个调用cl和nmake的makefile,以便演示在不同平台上针对同一源代码如何编译,其思想是把平台与输出分离。但即使是把vc?.pdb文件放在正确位置,并且也把编译器临时目录分离,makefile在多平台同时生成程序时,还是会有问题。
如果你正在使用Visual Studio IDE,可以很容易地导出配置文件、指定输出目录$(OUTDIR)、按需调整好编译器,然后在目标平台上打开一个Platform SDK命令行窗口,用如下命令devenv /build /useenv myproject.sln "Win32 - Debug(X64)"来构建一个工程。可以考虑一下最新的VS.NET 2005和它的跨平台交叉编译器,只要在每一个配置中指定目标平台,就可以很容易地生成应用(或工程)。在AMD的官方网站上,有一个示例,演示了如何使用Visual Studio和Platform SDK,从现有的工程文件中,生成64位二进制程序。
最后当然还要说一下软件安装的问题,如果有一个面向32位、64位(IA64和x64)的混合安装程序,在一开始就需要仔细地计划。如果使用Windows Installer,那么针对每一个平台架构,都会有一个MSI文件。有趣的是,在64位的安装中,可使用32位的用户定制(Custom Action)DLL,这暗示着在此之下,有一对协同工作的32位和64位进程。但这不在本文讨论范畴之内。
不是每个人都需要把他们的程序移植到本地64位平台上,事实上,如果依然作为运行在64位处理器上的32位程序,可能会更加小巧,方便部署——当然除了安腾处理器。目前唯一清楚的是,微软为它的32位仿真层做了大量卓越的工作,而64位处理器和主板,价格便宜量又足,它们会越来越受到欢迎,因此,不管是运行现有32位程序、或是新游戏、还是复杂的商业程序,我们都没有理由——不拥抱64位Windows!!
阅读(1386) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 3ds破解后系统显示sys 的文章

 

随机推荐