re-for-50-plz-50

这题目属实没法看伪代码(当然,可以下载插件进行一系列帮助),在这里呢,我直接读mips的指令集,因为涉及到的指令挺简单的

MIPS32指令集对照

全部指令


.text:00401398 var_18          = -0x18
.text:00401398 var_10          = -0x10
.text:00401398 var_8           = -8
.text:00401398 var_4           = -4
.text:00401398 arg_0           =  0
.text:00401398 arg_4           =  4
.text:00401398
.text:00401398                 addiu   $sp, -0x28
.text:0040139C                 sw      $ra, 0x28+var_4($sp)
.text:004013A0                 sw      $fp, 0x28+var_8($sp)
.text:004013A4                 move    $fp, $sp
.text:004013A8                 li      $gp, 0x4AC770
.text:004013B0                 sw      $gp, 0x28+var_18($sp)
.text:004013B4                 sw      $a0, 0x28+arg_0($fp)
.text:004013B8                 sw      $a1, 0x28+arg_4($fp)
.text:004013BC                 sw      $zero, 0x28+var_10($fp)
.text:004013C0                 j       loc_401434
.text:004013C4                 move    $at, $at
.text:004013C8  # ---------------------------------------------------------------------------
.text:004013C8
.text:004013C8 loc_4013C8:                              # CODE XREF: main+A4j
.text:004013C8                 lui     $v0, 0x4A
.text:004013CC                 addiu   $v1, $v0, (meow - 0x4A0000)  # "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ"
.text:004013D0                 lw      $v0, 0x28+var_10($fp)
.text:004013D4                 addu    $v0, $v1, $v0
.text:004013D8                 lb      $v1, 0($v0)
.text:004013DC                 lw      $v0, 0x28+arg_4($fp)
.text:004013E0                 addiu   $v0, 4
.text:004013E4                 lw      $a0, 0($v0)
.text:004013E8                 lw      $v0, 0x28+var_10($fp)
.text:004013EC                 addu    $v0, $a0, $v0
.text:004013F0                 lb      $v0, 0($v0)
.text:004013F4                 xori    $v0, 0x37
.text:004013F8                 sll     $v0, 24
.text:004013FC                 sra     $v0, 24
.text:00401400                 beq     $v1, $v0, loc_401428
.text:00401404                 move    $at, $at
.text:00401408                 lui     $v0, 0x47
.text:0040140C                 addiu   $a0, $v0, (aNooooooooooooo - 0x470000)  # "NOOOOOOOOOOOOOOOOOO\n"
.text:00401410                 jal     print
.text:00401414                 move    $at, $at
.text:00401418                 lw      $gp, 0x28+var_18($fp)
.text:0040141C                 jal     exit_funct
.text:00401420                 move    $at, $at
.text:00401424                 lw      $gp, 0x28+var_18($fp)
.text:00401428
.text:00401428 loc_401428:                              # CODE XREF: main+68j
.text:00401428                 lw      $v0, 0x28+var_10($fp)
.text:0040142C                 addiu   $v0, 1
.text:00401430                 sw      $v0, 0x28+var_10($fp)
.text:00401434
.text:00401434 loc_401434:                              # CODE XREF: main+28j
.text:00401434                 lw      $v0, 0x28+var_10($fp)
.text:00401438                 slti    $v0, 0x1F
.text:0040143C                 bnez    $v0, loc_4013C8
.text:00401440                 move    $at, $at
.text:00401444                 lui     $v0, 0x47
.text:00401448                 addiu   $a0, $v0, (aC0ngr4ssulatio - 0x470000)  # "C0ngr4ssulations!! U did it."
.text:0040144C                 la      $v0, puts
.text:00401450                 move    $t9, $v0
.text:00401454                 jalr    $t9 ; puts
.text:00401458                 move    $at, $at
.text:0040145C                 lw      $gp, 0x28+var_18($fp)
.text:00401460                 jal     exit_funct
.text:00401464                 move    $at, $at
.text:00401468                 lw      $gp, 0x28+var_18($fp)
.text:0040146C                 li      $v0, 1
.text:00401470                 move    $sp, $fp
.text:00401474                 lw      $ra, 0x28+var_4($sp)
.text:00401478                 lw      $fp, 0x28+var_8($sp)
.text:0040147C                 addiu   $sp, 0x28
.text:00401480                 jr      $ra
.text:00401484                 move    $at, $at

