静态链接库,动态链接库【滴水逆向三期48笔记】(下)

简介: 静态链接库,动态链接库【滴水逆向三期48笔记】(下)

三.动态链接库的使用方法

静态链接库存在很多问题,那么动态链接库就能很好地解决静态链接库的问题。

. exe在可执行程序中没有相应库的代码,当软件运行起来再把库代码拷到内存。

1.dll文件创建

我们在visual studio中创建动态链接库:

在创建完成后我习惯将多余的文件全部删除,新增自己需要的文件:

MyDll.h文件:

#pragma once
_declspec(dllexport) int Plus(int x, int y);
_declspec(dllexport) int Sub(int x, int y);
_declspec(dllexport) int Mul(int x, int y);
_declspec(dllexport) int Div(int x, int y);

MyDll.cpp文件:

#include "MyDll.h"
int Plus(int x, int y)
{
  return x + y;
}
int Sub(int x, int y)
{
  return x - y;
}
int Mul(int x, int y)
{
  return x * y;
}
int Div(int x, int y)
{
  return x / y;
}

跟创建.lib文件后一样点击平时的编译运行按钮,提示无法运行(本来就无法单独运行),但已成功生成.dll 文件,去到 Debug 或 Release 目录下即可看到,注意同样还有个.lib文件,我们后面会用到。

.dll文件调用

1.隐式调用:

