学习笔记

1、正常操作

please input your serial:
  • 输入小于18个字符,返回wrong!
  • 输入超过18个字符,直接崩溃

看上去是要找一个序列号,输入正确才会有答案

但是题目描述是:菜鸡发现Flag似乎不一定是明文比较的

所以可能不是要找序列号

2、查壳

把程序拖入Exeinfo:

  • 有三个区段:.text .rdata .data
  • Image is 32 executable
  • Microsoft Visual C++ ver 5.0/6.0 - 2018-06-12
  • Big sec. 1 .text , Not packed

应该是没有壳

3、动态调试

  1. 首先,F8动态调试,大体走流程,大体找到了printf的call
  2. 使用F7单步步入,定位到了printf和scanf
  3. 紧接着scanf之后,是对字符串的校验,每次运行到这,寄存器窗口都会显示出数据窗口中的一段字符串(437261636b4d654a757374466f7246756e)
  4. 输入”123456”,发现每次循环处理一个字符,且把一个字符变成两个字符,例如1变成了31、2变成了32…….,最后还把这部分字符按原来顺序拼接起来了。
    1. 因此猜测是把输入的字符串进行某种运算(CALL 004012E2),将运算拼接后的字符串与程序自带的字符串进行比较,相等则success,所以当前目标变成找将一个输入字符映射到两个输出字符的规则。
  5. 依次输入”123456”、”abcdef”、”ABCDEF”发现
    • 大写字母是以0x41为基础加上各个字母与A的偏移
    • 小写字母是以0x61为基础加上各个字母与a的偏移
    • 例如43复原之后是C、6e与0x61之差为13所以复原之后是n(a+13=n)
  6. 因此把程序的字符串映射到输入字符为”CrackMeJustForFun”
  7. 最终flag:CrackMeJustForFun

4、解题经验

  • 目前对于16进制不敏感,实际上437261636b4d654a757374466f7246756e直接使用16进制转字符串就是最终结果。
  • 本题实际是把字符串的各个字符的十六进制ASCII码拼接起来,作为一个新的字符串,以ASCII码形式存储到了程序中

独立思考

1、入口点是什么意思?它会变吗?如何使用这个信息?

入口点就是指程序或函数的第一条指令地址。

在一个程序中,入口点的位置是不变的,因为已经编译好了。

常见入口点:

  • Entry Point of main module:主模块入口点,即文件的入口点

  • Winmain:程序Winmain()函数的入口点

在OllyDbg中可以指定加载程序之后的第一次中断点为某个入口点,便于调试分析。

在OllyDbg中汇编代码对应的地址为虚拟地址,程序不被改变的话换一台电脑该地址一般不会变,OllyDbg中用户代码的地址一般是0x0040????,Exeinfo软件能识别出一个入口点地址,一般在OllyDbg中Winmain入口点的地址就是该地址加上0x00400000.

产生过的疑问

  1. 入口点是什么意思?它会变吗?如何使用这个信息?