Mohammad Dayyan
Mohammad Dayyan

Reputation: 22411

How to distinguish between normal exe file and self-extracting file in C#?

I want to detect exe file that created with zip tools? like 7z or WinRAR or ..., I mean SFX (self-extracting executable) files

So I have to find a way to distinguish between normal exe files and SFX files in C#?
Are there any ways to detect them in C#?

Upvotes: 2

Views: 2911

Answers (4)

ssokolow
ssokolow

Reputation: 15345

The approach to take if you want to detect a self-extractor varies depending on whether you want to detect self-extractors within a known set of formats with 100% reliability or whether you want to detect unfamiliar self-extractors with less reliability.

(Both approaches have their uses. The latter is good for calling in a human for a second opinion, for example.)

Option A would be to use the same approach archival tools use.

A self-extracting archive is just a regular archive, concatenated onto an EXE file, with the offsets fixed up. (For Zip files, you can do that manually by using zip -A from Info-ZIP), so open the file and scan through, looking for valid RAR/Zip/etc. header/trailers. (To do it efficiently, use an algorithm like Aho-Corasick to search for all candidate strings in a single pass.)

For extra reliability, parse the MZ and NE or PE header to figure out how many bytes to skip to get past any potential matching strings within the EXE itself.

Option B would be to parse the MZ header as described by Medinoc but then, instead of looking for a specific section in the PE header, calculate the total length of the NE or PE binary (Win16 self-extractors do exist, as created by tools like WinZIP 6.3 SR-1 and below) and skip it all.

Then, do some heuristic check, such as comparing the size of the skipped EXE portion to the size of the file overall and deciding whether the smallness of the EXE portion and the largeness of the stuff concatenated onto it look characteristic of a self-extractor.

(Bearing in mind that this might also catch DPMI-based DOS applications if you don't do additional checking for non-NE/non-PE files to rule them out, since they also use that "stub plus stuff concatenated on" structure.)

The most reliable solution would be to combine both approaches:

  1. Use option A and check for the identifying headers/trailers for all modern or historically common EXE-based self-extractor formats (7z, RAR, ACE, Zip, ARJ, ARC, Lha/LZH, Zoo, InnoSetup installer, NSIS installer, single-file InstallShield installers from the pre-.msi era, or an EXE containing a .cab or .msi bundle.)

  2. If you didn't get a match, use option A to rule out .NET EXE files, common DPMI extenders, and other common bulk content that might have been concatenated onto the EXE as a poor man's resource bundle. (eg. images, audio, video, etc.)

    To create test files for DPMI EXEs, just compile a "Hello, World!" to the DPMI target using djgpp (Linux) and Open Watcom C/C++ (1.9, 2.0). djgpp will get you CWSDPMI, while OpenWatcom C/C++ includes the DOS/4GW, PMODE/W, DOS/32A, and CauseWay DPMI extenders, the Win386 windows extender, and is compatible with the other free/freed extenders. (PharLap's extenders, which Microsoft licensed for inclusion with with Microsoft C/C++, are the only notable ones I'm aware of which didn't get freed, but I believe Open Watcom can at least generate the binary that they're supposed to be prepended onto.)

    You may also need to rule out executable packers, since they use a stub-based system. UPX is pretty much the only one in use today but, historically, there were a lot of them.

  3. As a fallback, parse the MZ and LE, NE, or PE headers to properly count embedded resources (eg. icons) as part of the EXE portion and then, if the file is more than some percentage "extra data", it's likely to be a self-extractor.

Upvotes: 2

Medinoc
Medinoc

Reputation: 6608

I don't know about other utilities, but the "classic" self-extractor from Nico Mak Computing creates executables containing a _winzip_ section. These could be detected by reading the section table of the executable, which is an array of IMAGE_SECTION_HEADER structures.

To access it without using specialized libraries, you would need to:

  • Open a stream on the file
  • Read the 64-byte IMAGE_DOS_HEADER structure
  • Take its last member (four bytes) as the offset of the next header
  • Seek to this offset
  • Read the 4-byte PE magic
  • Read the 20-byte IMAGE_FILE_HEADER structure
  • Take its member SizeOfOptionalHeader (second-to-last WORD)
  • Skip that many bytes
  • The stream is now pointing at the section table

Then it's just a matter of reading the section table (the IMAGE_FILE_HEADER structure has a member NumberOfSections), and seeing if any one of them is named _winzip_.

Upvotes: 2

Jack Gajanan
Jack Gajanan

Reputation: 1670

if it is SFX from any compression it will be a standard executable file for sure..

so you can take approach to validate executable or not

How to find if a file is an exe?

check answer of Chris Schmich

Upvotes: 1

WQYeo
WQYeo

Reputation: 4046

You can just make the .exe format into .rar format and double-click to open(NOT extract) it up to view the contents, most likely it would be a self-extracting file if your WinRAR or 7z manages to open it up for you. But if you get an error while trying to view the contents in the .rar file, then most likely it would be be a normal .exe file.

I believe there are other methods but this is the one that I commonly use since its quite simple.

With that being said, what you need to let the C# do is this :

  1. Change the file's format to .rar
  2. Open up the file using WinRAR or 7z
  3. Using try-catch block, give an error message if fails to open , otherwise, give a positive message if opening is successful.

If you need help with changing the file format , you can look up on this : Change File Extension Using C#

If you need help with opening the file : How do I launch files in C#

Upvotes: 1

Related Questions