逆向练习及相关总结

news2025/1/10 17:00:29

文章目录

  • crakeme练习
    • crackme1
    • crackme2
    • crackme3
  • 解题步骤
  • 总结
    • 关键代码查找方法
    • 常见代码
    • C++类对象逆向分析
    • C++虚函数逆向分析

crakeme练习

crackme1

学到的知识点:

  1. main函数查找方法:运行到EntryPoint -> 第一个call(一般在第三行) -> 第二个call(一般在第四行) -> 向下翻,找push,add,mov的三个连续call位置,选中间的call -> 找一群int3的位置上面的call。此时就进入了主函数。
  2. VS防止栈内存溢出的安全机制代码(一般放在函数开头):
push ebp
mov ebp,esp
sub esp,1C
mov eax,dword ptr ds:[448004]
xor eax,ebp
mov dword ptr ss:[ebp-4],eax
  1. [ebp-xxx]:一般表示局部变量;[ebp+xxx]:一般表示函数参数

第一个参数:[ebp+0x8]
第二个参数:[ebp+0xC]

  1. add esp, xxx:一般在call函数调用完之后,用于堆栈平衡,xxx一般为【参数所占字节数】,可以根据xxx的大小判断函数传入的参数的个数

注意:xxx要用16进制

crackme2

学到的知识点:

  1. 可以根据程序运行的情况(关键API)来下断点,然后返回到上层调用,从而找到关键代码。

例如:bp MessageBoxA;或者在od上按ctrl+G

crackme3

思路:

  1. 按照常用思路找到主函数
  2. 发现第一个关键函数:
    在这里插入图片描述经过分析发现该函数是用来判断输入的字符串是否是在’0’和’9’之间的字符
  3. 经过第一个关键函数,如果输入了0-9之外的字符,那么eax就会被设置为0,从而直接跳转到失败。如果输入的都是0-9之间的字符串,那么eax就会被设置为1,继续执行下面的代码。
  4. 发现第二个关键函数:
    在这里插入图片描述 进入查看这个函数的具体内容,发现以下代码段:
    在这里插入图片描述
    经过分析发现这段代码是将输入的字符当作数字依次与5异或,得出的结果为"16716724"。
  5. 这样就明确了思路,需要输入一段数字,使得每个数字与5异或之后,要和"16716724"这段数字对应相等:
    写出如下python脚本:
xor_string = '16716724'
xor_num = 5
int_list = [int(i) for i in xor_string]
result_str = ''
for num in int_list:
   result_str += str(num ^ xor_num)
print(result_str)
  1. 得到payload=43243271

解题步骤

  1. 运行程序,观察程序功能
  2. 明确目标
  3. 找到关键代码的位置:
    • 根据字符串查找
    • 根据程序运行时的特征,比如程序运行时弹出了一个MessageBoxA窗口,那么就可以在所有的MessageBoxA位置下断点:bp MessageBoxA。然后返回到上层调用,从而找到关键代码。

总结

关键代码查找方法

  • main函数查找方法:运行到EntryPoint -> 第一个call(一般在第三行) -> 第二个call(一般在第四行) -> 向下翻,找push,add,mov的三个call位置,选中间的call -> 找一群int3的位置上面的call。此时就进入了主函数。
  • 可以根据程序运行的情况(关键API)来下断点,然后返回到上层调用,从而找到关键代码。

例如:bp MessageBoxA;或者在od上按ctrl+G

常见代码

  • VS防止栈内存溢出的安全机制代码(一般放在函数开头):
push ebp
mov ebp,esp
sub esp,1C
mov eax,dword ptr ds:[448004]
xor eax,ebp
mov dword ptr ss:[ebp-4],eax
  • [ebp-xxx]:一般表示局部变量;[ebp+xxx]:一般表示函数参数

第一个参数:[ebp+0x8]
第二个参数:[ebp+0xC]

  • add esp, xxx:一般在call函数调用完之后,用于堆栈平衡,xxx一般为【参数所占字节数】,可以根据xxx的大小判断函数传入的参数的个数

注意:xxx要用16进制

C++类对象逆向分析

#include<stdio.h>
class Base {
public:
	Base() {
		printf("Base::Base()\n");
	}
};

class Child : public Base {
public:
	Child() {
		printf("Child::Child()\n");
	}
};

