user-0 提问: 用c判断exe是32位还是64位的？

回复:
user: user-1
content: 主要代码如下：  // 获取机器标志码 // -1 打开文件失败 // -2 读取文件失败 // -3 文件格式错误 // 0      任何处理器 // 0x14c  x86处理器 // 0x8664 x64处理器 // 0x166  MIPS处理器 // 0x1C0  ARM处理器 INT GetMachine(const TCHAR * szFilePath) {     // _tprintf(TEXT("%s\n"), szFilePath);      // 打开文件     FILE * fp = _tfopen(szFilePath, TEXT("rb"));     if( fp == NULL )     {         return -1;     }      // 获取文件长度     long len = filelength(fileno(fp));     if( len < 0 )     {         fclose(fp);         return -1;     }      // 文件格式错误     if( len < 0x40 )     {         fclose(fp);         return -3;     }      WORD buf;      // 读取MZ文件头     if( fread(&buf, 1, 2, fp) != 2 )     {         fclose(fp);         return -2;     }      // 文件格式错误     if( buf != 0x5A4D )     {         fclose(fp);         return -3;     }      // 移到PE头偏移     if( fseek(fp, 0x3C, SEEK_SET) )     {         fclose(fp);         return -2;     }      // 读取PE头偏移     if( fread(&buf, 1, 2, fp) != 2 )     {         fclose(fp);         return -2;     }      // 文件格式错误     if( len < buf + 6 )     {         fclose(fp);         return -3;     }      // 移到PE头     if( fseek(fp, buf, SEEK_SET) )     {         fclose(fp);         return -2;     }      // 读取PE头     if( fread(&buf, 1, 2, fp) != 2 )     {         fclose(fp);         return -2;     }      // 文件格式错误     if( buf != 0x4550 )     {         fclose(fp);         return -3;     }      // 移到机器码     if( fseek(fp, 2, SEEK_CUR) )     {         fclose(fp);         return -2;     }      // 读取机器码     if( fread(&buf, 1, 2, fp) != 2 )     {         fclose(fp);         return -2;     }      fclose(fp);     return buf; }  　　如果要检测64位系统System32目录下的文件，需要把文件重定向关闭：  BOOL DisableWow64FsRedirection() {     typedef BOOL (WINAPI* WOW64DISABLEWOW64FSREDIRECTION)(PVOID *OldValue);     WOW64DISABLEWOW64FSREDIRECTION Wow64DisableWow64FsRedirection;      HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));     if( hKernel32 == NULL )     {         return FALSE;     }      Wow64DisableWow64FsRedirection = (WOW64DISABLEWOW64FSREDIRECTION)GetProcAddress(hKernel32, "Wow64DisableWow64FsRedirection");     if( Wow64DisableWow64FsRedirection == NULL )     {         return TRUE;     }      PVOID OldValue = NULL;     if( Wow64DisableWow64FsRedirection(&OldValue) == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )     {         return FALSE;     }      return TRUE; }

user: user-1
content: https://www.cnblogs.com/God4/articles/11721559.html 关于exe或dll等PE格式文件32位还是64位的检测  代码很简单，工具审核通过后传上去。

user: user-2
content: https://blog.csdn.net/jiangqin115/article/details/45562161?utm_source=blogxgwz8

user: user-0
content: 查winnt.h  #define IMAGE_FILE_MACHINE_UNKNOWN           0 #define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386. #define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian #define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian #define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian #define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2 #define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP #define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian #define IMAGE_FILE_MACHINE_SH3DSP            0x01a3 #define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian #define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian #define IMAGE_FILE_MACHINE_SH5               0x01a8  // SH5 #define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian #define IMAGE_FILE_MACHINE_THUMB             0x01c2  // ARM Thumb/Thumb-2 Little-Endian #define IMAGE_FILE_MACHINE_ARMNT             0x01c4  // ARM Thumb-2 Little-Endian #define IMAGE_FILE_MACHINE_AM33              0x01d3 #define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian #define IMAGE_FILE_MACHINE_POWERPCFP         0x01f1 #define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64 #define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS #define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64 #define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS #define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS #define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64 #define IMAGE_FILE_MACHINE_TRICORE           0x0520  // Infineon #define IMAGE_FILE_MACHINE_CEF               0x0CEF #define IMAGE_FILE_MACHINE_EBC               0x0EBC  // EFI Byte Code #define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8) #define IMAGE_FILE_MACHINE_M32R              0x9041  // M32R little-endian #define IMAGE_FILE_MACHINE_CEE               0xC0EE  从这个定义看，只是处理器的类型而已，不能作为判断程序是32位还是64位，还有IMAGE_FILE_MACHINE_UNKNOWN这样的值呢........

user: user-0
content: 希望谁能有更好的办法，或者指出我的程序的错误在哪里....................

