//调用头文件和链接库 include windows.inc //一些常量 include kernel32.inc //kernel32.dll中的一些系统函数 include user32.inc //user32.dll的一些函数 includelib kernel32.lib includelib user32.lib
//定义字符串 .data szCaption db 'hello', 0 //db是字节的意思,定义hello字符串,汇编中win32用,'\0'进行结尾 szText db 'hello world!', 0
typedefstruct _IMAGE_DOS_HEADER { WORD e_magic; //00h EXE标志MZ,MZ是一个人名的缩写 WORD e_cblp; //02h 最后(部分)页中的字节数 WORD e_cp; //04h 文件中的全部和部分页数 WORD e_crlc; //06h 重定位表中的指针数 WORD e_cparhdr; //08h 头部尺寸,以段落为单位 WORD e_minalloc; //0Ah 所需的最小附加段 WORD e_maxalloc; //0Ch 所需的最大附加段 WORD e_ss; //0Eh 初始的SS值(相对偏移量) WORD e_sp; //10h 初始的SP值 WORD e_csum; //12h 校验和 WORD e_ip; //14h 初始的IP值 WORD e_cs; //16h 初始的CS值 WORD e_lfarlc; //18h 重定位表的字节偏移量 WORD e_ovno; //1Ah 覆盖号 WORD e_res[4]; //1Ch 保留字 WORD e_oemid; //24h EM标识符(相对e_oeminfo ) WORD e_oeminfo; //26h OEM信息; e_oemid specific WORD e_res2[10]; //28h 保留字 LONG e_lfanew; //3Ch PE头相对于文件的偏移地址 } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; #define IMAGE_DOS_SIGNATURE 0x4D5A //MZ
我们关注的主要是两个属性:e_magic 和 e_lfanew
e_magic用来标志这是一个PE文件
e_lfanew用来标志NT头的偏移。
一般来说DOS头的大小为0x40 byte,即64个字节
65开始为PE头
3.2 DOS存根
那么,其他属性的作用是什么呢?
我们把00000000到000000B0之间的数据拷贝下来粘贴进一个新文件,保存为dos.bin
这一块代码实际上是在编译-连接的时候自动添加进来的一个程序,被称为DOS存根
读一下汇编,它的作用就是输出”This program cannot be run in DOS mode.”这个字符串,然后功能吗是4C01,即退出程序。
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.没有重定位 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).表示是可执行的 #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.跳过行号 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file跳过符号 #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine是32位机器 #define IMAGE_FILE_SYSTEM 0x1000 // System File.是系统文件 #define IMAGE_FILE_DLL 0x2000 // File is a DLL.是DLL文件
SetConsoleTextAttribute(handle, 0x07); } SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN); printf("--> 标志(属性块) 常用特征值对照表:<--\n"); printf("[值:00000020h](*包含可执行代码)\n");//IMAGE_SCN_CNT_CODE printf("[值:00000040h](*该块包含已初始化的数据)\n");//IMAGE_SCN_CNT_INITIALIZED_DATA printf("[值:00000080h](*该块包含未初始化的数据)\n");//IMAGE_SCN_CNT_UNINITIALIZED_DATA printf("[值:00000200h][Section contains comments or some other type of information.]\n");//IMAGE_SCN_LNK_INFO printf("[值:00000800h][Section contents will not become part of image.]\n");//IMAGE_SCN_LNK_REMOVE printf("[值:00001000h][Section contents comdat.]\n");//IMAGE_SCN_LNK_COMDAT printf("[值:00004000h][Reset speculative exceptions handling bits in the TLB entries for this section.]\n");//IMAGE_SCN_NO_DEFER_SPEC_EXC printf("[值:00008000h][Section content can be accessed relative to GP.]\n");// IMAGE_SCN_GPREL printf("[值:00500000h][Default alignment if no others are specified.]\n");//IMAGE_SCN_ALIGN_16BYTES printf("[值:01000000h][Section contains extended relocations.]\n");//IMAGE_SCN_LNK_NRELOC_OVFL printf("[值:02000000h][Section can be discarded.]\n");//IMAGE_SCN_MEM_DISCARDABLE printf("[值:04000000h][Section is not cachable.]\n");//IMAGE_SCN_MEM_NOT_CACHED printf("[值:08000000h][Section is not pageable.]\n");//IMAGE_SCN_MEM_NOT_PAGED printf("[值:10000000h](*该块为共享块).\n");//IMAGE_SCN_MEM_SHARED printf("[值:20000000h](*该块可执行)\n");//IMAGE_SCN_MEM_EXECUTE printf("[值:40000000h](*该块可读)\n");//IMAGE_SCN_MEM_READ printf("[值:80000000h](*该块可写)\n\n");// IMAGE_SCN_MEM_WRITE SetConsoleTextAttribute(handle, 0x07);//IMAGE_SCN_MEM_WRITE