PE学习(4)

扩大节

节有很多个,在我们扩大节时,一般会选择扩大最后一个节,因为如果扩大其他节,那么要修改这个节后面所有节的偏移和属性,如果扩大最后一个节,那么只需修改最后一个节的数据。

扩大节的步骤:

  1. 拉伸到内存
  2. 分配一块新空间,大小为原来的sizeofimage(内存中整个PE文件的映射的尺寸)+EX(需要扩大的大小+)
  3. 将最后一个节的节表里面的SizeOfRawData(节在文件中对齐后的尺寸)和VirtualSize(节在没有对齐前的真实尺寸)都改成N(N = SizeOfRawData和VirtualSize中大的一个+EX)。
    也可以直接在这两个数据后加上EX。
  4. 修改sizeofimage的大小

操作:

1.扩大内存:

假设我要增加的内存是0x1000,那么文件大小就要调为0x1B000(初始大小)+0x1000=0x1C000 

,调整完后就获得了0x1000的空间。

2.修改SizeOfRawData和VirtualSize成员的值。

将SizeOfRawData加0x1000 (0x800+0x1000=0x1800)

将VirtualSize加0x1000(0x1000+0x1000=0x2000)

3.修改sizeofimage:

sizeofimage的值修改为0x1F000 (0x1E000 + 0x1000)

合并节

1.先将文件对齐改为和内存对齐一样:

  • 先查看文件的内存对齐和文件对齐

     

         如图,文件对齐是0x200,内存对齐是0x1000。

  • 修改每一个节的SizeOfRawData和VirtualSize。取SizeOfRawData和VirtualSize之间的最大值按内存对齐展开


    例如,图中这个节SizeOfRawData和VirtualSize之间的最大值是0x15000按内存对齐后还是0x15000,所以将SizeOfRawData和VirtualSize都修改成这个值。
  • 用刚才得到的值0x15000减去SizeOfRawData修改前的值0x14600得到通过这种方式这个节在文件中扩展的大小0x400。
  • 在这个节的末尾添加0x400的空间
  • 这里这个节的大小改变了,那么后面节的偏移也会一并改变,所以后面节的PointerToRawData都加0x400。
  • 以此方法将所有节都按文件对齐展开

2. 合并:

  • 用SizeOfImage减去SizeOfHeaders(按内存对齐后)得到所有节的大小。

    0x1E000 - 0x1400 = 0x1CC00
    然后将该值赋给第一个节的SizeOfRawData和VirtualSize
  • 将第一个节的属性改为包含所有节的属性。将所有节的Characteristics进行或运算的到的结果存入第一个节的Characteristics中。
  • 修改NumberOfSections的值为1

静态链接库

静态链接库(Static Library)是程序在编译时就已经被链接到最终的可执行文件中的库。这种库文件通常具有.lib(在Windows平台上)或.a(在Unix/Linux平台上,包括macOS)的扩展名。与动态链接库(Dynamic Link Library, DLL或.so文件)不同,静态链接库在程序运行时不需要额外加载,因为它们的代码和数据已经被直接嵌入到了最终的可执行文件中,我们通常使用的函数都是动态链接库里面的。

静态链接库的构建

先在VS里面创建一个静态库项目

创建后会有一个头文件和源文件

在项目名字处按右键选择添加,然后选择添加类

添加完后,在源文件里面会出现一个所创建类的.cpp文件在,在头文件里面会出现一个所创建类的.h文件。

在.cpp文件里面编写函数

在.h文件里面声明函数

在项目文件的Debug文件里面找到lib文件,把头文件和lib文件都复制出来

使用

把头文件和lib文件复制到需要用到的项目的目录下

法一:

写入#include "libtools.h"和#pragma comment(lib, "testlib.lib")

运行即可看到成功调用了

法二:

不写“#pragma comment(lib, "testlib.lib")​​​​​​​”这一句,需要写“#include "libtools.h"”。然后右键项目,属性->连接器–>常规–>附加库目录–>编辑

点击右边4个图标中的第一个后,填入lib文件名称

静态链接库就配置好了。

动态链接库

动态链接库的创建:

创建项目,选择动态链接库

添加一个类

删除class,清空.h文件

在.h文件做函数声明

在.cpp文件写函数功能

生成->生成解决方案,会得到.lib文件和.dll文件

复制.lib文件和.dll文件

使用

法一:隐式连接

将.lib文件和.dll文件复制到需要调用项目目录下,然后导入

运行

法二:显式调用

将.lib文件和.dll文件复制到需要调用项目目录下,然后导入

#include<Windows.h>
#include<iostream>

//#pragma comment(lib, "testdll.lib")​​​​​​​
typedef int (*lpadd)(int, int);
typedef int (*lpsub)(int, int);
int main()
{
    lpadd myadd;
    lpsub mysub;
    HINSTANCE hModule = LoadLibrary(TEXT("testdll.dll"));
    myadd = (lpadd)GetProcAddress(hModule, "add");
    mysub = (lpsub)GetProcAddress(hModule, "sub");   
    printf("%d", myadd(3, 2));
}

运行

注记:

extern "C" _declspec(dllimport) int add(int x, int y)这句语句中,extern是指函数是全局函数,可以在其他地方调用;"C"代表用C语言的方式编译、链接;_declspec(dllimport)告诉编译器该函数是导入函数。

静态链接库与动态链接库的区别

  1. 静态链接库在调用时将代码直接编译到exe里面去,动态链接库的代码不在exe里面,他在自己独立的模块里面。
    因此,如果静态链接库的代码有问题,就需要修改后重新编译程序,而如果动态链接库出了问题,只需要修改动态链接库的代码就行了。
  2. 静态链接库:在程序编译链接阶段,静态链接库的代码和数据被直接链接到目标程序中,成为可执行文件的一部分。这意味着在程序运行时,不再需要加载静态链接库,因为它已经被编译到程序中了。
  3. 动态链接库:动态链接库在程序运行时由操作系统动态加载到内存中。程序通过调用库中的函数来实现所需的功能。多个程序可以同时共享同一个动态链接库,从而节省内存空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值