int main() {
	Child child;
	return 0;
}

  • this指针的构造
    在这里插入图片描述
    在这里插入图片描述
  1. 首先定义child,然后将child对象的地址放到ecx中
  2. 然后进入Child类中,将ecx的内容放到this指针中
  • 子类中调用父类构造函数的方法
    在这里插入图片描述

子类会在自己的构造函数内部添加一段call父类构造函数的代码,添加该代码的位置为子类构造函数中的所有命令前

#include<stdio.h>
class Base {
public:
	~Base() {
		printf("Base::~Base()\n");
	}
};

class Child : public Base {
public:
	~Child() {
		printf("Child::~Child()\n");
	}
};

int main() {
	Child child;
	return 0;
}
  • 子类中调用父类析构函数的方法
    在这里插入图片描述

子类会在自己的析构函数内部添加一段call父类析构函数的代码,添加该代码的位置为子类析构函数中的所有命令后

  • 当编译器认为构造函数是不必要(没有执行指令)的时候,它是不会创建构造函数的
#include<stdio.h>
class CObj {
private:
	int a = 1;
	int b = 2;
public:
	void set(int n1, int n2) {
		a = n1;
		b = n2;
		printf("set(int a, int b)\n");
	}
};

int main() {
	CObj obj;
	obj.set(20, 30);
	return 0;
}
  • 类中成员变量及其赋值方法
    在这里插入图片描述
  1. 首先将obj的地址通过ecx赋值给this指针([this]),然后在传给eax
  2. 然后把1赋值给[eax],即源代码中的int a=1
  3. 再把2赋值给[eax+4],即源代码中的int b=2
  • 调用成员函数修改成员变量
    在这里插入图片描述
    在这里插入图片描述
  1. 将参数传入
  2. 执行成员函数,首先将[this](对象的地址)赋值给eax
  3. 再将参数n1赋值给ecx
  4. 然后将ecx放到[eax]中,即对象的内存中
  5. b = n2同理

总结:

  • 构造函数调用过程:先调用子类构造函数,进入子类构造函数内部,先去调用父类的构造函数,之后再去执行自己的代码
  • 析构函数调用过程,先调用子类析构函数,进入子类析构函数内部,先去执行自己的代码,之后再去调用父类的析构函数
  • 函数成员变量的访问:都是通过this指针+偏移的形式去访问。调用成员函数的时候,编译器会默认传this指针,放到我们的ecx寄存器。

C++虚函数逆向分析

#include <stdio.h>
#include <Windows.h>

class CObj
{
public:
	int a = 1;
	virtual void show()
	{
		printf("虚函数show\n");
	}
	void fun1() {
		printf("成员函数fun1\n");
	}
};

void show2()
{
	printf("外部函数show2\n");
}


int main() {
	CObj obj;
	CObj* pObj = &obj;
	pObj->show();
	return 0;
}

虚函数会在对象的首地址(低地址)存放一个虚函数表指针(虚函数表用于存放所有的虚函数地址),该指针存放的是虚函数表的首地址。

  • 执行虚函数的过程
    在这里插入图片描述
  1. 将[pObj]的值(即Obj对象的地址)存放到eax中
  2. 去除Obj对象的前四个字节放到edx中,即将虚函数表指针放到edx中
  3. 将[edx]的值(虚函数表的前四个字节,即第一个虚函数的地址)存放到eax中
  4. call eax,即调用虚函数
  • 根据虚函数调用的原理,将外部函数show2来替换虚函数show,即要使得pObj->show()调用show2函数。修改代码如下:
#include <stdio.h>
#include <Windows.h>

class CObj
{
public:
	int a = 1;
	virtual void show()
	{
		printf("虚函数show\n");
	}
	void fun1() {
		printf("成员函数fun1\n");
	}
};

void show2()
{
	printf("外部函数show2\n");
}



