《加密与解密》个人阅读笔记 四(下)

前言

首先免责声明:本篇博客并没有摘抄书中所有的知识点,要全面地学习还是要看书:)
废话少说,开始学习吧
在这里插入图片描述

x64程序逆向技术

32位程序和64位程序有什么区别呢:Windows上的64位和32位的区别是什么?

x86名称是怎么来的?因为因特尔公司有一个系列的cpu名称都以86结尾,而它们都是32位的,随着时间的推移,慢慢地大家就使用x86的说法指代32位cpu了

x64应用程序的调用规定

上篇文章介绍了在x86架构下的一些函数调用规定,如stdcall,_cdelcl等等。但是在x64架构中只有一种调用规定:前四个参数放在固定的寄存器中,剩下的参数从右往左入栈,由函数调用者平衡栈。(pwn中也有用到)
虽然前四个参数放在寄存器中,但是编译器依旧为这些参数预留了栈空间(4*8=32字节)。如果函数的参数比较多,寄存器的数量不够,可以使用预留的栈空间。

参数传递规则如下

参数类型浮点类型
第一个参数RCXXMM0
第二个参数RDXXMM1
第三个参数R8XMM2
第四个参数R9XMM3

XMM寄存器是啥?深入解析计算机系统中的XMM寄存器

参数传递(具体汇编代码看书)

  • 当函数参数个数小于等于4时,编译器操作如下:
    1. rdi寄存器入栈,保存环境
    2. rsp(栈顶指针)会减少32字节,由于栈是从低地址到高地址增长的,所以栈会开辟32字节的空间。
    3. 接下来是函数传参:从右往左把对应的参数放入寄存器中
    4. 调用函数
    5. rsp增加32字节,用于平衡栈。(在函数外平衡)
    6. rdi寄存器恢复原值
  • 当函数参数个数大于4个时,其他步骤和上面的一致,编译器只改变第三步的做法:
    由于参数是从右往左入栈,当剩下的参数个数>4个时,当前的参数放入栈,当参数个数<=4时,参数放到寄存器中

放上代码

// 调用函数
Add(1,2,3,4,5,6);l

//对应汇编语言如下
000000014000107D mov ecx, [rsp+40h] ;
0000000140001081 mov dword ptr [rsp+28h], 6 ;参数6入栈
0000000140001089 mov dword ptr [rsp+20h],5 ;参数5人栈
0000000140001091 mov r9d, 4 ;参数4 
0000000140001097 mov r8d, 3 ;参数3 
000000014000109D mov edx, 2 ;参数2 
00000001400010A2 mov ecx, 1 ;参数1 
00000001400010A7 call sub_140001005 ;调用Add函数

控制语句和循环语句

在程序中,控制语句一般会涉及到程序的核心功能,比如验证序列号等等,所以识别各种控制语句的特点就十分重要了。(借用书中的例子,介绍if , while, do while , switch等等语句的特征)

if语句

if语句的语法如下

if(expression)
{
	if_code;
}  // if_end

运行规则:

  • 计算expression的值,如果为true就执行if_code,如果为false就跳转到if_end

因此,if语句可以简化为一个向下的,有条件的跳转。如果用图像表示法,有条件的跳转(jxx)用虚线表示,无条件的跳转(jmp)用实线表示。
在这里插入图片描述

if-else语句

if-else语句语法如下

if(expresion){
	if_code;
}else {
	else_code;
} // if_end

运行规则

  • 计算expression的值,如果为true就执行if_code,忽略else _code,如果为false就执行else_code,忽略if_code

需要两个跳转语句来实现if-else语句:当if_code语句执行完毕后,需要无条件跳转到if_end。当expresionfalse时,需要直接跳转到else_code,这是个有条件跳转

特征如下图(借用书中的图片)
在这里插入图片描述

switch语句

switch语句的语法如下

switch(expression):
	case constant_expression1:
		code1;
	case constant_expression2:
		code2;
	default:
		code3;

需要注意break会影响程序流

接下来是编译器怎么实现switch的,这部分内容我没有验证过。。摘抄一下书里的内容

  • 当case的个数<=6个时,编译器会使用if-else来实现switch语句
  • 当case的个数较多时,编译器会使用if语句实现switch语句
    为了减少if条件的判断次数,编译器使用判断树来实现

判断树是一棵平衡二叉排序树,关于平衡二叉排序树的介绍,可以看这一篇博客:平衡二叉排序树


do-while循环

do-while循环的语法如下

do
{
	code;
}while(expression) 
//do_while_end

运行规则:

  1. 执行code处的代码
  2. 如果expression的值为true,程序执行步骤1,否则跳转到do_while_end

由于do-while循环的code一定会执行至少一次,所以不需要额外的有条件向下跳转,只需要一个向上跳转循环执行代码

特征如下图:
在这里插入图片描述

while循环

while循环语法如下

while(expression) // while_begin
{
	code;
}// while_end

运算规则

  1. 计算expression的值
  2. 如果为真就执行code处的代码,并且回到步骤1,如果为假就跳转到while_ends

实现这个循环需要两个跳转语句:第一个有条件跳转需要在expressionfalse时跳转到while_end处,第二个无条件跳转需要在code执行结束后跳转到while_begin处,判断要不要开始下一次循环

特征如下
在这里插入图片描述

for循环

for循环语法如下

for ( init; condition; increment )
{
   code;
} // for_end

由于for循环有点复杂,这里先把特征图放出来,再介绍for循环的流程
在这里插入图片描述
运算规则

  1. 进入for循环前,先计算init的值,也就是初始化步长
  2. 接下来程序跳转到code处的代码前面(对应图中for_if向下跳转
  3. 判断condition的值,如果结果为true,执行code语句,执行结束后调用increment更新步长(对应图中的for_step向上跳转,然后运行步长代码)。如果结果为false,执行jxx向下跳转,循环结束

休息一下:)
在这里插入图片描述
休息结束:)


一些个人觉得不用解释原理的知识点:

  • 使用汇编语句访问数组有两种写法
    1. [数组首元素地址+n]
    2. [数组首元素地址+n*寄存器]

关于虚函数的部分,看不懂。。。而且目前我也没有遇到过(可能遇到了但没有认出来),先跳过吧
本文结束

后记

接下来的内容与本文无关,都是一些废话:<
感觉这次的文章好水。。主要是跳过了关于虚函数的内容。。而c语言的循环和选择语句又比较简单。。

照例的meme时间

打ctf比赛被零封时,我的心路历程be like
在这里插入图片描述
阅读题目->信心满满->发现不对劲->vocal一道题都不会->遗憾离场:(

看大佬wp时,心情be like↓
请添加图片描述


扯一下最近的学习情况

  • 在复现2023i春秋冬季赛的re题目,学到好多新的东西,但是有好多内容是我现在看不懂的。。。
    顺便膜拜一下官方wp的exp,真的很优雅
    def xor_encrypt(input_file_path, output_file_path, key):
    try:
        with open(input_file_path, 'rb') as input_file:
            content = input_file.read()
            encrypted_content = bytes([byte ^ key for byte in content])

            with open(output_file_path, 'wb') as output_file:
                output_file.write(encrypted_content)
    except Exception as e:
        print(str(e))
        
input_file_path = 'DATA101.bin'
output_file_path = 'DATA101_out.bin'
encryption_key = 0x33  

xor_encrypt(input_file_path, output_file_path, encryption_key)
  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值