《Windows PE》12.4 万能补丁

本节我们将介绍基于嵌入式补丁的万能补丁技术。

本节必须掌握的知识点:

        万能补丁原理

        示例程序

12.4.1 万能补丁原理

上一节中,我们介绍了嵌入补丁,就是把补丁代码嵌入到目标程序的代码段中。如果补丁代码过于庞大,可能需要修改各个节区的大小和地址,带来不必要的麻烦。我们可以使用万能补丁轻松解决这个问题。

万能补丁的原理

我们可以制作两个补丁代码,补丁代码一负责嵌入目标程序的代码段。补丁代码二负责实现具体功能,并将其打包为一个DLL,这样补丁DLL就可以脱离于目标程序,因此补丁DLL的大小和功能不受目标程序的限制。而补丁代码一的功能自然就是实现动态加载补丁DLL。【注意】动态加载DLL的API函数是kernel32.dll中的LoadLibraryx系列函数,所以,补丁代码一需要做的工作就是找到内存中的kernel32.dll的基地址,然后査找其导出表并获取LoadLibraryA的VA地址。

为了不影响目标程序的原有功能,我们可以将补丁代码一嵌入到目标程序代码段的结尾处,并将补丁代码一的最后一条语句“0E9h,0F0h,0FFh,0FFh,0FFh”的跳转地址修改为目标程序的原入口地址。

万能补丁实现过程

我们将万能补丁的实现过程总结如下:

●补丁代码一:

1.通过PEB获取kernel32.dll基地址。

2.获取LoadLibraryA的函数VA。

3.调用LoadLibraryA函数,动态引入动态链接库pa.dll(winResult.dll改一下入口函数)。

4.跳转到入口地址执行,该部分代码也可以使用FF 25无条件跳转指令。

●补丁代码二

1.编写DLL入口函数。当一个进程动态加载外部DLL文件时,除了将DLL内容映射到内存外,还会执行DLL 的入口函数;因此我们可以在DLL入口函数中添加想要实现的功能代码。

2.编写DLL导出函数。

我们可以用示意图表示万能补丁的实现过程,如下所示:

图12-7 万能补丁原理示意图

12.4.2 示例程序

32位PE

实验八十九:32位万能补丁

示例先完成一个汇编代码写的patch1.exe补丁代码一程序,然后将补丁程序字节码.text节区结尾处。补丁代码一动态获取LoadLibrayA函数地址,动态加载由补丁代码二生成的DLL。最后一条JMP指令跳转到目标程序入口地址处。补丁代码二改写第五章写的winResult.dll,在DllMain入口函数内添加一个MessageBox函数调用。

●补丁代码一

;------------------------------------------------------------------------
; FileName:patch1.asm
; 实验89:32位万能补丁码
; 功能:获取LoadLibraryA的函数地址并调用
; (c) bcdaren, 2024
;-----------------------------------------------------------------------*/
    .386
    .model flat,stdcall
    option casemap:none

include    windows.inc
include    user32.inc
includelib user32.lib
include    kernel32.inc
includelib kernel32.lib

;数据段(数据段冗余,仅供对比参考)
    .data

szText  db 'LoadLibrary的函数地址为: %08x',0
szOut   db '%08x',0dh,0ah,0
szBuffer db 256 dup(0)

;代码段
    .code

start:
   mov edi,edi
   call loc0
   db 'LoadLibraryA',0  ;特征函数名
   db 'pach2',0         ;动态链接库pach2.dll
loc0:
   pop edx            ;edx中存放了特征函数名所在地址
   push edx

   push edx

   assume fs:nothing
   mov eax,fs:[30h] ;获取PEB所在地址
   mov eax,[eax+0ch] ;获取PEB_LDR_DATA 结构指针
   mov esi,[eax+1ch] ;获取InInitializationOrderModuleList 链表头
                     ;第一个LDR_MODULE节点InInitializationOrderModuleList成员的指针
   lodsd             ;获取双向链表当前节点后继的指针
   mov ebx,[eax+8]   ;获取kernel32.dll的基地址

