DllExport int GetSubSystem(PTCHAR exeName) { HANDLE hImage; DWORD bytes; DWORD iSection; DWORD SectionOffset; DWORD CoffHeaderOffset; DWORD MoreDosHeader[16]; ULONG ntSignature; IMAGE_DOS_HEADER image_dos_header; IMAGE_FILE_HEADER image_file_header; IMAGE_OPTIONAL_HEADER image_optional_header; IMAGE_SECTION_HEADER image_section_header; int res = -1; if(exeName == NULL) return -1; hImage = CreateFile(exeName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hImage) { //printf("Could not open %s, error %lu\n", argv[1], GetLastError()); //exit(1); return -1; } /* * Read the MS-DOS image header. */ res = ReadBytes(hImage, &image_dos_header, sizeof(IMAGE_DOS_HEADER)); if(res == -1) return -1; if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic) { // printf("Sorry, I do not understand this file.\n"); // exit(1); return -1; } /* * Read more MS-DOS header. */ res = ReadBytes(hImage, MoreDosHeader, sizeof(MoreDosHeader)); if(res == -1) return -1; /* * Get actual COFF header. */ CoffHeaderOffset = AbsoluteSeek(hImage, image_dos_header.e_lfanew) + sizeof(ULONG); if(CoffHeaderOffset == -1) return -1; res = ReadBytes (hImage, &ntSignature, sizeof(ULONG)); if(res == -1) return -1; if (IMAGE_NT_SIGNATURE != ntSignature) { //printf("Missing NT signature. Unknown file type.\n"); //exit(1); return -1; } SectionOffset = CoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL_HEADER; ReadBytes(hImage, &image_file_header, IMAGE_SIZEOF_FILE_HEADER); /* * Read optional header. */ res = ReadBytes(hImage, &image_optional_header, IMAGE_SIZEOF_NT_OPTIONAL_HEADER); if(res == -1) return -1; return image_optional_header.Subsystem; }
/* if we can't determine it, we will return true */ static int is_gui_app (char *exe) { HANDLE hImage; DWORD bytes; DWORD iSection; DWORD SectionOffset; DWORD CoffHeaderOffset; DWORD MoreDosHeader[16]; CHAR *file; size_t nlen; ULONG ntSignature; IMAGE_DOS_HEADER image_dos_header; IMAGE_FILE_HEADER image_file_header; IMAGE_OPTIONAL_HEADER image_optional_header; IMAGE_SECTION_HEADER image_section_header; /* * Open the reference file. */ nlen = strlen (exe); file = exe; if (nlen > 2) { if (exe[0] == '"') { /* remove quotes */ nlen -= 2; file = malloc ((nlen + 1) * sizeof (char)); memcpy (file, &exe[1], nlen); file [nlen] = '\0'; } } hImage = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file != exe) { free (file); } if (INVALID_HANDLE_VALUE == hImage) { report_file_error ("Could not open exe: ", Qnil); report_file_error (exe, Qnil); report_file_error ("\n", Qnil); CloseHandle (hImage); return -1; } /* * Read the MS-DOS image header. */ ReadBytes(hImage, &image_dos_header, sizeof(IMAGE_DOS_HEADER)); if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic) { report_file_error("Sorry, I do not understand this file.\n", Qnil); CloseHandle (hImage); return -1; } /* * Read more MS-DOS header. */ ReadBytes(hImage, MoreDosHeader, sizeof(MoreDosHeader)); /* * Get actual COFF header. */ CoffHeaderOffset = AbsoluteSeek(hImage, image_dos_header.e_lfanew) + sizeof(ULONG); if (CoffHeaderOffset < 0) { CloseHandle (hImage); return -1; } ReadBytes (hImage, &ntSignature, sizeof(ULONG)); if (IMAGE_NT_SIGNATURE != ntSignature) { report_file_error ("Missing NT signature. Unknown file type.\n", Qnil); CloseHandle (hImage); return -1; } SectionOffset = CoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL_HEADER; ReadBytes(hImage, &image_file_header, IMAGE_SIZEOF_FILE_HEADER); /* * Read optional header. */ ReadBytes(hImage, &image_optional_header, IMAGE_SIZEOF_NT_OPTIONAL_HEADER); CloseHandle (hImage); switch (image_optional_header.Subsystem) { case IMAGE_SUBSYSTEM_UNKNOWN: return 1; break; case IMAGE_SUBSYSTEM_NATIVE: return 1; break; case IMAGE_SUBSYSTEM_WINDOWS_GUI: return 1; break; case IMAGE_SUBSYSTEM_WINDOWS_CUI: return 0; break; case IMAGE_SUBSYSTEM_OS2_CUI: return 0; break; case IMAGE_SUBSYSTEM_POSIX_CUI: return 0; break; default: /* Unknown, return GUI app to be preservative: if yes, it will be correctly launched, if no, it will be launched, and a console will be also displayed, which is not a big deal */ return 1; break; } }
DWORD GetExeSize() { DWORD dwSize = 0; HANDLE hImage; DWORD dwSectionOffset; DWORD dwCoffHeaderOffset; DWORD moreDosHeader[16]; ULONG NTSignature; IMAGE_DOS_HEADER image_dos_header; IMAGE_FILE_HEADER image_file_header; IMAGE_OPTIONAL_HEADER image_optional_header; IMAGE_SECTION_HEADER image_section_header; // Open the EXE file. hImage = CreateFile(g_sExeFullFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hImage) { ErrorMsg(L"Could not open the EXE"); return 0; } // Read the MS-DOS image header. ReadBytes(hImage, &image_dos_header, sizeof(image_dos_header)); if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic) { ErrorMsg(L"Unknown file format."); return 0; } // Read more MS-DOS header. ReadBytes(hImage, moreDosHeader, sizeof(moreDosHeader)); // Get actual COFF header. dwCoffHeaderOffset = AbsoluteSeek(hImage, image_dos_header.e_lfanew) + sizeof(ULONG); ReadBytes (hImage, &NTSignature, sizeof(NTSignature)); if (IMAGE_NT_SIGNATURE != NTSignature) { ErrorMsg(L"Missing NT signature. Unknown file type."); return 0; } dwSectionOffset = dwCoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_NT_OPTIONAL_HEADER; ReadBytes(hImage, &image_file_header, IMAGE_SIZEOF_FILE_HEADER); // Read optional header. ReadBytes(hImage, &image_optional_header, IMAGE_SIZEOF_NT_OPTIONAL_HEADER); WORD nNumSections = image_file_header.NumberOfSections; for (WORD i = 0; i < nNumSections; i++) { ReadBytes(hImage, &image_section_header, sizeof(IMAGE_SECTION_HEADER)); DWORD dwRawData = image_section_header.PointerToRawData + image_section_header.SizeOfRawData; if (dwRawData > dwSize) dwSize = dwRawData; } CloseHandle(hImage); return dwSize; }