user: user-0
content: 在32位程序里调用hLibrary = LoadLibrary(szFileName); 如果是32位程序，hLibrary肯定不为空，64为程序hLibrary肯定为空。程序如下，编译成32位的，找个大家都能下载的程序，360杀毒64位.exe，hLibrary为空，说明是64位程序，但是wWord1 为276（x10b），说明64位程序的Magic不一定是0x2xx。现在我程序就用hLibrary = LoadLibrary(szFileName) 来判断了.........   #include "stdafx.h" #include <Windows.h>   int _tmain(int argc, _TCHAR* argv[]) { 	HANDLE hFile; 	DWORD dwFileSize; 	//char szFileName[] = "D:\\Windows技术详解\\Result\\X64Test\\Debug\\X64Test1.exe";  	char szFileName[] = "D:\\Windows技术详解\\Result\\X64Test\\Debug\\360杀毒64位.exe";  	BOOL bRet = FALSE; 	BOOL bFileX64 = FALSE; 	HMODULE hLibrary;  	hLibrary = LoadLibrary(szFileName);  	if (NULL != hLibrary) 	{ 		FreeLibrary(hLibrary); 		bFileX64 = FALSE; 	} 	else 	{ 		bFileX64 = TRUE; 	}  	hFile = CreateFile(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 	dwFileSize = GetFileSize(hFile, 0);  	BYTE *pData = new BYTE[dwFileSize]; 	if (NULL == pData) 	{ 		return bRet; 	} 	DWORD dwBytesRead = 0; 	ReadFile(hFile, pData, dwFileSize, &dwBytesRead, NULL); 	CloseHandle(hFile);  	WORD wWord = *(WORD*)(pData + 0x3c);  	wWord = wWord + 0x18;  	WORD wWord1 = *(WORD*)(pData + wWord);  	return 0; }

user: user-3
content: 给我个下载码给我个下载码给我个下载码

user: user-0
content: 引用 22 楼 stherix 的回复:[quote=引用 20 楼 wula0010 的回复:] 这个word是imageNtHeaders.FileHeader.Machine ，我还是不认为通过这个可以判断程序是32位还是64位的，看我上面贴的winnt.h里的定义，这个只是处理器的类型。   我最后还是通过LoadLibrary来判断的，.......  我给你的方法,并不是读文件头里的imageNtHeaders.FileHeader.Machine,这个有可能不准确 而是读可选头的Magic字,这两者不是同一个东西![/quote]  是我搞错了，你是对的

user: user-4
content: 引用 20 楼 wula0010 的回复:这个word是imageNtHeaders.FileHeader.Machine ，我还是不认为通过这个可以判断程序是32位还是64位的，看我上面贴的winnt.h里的定义，这个只是处理器的类型。   我最后还是通过LoadLibrary来判断的，.......  我给你的方法,并不是读文件头里的imageNtHeaders.FileHeader.Machine,这个有可能不准确 而是读可选头的Magic字,这两者不是同一个东西!

user: user-0
content: 还是我搞错了， 把imageNtHeaders.FileHeader.Machine 和  OptionalHeader.Magic搞混了，根据OptionalHeader.Magic应该是可以的。

user: user-0
content: 引用 19 楼 stherix 的回复:[quote=引用 18 楼 wula0010 的回复:] [quote=引用 17 楼 stherix 的回复:] [quote=引用 13 楼 wula0010 的回复:] 希望谁能有更好的办法，或者指出我的程序的错误在哪里....................  我下了个360 64位的 它的安装程序是32位的,并不是64的  不要混淆安装程序和运行程序[/quote]  真是32位么？你按我说的方法试试，在32位程序里调用hLibrary = LoadLibrary(szFileName); 这样能加载么？？？？[/quote]  你用64位的程序去 LoadLibrary看下? 加载不成功有很多因素,未必是32/64不匹配[/quote] 我搞错了，32位的可以加载成功 “360杀毒64位.exe”，这个是32位的安装程序。  这个word是imageNtHeaders.FileHeader.Machine ，我还是不认为通过这个可以判断程序是32位还是64位的，看我上面贴的winnt.h里的定义，这个只是处理器的类型。   我最后还是通过LoadLibrary来判断的，.......

user: user-4
content: 引用 18 楼 wula0010 的回复:[quote=引用 17 楼 stherix 的回复:] [quote=引用 13 楼 wula0010 的回复:] 希望谁能有更好的办法，或者指出我的程序的错误在哪里....................  我下了个360 64位的 它的安装程序是32位的,并不是64的  不要混淆安装程序和运行程序[/quote]  真是32位么？你按我说的方法试试，在32位程序里调用hLibrary = LoadLibrary(szFileName); 这样能加载么？？？？[/quote]  你用64位的程序去 LoadLibrary看下? 加载不成功有很多因素,未必是32/64不匹配