int main()
{
	DWORD OldProtect = 0;
	LPVOID Addr = 0;
	CObj obj;
	CObj* pObj = &obj;

	// 获取虚函数表
	__asm
	{
		mov eax, dword ptr[pObj]; //取对象首地址
		mov eax, [eax]; //取虚函数表指针,放到eax中
		mov Addr, eax; // Addr存放虚函数表指针
		push eax; //保存eax,防止VirtualProtect改变eax
	}

	if (Addr) VirtualProtect(Addr, 0x4, PAGE_READWRITE, &OldProtect);// 修改[eax]的读写权限,使得[eax]的内容可以更改

	__asm
	{
		pop eax
		mov edx, show2;		//将show2函数的地址存放到edx中
		mov [eax], edx; //将show2函数地址替换虚函数表中的第一个虚函数(即show函数)
	}

	if (Addr) VirtualProtect(Addr, 0x4, OldProtect, &OldProtect); // 将读写权限修改回来

	pObj->show();

	return 0;
}

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

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

相关文章

如何用u盘重装系统win7

​如今的U盘重装win7系统是比较常见的重装win7系统的方法&#xff0c;适用性比较高&#xff0c;操作也十分的简单。有的小伙伴想给自己的电脑重装win7&#xff0c;那么我们用u盘重装系统怎么安装win7?现在小编就来教大家如何用u盘重装系统教程。 工具/原料&#xff1a; 系统…

CTR预估之FMs系列模型:FM/FFM/FwFM/FEFM

前言 ctr预估&#xff08;点击率&#xff0c;click-through rate, CTR&#xff09;&#xff0c;指一个user在某个特定的场景下会点击一个item的概率估计&#xff0c;这里的item可以是广告、商品等&#xff0c;是推荐和广告系统中十分重要的模块。另外&#xff0c;这里的user-i…

《程序员面试金典(第6版)》面试题 16.18. 模式匹配(暴力破解 + 剪枝)

题目描述 你有两个字符串&#xff0c;即pattern和value。 pattern字符串由字母"a"和"b"组成&#xff0c;用于描述字符串中的模式。 例如&#xff0c;字符串"catcatgocatgo"匹配模式"aabab"&#xff08;其中"cat"是"a&q…

Redis基础复习

1 Redis基础概述 Redis 是C语言开发的一个开源高性能键值对的内存数据库&#xff0c;可以用来做数据库、缓存、消息中间件等场景&#xff0c;是一种NoSQL(not-only sql,非关系型数据库)的数据库 1.1 参考网站&#xff1a; 官网 中文文档 1.2 安装 linux安装Redis7 1.3 Re…

全新上线!能源行业大型的S/4升级项目——E.ON(意昂)第五次迁移成功完成

意昂集团是一家德国能源集团的控股公司&#xff0c;总部位于埃森。该公司主要活跃在能源网络、能源服务、可再生能源以及德国核电站的运营和退役领域。 意昂于2019年启动了全公司范围内的S/4联合项目&#xff0c;这是SAP大型S/4项目之一&#xff0c;也是能源行业的大型S/4项目。…

linux下mysql如何修改密码,包括本地密码和远程密码。navicat远程登录

当服务器部署mysql,navicat远程访问&#xff0c;修改密码时需要修改两次 1、修改本地登录密码 mysql > SET PASSWORD PASSWORD(123456); mysql > FLUSH PRIVILEGES;重启mysql服务 service mysql restart上面命令如果报错&#xff0c;则采取以下方法&#xff1a; [ro…

SpringBoot基础篇2(整合第三方技术)

一、SpringBoot整合Junit 直接配置的module&#xff0c;默认就可以测试。 SpringBoot整合第三方技术&#xff1a; 1.pom.xml中引入对应的starter&#xff08;有勾选的勾选&#xff0c;没有勾选的选项手动导入。在这里查 查依赖的网站&#xff09; 2.配置相关信息 二、SpringB…

vue diff算法与虚拟dom知识整理(6) 感受diff算法 (不要神话虚拟dom更不要做完美主义)

我们还是打开之前的案例 然后 将src下的index.js代码修改如下 import {init,classModule,propsModule,styleModule,eventListenersModule,h,} from "snabbdom";//创建patch函数const patch init([classModule,propsModule,styleModule,eventListenersModule]);//创…

tcp 三次握手和四次挥手报文分析

1&#xff0c;tcp 三次握手 报文抓取如下&#xff1a; 三段报文分析&#xff1a; 第一次&#xff1a;26->96报文交互 Seq-num 567391014, ACK_NUM 0; flags SYN 第二次&#xff1a;96->26报文交互 Seq-num 416352681, ACK_NUM Seq-num 1 567391014 1 567391015,…

硬件系统工程师宝典(22)-----电容、电感的特性,你都知道吗?