逐步分析

.text:00401398                 addiu   $sp, -0x28
.text:0040139C                 sw      $ra, 0x28+var_4($sp)
.text:004013A0                 sw      $fp, 0x28+var_8($sp)
.text:004013A4                 move    $fp, $sp
.text:004013A8                 li      $gp, 0x4AC770
.text:004013B0                 sw      $gp, 0x28+var_18($sp)
.text:004013B4                 sw      $a0, 0x28+arg_0($fp)
.text:004013B8                 sw      $a1, 0x28+arg_4($fp)
.text:004013BC                 sw      $zero, 0x28+var_10($fp)

这几行作用是代码把栈顶抬升,然后进行一系列的存储指令 对其赋值操作

接下来遇到无条件跳转指令,

.text:004013C0                 j       loc_401434

无条件跳转

.text:00401434                 lw      $v0, 0x28+var_10($fp)
.text:00401438                 slti    $v0, 0x1F
.text:0040143C                 bnez    $v0, loc_4013C8
.text:00401440                 move    $at, $at
.text:00401444                 lui     $v0, 0x47
.text:00401448                 addiu   $a0, $v0, (aC0ngr4ssulatio - 0x470000)  # "C0ngr4ssulations!! U did it."
.text:0040144C                 la      $v0, puts
.text:00401450                 move    $t9, $v0
.text:00401454                 jalr    $t9 ; puts
.text:00401458                 move    $at, $at
.text:0040145C                 lw      $gp, 0x28+var_18($fp)
.text:00401460                 jal     exit_funct
.text:00401464                 move    $at, $at
.text:00401468                 lw      $gp, 0x28+var_18($fp)
.text:0040146C                 li      $v0, 1
.text:00401470                 move    $sp, $fp
.text:00401474                 lw      $ra, 0x28+var_4($sp)
.text:00401478                 lw      $fp, 0x28+var_8($sp)
.text:0040147C                 addiu   $sp, 0x28
.text:00401480                 jr      $ra
.text:00401484                 move    $at, $at
.text:00401434                 lw      $v0, 0x28+var_10($fp)
.text:00401438                 slti    $v0, 0x1F


这两行指令的话,取了一个数,0x28+var_10($fp)里面放的是0(上面用zero寄存器去初始化的内存单元),然后取出放在v0寄存器里面,这个数去和31比较,比较后的关系用1和0放在v0里面
解释一下,v0<31的话,那么v0会被赋值为1,v0>=31的话,那么v0会被赋值为0

.text:0040143C                 bnez    $v0, loc_4013C8

BENZ R1,NAME;//R1!=0,程序跳转,以NAME为偏移地址
BEQZ R1,NAME;//R1=0,程序跳转到,以NAME为偏移地址。
根据以上条件,然后0<31,成立,即跳转到loc_4013C8

条件跳转(主体代码)