user: user-0
content: 引用 17 楼 stherix 的回复:[quote=引用 13 楼 wula0010 的回复:] 希望谁能有更好的办法，或者指出我的程序的错误在哪里....................  我下了个360 64位的 它的安装程序是32位的,并不是64的  不要混淆安装程序和运行程序[/quote]  真是32位么？你按我说的方法试试，在32位程序里调用hLibrary = LoadLibrary(szFileName); 这样能加载么？？？？

user: user-4
content: 引用 13 楼 wula0010 的回复:希望谁能有更好的办法，或者指出我的程序的错误在哪里....................  我下了个360 64位的 它的安装程序是32位的,并不是64的  不要混淆安装程序和运行程序

user: user-4
content: 引用 12 楼 wula0010 的回复:在32位程序里调用hLibrary = LoadLibrary(szFileName); 如果是32位程序，hLibrary肯定不为空，64为程序hLibrary肯定为空。程序如下，编译成32位的，找个大家都能下载的程序，360杀毒64位.exe，hLibrary为空，说明是64位程序，但是wWord1 为276（x10b），说明64位程序的Magic不一定是0x2xx。现在我程序就用hLibrary = LoadLibrary(szFileName) 来判断了.........  你建个64位程序,返回也可能为空的,你试下

user: user-4
content: 引用 8 楼 stherix 的回复:[quote=引用 7 楼 wula0010 的回复:] [quote=引用 3 楼 stherix 的回复:] WORD wWord1 = *(pData + wWord)  不对  要 WORD wWord1 = *(WORD *)(pData + wWord) 这样修改后，32位和64位读出来的都是267,.........................  还有，我理解你这个读的数据，还是pe头里的数据，pe头里没这个数据应该..........................................[/quote]  267也就是0x10B,肯定是32位的[/quote]  这个WORD叫Magic,是可选头的最开始部分 10B则为32位程序,20B则是64位的  64位的exe读出来不可能是10B

user: user-4
content: 引用 7 楼 wula0010 的回复:[quote=引用 3 楼 stherix 的回复:] WORD wWord1 = *(pData + wWord)  不对  要 WORD wWord1 = *(WORD *)(pData + wWord) 这样修改后，32位和64位读出来的都是267,.........................  还有，我理解你这个读的数据，还是pe头里的数据，pe头里没这个数据应该..........................................[/quote]  267也就是0x10B,肯定是32位的

user: user-0
content: 引用 3 楼 stherix 的回复:WORD wWord1 = *(pData + wWord)  不对  要 WORD wWord1 = *(WORD *)(pData + wWord) 这样修改后，32位和64位读出来的都是267,.........................  还有，我理解你这个读的数据，还是pe头里的数据，pe头里没这个数据应该..........................................

user: user-5
content: IMAGE_DOS_HEADER DosHead = { 0 }; IMAGE_NT_HEADERS NtHead = { 0 }; IMAGE_SECTION_HEADER ImageSectionHeader = { 0 }; FILE* fp; _wfopen_s(&fp, szFile, L"rb"); fread(&DosHead, sizeof(IMAGE_DOS_HEADER), 1, fp); fseek(fp, DosHead.e_lfanew, SEEK_SET); fread(&NtHead, sizeof(IMAGE_NT_HEADERS), 1, fp); if (NtHead.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { 	//32位 } if (NtHead.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) { 	//64位 }

user: user-6
content: //读0x3C WORD //这个WORD加上0x18 //再Seek到这个位置,读WORD //0x1xx就是32位 //0x2xx就是64位 #pragma warning(disable:4996) //开头加这句或项目、属性、配置属性、C/C++、预处理器、预处理器定义中添加“_CRT_SECURE_NO_WARNINGS” typedef unsigned short int WORD; #include <stdio.h> FILE *f; WORD w; int main(int argc,char **argv) {     if (argc==1) {         printf("Usage:\n    %s filename.exe\nto show 32/64 bit program\n",argv[0]);         return 1;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         printf("Can not open file %s\n",argv[1]);         return 2;     }     if (fseek(f,0x3C,SEEK_SET)) {         printf("Can not seek to 0x3C\n");         fclose(f);         return 3;     }     if (1!=fread(&w,2,1,f)) {         printf("Can not read a word at offset 0x3C\n");         fclose(f);         return 4;     }     if (fseek(f,w+0x18,SEEK_SET)) {         printf("Can not seek to word ptr (0x3C)+0x18\n");         fclose(f);         return 5;     }     if (1!=fread(&w,2,1,f)) {         printf("Can not read a word at offset word ptr (0x3C)+0x18\n");         fclose(f);         return 6;     }     fclose(f);     w&=0xFF00;          if (0x0100==w) printf("%s is a 32 bit program",argv[1]);     else if (0x0200==w) printf("%s is a 64 bit program",argv[1]);     else                printf("%s is a 32/64  program",argv[1]);     return 0; }