深入理解Os--调用劫持

news2024/11/18 13:58:01

1.调用劫持
以Linux系统为例,介绍三种可实现调用劫持的技术。

1.1.编译时调用劫持
以一个实例展开介绍
在这里插入图片描述
(1).main.cpp

#include <stdio.h>
#include <malloc.h>
int main()
{
	int* p = (int*)malloc(32);
	free(p);
	return (0);
}

(2).mymalloc.cpp

#include <stdio.h>
#include <malloc.h>
void* mymalloc(size_t nS)
{
    printf("mymalloc\n");
    return malloc(nS);
}

void myfree(void* p)
{
    printf("myfree\n");
    free(p);
}

(3).malloc.h

#pragma once
#define malloc(nS) mymalloc(nS)
#define free(ptr) myfree(ptr)
void* mymalloc(size_t);
void myfree(void*);

(4).makefile

t2 : t1
	g++ -std=c++11 -I. main.cpp mymalloc.o

t1 :
	g++ -std=c++11 mymalloc.cpp -c

clean :
	rm *.o *.out

这样我们编译得到mymalloc.o过程中,mymalloc.cpp的头文件malloc.h将在默认搜索路径中搜索。这样搜索得到的malloc,free将是 c 库中定义的符号。

我们编译main.cpp为main.o过程中由于指定了-I.,所以,会优先在当前目录下搜索main.cpp中的头文件,这样将采用我们自定义的malloc.h,这样main.cpp中对malloc,free的引用将由于宏替换变为引用mymalloc,myfree。这样在基于main.o,mymalloc.o链接得到可执行程序a.out的过程中,main.o中对mymalloc,myfree的引用将关联到mymalloc.o中的定义。mymalloc.o中对malloc,free的引用将关联到c库中的符号定义。进而达到了调用劫持效果。

这里为了达到引用劫持,我们需要干预main.cpp的编译过程。

1.2.链接时劫持
以一个实例展开介绍
在这里插入图片描述
(1). main.cpp

#include <stdio.h>
#include <malloc.h>

int main()
{
    int *p = (int*)malloc(32);
    free(p);
    return 0;
}

(2). mymalloc.cpp

#include <stdio.h>
extern "C" void *__real_malloc(size_t size);
extern "C" void __real_free(void *ptr);
extern "C" void *__wrap_malloc(size_t size)
{
    void *ptr = __real_malloc(size);
    printf("malloc(%d)=%p\n", (int)size, ptr);
    return ptr;
}

extern "C" void __wrap_free(void *ptr)
{
    __real_free(ptr);
    printf("free(%p)\n", ptr);
}

(3). makefile

t : t1 t2
	g++ -std=c++11 -Wl,--wrap,malloc -Wl,--wrap,free main.o mymalloc.o
t1 :
	g++ -std=c++11 mymalloc.cpp -c
t2 :
	g++ -std=c++11 main.cpp -c

我们编译得到mymalloc.o的过程中,按常规方式编译即可。注意,这里对引用的符号__real_malloc__real_free和定义的符号__wrap_malloc__wrap_free均加了extern "C"修饰,这是为了使得通过c++编译器编译时,放置符号名被编译器重新命名。

我们编译得到main.o的过程中,按常规方式编译即可。

我们之所以可以劫持main.cpp中对malloc,free的调用,是因为通过main.o,mymalloc.o链接得到可执行程序过程中我们使用了-Wl,--wrap,malloc-Wl,--wrap,free编译选项。

-Wl,--wrap,malloc可以达到的效果是,将所有引用malloc的地方替换为对__wrap_malloc的引用。将所有引用__real_malloc的地方替换为对malloc的引用。
-Wl,--wrap,free可以达到的效果是,将所有引用free的地方替换为对__wrap_free的引用。将所有引用__real_free的地方替换为对free的引用。

这样通过上述引用替换后,重定位阶段main.o中将分别重定位到对mymalloc.o中定义符号的引用。mymalloc.o中将分别重定位到对 C 库中定义符号的引用。

这里为了达到引用劫持,我们需要干预得到可执行程序的链接过程。

1.3.运行时劫持
以一个实例展开介绍
在这里插入图片描述
(1). main.cp

#include <stdio.h>
#include <malloc.h>

int main()
{
    int *p = (int*)malloc(32);
    free(p);
    return 0;
}

(2).mymalloc.cpp

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