loc2:   ;遍历导出表
   mov esi,dword ptr [ebx+3ch] 
   add esi,ebx ;ESI指向PE头
   mov esi,dword ptr [esi+78h]
   add esi,ebx ;ESI指向数据目录中的导出表
   mov edi,dword ptr [esi+20h] ;指向导出表的AddressOfNames
   add edi,ebx ;EDI为AddressOfNames数组起始位置
   mov ecx,dword ptr [esi+14h] ;指向导出表的NumberOfNames

   push esi
   xor eax,eax

loc3:
   push edi
   push ecx
   mov edi,dword ptr [edi]
   add edi,ebx  ;edi指向了第一个函数的字符串名起始
   mov esi,edx  ;esi指向了特征函数名起始
   xor ecx,ecx
   mov cl,0ch   ;特征函数名的长度
   repe cmpsb
   je loc4    ;找到特征函数,转移

   pop ecx
   pop edi
   add edi,4  ;edi移动到下一个函数名所在地址
   inc eax    ;eax为索引
   loop loc3
loc4:
   pop ecx
   pop edi
   pop esi ;ESI指向数据目录中的导出表   
   mov edi,dword ptr [esi+24h] ;指向导出表的Name索引
   add edi,ebx ;EDI为AddressOfNamesOrdinals数组起始位置

   ;计算eax处的值
   sal eax,1   ;eax中存放了指定索引距离数组的偏移
   add edi,eax
   mov ax,word ptr [edi]  ;又是一个索引
   mov edi,dword ptr [esi+1ch]  ;AddressOfFunctions
   add edi,ebx   
   
   sal eax,2
   add edi,eax
   mov eax,dword ptr [edi]
   add eax,ebx

   ;edx指向patch.dll
   ;加载dll,引发对补丁的调用
   pop edx		;db 'LoadLibraryA'地址
   add edx,0dh  ;'pach2'地址
   push edx
   call eax	;LoadLibraryA
   ;跳转
   db 0E9h,0FFh,0FFh,0FFh,0FFh
   end start

  总结

pach1.asm 流程:

1.通过PEB获取kernel32.dll基地址。

2.获取LoadLibraryA的函数VA。

3.调用LoadLibraryA函数,动态引入动态链接库pach2.dll(winResult.dll改一下入口函数)。

4.跳转到入口地址执行,该部分代码也可以使用FF 25无条件跳转指令。

       ●补丁代码二(32位C语言程序补丁DLL)

       winResult.h

/*
; winResult.dll 导出函数:
; 1、AnimateOpen(DWORD)
;	窗口抖动进入效果
; 2、AnimateClose(DWORD)
;	窗口抖动退出效果
; 3、FadeInOpen(DWORD)
;	窗口淡入效果,仅运行在2000/XP以上操作系统
; 4、FadeOutClose(DWORD)
;	窗口淡出效果,仅运行在2000/XP以上操作系统
; ******************************************************************** /
*/
#pragma once
#include <windows.h>

#ifdef _cplusplus //如果C++模式编译

	#ifdef API_EXPORT 
		#define EXPORT   extern "C" __declspec(dllexport)   //C和C++程序都能使用这个DLL
	#else
		#define EXPORT    extern "C" __declspec(dllimport)	//当头文件供调用库的程序使用时
	#endif
#else
	#ifdef API_EXPORT 
		#define EXPORT  __declspec(dllexport) //导出DLL中任何函数、变量、或者类
	#else
		#define EXPORT  __declspec(dllimport) //当头文件供调用库的程序使用时
	#endif
#endif

EXPORT  void AnimateOpen(HWND);
EXPORT  void AnimateClose(HWND);
EXPORT  void FadeInOpen(HWND);
EXPORT  void FadeOutClose(HWND);

	winResult.c
	/*------------------------------------------------------------------------
 FileName:winResult.c
 实验89:一个简单的动态链接库例子,DLL入口函数增加一个对话框
 (c) bcdaren, 2024
-----------------------------------------------------------------------*/
#include <windows.h>
#define API_EXPORT
#include "winResult.h"

