读文件头数据判断 PE 文件格式和类型
namespace X.Reflection
{
using System;
using System.IO;
public static partial class ReflectionX
{
public static PeType GetPeType(this string filepath)
{
using (var fs = File.OpenRead(filepath))
using (var br = new BinaryReader(fs))
{
try
{
if (IMAGE_DOS_SIGNATURE != br.ReadInt16()) return PeType.NotExecutable; fs.Seek(offset__IMAGE_DOS_HEADER__e_lfanew, SeekOrigin.Begin);
var offsetNH = br.ReadUInt32();
if (offsetNH > fs.Length || != offsetNH % || == offsetNH) return PeType.MsDosExecutable;
if (offsetNH + + sizeof__IMAGE_FILE_HEADER + >= fs.Length) return PeType.OptionalHeaderMagicExceedFileLength; fs.Seek(offsetNH, SeekOrigin.Begin);
switch (br.ReadInt16())
{
case IMAGE_NT_SIGNATURE_LOWORD:
if (IMAGE_NT_SIGNATURE_HIWORD == br.ReadInt16()) break;
return PeType.MsDosExecutable; case IMAGE_OS2_SIGNATURE: return PeType.Windows16BitExecutable;
case IMAGE_VXD_SIGNATURE: return PeType.Windows16BitVirtualDeviceDriver;
default: return PeType.MsDosExecutable;
} //fs.Seek //紧跟前面的 pimNH64->Signature,所以不用 fs.Seek
//var machine = br.ReadUInt16();
fs.Seek(offsetNH + offset__IMAGE_NT_HEADERS__FileHeader__Characteristics, SeekOrigin.Begin);
var characteristics = br.ReadUInt16();
//var is32bit = IMAGE_FILE_32BIT_MACHINE & characteristics;
var dllfile = IMAGE_FILE_DLL & characteristics;
//fs.Seek //紧跟前面的 pimNH64->OptionalHeader.Magic,所以不用 fs.Seek
var magic = br.ReadUInt16(); //get RVA
uint rvaCH;
switch (magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
//if (IMAGE_FILE_MACHINE_I386 != machine)
// throw new BadImageFormatException(
// $"幻数值与目标机器类型不一致: IMAGE_NT_HEADERS.OptionalHeader.Magic({magic:X4})/IMAGE_NT_HEADERS.FileHeader.Machine({machine:X4})",
// filepath);
if (offsetNH + offset__IMAGE_NT_HEADERS__OptionalHeader + sizeof__IMAGE_OPTIONAL_HEADER32 > fs.Length)
return PeType.OptionalHeader32ExceedFileLength;
fs.Seek(offsetNH + offset__IMAGE_NT_HEADERS32__OptionalHeader__DataDirectory__14__VirtualAddress, SeekOrigin.Begin);
rvaCH = br.ReadUInt32();
break; case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
//if (IMAGE_FILE_MACHINE_AMD64 != machine)
// throw new BadImageFormatException(
// $"幻数值与目标机器类型不一致: IMAGE_NT_HEADERS.OptionalHeader.Magic({magic:X4})/IMAGE_NT_HEADERS.FileHeader.Machine({machine:X4})",
// filepath);
if (offsetNH + offset__IMAGE_NT_HEADERS__OptionalHeader + sizeof__IMAGE_OPTIONAL_HEADER64 > fs.Length)
return PeType.OptionalHeader64ExceedFileLength;
fs.Seek(offsetNH + offset__IMAGE_NT_HEADERS64__OptionalHeader__DataDirectory__14__VirtualAddress, SeekOrigin.Begin);
rvaCH = br.ReadUInt32();
break; default:
//throw new BadImageFormatException(
// //$"预料之外的幻数值: IMAGE_NT_HEADERS.OptionalHeader.Magic({magic:X4})/IMAGE_NT_HEADERS.FileHeader.Machine({machine:X4})",
// $"预料之外的幻数值: IMAGE_NT_HEADERS.OptionalHeader.Magic({magic:X4})",
// filepath);
return PeType.OptionalHeaderMagicNot3264;
} fs.Seek(offsetNH + offset__IMAGE_NT_HEADERS__OptionalHeader__Subsystem, SeekOrigin.Begin);
var subSystem = br.ReadInt16(); PeType pt;
if ( != rvaCH)
{
//translate RVA to file offset
uint offsetCH = ;
fs.Seek(offsetNH + offset__IMAGE_NT_HEADERS__FileHeader__SizeOfOptionalHeader, SeekOrigin.Begin);
uint offsetSH = offsetNH + offset__IMAGE_NT_HEADERS__OptionalHeader + br.ReadUInt16();
fs.Seek(offsetNH + offset__IMAGE_NT_HEADERS__FileHeader__NumberOfSections, SeekOrigin.Begin);
var numberOfSections = br.ReadUInt16();
while (numberOfSections-- > )
{
if (offsetSH + sizeof__IMAGE_SECTION_HEADER > fs.Length) return PeType.SectionHeaderExceedFileLength;
fs.Seek(offsetSH + offset__IMAGE_SECTION_HEADER__VirtualAddress, SeekOrigin.Begin);
var VirtualAddress = br.ReadUInt32();
var SizeOfRawData = br.ReadUInt32();
if (VirtualAddress <= rvaCH && rvaCH < VirtualAddress + SizeOfRawData)
{
offsetCH = br.ReadUInt32() + rvaCH - VirtualAddress;
break;
}
offsetSH += sizeof__IMAGE_SECTION_HEADER;
}
if (offsetCH + sizeof__IMAGE_COR20_HEADER > fs.Length) return PeType.Cor20HeaderExceedFileLength;
fs.Seek(offsetCH + offset__IMAGE_COR20_HEADER__Flags, SeekOrigin.Begin);
uint chFlags = br.ReadUInt32(); if ( != (COMIMAGE_FLAGS_ILONLY & chFlags))
{
if ( != (COMIMAGE_FLAGS_32BITREQUIRED & chFlags)) //X86
{
pt = (PeType)PeTypeBitness.X86 | (( != (COMIMAGE_FLAGS_32BITPREFERRED & chFlags))
? (PeType)PeTypePlatform.AnyCPU //AnyCPU32
: (PeType)PeTypePlatform.ILOnly //ILOnly32
);
}
else //X64
{
pt = (PeType)PeTypeBitness.X64;
switch (magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC: pt |= (PeType)PeTypePlatform.AnyCPU; break; //AnyCPU64
case IMAGE_NT_OPTIONAL_HDR64_MAGIC: pt |= (PeType)PeTypePlatform.ILOnly; break; //ILOnly64
}
}
}
else //Mixed
{
pt = (PeType)PeTypePlatform.Mixing;
switch (magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC: pt |= (PeType)PeTypeBitness.X86; break; //Mixed32
case IMAGE_NT_OPTIONAL_HDR64_MAGIC: pt |= (PeType)PeTypeBitness.X64; break; //Mixed64
}
} //file ext & subsystem
if ( == dllfile)
{
pt |= (PeType)PeTypeExt.Exe;
switch (subSystem)
{
case IMAGE_SUBSYSTEM_WINDOWS_GUI: pt |= (PeType)PeTypeSubSystem.WindowsGui; break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI: pt |= (PeType)PeTypeSubSystem.ConsoleCui; break;
}
}
else
{
pt |= (PeType)PeTypeExt.Dll;
}
}
else //Native
{
pt = (PeType)PeTypePlatform.Native;
switch (magic)
{
case IMAGE_NT_OPTIONAL_HDR32_MAGIC: pt |= (PeType)PeTypeBitness.X86; break; //Native32
case IMAGE_NT_OPTIONAL_HDR64_MAGIC: pt |= (PeType)PeTypeBitness.X64; break; //Native64
} //file ext & subsystem
if (IMAGE_SUBSYSTEM_NATIVE == subSystem)
{
pt |= (PeType)PeTypeExt.Drv;
}
else if ( == dllfile)
{
pt |= (PeType)PeTypeExt.Exe;
switch (subSystem)
{
case IMAGE_SUBSYSTEM_WINDOWS_GUI: pt |= (PeType)PeTypeSubSystem.WindowsGui; break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI: pt |= (PeType)PeTypeSubSystem.ConsoleCui; break;
}
}
else
{
pt |= (PeType)PeTypeExt.Dll;
}
}
return pt;
}
catch (Exception ex)
{
return PeType.ErrorOccurred;
}
}
} private const int offset__IMAGE_DOS_HEADER__e_lfanew = ;
private const int offset__IMAGE_NT_HEADERS__FileHeader__NumberOfSections = + ;
private const int offset__IMAGE_NT_HEADERS__FileHeader__SizeOfOptionalHeader = + ;
private const int offset__IMAGE_NT_HEADERS__FileHeader__Characteristics = + ;
private const int offset__IMAGE_NT_HEADERS__OptionalHeader = + sizeof__IMAGE_FILE_HEADER;
private const int offset__IMAGE_NT_HEADERS__OptionalHeader__Subsystem = offset__IMAGE_NT_HEADERS__OptionalHeader + * ;
private const int offset__IMAGE_NT_HEADERS32__OptionalHeader__DataDirectory__14__VirtualAddress = offset__IMAGE_NT_HEADERS__OptionalHeader + + * ;
private const int offset__IMAGE_NT_HEADERS64__OptionalHeader__DataDirectory__14__VirtualAddress = offset__IMAGE_NT_HEADERS__OptionalHeader + + * ;
private const int offset__IMAGE_SECTION_HEADER__VirtualAddress = + ;
private const int offset__IMAGE_COR20_HEADER__Flags = + + + ; private const int sizeof__IMAGE_FILE_HEADER = ;
private const int sizeof__IMAGE_OPTIONAL_HEADER32 = + * ;
private const int sizeof__IMAGE_OPTIONAL_HEADER64 = + * ;
private const int sizeof__IMAGE_SECTION_HEADER = ;
private const int sizeof__IMAGE_COR20_HEADER = ; private const int IMAGE_DOS_SIGNATURE = 0x5A4D;
private const int IMAGE_OS2_SIGNATURE = 0x454E;
private const int IMAGE_VXD_SIGNATURE = 0x454C;
private const int IMAGE_NT_SIGNATURE_LOWORD = 0x4550;
private const int IMAGE_NT_SIGNATURE_HIWORD = 0x0000;
private const int IMAGE_FILE_MACHINE_I386 = 0x014C;
private const int IMAGE_FILE_MACHINE_AMD64 = 0x8664;
private const int IMAGE_FILE_32BIT_MACHINE = 0x0100;
private const int IMAGE_FILE_DLL = 0x2000;
private const int IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10B;
private const int IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20B; //private const int IMAGE_SUBSYSTEM_UNKNOWN = 0; // Unknown subsystem.
private const int IMAGE_SUBSYSTEM_NATIVE = ; // Image doesn't require a subsystem.
private const int IMAGE_SUBSYSTEM_WINDOWS_GUI = ; // Image runs in the Windows GUI subsystem.
private const int IMAGE_SUBSYSTEM_WINDOWS_CUI = ; // Image runs in the Windows character subsystem.
//private const int IMAGE_SUBSYSTEM_OS2_CUI = 5; // image runs in the OS/2 character subsystem.
//private const int IMAGE_SUBSYSTEM_POSIX_CUI = 7; // image runs in the Posix character subsystem.
//private const int IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8; // image is a native Win9x driver.
//private const int IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9; // Image runs in the Windows CE subsystem.
//private const int IMAGE_SUBSYSTEM_EFI_APPLICATION = 10; //
//private const int IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11; //
//private const int IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12; //
//private const int IMAGE_SUBSYSTEM_EFI_ROM = 13;
//private const int IMAGE_SUBSYSTEM_XBOX = 14;
//private const int IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION = 16;
//private const int IMAGE_SUBSYSTEM_XBOX_CODE_CATALOG = 17; private const int COMIMAGE_FLAGS_ILONLY = 0x00000001;
private const int COMIMAGE_FLAGS_32BITREQUIRED = 0x00000002;
//private const int COMIMAGE_FLAGS_IL_LIBRARY = 0x00000004;
//private const int COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x00000008;
//private const int COMIMAGE_FLAGS_NATIVE_ENTRYPOINT = 0x00000010;
//private const int COMIMAGE_FLAGS_TRACKDEBUGDATA = 0x00010000;
private const int COMIMAGE_FLAGS_32BITPREFERRED = 0x00020000;
}
[Flags]
public enum PeTypePlatform
{
AnyCPU = 0x0001,
ILOnly = 0x0002,
Native = 0x0004,
Mixing = 0x0008, Unknow = 0x0000,
BitMask = 0x00FF,
BitMastDotNet = 0x0007,
}
[Flags]
public enum PeTypeBitness
{
X64 = 0x0100,
X86 = 0x0200, NoBit = 0x0000,
BitMask = 0x0F00,
}
[Flags]
public enum PeTypeExt
{
Exe = 0x1000,
Dll = 0x2000,
Drv = 0x3000, NoExt = 0x0000,
BitMask = 0xF000,
}
[Flags]
public enum PeTypeSubSystem
{
//DeviceDrv = 0x1_0000,
WindowsGui = 0x2_0000,
ConsoleCui = 0x3_0000,
//Win9xDrv = 0x8_0000, Unknow = 0x0_0000,
BitMask = 0xF_0000,
}
[Flags]
public enum PeType
{
AnyCPU32BitExeWindowsGui = PeTypePlatform.AnyCPU | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui,
AnyCPU64BitExeWindowsGui = PeTypePlatform.AnyCPU | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui,
ILOnly32BitExeWindowsGui = PeTypePlatform.ILOnly | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui,
ILOnly64BitExeWindowsGui = PeTypePlatform.ILOnly | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui,
Native32BitExeWindowsGui = PeTypePlatform.Native | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui,
Native64BitExeWindowsGui = PeTypePlatform.Native | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui,
Mixing32BitExeWindowsGui = PeTypePlatform.Mixing | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui,
Mixing64BitExeWindowsGui = PeTypePlatform.Mixing | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.WindowsGui, AnyCPU32BitExeConsoleCui = PeTypePlatform.AnyCPU | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui,
AnyCPU64BitExeConsoleCui = PeTypePlatform.AnyCPU | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui,
ILOnly32BitExeConsoleCui = PeTypePlatform.ILOnly | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui,
ILOnly64BitExeConsoleCui = PeTypePlatform.ILOnly | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui,
Native32BitExeConsoleCui = PeTypePlatform.Native | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui,
Native64BitExeConsoleCui = PeTypePlatform.Native | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui,
Mixing32BitExeConsoleCui = PeTypePlatform.Mixing | PeTypeBitness.X86 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui,
Mixing64BitExeConsoleCui = PeTypePlatform.Mixing | PeTypeBitness.X64 | PeTypeExt.Exe | PeTypeSubSystem.ConsoleCui, AnyCPU32BitExe = PeTypePlatform.AnyCPU | PeTypeBitness.X86 | PeTypeExt.Exe,
AnyCPU64BitExe = PeTypePlatform.AnyCPU | PeTypeBitness.X64 | PeTypeExt.Exe,
ILOnly32BitExe = PeTypePlatform.ILOnly | PeTypeBitness.X86 | PeTypeExt.Exe,
ILOnly64BitExe = PeTypePlatform.ILOnly | PeTypeBitness.X64 | PeTypeExt.Exe,
Native32BitExe = PeTypePlatform.Native | PeTypeBitness.X86 | PeTypeExt.Exe,
Native64BitExe = PeTypePlatform.Native | PeTypeBitness.X64 | PeTypeExt.Exe,
Mixing32BitExe = PeTypePlatform.Mixing | PeTypeBitness.X86 | PeTypeExt.Exe,
Mixing64BitExe = PeTypePlatform.Mixing | PeTypeBitness.X64 | PeTypeExt.Exe, AnyCPU32BitDll = PeTypePlatform.AnyCPU | PeTypeBitness.X86 | PeTypeExt.Dll,
AnyCPU64BitDll = PeTypePlatform.AnyCPU | PeTypeBitness.X64 | PeTypeExt.Dll,
ILOnly32BitDll = PeTypePlatform.ILOnly | PeTypeBitness.X86 | PeTypeExt.Dll,
ILOnly64BitDll = PeTypePlatform.ILOnly | PeTypeBitness.X64 | PeTypeExt.Dll,
Native32BitDll = PeTypePlatform.Native | PeTypeBitness.X86 | PeTypeExt.Dll,
Native64BitDll = PeTypePlatform.Native | PeTypeBitness.X64 | PeTypeExt.Dll,
Mixing32BitDll = PeTypePlatform.Mixing | PeTypeBitness.X86 | PeTypeExt.Dll,
Mixing64BitDll = PeTypePlatform.Mixing | PeTypeBitness.X64 | PeTypeExt.Dll, AnyCPU32BitDrv = PeTypePlatform.AnyCPU | PeTypeBitness.X86 | PeTypeExt.Drv,
AnyCPU64BitDrv = PeTypePlatform.AnyCPU | PeTypeBitness.X64 | PeTypeExt.Drv,
ILOnly32BitDrv = PeTypePlatform.ILOnly | PeTypeBitness.X86 | PeTypeExt.Drv,
ILOnly64BitDrv = PeTypePlatform.ILOnly | PeTypeBitness.X64 | PeTypeExt.Drv,
Native32BitDrv = PeTypePlatform.Native | PeTypeBitness.X86 | PeTypeExt.Drv,
Native64BitDrv = PeTypePlatform.Native | PeTypeBitness.X64 | PeTypeExt.Drv,
Mixing32BitDrv = PeTypePlatform.Mixing | PeTypeBitness.X86 | PeTypeExt.Drv,
Mixing64BitDrv = PeTypePlatform.Mixing | PeTypeBitness.X64 | PeTypeExt.Drv, MsDosExecutable,
Windows16BitExecutable,
Windows16BitVirtualDeviceDriver, Unknow = PeTypePlatform.Unknow | PeTypeBitness.NoBit | PeTypeExt.NoExt, ErrorOccurred = int.MinValue,
NotExecutable,
OptionalHeaderMagicNot3264,
OptionalHeaderMagicExceedFileLength,
OptionalHeader32ExceedFileLength,
OptionalHeader64ExceedFileLength,
SectionHeaderExceedFileLength,
Cor20HeaderExceedFileLength,
}
}
读文件头数据判断 PE 文件格式和类型的更多相关文章
- PE文件格式详解(下)
作者:MSDN译者:李马 预定义段 一个Windows NT的应用程序典型地拥有9个预定义段,它们是.text..bss..rdata..data..rsrc..edata..idata..pdata ...
- Python学习入门基础教程(learning Python)--5.6 Python读文件操作高级
前文5.2节和5.4节分别就Python下读文件操作做了基础性讲述和提升性介绍,但是仍有些问题,比如在5.4节里涉及到一个多次读文件的问题,实际上我们还没有完全阐述完毕,下面这个图片的问题在哪呢? 问 ...
- (四)关于读文件的结束的判别方法(EOF和feof)以及区别
关于读文件的时候判断文本是否读完的方式一般可以通过EOF,一般宏定义为-1.因为ASCII码中不可能出现-1. 当以文本形式读取文件内容, 读入的字符值等于EOF时, 表示读入的已不是正常的字符而是文 ...
- C++PE文件格式解析类(轻松制作自己的PE文件解析器)
PE是Portable Executable File Format(可移植的运行体)简写,它是眼下Windows平台上的主流可运行文件格式. PE文件里包括的内容非常多,详细我就不在这解释了,有兴趣 ...
- python读文件判断是否已到EOF
python读文件判断是否已到EOF,也即结尾,一般其它语言都是以EOF直接来判断的,比如 if ( fp.read(chunk_size) == EOF), 但python到结尾后是返回空字符串的, ...
- 0day笔记(1)PE文件格式与虚拟文件内存的映射
PE文件格式 PE 文件格式把可执行文件分成若干个数据节(section),不同的资源被存放在不同的节中. 一个典型的 PE 文件中包含的节如下: .text 存放着二进制的机器代码 .data 初始 ...
- 深入理解 Win32 PE 文件格式
深入理解 Win32 PE 文件格式 Matt Pietrek 这篇文章假定你熟悉C++和Win32. 概述 理解可移植可执行文件格式(PE)可以更好地了解操作系统.如果你知道DLL和EXE中都有些什 ...
- PE文件格式分析
PE文件格式分析 PE 的意思是 Portable Executable(可移植的执行体).它是 Win32环境自身所带的执行文件格式.它的一些特性继承自Unix的Coff(common object ...
- 深入理解 Win32 PE 文件格式 Matt Pietrek(慢慢体会)
这篇文章假定你熟悉C++和Win32. 概述 理解可移植可执行文件格式(PE)可以更好地了解操作系统.如果你知道DLL和EXE中都有些什么东西,那么你就是一个知识渊博的程序员.这一系列文章的第一部分, ...
随机推荐
- 洛谷—— P1328 生活大爆炸版石头剪刀布
https://www.luogu.org/problem/show?pid=1328 题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负.在< ...
- CSS 类、伪类和伪元素差别具体解释
CSS中的类(class)是为了方便过滤(即选择)元素,以给这类元素加入样式,class是定义在HTML文档树中的. 可是这在一些情况下是不够用的,比方用户的交互动作(悬停.激活等)会导致元素状态发生 ...
- OpenCASCADE Face Normals
OpenCASCADE Face Normals eryar@163.com Abstract. 要显示一个逼真的三维模型,其顶点坐标.顶点法向.纹理坐标这三个信息必不可少.本文主要介绍如何在Open ...
- hadoop集群环境配置成功与否查看方法
1.Hadoop启动jobhistoryserver来实现web查看作业的历史运行情况,由于在启动hdfs和Yarn进程之后,jobhistoryserver进程并没有启动,需要手动启动jobhist ...
- 1>LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
解决方法如下:项目\属性\配置属性\清单工具\输入和输出\嵌入清单:原来是“是”,改成“否”. 终极解决方案:VS2010在经历一些更新后,建立Win32 Console Project时会出“err ...
- Ansible学习记录二:命令
0.ansible 命令参数详解: [root@localhost ~]# ansible Usage: ansible <host-pattern> [options] Options: ...
- 如何优雅的写UI——(4)选项卡美化
现在做出来的选项卡实在太丑的,咱们怎么把他弄得好看一点呢 tabctrl是可以添加icon图标的,那派生与tabctrl的mfctabctrl肯定也能添加图标,他们两个添加图标的原理一样,但是还是有点 ...
- VPS搭建与IPv6使用教程
VPS搭建与IPv6使用教程 SoftEther命令: yum -y install gcc zlib-devel openssl-devel readline-devel ncurses-devel ...
- android audio
package com.javacodegeeks.android.audiocapturetest; import java.io.IOException; import android.media ...
- 【arc062e】Building Cubes with AtCoDeer
Description STL有n块瓷砖,编号从1到n,并且将这个编号写在瓷砖的正中央: 瓷砖的四个角上分别有四种颜色(可能相等可能不相等),并且用Ci,0,Ci,1,Ci,2,Ci,3分别表示左上. ...