这次找小伙伴要了他的一个CM,怎么说呢,这CM让我学到了不少,其实搞出来后感觉不难,就是有不少FPU浮点相关的指令和FPU寄存器完全没学过,查了不少资料,学到了很多

打开是这样

无壳程序,我们直接od查找字符串,爆破我就不说了,直接改跳转

我第一次是找到这个判断的函数开头,一行行快速单步,确实发现了输入,但是后来很多命令不懂意思我也单步,导致看到后来也不知道怎么判断的

然后我改了策略,先逆着就近看看,怎么才能使条件成立

004010EA  |.  F6C4 41       test ah,0x41                             ;  zf=0 -> ah & 0x41 != 0
004010ED |. B8 00000000 mov eax,0x0
004010F2 |. 0f95c0 setne al ; eax=1 -> al=1 -> zf=0
004010F5 |. 8945 D0 mov [local.12],eax
004010F8 |. 837D D0 01 cmp [local.12],0x1
004010FC |. 0F85 39000000 jnz 测试.0040113B ; 要求zf=1,即eax=0x1
00401102 |. BB 06000000 mov ebx,0x6
00401107 |. E8 F8FEFFFF call 测试.00401004
0040110C |. 68 01030080 push 0x80000301
00401111 |. 6A 00 push 0x0
00401113 |. 68 00000000 push 0x0
00401118 |. 68 04000080 push 0x80000004
0040111D |. 6A 00 push 0x0
0040111F |. 68 6D1B4800 push 测试.00481B6D ; 成功
00401124 |. 68 04000000 push 0x4
00401129 |. BB 90164000 mov ebx,测试.00401690
0040112E |. E8 36010000 call 测试.00401269
00401133 |. 83C4 34 add esp,0x34
00401136 |. E9 34000000 jmp 测试.0040116F
0040113B |> BB 06000000 mov ebx,0x6
00401140 |. E8 BFFEFFFF call 测试.00401004
00401145 |. 68 01030080 push 0x80000301
0040114A |. 6A 00 push 0x0
0040114C |. 68 00000000 push 0x0
00401151 |. 68 04000080 push 0x80000004
00401156 |. 6A 00 push 0x0
00401158 |. 68 721B4800 push 测试.00481B72 ; 失败
0040115D |. 68 04000000 push 0x4

也就是说需要找ah相关的

接下来我们整体看看,因为第一次接触FPU浮点相关的指令和FPU寄存器,所以注释写的比较繁琐,望大家见谅