首先,我们将前面创建好的.lib文件和.dll文件放入项目目录下面(静态链接库函数是放在.lib文件中的,但是动态链接库的.lib文件中,可以理解为只放了函数在哪里,而真正的函数是放在.dll文件中的。

完成之后,添加代码:

#pragma comment(lib,"dll名.lib");

然后加入函数声明:

extern "C" _declspec(dllexport) int Plus(int x, int y);

这里解释一下该代码:

extren “C”表示这是个全局函数,可以供各个其他函数调用。

“C”表示按照C语言的方式进行编译和链接,那么我们为什么要用C语言的方式进行编译呢?原因是C++函数重载,编译器为了避免出现函数名一样的函数,会将我们写好的函数名进行更改,而使用C语言方式进行编译后就不会更改我们的函数名了。

_declspec(dllexport)是告诉编译器,此函数为导出函数。

2.显式调用:

1.定义函数指针:

typedef int (_stdcall *Plus)(int,int);

2.声明函数指针变量:

lpPlus myPlus;

3.动态加载dll到内存中

HINSTANCE HModule=LoadLibrary("DllName.dll");

4.获取函数地址:

myPlus=(lpPlus)GetProAddress(hModule,"_Plus@8");

5.调用函数:

int a=myPlus(1,2);

特别说明:

1.Handle代表系统的内核对象,如文件句柄,线程句柄,进程句柄

2.HMODULE是代表程序载入的模块

3.HINSTANCE在Win32下与HMODULE是相同的东西,Win16一六

4.HWND是窗口句柄

实际上,这些都是无符号的整形,Windows之所以这样设计,主要有两个目的:

1.方便区分

2.避免使用者误进行运算

动态调用主要通过 LoadLibrary 获取 加载dll 并获取其地址,后通过 GetProcAddress 通过 dll 句柄和函数名或者函数序号(后面会说)获取真正的函数地址,得到地址,套上和该函数格式一模一样的函数指针。即可成功调用。

三.导出函数名问题

我们可以通过visual C++提供的工具DEPENDS.EXE来观看.dll文件,可以编译器为我们导出的函数名,在我们进行开发过程中,通常函数名都是见名知其意,那么别人就能够通过函数名来猜测我们函数的功能,那么我们如何隐藏函数名呢?

可以通过添加 def 文件,在源文件->添加->新建项->搜索def,即可添加def文件。

或者在文件中直接弄个空文件改成.def,然后在添加到项目的源文件中 也可以。

添加到项目的源文件后,需要在如下项目属性的这里,填入添加的def的文件名才能正常使用。

.def文件中写入一下文本:

EXPORTS 
Plus    @12
Sub     @15 NONAME
Mul     @13
Div     @16

这里的Plus,Sub,Mul,DIV都是我写好的函数,如果要隐藏哪个函数名,可以根据这个来隐藏,其中@后的就是导出序号,其中NONAME表示只有序号,没有函数名,在观看.dll文件时,只能看到导出序号,看不到函数名。

由于之前我们有学习过C++,更没有学习过关于库的知识,所以在课程中可能有很多理解不到位的地方,还希望大家指出,我会非常虚心地学习,希望我们大家共同进步!

相关文章
|
Java Maven
IDEA自带Maven添加阿里镜像
IDEA自带Maven添加阿里镜像
IDEA自带Maven添加阿里镜像
sklearn中分类模型评估指标(一):准确率、Top准确率、平衡准确率
accuracy_score函数计算准确率分数,即预测正确的分数(默认)或计数(当normalize=False时)。 在多标签分类中,该函数返回子集准确率(subset accuracy)。 如果样本的整个预测标签集与真实标签集严格匹配,则子集准确率为 1.0; 否则为 0.0。
|
12月前
|
JSON 监控 API
京东商品列表 API 接口系列(京东 API)
京东商品列表API接口为开发者提供获取店铺内商品详细信息的功能,包括名称、价格、库存、图片、ID、销量等。通过HTTP GET请求并包含必要参数(如店铺ID、API密钥),可获取JSON格式的商品列表数据,适用于展示、库存管理、价格监控等场景。示例代码展示了使用Python调用该接口的方法,返回的数据包含状态码、商品总数、分页信息及具体商品详情。
|
JSON 缓存 JavaScript
使用 jsDelivr 免费加速 GitHub Pages 博客的静态资源(二)
使用 jsDelivr 加速 GitHub Pages 的图片资源和动态编译的 JSON 资源。
260 2
|
图形学
【unity小技巧】Unity中实现一个战斗连击连招系统,可以动态添加减少连击连招段数功能
【unity小技巧】Unity中实现一个战斗连击连招系统,可以动态添加减少连击连招段数功能
734 0
成功解决:Could not resolve dependency: npm ERR! peer vue@“^3.0.2“ from vuex@4.0.2
这篇文章讨论了在使用npm安装依赖时遇到的一个常见问题,即无法解析依赖导致的"peer dependency"冲突错误。文章提供了几种解决方法,包括清除npm缓存、删除`node_modules`文件夹和`package-lock.json`文件,然后重新尝试安装,以解决版本冲突问题。
|
机器学习/深度学习 Python
【视频】ARIMA时间序列模型原理和R语言ARIMAX预测实现案例
【视频】ARIMA时间序列模型原理和R语言ARIMAX预测实现案例
|
监控 网络协议 JavaScript
WebSocket技术详解与应用指南
WebSocket是全双工TCP协议,解决HTTP的单向通信问题,允许服务器主动推送信息。本文档介绍了WebSocket的基本概念、工作原理(基于HTTP握手,通过帧进行数据通信)、应用场景(实时聊天、在线游戏、数据监控等)和实现方法(客户端使用JavaScript API,服务器端有多种编程语言库支持)。学习WebSocket能提升Web应用的实时性和交互性。
2759 1
|
存储 缓存 移动开发
html实现离线缓存(工作原理+怎么使用+应用场景)
html实现离线缓存(工作原理+怎么使用+应用场景)
1125 0
|
XML Java Android开发
Unity与 SO 交互 ☀️| 详细讲解 怎样通过 Android Studio 生成一个.so文件 并简单调用!
📢前言 🎬SO文件生成 🍺通过Android Studio生成.so文件 🏳️‍🌈第一步:下载配置好NDK 🏳️‍🌈第二步:新建一个AS工程,新建一个JniTest.java文件 🏳️‍🌈第三步:选中JniTest.java文件,进行Make Project 🏳️‍🌈第四步:新建一个jni文件夹,生成.h头文件 🏳️‍🌈第五步:新建 一个c/c++source file文件test.c 和 Android.mk、Application.mk文件 🏳️‍🌈第六步:关联下载好的NDK包 🏳️‍🌈第七步:简单在AS端调用一下 💬总结
Unity与 SO 交互 ☀️| 详细讲解 怎样通过 Android Studio 生成一个.so文件 并简单调用!