typedef void *(*Mallocp)(size_t size);
typedef void (*Freep)(void*);
void* malloc(size_t size)
{
    Mallocp mallocp;
    char *error;
    mallocp = (Mallocp)dlsym(RTLD_NEXT, "malloc");
    if((error = dlerror()) != NULL)
    {
        fputs(error, stderr);
        exit(1);
    }

    char *ptr = (char*)mallocp(size);
    printf("malloc(%d) = %p\n", (int)size, ptr);
    return ptr;
}

void free(void *ptr)
{
    Freep freep;
    char *error;
    if(!ptr)
        return;
    freep = (Freep)dlsym(RTLD_NEXT, "free");
    if((error = dlerror()) != NULL)
    {
        fputs(error, stderr);
        exit(1);
    }

    freep(ptr);
    printf("free(%p)\n", ptr);
}

(3).makefile

t : t1
	g++ -std=c++11 main.cpp
t1 :
	g++ -shared -fpic -o mymalloc.so mymalloc.cpp -ldl

上述过程,我们维持可执行程序编译链接的过程。
我们通过一个额外的动态库,这个动态库里面对我们想劫持的调用提供了新的定义。
(4).s.sh

export LD_PRELOAD="./mymalloc.so" 
./a.out

我们通过在启动可执行进程前,设置LD_PRELOAD,使得,可执行程序执行前首先加载LD_PRELOAD中指定的动态库。
这样,后续可执行程序加载运行时,需要执行对动态链接符号的重定位时,将优先搜索LD_PRELOAD中的库是否提供了符号定义,若提供,则采用库中定义的版本。这样,main.cpp中对malloc,free的引用会被重定位到我们提供的动态库中的版本。
我们动态库中想使用c库中定义的malloc,free时,采用dlsym的方式。通过参数 1 指定RTLD_NEXT来使得跳过LD_PRELOAD库中的定义,继续向后寻找符号定义,最终将其关联到 c 库中的符号定义。

这里为了达到引用劫持,无需干预可执行程序的编译链接过程。只需在启动脚本设置LD_PRELOAD并提供实现了想劫持调用的动态库即可。具有最大的灵活性,最易于实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1298647.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

30、卷积 - 参数 stride 的作用

在卷积运算中,还有一个参数叫做 stride,它对卷积的运算以及运算结果影响也很大。 还是先看卷积动图,从图上你能猜到 stride 参数在哪吗? 在卷积操作中,stride 指的是卷积核在滑动过程中每次跳过的像素数量。 stride 决定了卷积核在输入图像上移动的速度。例如,如果 str…

【Angular 开发】Angular 信号的应用状态管理

自我介绍 做一个简单介绍&#xff0c;年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【架构…

STM32基于USB串口通信应用开发

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

使用selenium的edge浏览器登录某为

互联网上基本都是某哥的用法&#xff0c;其实edge和某哥的用法是一样的就有一下参数不一样。 一、运行环境 Python&#xff1a;3.7 Selenium&#xff1a;4.11.2 Edge&#xff1a;版本 120.0.2210.61 (正式版本) (64 位) 二、执行代码 from time import sleepfrom selenium…

Course2-Week4-决策树

Course2-Week4-决策树 文章目录 Course2-Week4-决策树1. 决策树的直观理解2. 构建单个决策树2.1 熵和信息增益2.2 构建决策树——二元输入特征2.3 构建决策树——多元输入特征2.4 构建决策树——连续的输入特征2.5 构建回归树——连续的输出结果(选修)2.6 代码实现-递归构建单个…

基于K-means与CNN的遥感影像分类方法

基于K-means与CNN的遥感影像分类 一、引言 1.研究背景 航天遥感技术是一种通过卫星对地观测获取遥感图像信息数据的技术&#xff0c;这些图像数据在各领域都发挥着不可或缺的作用。遥感图像分类主要是根据地面物体电磁波辐射在遥感图像上的特征&#xff0c;判断识别地面物体的属…

BUUCTF pwn rip WriteUp

文件分析 下载附件&#xff0c;分析文件 可以看到是64位ELF文件&#xff0c;elf可以理解为Linux中的可执行文件&#xff0c;就像Windows中的exe文件 用ida打开文件 查看main函数的伪代码&#xff0c;可以看到有一个15位的字符数组&#xff0c;该数组通过gets函数传值 还有一…

Jupyter notebook修改背景主题