.text:004013C8                 lui     $v0, 0x4A
.text:004013CC                 addiu   $v1, $v0, (meow - 0x4A0000)  # "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ"
.text:004013D0                 lw      $v0, 0x28+var_10($fp)
.text:004013D4                 addu    $v0, $v1, $v0
.text:004013D8                 lb      $v1, 0($v0)
.text:004013DC                 lw      $v0, 0x28+arg_4($fp)
.text:004013E0                 addiu   $v0, 4
.text:004013E4                 lw      $a0, 0($v0)
.text:004013E8                 lw      $v0, 0x28+var_10($fp)
.text:004013EC                 addu    $v0, $a0, $v0
.text:004013F0                 lb      $v0, 0($v0)
.text:004013F4                 xori    $v0, 0x37
.text:004013F8                 sll     $v0, 24
.text:004013FC                 sra     $v0, 24
.text:00401400                 beq     $v1, $v0, loc_401428
.text:00401404                 move    $at, $at
.text:00401408                 lui     $v0, 0x47
.text:0040140C                 addiu   $a0, $v0, (aNooooooooooooo - 0x470000)  # "NOOOOOOOOOOOOOOOOOO\n"
.text:00401410                 jal     print
.text:00401414                 move    $at, $at
.text:00401418                 lw      $gp, 0x28+var_18($fp)
.text:0040141C                 jal     exit_funct
.text:00401420                 move    $at, $at
.text:00401424                 lw      $gp, 0x28+var_18($fp)

逐步分析主体

第一步

.text:004013C8                 lui     $v0, 0x4A
.text:004013CC                 addiu   $v1, $v0, (meow - 0x4A0000)  # "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ"

lui指令是load unsigned int 加载一个立即数进入v0寄存器的高16位
低16位填0,v0此时值为0x4A0000

第二行 addiu $v1, $v0, (meow - 0x4A0000) # 此时即可解释为
v1=v0+meow - 0x4A0000
v1=meow,meow此时应该是这个字符串的首地址,即把字符串首地址放入了
v1寄存器

.text:004013D0                 lw      $v0, 0x28+var_10($fp)

从一个fp里面存放一个地址值,然后fp里面的地址值+0x28+var_10这个地址中的值读取一个字到$v0,而且根据

所述,fp里面的地址值+0x28+var_10(处理相对于字符首地址的偏移,到后面就会发现,这个地方会依次+1)这个地址中的值是为0,即寄存器v0存储是为0

第二步

接下来分析这里

.text:004013D4                 addu    $v0, $v1, $v0
.text:004013D8                 lb      $v1, 0($v0)
.text:004013DC                 lw      $v0, 0x28+arg_4($fp)
.text:004013E0                 addiu   $v0, 4
.text:004013E4                 lw      $a0, 0($v0)
.text:004013E8                 lw      $v0, 0x28+var_10($fp)
.text:004013EC                 addu    $v0, $a0, $v0
.text:004013F0                 lb      $v0, 0($v0)
.text:004013F4                 xori    $v0, 0x37
.text:004013D4                 addu    $v0, $v1, $v0

v0=v1+v0也就是v0=v1+0v0=v1,也就是v0里面存放着字符串首地址

.text:004013D8                 lb      $v1, 0($v0)

取出v0所指处的第一个字符串放在v1里面。

.text:004013DC                 lw      $v0, 0x28+arg_4($fp)

0x28+arg_4($fp)这个里面东西,

是从a1寄存器存进内存单元的,大概猜测是我们所输进去的字符首地址(可是实际上不是)

.text:004013E0                 addiu   $v0, 4

这个加4的话,需要+4才能找到从我们传进来的参数里面找到存储字符串地址的内存单元

.text:004013E4                 lw      $a0, 0($v0)

取出这个地址的一个字,这个字单元里面存储了我们输入字符串的首地址

.text:004013E8                 lw      $v0, 0x28+var_10($fp)

v0清零处理(处理相对于字符首地址的偏移,到后面就会发现,这个地方会依次+1)0x28+var_10($fp)这个里面存放的是$zero

.text:004013EC                 addu    $v0, $a0, $v0

这里是v0=v0+a0,即v0=a0,到这里我感觉才是我们输入字符串的首地址

.text:004013F0                 lb      $v0, 0($v0)

然后取出一个字节的字符出来放在v0里面

.text:004013F4                 xori    $v0, 0x37

这个字符再和0x37进行异或操作

