How to detect the types of executable files

type

  {
IMAGE_DOS_HEADER:
DOS .EXE header.
}
IMAGE_DOS_HEADER = packed record
e_magic : Word; // Magic number ("MZ")
e_cblp : Word; // Bytes on last page of file
e_cp : Word; // Pages in file
e_crlc : Word; // Relocations
e_cparhdr : Word; // Size of header in paragraphs
e_minalloc: Word; // Minimum extra paragraphs needed
e_maxalloc: Word; // Maximum extra paragraphs needed
e_ss : Word; // Initial (relative) SS value
e_sp : Word; // Initial SP value
e_csum : Word; // Checksum
e_ip : Word; // Initial IP value
e_cs : Word; // Initial (relative) CS value
e_lfarlc : Word; // Address of relocation table
e_ovno : Word; // Overlay number
e_res : packed array [..] of Word; // Reserved words
e_oemid : Word; // OEM identifier (for e_oeminfo)
e_oeminfo : Word; // OEM info; e_oemid specific
e_res2 : packed array [..] of Word; // Reserved words
e_lfanew : Longint; // File address of new exe header
end; {
TExeFileKind:
The kinds of files recognised.
}
TExeFileKind = (
fkUnknown, // unknown file kind: not an executable
fkError, // error file kind: used for files that don't exist
fkDOS, // DOS executable
fkExe32, // 32 bit executable
fkExe16, // 16 bit executable
fkDLL32, // 32 bit DLL
fkDLL16, // 16 bit DLL
fkVXD // virtual device driver
); function ExeType(const FileName: string): TExeFileKind;
{Examines given file and returns a code that indicates the type of
executable file it is (or if it isn't an executable)}
const
cDOSRelocOffset = $; // offset of "pointer" to DOS relocation table
cWinHeaderOffset = $3C; // offset of "pointer" to windows header in file
cNEAppTypeOffset = $0D; // offset in NE windows header of app type field
cDOSMagic = $5A4D; // magic number for a DOS executable
cNEMagic = $454E; // magic number for a NE executable (Win 16)
cPEMagic = $; // magic nunber for a PE executable (Win 32)
cLEMagic = $454C; // magic number for a Virtual Device Driver
cNEDLLFlag = $ // flag in NE app type field indicating a DLL
var
FS: TFileStream; // stream to executable file
WinMagic: Word; // word containing PE or NE magic numbers
HdrOffset: LongInt; // offset of windows header in exec file
ImgHdrPE: IMAGE_FILE_HEADER; // PE file header record
DOSHeader: IMAGE_DOS_HEADER; // DOS header
AppFlagsNE: Byte; // byte defining DLLs in NE format
DOSFileSize: Integer; // size of DOS file
begin
try
// Open stream onto file: raises exception if can't be read
FS := TFileStream.Create(FileName, fmOpenRead + fmShareDenyNone);
try
// Assume unkown file
Result := fkUnknown;
// Any exec file is at least size of DOS header long
if FS.Size < SizeOf(DOSHeader) then
Exit;
FS.ReadBuffer(DOSHeader, SizeOf(DOSHeader));
// DOS files begin with "MZ"
if DOSHeader.e_magic <> cDOSMagic then
Exit;
// DOS files have length >= size indicated at offset $02 and $04
// (offset $02 indicates length of file mod 512 and offset $04
// indicates no. of 512 pages in file)
if (DOSHeader.e_cblp = ) then
DOSFileSize := DOSHeader.e_cp *
else
DOSFileSize := (DOSHeader.e_cp - ) * + DOSHeader.e_cblp;
if FS.Size < DOSFileSize then
Exit;
// DOS file relocation offset must be within DOS file size.
if DOSHeader.e_lfarlc > DOSFileSize then
Exit;
// We assume we have an executable file: assume its a DOS program
Result := fkDOS;
// Try to find offset of Windows program header
if FS.Size <= cWinHeaderOffset + SizeOf(LongInt) then
// file too small for windows header "pointer": it's a DOS file
Exit;
// read it
FS.Position := cWinHeaderOffset;
FS.ReadBuffer(HdrOffset, SizeOf(LongInt));
// Now try to read first word of Windows program header
if FS.Size <= HdrOffset + SizeOf(Word) then
// file too small to contain header: it's a DOS file
Exit;
FS.Position := HdrOffset;
// This word should be NE, PE or LE per file type: check which
FS.ReadBuffer(WinMagic, SizeOf(Word));
case WinMagic of
cPEMagic:
begin
// 32 bit Windows application: now check whether app or DLL
if FS.Size < HdrOffset + SizeOf(LongWord) + SizeOf(ImgHdrPE) then
// file not large enough for image header: assume DOS
Exit;
// read Windows image header
FS.Position := HdrOffset + SizeOf(LongWord);
FS.ReadBuffer(ImgHdrPE, SizeOf(ImgHdrPE));
if (ImgHdrPE.Characteristics and IMAGE_FILE_DLL)
= IMAGE_FILE_DLL then
// characteristics indicate a 32 bit DLL
Result := fkDLL32
else
// characteristics indicate a 32 bit application
Result := fkExe32;
end;
cNEMagic:
begin
// We have 16 bit Windows executable: check whether app or DLL
if FS.Size <= HdrOffset + cNEAppTypeOffset
+ SizeOf(AppFlagsNE) then
// app flags field would be beyond EOF: assume DOS
Exit;
// read app flags byte
FS.Position := HdrOffset + cNEAppTypeOffset;
FS.ReadBuffer(AppFlagsNE, SizeOf(AppFlagsNE));
if (AppFlagsNE and cNEDLLFlag) = cNEDLLFlag then
// app flags indicate DLL
Result := fkDLL16
else
// app flags indicate program
Result := fkExe16;
end;
cLEMagic:
// We have a Virtual Device Driver
Result := fkVXD;
else
// DOS application
{Do nothing - DOS result already set};
end;
finally
FS.Free;
end;
except
// Exception raised in function => error result
Result := fkError;
end;
end;

How to detect the types of executable files的更多相关文章

  1. Files and Directories

    Files and Directories Introduction     In the previous chapter we coveredthe basic functions that pe ...

  2. The Portable Executable File Format from Top to Bottom(每个结构体都非常清楚)

    The Portable Executable File Format from Top to Bottom Randy KathMicrosoft Developer Network Technol ...

  3. System startup files

    System startup files When you log in, the shell defines your user environment after reading the init ...

  4. How To Get Log, Trace Files In OA Framework Pages And Concurrent Request Programs

    Goal   Solution   References APPLIES TO: Oracle Supplier Lifecycle Management - Version 12.1.2 and l ...

  5. Guava Files 源码分析(一)

    Files中的工厂 Files类中对InputStream, OutputStream以及Reader,Writer的操作封装了抽象工厂模式,抽象工厂是InputSupplier与OutputSupp ...

  6. CentOS 6.7 中安装Emacs 24.5

    Emacs 版本:http://mirror.bjtu.edu.cn/gnu/emacs/emacs-24.5.tar.gz CentOS 内核版本:2.6.32-573.el6.x86_64 参考资 ...

  7. malware analysis、Sandbox Principles、Design && Implementation

    catalog . 引言 . sandbox introduction . Sandboxie . seccomp(short for secure computing mode): API级沙箱 . ...

  8. Code Complete阅读笔记(二)

    2015-03-06   328   Unusual Data Types    ——You can carry this technique to extremes,putting all the ...

  9. Hibernate Validator 6.0.9.Final - JSR 380 Reference Implementation: Reference Guide

    Preface Validating data is a common task that occurs throughout all application layers, from the pre ...

随机推荐

  1. PB程序调用C++ COM生成对象发回-2问题

    C++写的COM组件用于读CPU卡,在C#中正常能够引用使用,但是在PB中却是返回-2,不识别类名,代码如下: OleObject ole_AddComole_AddCom = Create OLEO ...

  2. CF359B Permutation (构造)

    CF359B Permutation \(solution:\) 作为一道构造题,这题也十分符合构造的一些通性----(找到一些规律,然后无脑循环). 构造一个长度为 \(2n\) 的排列 \(a\) ...

  3. Comparable和Comparator的区别&Collections.sort的两种用法

    在Java集合的学习中,我们明白了: 看到tree,可以按顺序进行排列,就要想到两个接口.Comparable(集合中元素实现这个接口,元素自身具备可比性),Comparator(比较器,传入容器构造 ...

  4. 【转载】chmod命令详解

    查看linux文件的权限:ls -l 文件名称 查看linux文件夹的权限:ls -ld 文件夹名称(所在目录) 修改文件及文件夹权限: sudo chmod -(代表类型)×××(所有者)×××(组 ...

  5. BAT修改文本内容

    @echo off (for /f "delims=" %%a in (文件名) do ( set "str=%%a" setlocal enabledelay ...

  6. linux backtrace()详细使用说明,分析Segmentation fault【转】

    转自:http://velep.com/archives/1032.html 在此之前,开发eCos应用程序时,经常碰到程序挂掉后,串口打印输出一大串让人看不懂的数据.今天才明白,原来这些数据是程序挂 ...

  7. linux 串口驱动(二)初始化 【转】

    转自:http://blog.chinaunix.net/uid-27717694-id-3493611.html 8250串口的初始化: (1)定义uart_driver.uart_ops.uart ...

  8. 协议中UART的两种模式 【转】

    转自:http://wjf88223.blog.163.com/blog/static/3516800120104179327286/ ^^…… 协议栈中UART有两种模式:1.中断2.DMA 对于这 ...

  9. Python学习一|anaconda的安装问题以及Python语言的特点

    安装时遇到的问题 安装anaconda3.0到D盘之后,配置好两个环境变量:D:\anaconda和D:\anaconda\Scripts.发现在命令行中执行python指令可以,但conda指令却是 ...

  10. 源码安装svn 1.8.9

    2014年5月25日 12:26:14 需要文件: svn apr apr-util sqlite3 serf svn : http://subversion.apache.org/download/ ...