#define MAX_XYSTEPS		50
#define DELAY_VALUE		50	//动画效果使用的步长
#define X_STEP_SIZE		10
#define Y_STEP_SIZE		9
#define X_START_SIZE		20
#define Y_START_SIZE		10
#define LMA_ALPHA		2
#define LMA_COLORKEY	1

//入口和退出点
int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
	const TCHAR szHello[] = TEXT("HelloWorldPE");
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		MessageBox(NULL,szHello,NULL,MB_OK);
		break;
	default:
		break;
	}
	return TRUE;
}

//私有函数:本函数在dll内部使用
DWORD TopXY(DWORD wDim,DWORD sDim)
{
	return (sDim / 2 - wDim / 2);
}

//窗口抖动进入效果
EXPORT  void AnimateOpen(HWND hWin)
{
	RECT rect;
	DWORD Xsize, Ysize,Xplace,Yplace;
	int sWth,sHth,counts;

	GetWindowRect(hWin, &rect);
	Xsize = X_START_SIZE;
	Ysize = Y_START_SIZE;
	sWth = GetSystemMetrics(SM_CXSCREEN);
	Xplace = TopXY(Xsize, sWth);
	sHth = GetSystemMetrics(SM_CYSCREEN);
	Yplace = TopXY(Ysize, sHth);
	counts = MAX_XYSTEPS;
	while (counts--)
	{
		MoveWindow(hWin, Xplace, Yplace, Xsize, Ysize, FALSE);
		ShowWindow(hWin, SW_SHOWNA);
		Sleep(DELAY_VALUE);
		ShowWindow(hWin, SW_HIDE);
		Xsize += X_STEP_SIZE;
		Ysize += Y_STEP_SIZE;
		Xplace = TopXY(Xsize, sWth);
		Yplace = TopXY(Ysize, sHth);
	}
	Xsize = rect.right - rect.left;
	Ysize = rect.bottom - rect.top;
	Xplace = TopXY(Xsize,sWth);
	Yplace = TopXY(Ysize,sHth);
	MoveWindow(hWin,Xplace,Yplace,Xsize,Ysize,TRUE);
	ShowWindow(hWin, SW_SHOW);
}

