PE文件格式详解(4)

编写PE文件解析器(三) 下面有几个表网上资料比较少,因为几乎用不到,我查文档写写吧,这篇写得比较久很抱歉。 7、IMAGE_DIRECTORY_ENTRY_EXCEPTION【异常处理表】 CPU特定的并且基于表的异常处理。用于除x86之外的其它CPU上。偏移到一个IMAGE_XXX_RUNTIME_FUNCTION_ENTRY数组,根据文件头的Machine来确定结构,64位用IMAGE_IA64_RUNT 阅读详情

作者:MSDN
译者:李马 (http://home.nuc.edu.cn/~titilima

)
导入数据段,.idata

   .idata段是导入数据,包括导入库和导入地址名称表。虽然定义了IMAGE_DIRECTORY_ENTRY_IMPORT,但是WINNT.H之中并无相应的导入目录结构。作为代替,其中有若干其它的结构,名为IMAGE_IMPORT_BY_NAME、IMAGE_THUNK_DATA与IMAGE_IMPORT_DESCRIPTOR。在我个人看来,我实在不知道这些结构是如何和.idata段发生关联的,所以我花了若干个小时来破译.idata段实体并且得到了一个更简单的结构,我名之为IMAGE_IMPORT_MODULE_DIRECTORY。
// PEFILE.Htypedef struct tagImportDirectory{  DWORD dwRVAFunctionNameList;  DWORD dwUseless1;  DWORD dwUseless2;  DWORD dwRVAModuleName;  DWORD dwRVAFunctionAddressList;} IMAGE_IMPORT_MODULE_DIRECTORY, *PIMAGE_IMPORT_MODULE_DIRECTORY;
和其它段的数据目录不同的是,这个是作为文件中的每个导入模块重复出现的。你可以将它看作模块数据目录列表中的一个入口,而不是一个整个数据段的数据目录。每个入口都是一个指向特定模块导入信息的目录。
   IMAGE_IMPORT_MODULE_DIRECTORY结构中的一个域dwRVAModuleName是一个相对虚拟地址,它指向模块的名称。结构中还有两个dwUseless参数,它们是为了保持段的对齐。PE文件格式规范提到了一些东西,关于导入标记、时间/日期标志以及主/次版本,但是在我的实验中,这两个域自始而终都是空的,所以我仍然认为它们没有什么用处。
   基于这个结构的定义,你便可以获得可执行文件中导入的所有模块和函数名称了。以下的函数示范了如何获得特定的PE文件中的所有导入函数名称:
//PEFILE.Cint WINAPI GetImportModuleNames(LPVOID lpFile, HANDLE hHeap, char **pszModules){  PIMAGE_IMPORT_MODULE_DIRECTORY pid;  IMAGE_SECTION_HEADER idsh;  BYTE *pData;  int nCnt = 0, nSize = 0, i;  char *pModule[1024];  char *psz;  pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)ImageDirectoryOffset       (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);  pData = (BYTE *)pid;  /* 定位.idata段头部 */  if (!GetSectionHdrByName(lpFile, &idsh, ".idata"))    return 0;  /* 提取所有导入模块 */  while (pid->dwRVAModuleName)  {    /* 为绝对字符串偏移量分配缓冲区 */    pModule[nCnt] = (char *)(pData +         (pid->dwRVAModuleName-idsh.VirtualAddress));    nSize += strlen(pModule[nCnt]) + 1;    /* 增至下一个导入目录入口 */    pid++;    nCnt++;  }  /* 将所有字符串赋值到一大块的堆内存中 */  *pszModules = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, nSize);  psz = *pszModules;  for (i = 0; i < nCnt; i++)  {    strcpy(psz, pModule );    psz += strlen (psz) + 1;  }  return nCnt;}  
这个函数非常好懂,然而有一点值得指出——注意while循环。这个循环当pid->dwRVAModuleName为0的时候终止,这就暗示了在IMAGE_IMPORT_MODULE_DIRECTORY结构列表的末尾有一个空的结构,这个结构拥有一个0值,至少dwRVAModuleName域为0。这便是我在对文件的实验中以及之后在PE文件格式中研究的行为。
   这个结构中的第一个域dwRVAFunctionNameList是一个相对虚拟地址,这个地址指向一个相对虚拟地址的列表,这些地址是文件中的一些文件名。如下面的数据所示,所有导入模块的模块和函数名称都列于.idata段数据中了:
