Announcement

Collapse
No announcement yet.

How to determine if file is exe or dll by examining header?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to determine if file is exe or dll by examining header?

    I've got a few programs, such as "PEBrowse Professional", and even "QuickView", that both state the following as Characteristics when they are pointed at a DLL file:
    File is executable
    Line numbers stripped from file
    Local symbols stripped from file
    32 bit word machine
    File is a DLL

    My question is HOW are those programs able to determine "File is a DLL"? (it says that even if you rename the file to .exe)
    Surely there is a flag somewhere in the PE header? I need to know this for a program I'm writing - but currently stuck on!
    In win32api.inc exists TYPE IMAGE_OPTIONAL_HEADER, which has "DllCharacteristics AS WORD" in it - is this the key?



    ------------------
    -

  • #2
    There are flags in the PE header... see http://www.wotsit.org/download.asp?f=pe

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      Thanks Lance, im slowly zeroing in on it - I've isolated it down to the 22nd byte counting after "PE" in the file.
      I also used this program to help verify:
      Code:
      #COMPILE DLL
      FUNCTION PBMAIN() AS LONG
      END FUNCTION
      Compiled as a DLL, that magic byte is 23h. When set to #COMPILE EXE, the byte is 03h... that's not true for all DLLs though, although the byte position is correct, but they aren't always 23h - a lot are though! I think it's probably due to "DLL Flags" (assumingly that byte) being made up of four parts
      Wotsit is a superb resource btw


      [This message has been edited by Wayne Diamond (edited May 21, 2001).]
      -

      Comment


      • #4
        Success!
        I made a program to check every DLL and EXE on my C drive to see what they were holding as their magic 22nd byte... as it turned out, EXE's only returned these values, in these frequencies:
        Code:
        Val  Frequency
        1:   1894
        3:   570
        5:   7
        7:   2
        15:  1
        129: 297
        201: 2
        So here is my final IsDLL() function - it seems rather mundane but it's about 99% successful (100% with PB DLLs and EXEs), and good enough for my purposes, so problem solved! Thanks for the tip off Lance

        Code:
        #COMPILE EXE  'PB/CC
        #INCLUDE "win32api.inc"
         
        FUNCTION IsDLL(sDLLFile AS STRING) AS LONG
        ON ERROR RESUME NEXT
        DIM MZHeader AS STRING * %MAX_PATH
        DIM hFile AS LONG, PEStart AS LONG
        hFile = FREEFILE
        OPEN sDLLFile FOR BINARY ACCESS READ AS hFile
         GET hFile, 1, MZHeader
        CLOSE hFile
        PEStart = INSTR(1, MZHeader, "PE")
        IF PEStart = 0 THEN
           FUNCTION = -1
           EXIT FUNCTION
        END IF
        SELECT CASE ASC(MID$(MZHeader, PEStart + 23,1)) 'DLL Flags are stored in this byte
         CASE 1, 3, 5, 7, 15, 129, 201:  'EXE
              FUNCTION = 0
              EXIT FUNCTION
         CASE ELSE: 'DLL
              FUNCTION = 1
              EXIT FUNCTION
        END SELECT
        END FUNCTION
         
        FUNCTION PBMAIN() AS LONG
        ON ERROR RESUME NEXT
        DIM DLLResult AS LONG
        DIM TestFile AS STRING
        Start:
        STDOUT "EXE or DLL file to check: ";
        STDIN LINE TestFile
        IF DIR$(TestFile,39) = "" THEN
           STDOUT "File not found"
           GOTO Start
        END IF
        DLLResult = IsDLL(TestFile)
        IF DLLResult = 1 THEN
            STDOUT "This file is a DLL"
        ELSEIF DLLResult = 0 THEN
            STDOUT "This file is a EXE"
        ELSE
            STDOUT "Not a PE executable"
        END IF
        END FUNCTION

        [This message has been edited by Wayne Diamond (edited May 21, 2001).]
        -

        Comment


        • #5
          wayne,
          a while ago i wrote a crude program that would dump a header from
          an exe or dll. i posted it in the source code forum back in '99
          i think.
          to check if a file is a dll test bit 13 in the
          image_file_header
          under the characteristics field
          and that will tell you if it is a dll or not.

          here is the like to that code i wrote.
          hope this helps
          kevin

          ------------------

          Comment


          • #6
            When the file has the version info compiled, you can add a filetype
            in a resource file you can use VFT_APP or VFT_DLL.

            Here's part of my "skeleton" *.rc files:

            Code:
            VS_VERSION_INFO VERSIONINFO
            FILEVERSION 2, 1, 0, 0
            PRODUCTVERSION 2, 1, 0, 0
            FILEOS VOS_WINDOWS32
            FILETYPE VFT_APP
            //* VFT_DLL FOR DLLs
            Assuming the FIELTYPE was set when the file was compiled, you query this value yourself using the GetFileVersionInfo API.

            MCM
            Michael Mattias
            Tal Systems Inc. (retired)
            Racine WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Kevin, that sounds like the proper way of doing it
              Superb code btw, I've compiled it before many months ago but just recompiled then and have gone through it, but I'm not sure about how to extract the 13th bit from a type ... would you be so kind as to modify your PE Header dump program so that it goes that one step further to say if its an exe or dll?
              Thanks very much, I'd love to know how to do this (and bit extraction) properly
              Wayne


              [This message has been edited by Wayne Diamond (edited May 21, 2001).]
              -

              Comment


              • #8
                Wayne
                Here is some updated code that checks that bit to see if it is a
                DLL or EXE then prints which one it is.
                Again this code is Crude but works. (I Hope)

                Here is the check to determine if it is a DLL or EXE
                PB has a nice function called BIT to test individual bits
                you just provide the number to test and which bit to test
                and it returns 1 or 0 depending on that status of that bit.


                Code:
                '******************************CHECK IF DLL OR NOT*************************
                Temp??? = BIT(ExeHdrInfo.FileHeader.Characteristics, 13)
                IF Temp??? = 1 THEN
                    CONTROL ADD LABEL, hDLG, 125, "This File is a DLL", 10, 235, 200, 10
                ELSE
                    CONTROL ADD LABEL, hDLG, 125, "This File is a EXE", 10, 235, 200, 10
                END IF
                '**************************************************************************
                here it is added to the program below. I know the formatting is not
                pretty, but well I am a device driver guy, I never said I was
                good with GUI or Graphics. In my original post many years ago
                I had in there to comment out some things in the Win32api.inc for
                this to work correctly. But PB must have updated it because it
                works fine with out modification, I just downloaded the newest
                Win32api.zip file to test and it is fine. So i took that part out.


                Code:
                'Dump EXE Header info
                '(C)1999 Kevin Voell
                'Released into Public Domain 11-20-1999
                #COMPILE EXE
                #INCLUDE "C:\pbdll60\winapi\WIN32API.INC"
                #INCLUDE "COMDLG32.INC"
                '=============================================================================
                'THIS FILE IS INCOLMPLETE AS IT STOPS REPORTING AFTER THE BaseOfData in the
                'Optional_Header_File.
                'The output it shows it not in a neat format (all the collums are off), 'but I got
                'the information out of this file that I needed and deceided to abandon it.
                'It is basiclly the same information that QuickView gives you.
                'It has no error checking to see if it is a valid WIN32 executable or not.
                'But it should NOT mess up any files. But I am not responsible if it does.
                'in other words USE AT YOUR OWN RISK!!!!
                'It really could be a neat little tool to have if someone wanted to finish 'it off.
                'You could add the rest of the Optional_Header_Image (I don't know why 'they call it
                '"optional", because you need to have it), add the Image_section_header.
                'It is not very well documented and for that i apologize :-(
                'But it is pretty simple to understand.
                'All values displayed are in hexadecimal format
                'The values marked signatures should be "5A4D" for DOS files (MZ in HEX)
                ' "4550" for WIN32 files (PE in HEX)
                ' "454E" for win16/DLL files (NE in HEX)
                ' "10B" for the optional header
                'most of the values are missing the preceeding zeros, it should be 'formated for example:
                '"Number of minimun DOS papagraphs needed: 0004"
                'Instead it prints:
                '"Number of minimun DOS paragraphs needed: 4"
                'If the File is already in use or otherwise open it will report all zeros.
                'TYPE IMAGE_FILE_HEADER
                ' Machine AS dWORD
                ' NumberOfSections AS WORD
                ' TimeDateStamp AS DWORD
                ' PointerToSymbolTable AS DWORD
                ' NumberOfSymbols AS DWORD
                ' SizeOfOptionalHeader AS WORD
                ' Characteristics AS WORD
                'END TYPE
                'TYPE IMAGE_NT_HEADERS
                ' Signature AS WORD
                ' FileHeader AS IMAGE_FILE_HEADER
                ' OptionalHeader AS IMAGE_OPTIONAL_HEADER
                'END TYPE
                'TYPE IMAGE_DOS_HEADER ' DOS .EXE header
                ' e_magic AS WORD ' Magic number
                ' e_cblp AS WORD ' Bytes on last page of file
                ' e_cp AS WORD ' Pages in file
                ' e_crlc AS WORD ' Relocations
                ' e_cparhdr AS WORD ' Size of header in paragraphs
                ' e_minalloc AS WORD ' Minimum extra paragraphs needed
                ' e_maxalloc AS WORD ' Maximum extra paragraphs needed
                ' e_ss AS WORD ' Initial (relative) SS value
                ' e_sp AS WORD ' Initial SP value
                ' e_csum AS WORD ' Checksum
                ' e_ip AS WORD ' Initial IP value
                ' e_cs AS WORD ' Initial (relative) CS value
                ' e_lfarlc AS WORD ' File address of relocation table
                ' e_ovno AS WORD ' Overlay number
                ' e_res(4) AS WORD ' Reserved words
                ' e_oemid AS WORD ' OEM identifier (for e_oeminfo)
                ' e_oeminfo AS WORD ' OEM information; e_oemid specific
                ' e_res2(10) AS WORD ' Reserved words
                ' e_lfanew AS LONG ' File address of new exe header
                'END TYPE
                'TYPE IMAGE_OPTIONAL_HEADER
                '
                ' Standard fields.
                '
                ' Magic AS WORD
                ' MajorLinkerVersion AS BYTE
                ' MinorLinkerVersion AS BYTE
                ' SizeOfCode AS DWORD
                ' SizeOfInitializedData AS DWORD
                ' SizeOfUninitializedData AS DWORD
                ' AddressOfEntryPoint AS DWORD
                ' BaseOfCode AS DWORD
                ' BaseOfData AS DWORD
                '
                ' NT additional fields.
                '
                ' ImageBase AS DWORD
                ' SectionAlignment AS DWORD
                ' FileAlignment AS DWORD
                ' MajorOperatingSystemVersion AS WORD
                ' MinorOperatingSystemVersion AS WORD
                ' MajorImageVersion AS WORD
                ' MinorImageVersion AS WORD
                ' MajorSubsystemVersion AS WORD
                ' MinorSubsystemVersion AS WORD
                ' Reserved1 AS DWORD
                ' SizeOfImage AS DWORD
                ' SizeOfHeaders AS DWORD
                ' CheckSum AS DWORD
                ' Subsystem AS WORD
                ' DllCharacteristics AS WORD
                ' SizeOfStackReserve AS DWORD
                ' SizeOfStackCommit AS DWORD
                ''SizeOfHeapReserve AS DWORD
                'SizeOfHeapCommit AS DWORD
                'LoaderFlags AS DWORD
                'NumberOfRvaAndSizes AS DWORD
                'DataDirectory(%IMAGE_NUMBEROF_DIRECTORY_ENTRIES) AS IMAGE_DATA_DIRECTORY
                'END TYPE
                
                FUNCTION PBMAIN()
                LOCAL ExeHdrInfo AS IMAGE_NT_HEADERS
                LOCAL DOSHdr AS Image_DOS_Header
                LOCAL hDLG AS LONG
                Path$ = CURDIR$
                f$ = "*.EXE"
                Style% = %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY OR %OFN_LONGNAMES
                RESULT% = OpenFileDialog(%HWND_DESKTOP, "Open File", f$, Path$, _
                "Executable Files|*.EXE|All Files|*.*", "EXE",%OFN_FILEMUSTEXIST OR _
                %OFN_HIDEREADONLY OR %OFN_LONGNAMES)
                X% = FREEFILE
                OPEN f$ FOR BINARY AS X%
                GET X%,, DosHdr
                SEEK X%, 0
                SEEK X%, DosHdr.e_lfanew + 1
                se% = SEEK(x%)
                GET X%,, ExeHdrInfo
                CLOSE X%
                DIALOG NEW %HWND_DESKTOP, f$ + "32BIT EXE FILE INFO", ,,300,500,%WS_SYSMENU OR _
                %WS_MAXIMIZEbox, TO hDLG
                DosHdrSig$ = MKWRD$(DosHdr.e_Magic)
                DosHdrSigHex$ = HEX$(DosHdr.e_magic)
                CONTROL ADD LABEL ,hDLG, 101, "DOS SIGNATURE: " + _
                DosHdrSigHex$ + " " + DosHdrSig$, 10, 4, 200, 10
                DosBytesLast$ = HEX$(DosHdr.e_cblp)
                CONTROL ADD LABEL ,hDLG, 102, "Number of Bytes in last page of File: " + _
                DosBytesLast$, 10, 14, 200, 10
                DosPages$ = HEX$(DosHdr.e_cp)
                CONTROL ADD LABEL, hDLG, 103, "Number of Pages in file: " +_
                DosPages$, 10, 24, 200, 10
                DosRelo$ = HEX$(DosHdr.e_crlc)
                CONTROL ADD LABEL, hDLG, 104, "Number of Relocatable Pages in File: " + _
                DosRelo$, 10, 34, 200, 10
                DosHeader$ = HEX$(DosHdr.e_cparhdr)
                CONTROL ADD LABEL, hDLG, 105, "Number of Paragraphs in DOS header: " + _
                DosHeader$, 10, 44, 200, 10
                DosMin$ = HEX$(DosHdr.e_minalloc)
                CONTROL ADD LABEL, hDLG, 106, "Number of Minimun DOS Paragraphs needed: " + _
                DosMin$, 10, 54, 200, 10
                DosMax$ = HEX$(DosHdr.e_maxalloc)
                CONTROL ADD LABEL, hDLG, 107, "Number of Maximun Dos Paragraphs needed: " + _
                DosMax$, 10, 64, 200, 10
                DosSS$ = HEX$(DosHdr.e_ss)
                CONTROL ADD LABEL, hDLG, 108, "Inital Stack Segment: " +_
                DosSS$, 10, 74, 200, 10
                DosSP$ = HEX$(DosHdr.e_sp)
                CONTROL ADD LABEL, hDLG, 109, "Inital Stack Pointer: " + _
                DosSP$, 10 , 84, 200, 10
                DosCheck$ = HEX$(DosHdr.e_csum)
                CONTROL ADD LABEL, hDLG, 110, "Checksum: " + _
                DosCheck$, 10, 94, 200, 10
                DosIP$ = HEX$(DosHdr.e_ip)
                CONTROL ADD LABEL, hDLG, 111, "Inital Intruction Pointer: " + _
                DosIP$, 10, 104, 200, 10
                DosCS$ = HEX$(DosHdr.e_cs)
                CONTROL ADD LABEL, hDLG, 112, "Inital Code Segment: " + _
                DosCS$, 10, 114, 200, 10
                DosReloAdd$ = HEX$(DosHdr.e_lfarlc)
                CONTROL ADD LABEL, hDLG, 113, "Address of relcation table: " + _
                DosReloAdd$, 10, 124, 200, 10
                DosOverlay$ = HEX$(DosHdr.e_ovno)
                CONTROL ADD LABEL, hDLG, 114, "Overlay Number: " + _
                DosOverlay$, 10, 134, 200, 10
                DIM DosRes$(0 TO 13)
                DosRes$(0) = HEX$(DosHdr.e_res(1))
                DosRes$(1) = HEX$(DosHdr.e_res(2))
                DosRes$(2) = HEX$(DosHdr.e_res(3))
                DosRes$(3) = HEX$(DosHdr.e_res(4))
                DosRes$(4) = HEX$(DosHdr.e_res2(1))
                DosRes$(5) = HEX$(DosHdr.e_res2(2))
                DosRes$(6) = HEX$(DosHdr.e_res2(3))
                DosRes$(7) = HEX$(DosHdr.e_res2(4))
                DosRes$(8) = HEX$(DosHdr.e_res2(5))
                DosRes$(9) = HEX$(DosHdr.e_res2(6))
                DosRes$(10) = HEX$(DosHdr.e_res2(7))
                DosRes$(11) = HEX$(DosHdr.e_res2(8))
                DosRes$(12) = HEX$(DosHdr.e_res2(9))
                DosRes$(13) = HEX$(DosHdr.e_res2(10))
                CONTROL ADD LABEL, hDLG, 115, "Reserved Words: " + _
                DosRes$(1) + _
                DosRes$(2) + DosRes$(3) + DosRes$(4) + DosRes$(5) + DosRes$(6) + DosRes$(7) +_
                DosRes$(8) +_
                DosRes$(9) + DosRes$(10) + DosRes$(11) + DosRes$(12) + DosRes$(13), 10,_
                144, 200, 10
                DosOffSet$ = HEX$(DosHdr.e_lfanew)
                CONTROL ADD LABEL, hDLG, 116, "Offset to New header: " + _
                DosOffSet$, 10, 154, 200, 10
                CONTROL ADD LABEL, hDLG, 117, " WIN32 HEADER INFO", 10, 164, 200, 10
                WinSign$ = HEX$(ExeHdrInfo.Signature)
                WinSignLet$ = MKWRD$(ExeHdrInfo.Signature)
                CONTROL ADD LABEL, hDLG, 118, "Win32 Signature: " + _
                WinSign$ + " " + WinSignLet$, 10, 174, 200, 10
                Machine$ = HEX$(ExeHdrInfo.FileHeader.Machine)
                'IMAGE_FILE_MACHINE_I386 (0x14c)
                'FOR Intel 80386 processor OR better
                '0x014d
                'FOR Intel 80486 processor OR better
                '0x014e
                'FOR Intel Pentium processor OR better
                '0x0160
                'FOR R3000 (MIPS) processor, big endian
                'IMAGE_FILE_MACHINE_R3000 (0x162)
                'FOR R3000 (MIPS) processor, little endian
                'IMAGE_FILE_MACHINE_R4000 (0x166)
                'FOR R4000 (MIPS) processor, little endian
                'IMAGE_FILE_MACHINE_R10000 (0x168)
                'FOR R10000 (MIPS) processor, little endian
                'IMAGE_FILE_MACHINE_ALPHA (0x184)
                'FOR DEC Alpha AXP processor
                'IMAGE_FILE_MACHINE_POWERPC (0x1F0)
                'FOR IBM Power PC, little endian
                IF Machine$ = "14C0000" THEN
                MachineName$ = "386"
                ELSEIF Machine$ = "14D0000" THEN
                MachineName$ = "486"
                ELSEIF Machine$ = "14E0000" THEN
                MachineName$ = "Pentium"
                END IF
                CONTROL ADD LABEL, hDLG, 119, "Machine: " + _
                MachineName$, 10, 184, 200, 10
                TimeDateStamp$ = HEX$(ExeHdrInfo.FileHeader.TimeDateStamp)
                'The Time and date stamp would be great to use for version checking
                'But unfortunally PBDLL always set it to 3039. I don't know why.
                'From what I uncovered it is seconds since January 1 1970 00:00:00' in UTC
                '- the format used by most C compilers FOR the time_t.)
                'I suppose that a brave programmer could write a utility to change it to a certain time
                'and use that to check diffrent versions of the same file even if the official version
                'did not change.
                CONTROL ADD LABEL, hDlg, 120, "Time and Date stamp: " + _
                TimeDateStamp$, 10, 194, 200, 10
                WinPTRSymbol$ = HEX$(ExeHdrInfo.FileHeader.PointerToSymbolTable)
                CONTROL ADD LABEL, hDLG, 121, "Pointer to symbol Table: " + _
                WinPTRSymbol$, 10, 204, 200, 10
                WinNumSymbols$ = HEX$(exeHdrInfo.FileHeader.NumberOfSymbols)
                CONTROL ADD LABEL, hDLG, 122, "Number of Symbols: " + _
                WinNumSymbols$, 10, 214, 200, 10
                WinSizeOptHeader$ = HEX$(ExeHdrInfo.FileHeader.SizeOfOptionalHeader)
                CONTROL ADD LABEL, hDLG, 123, "Size Of optional Header: " + _
                WinSizeOptHeader$, 10, 224, 200, 10
                WinChar$ = HEX$(ExeHdrInfo.FileHeader.Characteristics)
                CONTROL ADD LABEL, hDLG, 124, "Characteristics: " + _
                WinChar$, 10, 234, 200, 10
                '******************************CHECK IF DLL OR NOT*************************
                Temp??? = BIT(ExeHdrInfo.FileHeader.Characteristics, 13)
                IF Temp??? = 1 THEN
                    CONTROL ADD LABEL, hDLG, 125, "This File is a DLL", 10, 235, 200, 10
                ELSE
                    CONTROL ADD LABEL, hDLG, 125, "This File is a EXE", 10, 235, 200, 10
                END IF
                '**************************************************************************
                'Characteristics' is 16 bits and consists of a collection of flags, most
                'of them being valid only FOR object files AND libraries:
                'BIT 0 (IMAGE_FILE_RELOCS_STRIPPED) is SET IF there is no relocation
                ' information IN the file. This refers TO relocation information per
                ' section IN the sections themselves; it is NOT used FOR executables,
                ' which have relocation information IN the 'base relocation' directory
                ' described below.
                ' BIT 1 (IMAGE_FILE_EXECUTABLE_IMAGE) is SET IF the file is
                ' executable, i.e. it is NOT an object file OR a library. This flag
                ' may also be SET IF the linker attempted TO CREATE an executable but
                ' failed FOR some reason, AND keeps the IMAGE IN order TO DO e.g.
                ' incremental linking the NEXT time.
                ' BIT 2 (IMAGE_FILE_LINE_NUMS_STRIPPED) is SET IF the LINE number
                ' information is stripped; this is NOT used FOR executable files.
                ' BIT 3 (IMAGE_FILE_LOCAL_SYMS_STRIPPED) is SET IF there is no
                ' information about LOCAL symbols IN the file (this is NOT used
                ' FOR executable files).
                ' BIT 4 (IMAGE_FILE_AGGRESIVE_WS_TRIM) is SET IF the operating system
                ' is supposed TO trim the working SET of the running process (the
                ' amount of RAM the process uses) aggressivly by paging it out. This
                ' should be SET IF it is a demon-like application that waits most of
                ' the time AND only wakes UP once a day, OR the like.
                'Bits 7 (IMAGE_FILE_BYTES_REVERSED_LO) AND 15
                '(IMAGE_FILE_BYTES_REVERSED_HI) are SET IF the endianess of the file is
                'NOT what the machine would expect, so it must SWAP bytes before
                'reading. This is unreliable FOR executable files (the OS expects
                'executables TO be correctly BYTE-ordered).
                'BIT 8 (IMAGE_FILE_32BIT_MACHINE) is SET IF the machine is expected
                'TO be a 32 BIT machine. This is always SET FOR current
                'implementations; NT5 may work differently.
                'BIT 9 (IMAGE_FILE_DEBUG_STRIPPED) is SET IF there is no debugging
                'information IN the file. This is unused FOR executable files.
                'According TO other information ([6]), this BIT is called "fixed" AND
                'is SET IF the IMAGE can only run IF it is loaded AT the preferred
                'load address (i.e. it is NOT relocatable).
                'BIT 10 (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) is SET IF the application
                'may NOT run FROM a removable medium such AS a floppy OR a CD-ROM. IN
                'this CASE, the operating system is advised TO copy the file TO the
                'swapfile AND execute it FROM there.
                'BIT 11 (IMAGE_FILE_NET_RUN_FROM_SWAP) is SET IF the application may
                'NOT run FROM the network. IN this CASE, the operating system is
                'advised TO copy the file TO the swapfile AND execute it FROM there.
                'BIT 12 (IMAGE_FILE_SYSTEM) is SET IF the file is a system file such
                'AS a driver. This is unused FOR executable files; it is also NOT
                'used IN ALL the NT drivers I inspected.
                'BIT 13 (IMAGE_FILE_DLL) is SET IF the file is a DLL.
                'BIT 14 (IMAGE_FILE_UP_SYSTEM_ONLY) is SET IF the file is NOT
                'designed TO run ON multiprocessor systems (that is, it will crash
                'there because it relies IN some way ON exactly one processor).
                
                OptMagic$ = HEX$(ExeHdrInfo.OptionalHeader.magic)
                CONTROL ADD LABEL, hDLG, 126, " WIN32 OPTIONAL(?) HEADER INFO", 10,_
                244, 200, 10
                CONTROL ADD LABEL, hDLG, 125, "Optional Header Signature: " + _
                OptMagic$, 10, 254, 200, 10
                OptLinkerVer$ = HEX$(ExeHdrInfo.OptionalHeader.MajorLinkerVersion)
                CONTROL ADD LABEL, hDLG, 127, "Major Linker Version: " + _
                OptLinkerVer$, 10, 264, 200, 10
                OptMinLikerVer$ = HEX$(ExeHdrInfo.OptionalHeader.MinorLinkerVersion)
                CONTROL ADD LABEL, hDLG, 128, "Minor Linker Version: " + _
                OptMinLinkerVer$, 10, 274, 200, 10
                OptSizeCode$ = HEX$(ExeHdrInfo.OptionalHeader.SizeOfCode)
                CONTROL ADD LABEL, hDLG, 129, "Size of Code: " + _
                OptSizeCode$, 10, 284, 200, 10
                OptSizeData$ = HEX$(ExeHdrInfo.OptionalHeader.SizeOfUninitializedData)
                CONTROL ADD LABEL, hDLG, 130, "Size of Uninitialized Data: " + _
                OptSizeData$, 10, 294, 200, 10
                AddressEntyPoint$ = HEX$(ExeHdrInfo.OptionalHeader.AddressOfEntryPoint)
                CONTROL ADD LABEL, hDlg, 131, "Entry point to code: " + _
                AddressEntryPoint$, 10, 304, 200, 10
                BaseOfCode$ = HEX$(ExeHdrInfo.OptionalHeader.BaseOfCode)
                CONTROL ADD LABEL, hDLG, 132, "Base of Code: " + _
                BaseOfCode$, 10, 314, 200, 10
                BaseOfData$ = HEX$(ExeHdrInfo.OptionalHeader.BaseOfData)
                CONTROL ADD LABEL, hDLG, 133, "Base of Data: " + _
                BaseOfData$, 10, 324, 200, 10
                DIALOG SHOW MODAL hDLG
                END FUNCTION

                ------------------




                [This message has been edited by Kevin R Voell (edited May 21, 2001).]

                Comment


                • #9
                  Lance
                  BTW that site is the best!!! I think I have read everything on
                  that site. It is such a great resource.
                  Kevin

                  ------------------

                  Comment


                  • #10
                    Kevin,
                    Thanks! I didn't realise BIT() was so easy, that'll come in handy
                    But did you actually test it? It's saying "File is an EXE" on every DLL and EXE i've tested so far so something might not be right, but it seems like the right way to do it


                    ------------------
                    -

                    Comment


                    • #11
                      Wayne-
                      I Tested it on three of my PC's and it works fine on all of them.
                      One is a Windows XP (Whistler). The other two both run Windows ME
                      and Windows 2000 Pro.
                      That is strange that it doesn't work on yours.
                      If you want to email me the compiled program I can try it on
                      my PC's.

                      Kevin
                      [email protected]

                      ------------------

                      Comment


                      • #12
                        Wayne
                        I got it.
                        Just out of curiosity I reinstalled PBdll and got the same error
                        you got. everything kept saying it was an EXE.
                        Then I downloaded the latest WIN32API.zip off the PB website
                        and installed that. Now It works right. Returning exe or dll
                        as designed.
                        So just install the latest win32api.zip and it should work.
                        Kevin

                        ------------------

                        Comment


                        • #13
                          SUCCESS!! The latest win32api did the trick, a million and one thanks Kevin!
                          So here is the simple test i put together so that I can use it in other programs later
                          Code:
                          #COMPILE EXE  'PB/CC
                          #INCLUDE "WIN32API.INC"
                           
                          FUNCTION IsDLL(sFileName AS STRING) AS LONG
                          ON ERROR RESUME NEXT
                           IF DIR$(sFileName,39) = "" THEN
                              STDOUT "File not found!"
                              FUNCTION = -1
                              EXIT FUNCTION
                           END IF
                           LOCAL ExeHdrInfo AS IMAGE_NT_HEADERS
                           LOCAL DOSHdr AS Image_DOS_Header
                           LOCAL lBit AS LONG
                           X% = FREEFILE
                           OPEN sFileName FOR BINARY AS X%
                           GET X%,, DosHdr
                           SEEK X%, 0
                           SEEK X%, DosHdr.e_lfanew + 1
                           se% = SEEK(x%)
                           GET X%,, ExeHdrInfo
                           CLOSE X%
                           IF LEFT$(DosHdr,2) <> "MZ" THEN
                              FUNCTION = 0
                              EXIT FUNCTION
                           END IF
                           lBit = BIT(ExeHdrInfo.FileHeader.Characteristics, 13)
                           IF lBit = 1 THEN
                              FUNCTION = 2
                           ELSE
                              FUNCTION = 1
                           END IF
                          END FUNCTION
                           
                          FUNCTION PBMAIN()
                          ON ERROR RESUME NEXT
                          DIM lResult AS LONG
                          DIM sTestFile AS STRING
                          STDOUT "File to test: ";
                          STDIN LINE sTestFile
                          lResult = IsDLL(sTestFile)
                          IF lResult = 2 THEN
                             STDOUT "File is a DLL"
                          ELSEIF lResult = 1 THEN
                             STDOUT "File is an EXE"
                          END IF
                          END FUNCTION


                          ------------------
                          -

                          Comment

                          Working...
                          X