.text:004013F8                 sll     $v0, 24
.text:004013FC                 sra     $v0, 24
.text:00401400                 beq     $v1, $v0, loc_401428
.text:00401404                 move    $at, $at
.text:00401408                 lui     $v0, 0x47
.text:0040140C                 addiu   $a0, $v0, (aNooooooooooooo - 0x470000)  # "NOOOOOOOOOOOOOOOOOO\n"
.text:00401410                 jal     print
.text:00401414                 move    $at, $at
.text:00401418                 lw      $gp, 0x28+var_18($fp)
.text:0040141C                 jal     exit_funct
.text:00401420                 move    $at, $at
.text:00401424                 lw      $gp, 0x28+var_18($fp)

异或结束后,再


把它们左移24位,然后再右移24位,它俩的意思也就是取后八位的意思,就是取一个字节

.text:00401400                 beq     $v1, $v0, loc_401428

相等的话,那就跳转喽,然后继续判断下一个字符

.text:00401428 loc_401428:
.text:00401428                 lw      $v0, 0x28+var_10($fp)
.text:0040142C                 addiu   $v0, 1
.text:00401430                 sw      $v0, 0x28+var_10($fp)

第一步用0x28+var_10($fp)v0清0,然后进行+1操作,再把它存储在0x28+var_10这个里面,
以此类推,下次到达这里也就是用1去覆盖v0喽,然后v0+1再去放在0x28+var_10这个里面,这个也就是那个字符串相对于首地址的偏移,以此来取出每个字符操作。

然后

text:00401434 loc_401434:                              # CODE XREF: main+28j
.text:00401434                 lw      $v0, 0x28+var_10($fp)
.text:00401438                 slti    $v0, 0x1F
.text:0040143C                 bnez    $v0, loc_4013C8

这里呢,就把相对于字符的首地址的偏移和0x1F 比较,也就是能否成功比较到最后一个,如果能的话,那么就跳到成功的地方去了,因为比较每个字符是否相等的操作之间的跳转已经在前面比较了,这里只需要比较是否到达最后即可。

GAMEOVER

#include <iostream>
using namespace std;
int main()
{char a[] = { "cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ" };for (int i = 0; i < 31; i++) {a[i] = a[i] ^ 0x37;cout << a[i];}
}

注意点

存储 从左往右
加载 从右往左

.text:004013DC                 lw      $v0, 0x28+arg_4($fp)
.text:004013E0                 addiu   $v0, 4
.text:004013E4                 lw      $a0, 0($v0)
.text:004013E8                 lw      $v0, 0x28+var_10($fp)
.text:004013EC                 addu    $v0, $a0, $v0
.text:004013F0                 lb      $v0, 0($v0)

只需要注意着点,这个传进来的参数0x28+arg_4($fp)存放的不是字符串的首地址,而是它存放的地址值+4之后才是存放输入字符串地址的内存单元,即
0x28+arg_4($fp)取出里面的地址值+4 操作后,我们需要再往里面取一个word地址,即

.text:004013E4                 lw      $a0, 0($v0)

然后a0里面存放的才是输入字符串的首地址