0040100C  /.  55            push ebp
0040100D |. 8BEC mov ebp,esp
0040100F |. 81EC 34000000 sub esp,0x34
00401015 |. 6A FF push -0x1
00401017 |. 6A 08 push 0x8
00401019 |. 68 02000116 push 0x16010002
0040101E |. 68 01000152 push 0x52010001
00401023 |. E8 47020000 call 测试.0040126F ; 执行后 输入的密码 -> eax(1886b8)
00401028 |. 83C4 10 add esp,0x10
0040102B |. 8945 FC mov [local.1],eax ; eax中你的输入 -> ebp-4
0040102E |. 68 04000080 push 0x80000004
00401033 |. 6A 00 push 0x0
00401035 |. 8B45 FC mov eax,[local.1]
00401038 |. 85C0 test eax,eax
0040103A |. 75 05 jnz short 测试.00401041
0040103C |. B8 5C1B4800 mov eax,测试.00481B5C
00401041 |> 50 push eax
00401042 |. 68 01000000 push 0x1
00401047 |. BB A0134000 mov ebx,测试.004013A0
0040104C |. E8 18020000 call 测试.00401269 ; eax=16进制(你的输入) ecx=0
00401051 |. 83C4 10 add esp,0x10 ; esp = 1000b
00401054 |. 8945 F8 mov [local.2],eax ; 16进制(你的输入) -> local.2
00401057 |. 8B5D FC mov ebx,[local.1] ; 你的输入 -> ebx
0040105A |. 85DB test ebx,ebx
0040105C |. 74 09 je short 测试.00401067
0040105E |. 53 push ebx ; 输入压栈 ebp-38 local.14
0040105F |. E8 F9010000 call 测试.0040125D
00401064 |. 83C4 04 add esp,0x4 ; [ebp-38] + 4
00401067 |> DB45 F8 fild [local.2] ; 十进制浮点(输入) -> st0
0040106A |. DD5D F0 fstp qword ptr ss:[ebp-0x10] ; st0 -> ebp-10H
0040106D |. DD45 F0 fld qword ptr ss:[ebp-0x10] ; ebp-10 -> st0
00401070 |. DC05 5D1B4800 fadd qword ptr ds:[0x481B5D] ; st0 = st0 + 520
00401076 |. DD5D E8 fstp qword ptr ss:[ebp-0x18] ; 十进制你的输入+520 -> ebp-18H
00401079 |. 6A FF push -0x1
0040107B |. 6A 08 push 0x8
0040107D |. 68 03000116 push 0x16010003
00401082 |. 68 01000152 push 0x52010001
00401087 |. E8 E3010000 call 测试.0040126F
0040108C |. 83C4 10 add esp,0x10
0040108F |. 8945 E4 mov [local.7],eax
00401092 |. 68 04000080 push 0x80000004
00401097 |. 6A 00 push 0x0
00401099 |. 8B45 E4 mov eax,[local.7]
0040109C |. 85C0 test eax,eax
0040109E |. 75 05 jnz short 测试.004010A5
004010A0 |. B8 5C1B4800 mov eax,测试.00481B5C
004010A5 |> 50 push eax
004010A6 |. 68 01000000 push 0x1
004010AB |. BB A0134000 mov ebx,测试.004013A0
004010B0 |. E8 B4010000 call 测试.00401269
004010B5 |. 83C4 10 add esp,0x10
004010B8 |. 8945 E0 mov [local.8],eax
004010BB |. 8B5D E4 mov ebx,[local.7]
004010BE |. 85DB test ebx,ebx
004010C0 |. 74 09 je short 测试.004010CB
004010C2 |. 53 push ebx
004010C3 |. E8 95010000 call 测试.0040125D
004010C8 |. 83C4 04 add esp,0x4
004010CB |> DB45 E0 fild [local.8] ; (641)10 -> st0
004010CE |. DD5D D8 fstp qword ptr ss:[ebp-0x28] ; st0 -> ebp-28H
004010D1 |. DD45 E8 fld qword ptr ss:[ebp-0x18] ; [ebp-18H](十进制你的输入+520) -> st0
004010D4 |. DC65 D8 fsub qword ptr ss:[ebp-0x28] ; st0 = st0 - [ebp-28H] (641)10
004010D7 |. D9E4 ftst ; st0和0.0比较,据此设置FPU状态字C0,C2,C3位
004010D9 |. DFE0 fstsw ax
004010DB |. F6C4 01 test ah,0x1
004010DE |. 74 02 je short 测试.004010E2
004010E0 |. D9E0 fchs ; st0改变符号位
004010E2 |> DC1D 651B4800 fcomp qword ptr ds:[0x481B65] ; st0和[481B65](无限接近0的一个正浮点数)比较,据此设置FPU状态字C0,C2,C3位,并把st0弹到[481B65]
004010E8 |. DFE0 fstsw ax ; FPU状态字 -> eax,根据下面可知,FPU状态字C0或C3为1均可
004010EA |. F6C4 41 test ah,0x41 ; zf=0 -> ah & 0x41 != 0
004010ED |. B8 00000000 mov eax,0x0
004010F2 |. 0f95c0 setne al ; eax=1 -> al=1 -> zf=0
004010F5 |. 8945 D0 mov [local.12],eax
004010F8 |. 837D D0 01 cmp [local.12],0x1
004010FC |. 0F85 39000000 jnz 测试.0040113B ; 要求zf=1,即eax=0x1
00401102 |. BB 06000000 mov ebx,0x6
00401107 |. E8 F8FEFFFF call 测试.00401004
0040110C |. 68 01030080 push 0x80000301
00401111 |. 6A 00 push 0x0
00401113 |. 68 00000000 push 0x0
00401118 |. 68 04000080 push 0x80000004
0040111D |. 6A 00 push 0x0
0040111F |. 68 6D1B4800 push 测试.00481B6D ; 成功
00401124 |. 68 04000000 push 0x4
00401129 |. BB 90164000 mov ebx,测试.00401690
0040112E |. E8 36010000 call 测试.00401269
00401133 |. 83C4 34 add esp,0x34
00401136 |. E9 34000000 jmp 测试.0040116F
0040113B |> BB 06000000 mov ebx,0x6
00401140 |. E8 BFFEFFFF call 测试.00401004
00401145 |. 68 01030080 push 0x80000301
0040114A |. 6A 00 push 0x0
0040114C |. 68 00000000 push 0x0
00401151 |. 68 04000080 push 0x80000004
00401156 |. 6A 00 push 0x0
00401158 |. 68 721B4800 push 测试.00481B72 ; 失败
0040115D |. 68 04000000 push 0x4