//窗口抖动退出效果
EXPORT void AnimateClose(HWND hWin)
{
	RECT rect;
	DWORD Xsize, Ysize, Xplace, Yplace;
	int sWth, sHth, counts;

	ShowWindow(hWin, SW_HIDE);
	GetWindowRect(hWin, &rect);
	Xsize = rect.right - rect.left;
	Ysize = rect.bottom - rect.top;
	sWth = GetSystemMetrics(SM_CXSCREEN);
	Xplace = TopXY(Xsize, sWth);
	sHth = GetSystemMetrics(SM_CYSCREEN);
	Yplace = TopXY(Ysize, sHth);
	counts = MAX_XYSTEPS;
	while (counts--)
	{
		MoveWindow(hWin, Xplace, Yplace, Xsize, Ysize, FALSE);
		ShowWindow(hWin, SW_SHOWNA);
		Sleep(DELAY_VALUE);
		ShowWindow(hWin, SW_HIDE);
		Xsize -= X_STEP_SIZE;
		Ysize -= Y_STEP_SIZE;
		Xplace = TopXY(Xsize, sWth);
		Yplace = TopXY(Ysize, sHth);
	}
}
//窗口淡入效果,仅运行在2000/XP以上操作系统
EXPORT void FadeInOpen(HWND hWin)
{
	const TCHAR User32[] = TEXT("user32.dll");
	const CHAR SLWA[] = "SetLayeredWindowAttributes";//函数名使用ASCII码字符
	FARPROC pSLWA;
	int Value = 90;

	LONG stl = GetWindowLong(hWin, GWL_EXSTYLE);//检索扩展的窗口样式
	// 增加“分层窗口”样式
	stl |= WS_EX_LAYERED;	
	SetWindowLong(hWin,GWL_EXSTYLE,stl);
	//获取SetLayeredWindowAttributes在user32.dll中的地址
	pSLWA = GetProcAddress(GetModuleHandle(User32), (LPCSTR)SLWA);
	//设置分层窗口的不透明度和透明度颜色键
	pSLWA(hWin,0,0,LMA_ALPHA);
	ShowW

相关推荐

《Windows PE》18.3 壳破解

看完了上一节,读者应该会有些感慨,破解是如此的简单。如果你是收费商业软件的一方,肯定会觉得应该需要做点什么。在本章的第一节,我们介绍了很多种不同的验证方式,可以根据具体情况,选择一种合适的验证方法。但是,不论采用什么样的验证方式,验证本身也是需要防护的。我们可以使用加密壳对验证代码进行加密保护。因此,加密壳又被称之为保护的保护。本节我们将介绍register.exe使用UPX壳加密,然后再破解的方法。脱壳后破解带壳破解。

bcdaren的博客 1182

《Windows PE》17.3 FSG壳

回顾第十六章PE病毒的16.2.2病毒分析案例一中,我们分析的病毒样本Lab01-03.exe使用了FSG壳。本节我们就来详细分析FSG壳。静态分析手工脱壳。

bcdaren的博客 953

《Windows PE》16.4.2 病毒查杀

当单步执行到从入口地址开始的0x61地址处(第一条PUSH指令的下一条指令地址01013061H)时,从context上下文中取出栈顶stCT.Esp的值(000DFF80H),然后调用ReadProcessMemory函数读取该地址处存储的原程序入口地址。接下来我们还是以Win32.Capric.exe的“X病毒”为例,首先使用手工的方法清理病毒,然后再写一个针对该病毒的专杀工具。由上一小节对病毒源代码的分析我们得知,如果需要彻底修复被感染的目标文件,我们需要将被病毒修改的部分逐一进行修复。

bcdaren的博客 1142

《Windows PE》15.1 资源捆绑

在下载应用程序时,我们会发现一些特殊的EXE应用程序。当我们运行EXE程序时会同时下载或生成若干个其他应用程序,并自动运行。这个过程通常会以一种静默的方式悄悄地进行。我们将这一技术称之为EXE捆绑。之所以这样做,好的方面是简化程序下载安装的过程。坏的方面是一些流氓软件可以借此牟利,侵犯用户的选择权。本章介绍两种常用的EXE捆绑的实现方法。本章学习知识概要:资源捆绑补丁捆绑。

bcdaren的博客 1146

《Windows PE》14.1最后一节插入补丁程序

如果我们希望添加不同功能的补丁,只需要替换补丁DLL就可以了。00010430 03 F3 8B 76 78 03 F3 8B 7E 20 03 FB 8B 4E 14 56 .髬vx.髬~ .麐N.V。00010420 00 00 00 8B 40 0C 8B 70 1C AD 8B 58 08 8B 73 3C ...婡.媝.瓔X.媠

bcdaren的博客 1008

《Windows PE》11.2.1 PE变形技术

恶意软件使用PE变形技术来修改PE文件的结构和代码,以产生不同的变种,从而使每个实例看起来不同,难以被传统的基于特征的病毒检测技术所识别。■●代码混淆:恶意软件使用各种技术,如指令替换、指令重排、无用代码插入等,来修改PE文件的代码,使其难以分析和识别。这样可以改变程序的控制流,增加分析的复杂性。【注】我们将在PE加密壳一章详细讲解代码混淆。●API重命名:恶意软件可能会修改PE文件中调用的系统API函数的名称,使其与正常的API名称不同。

bcdaren的博客 6868

《Windows PE》9.2 动态加载技术-获取kernel32.dll基址

上一节中我们介绍了如何动态调用DLL的方法。首先调用LoadLibrary函数动态加载DLL,然后调用GetProcAddress通过函数名获取DLL内的函数地址。但是LoadLibrary和GetProcAddress函数的调用仍然依赖于PE文件内的导入表和函数地址表的存在。在操作系统加载PE文件到内存时获取这两个函数的地址。本节我们将介绍一种完全不依赖于导入表和函数地址表的方法,实现对DLL动态链接库中函数的调用。简单来说,需要经过以下三步:步骤1获取kernel32.dll的基地址。

bcdaren的博客 1771

《Windows PE》7.4 资源表应用

本节我们将通过两个示例程序,演示对PE文件内图标资源的置换与提取。更改图标提取图标资源。

bcdaren的博客 1102

《Windows PE》7.3 遍历资源表

文件偏移:00003AB8 (代码页=0804, 长度2字节)文件偏移:00003AC0 (代码页=0804, 长度2字节)2.示例程序对于非资源内容(例如应用程序清单)归类于自定义资源类型。文件偏移:00007DD0 (代码页=0409, 长度381字节)●模块五:RvaToFileOffset.c(略)●模块七:GetResourceInfo.c。●模块六:Getpeinfo.c(略)●模块四:pemain.c(略)●模块1:resource.h。●模块2:peinfo.rc。●模块三:info.h。

bcdaren的博客 460

《Windows PE》7.2 资源表

在资源表中,IMAGE_RESOURCE_DIRECTORY_ENTRY 的 OffsetToData 字段指向一个 IMAGE_RESOURCE_DATA_ENTRY 结构,该结构描述了资源数据的位置和相关属性。PE 对话框资源的起始位置 01 00 FF FF 00 00 00 00 00 00 00 00 是对话框资源的标识符,用于识别和定位对话框资源在 PE 文件中的位置。资源的每一级目录都会有一个资源目录头,它标识 了该类资源的属性、创建日期和版本等信息,其中也包含了随后的目录项的数量描述信息。

bcdaren的博客 1254

《Windows PE》7.1 资源分类

自定义资源是指在程序中使用的非标准资源,这些资源可以是任何类型的数据或文件,用于存储和使用程序所需的特定信息或内容。在资源脚本文件(.rc 文件)中,可以使用自定义的资源类型来定义和描述这些资源。其在资源 文件中的定义语法如下:资源 ID 类型 ID [DISCARDABLE]BEGIN数据定义……END以下是一个示例:上述代码中,IDR_CUSTOM1 是自定义资源的唯一标识符(ID),CUSTOM 是自定义资源类型指示符,custom.dat 是自定义资源文件的名称。

bcdaren的博客 941

《Windows PE》6.4.2 远程注入DLL

测试步骤:当PEHeader.exe运行时,运行remoteThread.exe,点击文件菜单”插入到PEHeader.exe”,就可以将DLL远程注入到进程PEHeader.exe中了。对比无DLL注入的方法,使用DLL注入的方法不需要对代码和数据进行重定位(由操作系统自动完成),省去了很多不必要的麻烦,因此也是我们常用的方法。写一个窗口程序,将一个dll通过远程注入的方法,注入到第三章的示例程序PEHeader.exe中,支持32位和64位PE。1.打开本地进程(调用OpenProcess函数)。

bcdaren的博客 578

《Windows PE》6.4.1 无 DLL远程注入

一旦你的ThreadFunc中有错误,远程线程会立即崩溃。这样,远程进程中的ThreadFunc就会执行不存在的内存数据(至少没有在它自己的内存空间中)。如果我们能够熟练的掌握汇编语言,当然也可以直接使用汇编语言编写一个无DLL注入的程序,毕竟使用汇编语言可以非常方便的直接对代码和数据进行重定位,这是C语言无法做到的。如果这个有争议的CALL是编译器添加的(因为一些不该打开的编译开关比如/GZ打开了),它要么在ThreadFunc的开头要么在ThreadFunc接近结尾的地方。

bcdaren的博客 957

《Windows PE》6.3 无导入表和重定位表PE文件

本节我们将演示一个无导入表、无重定位表,并且只有一个.text节区的汇编代码程序。汇编代码重定位。

bcdaren的博客 533

6.2 遍历重定位表

本节我们将编写一个遍历重定位表的示例程序,打印重定位表。遍历重定位表。

bcdaren的博客 449

《Windows PE》6.1 重定位表

重定位表(relocation table)是在可执行文件或动态链接库(DLL)中用于指示系统在加载时对代码和数据进行重新定位的数据结构。在可执行文件或 DLL 中,代码和数据通常是使用相对地址进行引用的。当将可执行文件或 DLL 加载到内存中时,如果加载地址与文件中的基地址不匹配,就需要对代码和数据进行重新定位,以确保引用的地址正确。重定位表重定位表的结构与解析重定位表的修改。

bcdaren的博客 1481

《Windows PE》5.3 导出表应用

本节我们将通过三个实验来说明导出表的应用。实验一修改导出表中的函数地址。实验二直接替换导出函数的代码。实验三导出私有函数修改导出函数地址替换导出函数代码导出私有函数。

bcdaren的博客 1130

《Windows PE》5.2 遍历导出表

这段代码使用了 EnumProcessModules 函数遍历进程中的模块,并使用 GetModuleInformation 函数获取模块的基址。32位和64位PE文件导出表描述符是相同的,遍历导出表的区别只有两点,32位基址和64位基址,以及NT32位NT头和64位NT头的区别。实验34:方法一,使用常规方法实现,将程序读到内存指定位置,进行磁盘与内存的转换。实验35:方法二,使用常规方法实现,将程序读到内存指定位置,进行磁盘与内存的转换。使用常规方法实现,将程序读到内存指定位置,进行磁盘与内存的转换。

bcdaren的博客 1441

《Windows PE》5.1 导出表

该值也是一个指针,与AddressOfNames是一一对应关系,所不同的是,AddressOfNames指向的是字符串的指针数组,而AddressOfNameOrdinals则指向了该函数在AddressOfFunctions中的索引值。●导出函数序号表(Export Function Ordinal Table)是PE文件中导出表的一部分,用于映射导出函数的序号和地址。DLL中的第一个导出函数并不是从0开始的,某导出函数的编号等于从AddressOfFunctions开始的顺序号加上这个值。

bcdaren的博客 1450

《Windows PE》4.3 延迟加载导入表

与导入表不同的是,它所记录的这些DLL动态链接库并不会被操作系统的PE加载器加载,只有等到由其登记的相关函数被应用程序调用时,PE中注册的延迟加载函数才会根据延迟加载导入表中对该函数的描述,动态加载相关链接库并修正函数的VA地址,实现对函数的调用。不过,如果用户选择了Print命令,你就可以调用该DLL中的一个函数,然后它就能够自动进行DLL的加载。5.延迟加载的DLL具备的另一个特性是,按照默认设置,调用的函数可以与一些内存地址相链接,在这些内存地址上,系统认为函数将位于一个进程的地址中。

bcdaren的博客 1211

《Windows PE》4.2 绑定导入表

绑定导入表(Bound Import Table)是文件中的一个数据结构,用于存储已经绑定(即完成绑定导入)的外部函数的信息。绑定导入表数据结构实例分析。

bcdaren的博客 921

《Windows PE》4.1.4 手工重构导入表

【可选项】可以选择修改的字段包括导入表的大小、IAT表的大小、.text节区的实际大小、.rdata节区的实际大小和.data节区的实际大小。●手工实现,将Regedit.exe程序的代码、数据、IAT表和导入表添加到HelloWorld.exe程序中,并可以正确运行。第二步:定位副本文件中的.data节区,将Regedit.exe程序的.data节区数据写入到副本文件.data节区的结尾处。第八步:将Regedit.exe程序的.text节区数据复制到.text节区,并修正参数地址以及FF25跳转地址。

bcdaren的博客 1362

《Windows PE》4.1.3 IAT函数地址表

如果导入表描述符的TimeDateStamp和ForwarderChain字段是一个特殊的标志值,如0xFFFFFFFF,表示导入函数已绑定,则IAT函数地址表中存储的是真实的导入函数地址。在程序加载时,操作系统会根据导入描述符中的INT表和IAT表进行动态链接,将导入函数的实际入口地址填充到IAT表中的函数指针对应的位置。IAT表就是用来存储这些实际的函数入口地址。首先找到数据目录项的第12项,获取IAT函数地址表的RVA地址,加上基址后,得到并输出加载到内存中的IAT函数地址表的VA地址。

bcdaren的博客 1253

《Windows PE》4.1导入表

IMAGE_IMPORT_BY_NAME结构体用于描述PE文件中的导入地址表(Import Address Table,IAT)或原始未绑定导入地址表(Original Unbound Import Address Table)中,通过名称进行导入的函数的信息。然后根据导入表FOA地址,在PE文件中找到导入表描述符的起始地址,循环遍历获取导入表描述符的OriginalFirstThunk字段中保存的RVA地址,将此RVA地址转换为FOA地址,即INT表IMAGE_THUNK_DATA的起始地址。

bcdaren的博客 1958

《Windows PE》3.2.4节表

节表由多个节表项(IMAGE_SECTION_ HEADER)组成,每个节表项(40个字节)记录了 PE中与某个特定的节有关的信息,如节的属性、节 的大小、在文件和内存中的起始位置等。节表中节的数量由字段IMAGE_FILE_HEADER. NumberOfSections来定义。●节表项的数据结构详细定义如下:typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 节区名称,8 字节 u

bcdaren的博客 2025

《Windows PE》3.2.3 NT头-扩展头

4.32位HelloWorld.exe(Win XP汇编版本)文件偏移地址0000013CH地址处,将默认0010H修改为0000~0010H之间的任一值,我们会发现,当数据目录项的数目大于等于2时,PE文件可以在Windows 10系统正常运行。1.32位HelloWorld.exe(Win XP汇编版本)文件偏移地址0000013CH地址处,将默认0010H修改为0000~0010H之间的任一值,我们会发现,当数据目录项的数目大于等于2时,PE文件可以在Windows 10系统正常运行。

bcdaren的博客 1341

《Windows PE》3.2.3 NT头-文件头

原因是运行程序时,系统使用LoadString函数加载命令行参数字符串,如果第一个参数为自身的句柄,则会在当前路径或系统路径下寻找资源PE文件(没有代码的资源文件),名称为***.exe.mui。DOS块的后面接着就是NT头了。NT头包含了PE文件的各种信息,包括文件的签名、文件头和扩展头。在32位的PE文件中,Signature的值为0x00004550(或者ASCII字符"PE\0\0"),在64位的PE文件中,Signature的值同样为0x00004550(或者ASCII字符"PE\0\0")。

bcdaren的博客 1252

《Windows PE》3.2 PE头结构-DOS头和DOS块

在VS中输入#include "winnt.h" ,点击右键,打开文档。然后搜索 IMAGE_DOS_HEADER 或者在程序里面输入IMAGE_DOS_HEADER 按F12转到定义。■。

bcdaren的博客 1617

《Windows PE》3.1 基本概念

在正式讲解PE文件格式之前,我们有必要先熟悉和PE相关的一些基本概念,以便于更好的理解和掌握PE文件格式。地址指针数据目录项节对齐方式字符串编码格式。

bcdaren的博客 1692

《Windows PE》2.2.2 加载PE文件二

doc .mp3 .jpg等等都是有文件格式的,我们只需要关心.exe和.dll文件格式,因为.exe和.dll文件是可执行文件格式,其他的文件是不可执行的,不能在CPU上运行的。比如: PE 它是windows下的文件格式,是MZ打头的(4D5A)只有两个字节,后面很大一片就是对这个结构体的管理,比如代码在什么位置,图像在什么位置,文字在什么位置,在前面PE头中都是有记录的。除了默认的PE头之外,每个节区都是有命名的,例如.text节区为代码段,.data节区为数据段,.rsrc节区保存资源。

bcdaren的博客 1259
上一篇: 《Windows PE》11.2.1 PE变形技术
下一篇: 《Windows PE》14.1最后一节插入补丁程序
bcdaren
bcdaren 昆山爱达人信息技术有限公司官方账号 昆山爱达人信息技术有限公司官方账号
博客等级 码龄10年 2910粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值