re-for-50-plz-50 寒假逆向生涯(6/100)相关推荐

  1. notsequence 寒假逆向生涯(9/100)

    notsequence 这题目,挺简单的,首先无壳,直接拖进ida,然后查看了一下伪代码 轻易发现只需要满足三点就行 sub_80486CD((int)&unk_8049BE0) (unsig ...

  2. secret-galaxy-300 Replace(印象深刻) 寒假逆向生涯(8/100)

    secret-galaxy-300 脑洞题,直接没说法,就以后别碰这种脑洞题就行,,,,没任何帮助 显示界面 OD打开后,显示这个鬼东西.然后就没了. ida静态分析 看到上方输出框有字符串,所以我们 ...

  3. IgniteMe debug 寒假逆向生涯(2/100)

    IgniteMe 声明 这是道超级简单的题目,就不重复啰嗦了,找到需要加密的关键代码后,直接一步到位. memset(&v4, 0xCCu, 0xF4u);if ( strlen(a1) &g ...

  4. HWS计划 decryption 寒假逆向生涯(17/100)

    decryption 前奏 没法搞,直接拖ida 全局 首先输入flag,然后一个if判断一下长度是否符合,不符合直接结束 然后再new处一个数组,接着一个加密函数,把加密后的存放在new出来的数组里 ...

  5. easy_Maze 梅津美治郎 寒假逆向生涯(16/100)

    easy_Maze 这个题简单,迷宫题目,需要动调,或者不用动调也行,可以自己算出地图,我用的是动调. 生成地图的两个函数 只需要动调到这两个函数的下一步后,找到储存矩阵的空间的地址, 把这个地址转到 ...

  6. babymips(下) 寒假逆向生涯(14/100)

    babymips上 主要核心代码 var_10= -0x10 var_8= -8 var_4= -4 arg_0= 0addiu $sp, -0x28 sw $ra, 0x28+var_4($sp) ...

  7. babymips(上) 寒假逆向生涯(14/100)

    babymips 这题呢,看名字就知道,不出所料,还是mips指令,挺简单的,懒得找插件,直接分析吧,锻炼锻炼自己 开战 lui $v0, 0x40 addiu $a0, $v0, (aGiveMeY ...

  8. easyre-153 testre寒假逆向生涯(13/100)

    easyre-153 简单题目,流程走起,首先查壳, 脱壳 upx壳,利用工具把它脱掉 ida静态分析 int __cdecl main(int argc, const char **argv, co ...

  9. deedeedee crazy 寒假逆向生涯(11/100)

    deedeedee 这题没说法...直接用notepad++打开第二个文件,然后就看到了flag....人傻了... flag{t3mplat3_met4pr0gramming_is_gr8_4_3v ...

最新文章

  1. 用Quartus II Timequest Timing Analyzer进行时序分析 :实例讲解 (三)
  2. [WCF 4.0新特性] 默认终结点
  3. Attention的本质:从Encoder-Decoder(Seq2Seq)理解
  4. 单例-初始化动作只执行一次
  5. 《springcloud超级入门》Spring Cloud开发环境的准备和Lombok安装步骤《四》
  6. QueryDict对象
  7. Python 必备要点总结及环境搭建(上)
  8. Java编程练习题3
  9. 【WPS表格】函数的3种引用方式,4种切换模式
  10. 163个人邮箱注册申请流程,公司邮箱怎么注册?
  11. 摘果子问题(聚沙成塔问题)
  12. 用python画玫瑰花
  13. java里面不等于怎么打_不等于在c语言中怎么打
  14. 简明 Vim 练级攻略(转自酷壳)
  15. http服务器常见状态码
  16. 5.5G产业再提速!高通5GAdvanced-ready芯片商用终端下半年面世
  17. 求一个给定的n阶方阵的鞍点
  18. 开机后电脑只剩计算机和回收站,电脑开机后C盘拒绝访问,图标只剩下此电脑和回收站是怎么回事?...
  19. MacOS上效率神器 Alfred的基本用法
  20. 软件测试行业年度核心热点数据大揭秘(2018 )

热门文章

  1. 去掉状态条并全屏_一个人住180㎡,大大的落地窗,足够的收纳,简洁又舒适,宅在家是她最享受的状态!...
  2. 成功解决absl.flags._exceptions.UnrecognizedFlagError: Unknown command line flag 'data_format'
  3. Py之ipykernel:Python库之ipykernel简介、安装、使用方法之详细攻略
  4. Hyperopt中文文档:Cite引用
  5. WRF用户手册翻译:Chapter 5: WRF Model
  6. 【BZOJ5470】【FJOI2018】—所罗门王的宝藏(BFS)
  7. 数据结构实验之链表一:顺序建立链表(SDUT 2116)
  8. 霍金:AI或许能根除疾病和贫穷,但也可能摧毁人类 | GMIC 2017
  9. 在.Net中进行跨线程的控件操作(上篇:Control.Invoke)
  10. 视觉库—OpenCV