打开Anaconda Prompt&#xff0c;输入以下内容 1. pip install --upgrade jupyterthemes 下载对应背景主题包 出现Successfully installed jupyterthemes-0.20.0 lesscpy-0.15.1时&#xff0c;说明已经下载安装完成 2. jt -l 查看背景主题列表 3. jt -t 主题名称&#xff08;…

AI:92-基于深度学习的红外图像人体检测

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的核心代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新…

SQL命令---修改字段的数据类型

介绍 使用sql语句修改字段的数据类型。 命令 alter table 表明 modify 字段名 数据类型;例子 有一张a表&#xff0c;表里有一个id字段&#xff0c;长度为11。使用命令将长度修改为12 下面使用命令进行修改&#xff1a; alter table a modify id int(12) NOT NULL;下面使修…

【Dubbo3云原生微服务开发实战】「Dubbo前奏导学」 RPC服务的底层原理和实现

RPC服务 RPC服务介绍RPC通信模式RPC架构组成RPC技术要点RPC通信技术选项分析RPC实战开发6大基础组件基础组件之Guava基础组件之Hutools基础组件之ReflectionASM基础组件之FastJSON/FastJSON2基础组件之FST相比FastJSON的优势 基础组件之Commons-Codec RPC框架层面选项分析RPC组…

STM32-TIM定时器中断

目录 一、TIM&#xff08;Timer&#xff09;定时器简介 二、定时器类型 2.1基本定时器结构 2.2通用定时器结构 2.3高级定时器结构 三、定时中断基本结构 四、时序图分析 4.1 预分频器时序 4.2 计数器时序 4.3 计数器无预装时序&#xff08;无影子寄存器&#xff09; …

LVGL_V8.3入门二---实时时钟(模仿华为watch-UI)

系列文章目录 文章目录 系列文章目录前言一、实现效果二、代码解析 前言 在这个博客中&#xff0c;我们将深入探讨LVGL&#xff08;Light and Versatile Graphics Library&#xff09;版本8.3的实时时钟应用&#xff0c;以模仿华为 Watch UI 为例。LVGL是一款专为嵌入式系统和…

Jenkins简单介绍

学习目标 知道jenkins应用场景能够安装部署jenkins服务器能够实现gitgithubjenkins手动构建能够实现gitgitlabjenkins自动发布系统 认识jenkins Jenkins是一个可扩展的持续集成引擎&#xff0c;是一个开源软件项目&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软…

Kafka集成springboot

安装kafka&#xff0c;直接到官网下载bin文件&#xff0c;本文使用windows进行使用kafka。 下载之后&#xff0c;第一步&#xff0c;启动zookeeper&#xff1a; zookeeper-server-start.bat ..\..\config\zookeeper.properties 第二步&#xff0c;启动kafka&#xff1a; kafka…

oops-framework框架 之 多语言设置文本、精灵和骨骼动画

引擎&#xff1a; CocosCreator 3.8.0 环境&#xff1a; Mac Gitee: oops-plugin-excel-to-json 注&#xff1a; 作者dgflash的oops-framework框架QQ群&#xff1a; 628575875 简介 作者dgflash在oops-framework的框架中提供了多语言&#xff0c;主要用于对文本、图片、骨骼动…

Verilog基础:寄存器输出的两种风格

相关文章 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 Verilog中的寄存器操作一般指的是那些对时钟沿敏感而且使用非阻塞赋值的操作。例如状态机中的状态转移&#xff0c;实际上就是一种寄存器操作&#xff0c;因为这相…

【docker 】centOS 安装docker

官网 docker官网 github源码 卸载旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 安装软件包 yum install -y yum-utils \device-mapper-persistent-data…

自下而上-存储全栈(TiDB/RockDB/SPDK/fuse/ceph/NVMe/ext4)存储技术专家成长路线

数字化时代的到来带来了大规模数据的产生&#xff0c;各行各业都面临着数据爆炸的挑战。 随着云计算、物联网、人工智能等新兴技术的发展&#xff0c;对存储技术的需求也越来越多样化。不同应用场景对存储的容量、性能、可靠性和成本等方面都有不同的要求。具备存储技术知识和技…

基于 Gin 的 HTTP 中间人代理 Demo

前面实现的代理对于 HTTPS 流量是进行盲转的&#xff0c;也就是说直接在 TCP 连接上传输 TLS 流量&#xff0c;但是我们无法查看或者修改它的内容。当然了&#xff0c;通常来说这也是不必要的。不过对于某些场景下还是有必要的&#xff0c;例如使用 Fiddler 进行抓包或者监控其…