那么回到上面的问题,ah的值是从哪来的,我们在004010E8处可以看到,FPU状态码进了eax

那么根据我们的判断ah & 0x41 != 0,能得出对FPU状态字有什么要求呢?

我们看这张图

也就是说

    0100 0001
& -x-- -yzt
----------------

其中x代表C3,y代表C2,z代表C1,t代表C0

根据上面的判断,也就是说只能C3或C0为1

  • C3为1的话
004010E2  |>  DC1D 651B4800 fcomp qword ptr ds:[0x481B65]            ;  st0和[481B65](无限接近0的一个正浮点数)比较,据此设置FPU状态字C0,C2,C3位,并把st0弹到[481B65]

这段就是st0等于一个无限接近0的浮点数才能使C3为1,但是根据我们之前的st0 = st0 = 你的输入+520-641,st0不可能是等于一个无限接近0的浮点数,所以C3为1排除 fcomp命令参考处

  • C0为1的话

    C0为1是怎么来的呢?只有两个地方涉及到了FPU状态字的改变,分别是4010D74010E2

    4010E2处要使C0为1,必须st0小于那个无限接近0的浮点数,这个条件不足以我们判断,接着往上看

    4010D7处要使C0为1,必须st0等于0.0,也就是你的输入+520-641=0 ftst命令参考处

所以至此我们就得到了密码

密码+520-641=0 ==> 密码=121

这个CM怎么说呢,我刚开始是没想到会涉及到浮点寄存器的,因为我还没学这个,不过后来追到快判断的地方时,发现了FPU状态码进入eax参与过程了,然后查了关于FPU 状态寄存器的资料,就可以搞出来了

例子CM