各位同学大家好&#xff0c;欢迎继续做客电子工程学习圈&#xff0c;今天我们继续来讲这本书&#xff0c;硬件系统工程师宝典。上篇我们说到做电阻选型时要考虑阻值、功率、精度和封装大小。上下拉电阻除了给引脚一个稳定的电平&#xff0c;可以提高电压准位、增加输出功率以及…

法律 法规

第八章、法律 法规 从所涉及的法律法规角度 1️⃣著作权法 2️⃣计算机软件保护条例 3️⃣商标法 4️⃣专利法 从试题考点分布的角度 1️⃣保护期限 2️⃣知识产权人确定 3️⃣侵权判断 中国公民、法人或者其他组织的作品&#xff0c;不论是否发表&#xff0c;都享有著作…

Linux服务安装node,npm与yarn

目录 Linux服务安装node&#xff0c;npm与yarn 可以直接在win或者Linux安装node官网&#xff08;中文版&#xff09;下载所需要的版本 通过epel 的来安装 node 安装npm 利用npm安装yarn 卸载yarn 安装依赖 运行 本篇文章仅是本人遇到的问题&#xff0c;希望可以对你有帮…

基于海鸥算法优化的核极限学习机(KELM)分类算法-附代码

基于海鸥算法优化的核极限学习机(KELM)分类算法 文章目录 基于海鸥算法优化的核极限学习机(KELM)分类算法1.KELM理论基础2.分类问题3.基于海鸥算法优化的KELM4.测试结果5.Matlab代码 摘要&#xff1a;本文利用海鸥算法对核极限学习机(KELM)进行优化&#xff0c;并用于分类 1.KE…

Go基础知识入门

1、go语言介绍 2、go开发环境搭建 2.1、go的安装 go下载地址&#xff1a;All releases - The Go Programming Language&#xff0c;windows选择下载go1.20.2.windows-amd64.msi文件。 双击go1.20.2.windows-amd64.msi&#xff0c;点击"Next"&#xff0c;然后勾选同…

Linux——进程信号1

信号和信号量是俩个东西&#xff0c;俩者无关系。 信号 信号本质是一种通知机制&#xff0c;用户or操作系统通过发送一定的信号&#xff0c;通知进程&#xff0c;某些事件已经发送&#xff0c;让进程进行后续处理。 结合进程&#xff0c;信号结论&#xff1a; 进程要处理信号&a…

【Windows线程开发】线程基础

本篇文章来带领大家了解Windows线程&#xff0c;了解线程的基本概念&#xff0c;了解线程的创建方式&#xff0c;以及一些简单的线程操作。 文章目录 一.线程基本概念二.创建线程三.线程实例&#xff08;单线程&#xff0c;多线程&#xff09;单线程执行多线程执行 四.挂起&am…

ElasticSeach 集成 springboot

声明是ElasticSearch? ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c; 基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是 当前流行的企业级搜索引擎…

大数据 | (五)通过Sqoop实现从MySQL导入数据到HDFS

知识目录 一、前言二、导入前的准备2.1 Hadoop集群搭建2.2 Hadoop启停脚本 三、docker安装MySQL四、安装Sqoop4.1 Sqoop准备4.2 Sqoop连接Mysql数据测试 五、导入MySQL数据到hdfs5.1 准备MySQL数据5.2 导入数据 六、Sqoop现状七、结语 一、前言 各位CSDN的朋友们大家好&#x…

5.11组会衍生总结:train/eval/BN、CNN与特征图、极大似然与EM、方差n与n-1(有偏估计/无偏估计)

目录组会问题:1.关于模型的train/eval与batchnorm1-1.理论1-2.实际运用(包含loss反向传播)2.CNN详解,特征图是什么CNN处理过程特征图(也叫通道)(num_features)总结(包含CNN图片的规律分析):3.极大似然估计与EM最大期望4.方差的n与n-1(有偏估计与无偏估计) 组会问题:…

企业文化和品牌文化是两回事

商业通常谈两类文化&#xff1a;企业文化&#xff0c;品牌文化 1&#xff09;组织内部的文化 2&#xff09;品牌以产品为依托&#xff0c;给消费群体营造的文化 “积极稳定”的文化氛围打造是个慢活 企业文化&#xff0c;既要挂在墙上&#xff0c;又要挂在嘴上&#xff0c;最终…