E6A7 0000 F6A7 0000 08A8 0000 1AA8 0000 ................28A8 0000 3CA8 0000 4CA8 0000 0000 0000 (...<...L.......0000 4765 744F 7065 6E46 696C 654E 616D ..GetOpenFileNam6541 0000 636F 6D64 6C67 3332 2E64 6C6C eA..comdlg32.dll0000 2500 4372 6561 7465 466F 6E74 496E ..%.CreateFontIn6469 7265 6374 4100 4744 4933 322E 646C directA.GDI32.dl6C00 A000 4765 7444 6576 6963 6543 6170 l...GetDeviceCap7300 C600 4765 7453 746F 636B 4F62 6A65 s...GetStockObje6374 0000 D500 4765 7454 6578 744D 6574 ct....GetTextMet7269 6373 4100 1001 5365 6C65 6374 4F62 ricsA...SelectOb6A65 6374 0000 1601 5365 7442 6B43 6F6C ject....SetBkCol6F72 0000 3501 5365 7454 6578 7443 6F6C or..5.SetTextCol6F72 0000 4501 5465 7874 4F75 7441 0000 or..E.TextOutA..
以上的数据是EXEVIEW.EXE示例程序.idata段的一部分。这个特别的段表示了导入模块列表和函数名称列表的起始处。如果你开始检查数据中的这个段,你应该认出一些熟悉的Win32 API函数以及模块名称。从上往下读的话,你可以找到GetOpenFileNameA,紧接着是COMDLG32.DLL。然后你能发现CreateFontIndirectA,紧接着是模块GDI32.DLL,以及之后的GetDeviceCaps、GetStockObject、GetTextMetrics等等。
   这样的式样会在.idata段中重复出现。第一个模块是COMDLG32.DLL,第二个是GDI32.DLL。请注意第一个模块只导出了一个函数,而第二个模块导出了很多函数。在这两种情况下,函数和模块的排列的方法是首先出现一个函数名,之后是模块名,然后是其它的函数名(如果有的话)。
   以下的函数示范了如何获得指定模块的所有函数名。
// PEFILE.Cint WINAPI GetImportFunctionNamesByModule(LPVOID lpFile, HANDLE hHeap,    char *pszModule, char **pszFunctions){  PIMAGE_IMPORT_MODULE_DIRECTORY pid;  IMAGE_SECTION_HEADER idsh;  DWORD dwBase;  int nCnt = 0, nSize = 0;  DWORD dwFunction;  char *psz;  /* 定位.idata段的头部 */  if (!GetSectionHdrByName(lpFile, &idsh, ".idata"))    return 0;  pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)ImageDirectoryOffset       (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);  dwBase = ((DWORD)pid. idsh.VirtualAddress);  /* 查找模块的pid */  while (pid->dwRVAModuleName && strcmp (pszModule,       (char *)(pid->dwRVAModuleName+dwBase)))    pid++;  /* 如果模块未找到,就退出 */  if (!pid->dwRVAModuleName)    return 0;  /* 函数的总数和字符串长度 */  dwFunction = pid->dwRVAFunctionNameList;  while (dwFunction && *(DWORD *)(dwFunction + dwBase) &&      *(char *)((*(DWORD *)(dwFunction + dwBase)) + dwBase+2))  {    nSize += strlen ((char *)((*(DWORD *)(dwFunction +      dwBase)) + dwBase+2)) + 1;    dwFunction += 4;    nCnt++;  }  /* 在堆上分配函数名称的空间 */  *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nSize);  psz = *pszFunctions;  /* 向内存指针复制函数名称 */  dwFunction = pid->dwRVAFunctionNameList;  while (dwFunction && *(DWORD *)(dwFunction + dwBase) &&    *((char *)((*(DWORD *)(dwFunction + dwBase)) + dwBase+2)))  {    strcpy (psz, (char *)((*(DWORD *)(dwFunction + dwBase)) +        dwBase+2));    psz += strlen((char *)((*(DWORD *)(dwFunction + dwBase))+        dwBase+2)) + 1;    dwFunction += 4;  }  return nCnt;}  
就像GetImportModuleNames函数一样,这一函数依靠每个信息列表的末端来获得一个置零的入口。这在种情况下,函数名称列表就是以零结尾的。
   最后一个域dwRVAFunctionAddressList是一个相对虚拟地址,它指向一个虚拟地址表。在文件装载的时候,这个虚拟地址表会被装载器置于段数据之中。但是在文件装载前,这些虚拟地址会被一些严密符合函数名称列表的虚拟地址替换。所以在文件装载之前,有两个同样的虚拟地址列表,它们指向导入函数列表。

调试信息段,.debug

   调试信息位于.debug段之中,同时PE文件格式也支持单独的调试文件(通常由.DBG扩展名标识)作为一种将调试信息集中的方法。调试段包含了调试信息,但是调试目录却位于早先提到的.rdata段之中。这其中每个目录都涉及了.debug段之中的调试信息。调试目录的结构IMAGE_DEBUG_DIRECTORY被定义为:
// WINNT.Htypedef struct _IMAGE_DEBUG_DIRECTORY {  ULONG Characteristics;  ULONG TimeDateStamp;  USHORT MajorVersion;  USHORT MinorVersion;  ULONG Type;  ULONG SizeOfData;  ULONG AddressOfRawData;  ULONG PointerToRawData;} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
这个段被分为单独的部分,每个部分为不同种类的调试信息数据。对于每个部分来说都是一个像上边一样的调试目录。不同的调试信息种类如下:
// WINNT.H#define IMAGE_DEBUG_TYPE_UNKNOWN 0#define IMAGE_DEBUG_TYPE_COFF 1#define IMAGE_DEBUG_TYPE_CODEVIEW 2#define IMAGE_DEBUG_TYPE_FPO 3#define IMAGE_DEBUG_TYPE_MISC 4  
每个目录之中的Type域表示该目录的调试信息种类。如你所见,在上边的表中,PE文件格式支持很多不同的调试信息种类,以及一些其它的信息域。对于那些来说,IMAGE_DEBUG_TYPE_MISC信息是唯一的。这一信息被添加到描述可执行映像的混杂信息之中,这些混杂信息不能被添加到PE文件格式任何结构化的数据段之中。这就是映像文件中最合适的位置,映像名称则肯定会出现在这里。如果映像导出了信息,那么导出数据段也会包含这一映像名称。
   每种调试信息都拥有自己的头部结构,该结构定义了它自己的数据。这些结构都列于WINNT.H之中。关于IMAGE_DEBUG_DIRECTORY一件有趣的事就是它包括了两个标识调试信息的域。第一个是AddressOfRawData,为相对文件装载的数据虚拟地址;另一个是PointerToRawData,为数据所在PE文件之中的实际偏移量。这就使得定位指定的调试信息相当容易了。
   作为最后的例子,请你考虑以下的函数代码,它从IMAGE_DEBUG_MISC结构中提取了映像名称。
//PEFILE.Cint WINAPI RetrieveModuleName(LPVOID lpFile, HANDLE hHeap, char **pszModule){  PIMAGE_DEBUG_DIRECTORY pdd;  PIMAGE_DEBUG_MISC pdm = NULL;  int nCnt;  if (!(pdd = (PIMAGE_DEBUG_DIRECTORY)ImageDirectoryOffset(lpFile,       IMAGE_DIRECTORY_ENTRY_DEBUG)))  return 0;  while (pdd->SizeOfData)  {    if (pdd->Type == IMAGE_DEBUG_TYPE_MISC)    {      pdm = (PIMAGE_DEBUG_MISC)((DWORD)pdd->PointerToRawData + (DWORD)lpFile);      nCnt = lstrlen(pdm->Data) * (pdm->Unicode ? 2 : 1);      *pszModule = (char *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, nCnt+1);      CopyMemory(*pszModule, pdm->Data, nCnt);      break;    }    pdd ++;  }  if (pdm != NULL)    return nCnt;  else    return 0;}
你看到了,调试目录结构使得定位一个特定种类的调试信息变得相对容易了些。只要定位了IMAGE_DEBUG_MISC结构,提取映像名称就如同调用CopyMemory函数一样简单。
   如上所述,调试信息可以被剥离到单独的.DBG文件中。Windows NT SDK包含了一个名为REBASE.EXE的程序可以实现这一目的。例如,以下的语句可以将一个名为TEST.EXE的调试信息剥离:
   rebase -b 40000 -x c:/samples/testdir test.exe
   调试信息被置于一个新的文件中,这个文件名为TEST.DBG,位于c:/samples/testdir之中。这个文件起始于一个单独的IMAGE_SEPARATE_DEBUG_HEADER结构,接着是存在于原可执行映像之中的段头部的一份拷贝。在段头部之后,是.debug段的数据。也就是说,在段头部之后,就是一系列的IMAGE_DEBUG_DIRECTORY结构及其相关的数据了。调试信息本身保留了如上所描述的常规映像文件调试信息。

PE文件格式总结

   Windows NT的PE文件格式向熟悉Windows和MS-DOS环境的开发者引入了一种全新的结构。然而熟悉UNIX环境的开发者会发现PE文件格式与COFF规范很相像(如果它不是以COFF为基础的话)。
   整个格式的组成:一个MS-DOS的MZ头部,之后是一个实模式的残余程序、PE文件标志、PE文件头部、PE可选头部、所有的段头部,最后是所有的段实体。
   可选头部的末尾是一个数据目录入口的数组,这些相对虚拟地址指向段实体之中的数据目录。每个数据目录都表示了一个特定的段实体数据是如何组织的。
   PE文件格式有11个预定义段,这是对Windows NT应用程序所通用的,但是每个应用程序可以为它自己的代码以及数据定义它自己独特的段。
   .debug预定义段也可以分离为一个单独的调试文件。如果这样的话,就会有一个特定的调试头部来用于解析这个调试文件,PE文件中也会有一个标志来表示调试数据被分离了出去。

PEFILE.DLL函数描述

   PEFILE.DLL主要由一些函数组成,这些函数或者被用来获得一个给定的PE文件中的偏移量,或者被用来把文件中的一些数据复制到一个特定的结构中去。每个函数都有一个需求——第一个参数是一个指针,这个指针指向PE文件的起始处。也就是说,这个文件必须首先被映射到你进程的地址空间中,然后映射文件的位置就可以作为每个函数第一个参数的lpFile的值来传入了。
   我意在使函数的名称使你能够一见而知其意,并且每个函数都随一个详细描述其目的的注释而列出。如果在读完函数列表之后,你仍然不明白某个函数的功能,那么请参考EXEVIEW.EXE示例来查明这个函数是如何使用的。以下的函数原型列表可以在PEFILE.H中找到:
// PEFILE.H/* 获得指向MS-DOS MZ头部的指针 */BOOL WINAPI GetDosHeader(LPVOID, PIMAGE_DOS_HEADER);/* 决定.EXE文件的类型 */DWORD WINAPI ImageFileType(LPVOID);/* 获得指向PE文件头部的指针 */BOOL WINAPI GetPEFileHeader(LPVOID, PIMAGE_FILE_HEADER);/* 获得指向PE可选头部的指针 */BOOL WINAPI GetPEOptionalHeader(LPVOID, PIMAGE_OPTIONAL_HEADER);/* 返回模块入口点的地址 */LPVOID WINAPI GetModuleEntryPoint(LPVOID);/* 返回文件中段的总数 */int WINAPI NumOfSections(LPVOID);/* 返回当可执行文件被装载入进程地址空间时的首选基地址 */LPVOID WINAPI GetImageBase(LPVOID);/* 决定文件中一个特定的映像数据目录的位置 */LPVOID WINAPI ImageDirectoryOffset(LPVOID, DWORD);/* 获得文件中所有段的名称 */int WINAPI GetSectionNames(LPVOID, HANDLE, char **);/* 复制一个特定段的头部信息 */BOOL WINAPI GetSectionHdrByName(LPVOID, PIMAGE_SECTION_HEADER, char *);/* 获得由空字符分隔的导入模块名称列表 */int WINAPI GetImportModuleNames(LPVOID, HANDLE, char **);/* 获得一个模块由空字符分隔的导入函数列表 */int WINAPI GetImportFunctionNamesByModule(LPVOID, HANDLE, char *, char **);/* 获得由空字符分隔的导出函数列表 */int WINAPI GetExportFunctionNames(LPVOID, HANDLE, char **);/* 获得导出函数总数 */int WINAPI GetNumberOfExportedFunctions(LPVOID);/* 获得导出函数的虚拟地址入口点列表 */LPVOID WINAPI GetExportFunctionEntryPoints(LPVOID);/* 获得导出函数顺序值列表 */LPVOID WINAPI GetExportFunctionOrdinals(LPVOID);/* 决定资源对象的种类 */int WINAPI GetNumberOfResources (LPVOID);/* 返回文件中所使用的所有资源对象的种类 */int WINAPI GetListOfResourceTypes(LPVOID, HANDLE, char **);/* 决定调试信息是否已从文件中分离 */BOOL WINAPI IsDebugInfoStripped(LPVOID);/* 获得映像文件名称 */int WINAPI RetrieveModuleName(LPVOID, HANDLE, char **);/* 决定文件是否是一个有效的调试文件 */BOOL WINAPI IsDebugFile(LPVOID);/* 从调试文件中返回调试头部 */BOOL WINAPI GetSeparateDebugHeader(LPVOID, PIMAGE_SEPARATE_DEBUG_HEADER);  除了以上所列的函数之外,本文中早先提到的宏也定义在了PEFILE.H中,完整的列表如下:/* PE文件标志的偏移量 */#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + /                       ((PIMAGE_DOS_HEADER)a)->e_lfanew))/* MS操作系统头部标识了双字的NT PE文件标志;PE文件头部就紧跟在这个双字之后 */#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + /                        ((PIMAGE_DOS_HEADER)a)->e_lfanew + /                        SIZE_OF_NT_SIGNATURE))/* PE可选头部紧跟在PE文件头部之后 */#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + /                        ((PIMAGE_DOS_HEADER)a)->e_lfanew + /                        SIZE_OF_NT_SIGNATURE + /                        sizeof(IMAGE_FILE_HEADER)))/* 段头部紧跟在PE可选头部之后 */#define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + /                        ((PIMAGE_DOS_HEADER)a)->e_lfanew + /                        SIZE_OF_NT_SIGNATURE + /                        sizeof(IMAGE_FILE_HEADER) + /                        sizeof(IMAGE_OPTIONAL_HEADER)))  
要使用PEFILE.DLL,你只用包含PEFILE.H文件并在应用程序中链接到这个DLL即可。所有的这些函数都是互斥性的函数,但是有些函数的功能可以相互支持以获得文件信息。例如,GetSectionNames可以用于获得所有段的名称,这样一来,为了获得一个拥有独特段名称(在编译期由应用程序开发者定义的)的段头部,你就需要首先获得所有名称的列表,然后再对那个准确的段名称调用函数GetSectionHeaderByName了。现在,你可以享受我为你带来的这一切了!
PE文件格式详解 本文描述了Windows系统的PE文件格式。 阅读详情

相关推荐

初步了解PE文件格式(上)

今天这篇博客只对PE文件进行大致的分析,使用一个例子并结合一个简单的PE文件格式图来说明PE文件格式。

cuglzf的博客 4708

PE文件格式学习(九):调试表(DebugDirectory)

微软官方参考文档:https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#debug-type

tutucoo 1765

易语言编译PE文件格式详解与实践

PE(Portable Executable)文件格式是Windows操作系统中用于可执行文件、目标代码、DLL(动态链接库)等的标准格式。它是一种高级的执行文件格式,为Windows提供了丰富的结构化信息,这些信息对于系统的加载和执行过程至关重要。本章旨在提供PE文件格式的基本概念、结构及重要组成,帮助读者建立对PE文件格式的初步认识。PE文件格式从结构上来看,可以划分为几个主要部分:DOS头、PE签名、COFF文件头、可选头、节表以及节数据。

weixin_42610010的博客 1089

PE文件中各IMAGE_DATA_DIRECTORY的定义

   首先列出IMAGE_DATA_DIRECTORY结构:(简单的结构就不注释了)typedef struct _IMAGE_DATA_DIRECTORY {    DWORD VirtualAddress;    DWORD Size;} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;    VirtualAddress。是所指向的

testalllife的专栏 1万+

WIN下使用visual studio 2022安装GMSSL命令行工具

2.1 使用管理员权限打开visual studio(非常重要,否则最后一步 nmake install会失败)右键vs2022,以管理员身份运行即可。2.4 配置环境变量,gmssl可执行程序默认会被安装到如下目录。将如下路径添加到系统环境变量即可。添加后的环境变量如下。2.编译解压后的gmssl源码,编译过程主要参考install.md中的内容,README.md中的步骤不完整。2.2 打开vs2022的命令终端,右键文件,选择在终端中打开。1.下载gmssl源码,解压到相应目录。

qq_45794382的博客 1270

STC8H硬件IIC从机模式实战:手把手教你驱动OLED屏幕(附完整代码)

本文详细介绍了如何使用STC8H单片机的硬件IIC从机模式驱动SSD1306 OLED屏幕,包括硬件连接、寄存器配置、中断处理和实际应用中的优化技巧。通过完整的代码示例和实战经验分享,帮助开发者快速掌握I2C通信协议和OLED屏幕驱动技术,提升嵌入式开发效率。

weixin_33747129的博客 336

【PE】PE文件结构学习

【PE】PE文件结构学习PE文件内存对齐文件对齐PE结构分析DOS头结构PE头文件区块表输入表输出表:基址重定位表: PE文件 内存对齐 PE文件包括: DLL,EXE,OCX,SYS等。 Windows加载器遍历PE文件并将其复制到内存镜像。PE文件结构在磁盘中和内存中基本是一样的,但又不是完全复制,对齐方式有所不同。 如图:在Windows系统中,一个节在内存中对齐单位是一个页的大小。 对于32位操作系统来说,这个值是4KB(1000H) 对于64位系统来说,这个值是8KB(2000H) 文件

dr0op's blog 1786

STM32之W5500网络通信_w5500 profinet

*初始化8个socket*/setSHAR(ConfigMsg.mac);/*配置Mac地址*/setSUBR(ConfigMsg.sub);/*配置子网掩码*/setSIPR(ConfigMsg.lip);/*配置Ip地址*/setGAR(ConfigMsg.gw);/*配置默认网关*/setRTR(2000);/*设置溢出时间值*/setRCR(3);/*设置最大重新发送次数*/

2501_90250923的博客 1462

PE文件格式详解(7)

调试信息段,.debug  调试信息位于.debug段之中,同时PE文件格式也支持单独的调试文件(通常由.DBG扩展名标识)作为一种将调试信息集中的方法。调试段包含了调试信息,但是调试目录却位于早先提到的.rdata段之中。这其中每个目录都涉及了.debug段之中的调试信息。调试目录的结构IMAGE_DEBUG_DIRECTORY被定义为:WINNT.Htypedef struct _IMAG

马说@优快云 2798

内网环境下的高德地图离线化实战:从瓦片下载到交互功能集成

本文详细介绍了在内网环境中部署离线高德地图的完整实战方案。针对军工、能源、金融等对网络隔离与数据安全有严格要求的场景,文章核心解决了离线地图的两大基石:地图瓦片数据的高效下载与本地化,以及高德地图JS API的获取与插件集成。通过具体代码示例,进一步讲解了如何实现地图初始化、海量点标注与聚合、自定义图标及框选查询等核心交互功能,并分享了内网部署的路径配置、性能优化及法律合规等关键注意事项,为开发者在封闭网络环境下构建稳定、可控的地图应用提供了清晰指南。

Apple的专栏 395

深入浅出卡尔曼滤波器算法

深入浅出讲解卡尔曼滤波器的工作原理及其公式推导,讨论卡尔曼滤波器的核心公式所代表的意义及个人的理解。

m0_37835056的博客 1366

PE文件格式概述

本章提要·           PE文件格式概述·           PE文件结构·           如何获取PE文件中的OEP·           如何获取PE文件中的资源·           如何修改PE文件使其显示MessageBox的实例2.1  引言通常Windows下的EXE文件都采用PE格式。PE是英文Portable Executable的缩写

bairny的专栏 1万+

​热电偶测温电路图(一)​

高精度热电偶测温电路图 此设计概括了提供传感器诊断所必需的抗混叠滤波器和偏置电阻器。此示例还提供了一种新颖的方式,即使用ADS1118上的板载温度传感器完成对系统的冷端补偿。对于热电偶线性化,此设计还提供了一种非常简单的、可以在大多数微控制器上实施的线性算法。 缺点就是太贵。 特性 测量K型热电偶温度 精度1°C 高精度/可重复性0.2°C 包含冷端补偿 包含软件算法 使用ADS111816位ADC(带PGA) 原理图/方框图 热电偶测温电路图(二) OP07构成的高稳定热电

zxm8513优快云博客 2万+

PE文件格式

一、前言(Preface)------------------PE(“portableexecutable”,可移植的可执行文件)文件格式,是微软WindwosNT,Windows95和Win32子集①中的可执行的二进制文件的格式;在WindowsNT中,驱动程序也是这种格式。它还能被应用于各种目标文件②和库文件中。这种文件格式是由微软设计的,并于1993年被TIS(toolinte...

diexiequ0204的博客 299

【26美赛B题】2026美赛数学建模(MCM/ICM)思路解析及代码分享

2026美赛数学建模B题解析与备赛指南:本文针对B题"数据+预测+决策优化"的特点,提出通用建模路线图,包含数据预处理、特征工程、预测模型构建、策略优化和稳定性验证等关键环节。提供赛题拆解方法、Python/Matlab双实现方案、AI辅助建模技巧及论文写作模板。适用于2026美赛B题参赛者及其他数学建模竞赛选手,帮助掌握从数据到决策的闭环建模流程,特别强调逻辑严谨性和结果可视化呈现。订阅者可获取历年真题解析和持续更新的备赛资源。

一键难忘的博客 2117

【无人机基站】基于K-mean算法实现无人机基站部署附matlab代码

【无人机基站】基于K-mean算法实现无人机基站部署附matlab代码

天天酷科研的博客 246

最详细PE文件格式讲解!!!!!

每个PE文件都是以一个DOS程序开始的,有了它,一旦程序在DOS下执行,DOS就能执行识别出这是一个有效的执行体,然后运行紧随MZ header的DOS stub(DOS块)。e_lfanew 字段是真正的PE文件头的相对偏移(RVA),指向真正的PE头的文件偏移位置,占用4字节,位于文件开始偏移3ch字节处。当PE文件通过加载器载入内存后,内存中的版本称为模块(Module),映射文件的起始地址称为模块句柄(hModule),可以通过模块句柄访问内存中的其他数据结构。基地址的值是由PE文件本身设定的。

SXXYNHHXX的博客 4123

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

PE文件格式全解读

PE文件包括DOS部分、PE文件头和节表和节数据。从DOS头(DOS header)到节区头(Sectionheader)是PE头部分,其下的节区合称PE体。节数据包括代码(.text)、数据(.data)、资源(.rsrc)节,分别保存。1.DOS部分:IMAGE_DOS_HEADER结构体的大小为40字节,需要注意的2个重要成员:0x0-0x01e_magic: DOS签名,表文件开始标识0x4d5a=”MZ”0x3c-0x3fe_lfanew:PE头部分的偏移0x000000b0.DOS存根位于DOS

凌阳的博客 5574

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

PE文件格式详解(上)

Windows NT 3.1引入了一种名为PE文件格式的新可执行文件格式。PE文件格式的规范包含在了MSDN的CD中(Specs and Strategy, Specifications, Windows NT File Format Specifications),但是它非常之晦涩。     然而这一的文档并未提供足够的信息,所以开发者们无法很好地弄懂PE格式。本文旨在解决这一问题,它会对整个

feidegengao的专栏 6512

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

PE文件格式粗浅认识

前言:最近开始学习PE文件格式,写点笔记做点记录,希望能够对和我一样正在学习PE文件的小伙伴有些启发,生出很棒的点子 ,当然,下面这些只是我这个初学者的一些简单的认识,针对和我一样的初学者,dalao可以绕道,另外,如果大家可以指出我的错误,我当感激不尽! 1.PE文件格式图总览 2.PE文件格式介绍 PE(Portable Execute)文件是Windows下可执行文件的总称,常见的有EX...

qq_45444695的博客 1131
上一篇: PE文件格式详解(3)
下一篇: Win32 API
Matrix_Designer
博客等级 码龄16年 58粉丝 296原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值