一个涉及到浮点寄存器的CM的更多相关文章

  1. C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例

    一个奇怪的C语言问题,涉及到指针.数组.堆栈.以及printf.以下实现: 整数向字符串的转换,返回字符串指针,并在main函数中调用printf显示. #include<stdio.h> ...

  2. [zt]系统中常用MIPS指令

    指令 功能 应用实例 LB 从存储器中读取一个字节的数据到寄存器中 LB R1, 0(R2) LH 从存储器中读取半个字的数据到寄存器中 LH R1, 0(R2) LW 从存储器中读取一个字的数据到寄 ...

  3. [转] RISC-V架构介绍

    1. RISC-V和其他开放架构有何不同 如果仅从"免费"或"开放"这两点来评判,RISC-V架构并不是第一个做到免费或开放的处理器架构. 在开始之前,我们先通 ...

  4. 关于RiscV的一些资料整理

    1. 基于RISC-V架构的开源处理器及SoC研究综述 https://mp.weixin.qq.com/s/qSD-q8y0_MY8R0MBA85ZZg 原文链接: https://blog.csd ...

  5. RISCV 入门 (学习笔记)

    文章目录 1. risv 相关背景 1.1 arm 授权费 1.2 riscv 发展历史 1.3 riscv 风险 2. 指令集 2.1 可配置的通用寄存器组 2.2 规整的指令编码 2.3 简洁的存 ...

  6. 汇编 浮点指令FLD,FSTP,FADD与FPU寄存器

    知识点:  浮点数的存放方式  st0至st7  FLD,FST,FADD指令 一.浮点数的存放方式 00401000 /$ 55 PUSH EBP 00401001 |. 8BEC MOV E ...

  7. x86寄存器总结

    X86寄存器 ·x86寄存器分类: 8个通用寄存器:EAX.EBX.ECX.EDX.ESI.EDI.ESP.EBP 1个标志寄存器:EFLAGS 6个段寄存器:CS.DS.ES.FS.GS.SS 5个 ...

  8. 汇编,浮点运算符,fldpi,fmul等指令说明.

    协处理器指令系统 协处理器共有68条不同的指令,汇编程序在遇到协处理器指令助记符时,都会将其转换成机器语言的ESC指令,ESC指令代表了协处理器的操作码. 协处理器指令在执行过程中,需要访问内存单元时 ...

  9. X86-64寄存器和栈帧

    简介 通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果.除此之外,它们还各自具有一些特殊功能.通用寄存器的长度取决于机器字长,汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途, ...

随机推荐

  1. 软工网络15团队作业4——Alpha阶段敏捷冲刺8.0

    软工网络15团队作业4--Alpha阶段敏捷冲刺8.0 1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 2.1 任务完成安排: 成员 昨日已完成 ...

  2. Vue系列之 => 自定义键盘修饰符

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Android开发随笔记_1

    1):android:configChanges="keyboardHidden|orientation":配置的好处:一般在AndroidManifest.xml文件中都没有使用 ...

  4. 05 enumerate index使用

    # enumerate 自动生成一列, 默认0开始,每次自增+1li = ["电脑","鼠标垫","U盘","游艇"]f ...

  5. MySQL超时配置

    connect_timeout:连接响应超时时间.服务器端在这个时间内如未连接成功,则会返回连接失败. wait_timeout:连接空闲超时时间.与服务器端无交互状态的连接,直到被服务器端强制关闭而 ...

  6. MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!

    最近做数据备份的时候发现了有个很严重的问题,那就是数据丢失(最后证明没丢,是别的问题造成的). 问题如下: 我通过两种方式在两个mongoDB集群中,对一组collection进行备份,最后2个备份数 ...

  7. 以太坊erc20转账失败的情况和原因

    以太坊erc20转账失败的情况和原因 eth转账失败有多种情况,除了手续费过低以外(Out of gas),众筹额度满了(Bad instruction)也会失败链上转账有可能失败,转账失败转账的币退 ...

  8. html5实现移动端下拉刷新(原理和代码)

    这篇文章给大家介绍的内容是关于html5实现移动端下拉刷新(原理和代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 移动端的下拉刷新是一个很常见的功能,也有许多开源库实现了这个功 ...

  9. java连接oracle数据库使用SERVICE NAME、SID以及TNSName不同写法

    格式一: 使用ServiceName方式: jdbc:oracle:thin:@//<host>:<port>/<service_name> 例 jdbc:orac ...

  10. 需求中碰到的简单Map集合 key相同合并 value的思路

    从两个接口获取到了数据Map集合, 但是要展示到同一页面 根据了播控人为key 将两个返回的进行遍历 将他们存在新的map里面 只有单个key value 就存为(MAP<object,obje ...