BCTF_海报探秘(300)

2023-05-16

这个题目来自上周的BCTF比赛,题目是海报探秘(300),一张png图片中隐藏了KEY,解出KEY,具体报告,

请下载:http://download.csdn.net/detail/l0g1n/7042787

我对217战队的这个题目报告进行了学习,对他的代码进行注释,理解。

我至少学习到了三点:png文件的解压,文件对齐的处理,还有这优雅的代码。分享给大家:


#include <bits/stdc++.h>
#include <zlib.h>

typedef unsigned char Byte;
//把二进制的大小转换为长度
inline unsigned convert_uint(Byte *b)
{
    unsigned ret = 0;
    for(int i = 0;i < 4; i++)
        ret = ret << 8 | b[i];
    return ret;
}

Byte chunk_len_buf[4];
Byte chunk_name[4];
Byte chunk_data[8 << 10];
Byte raw_data[8 << 20];


int main(int argc, char *argv[])
{
    //原始文件路径
    FILE *fin = fopen(argv[1], "r");
    //要输出的文件路径
    FILE *fout = fopen(argv[2], "w");
    //跳过png文件头部分
    fseek(fin, 8 + 4 + 4 + 13 + 4, SEEK_CUR);
    //zlib中用来解压的模块
    z_stream zs;
    //清0
    memset(&zs, 0, sizeof(zs));
    //初始化zs
    inflateInit(&zs);
    //设置用来保存解压后数据的路径
    zs.next_out = raw_data;
    //大小
    zs.avail_out = sizeof(raw_data);
    //读取节的长度
    while(fread(chunk_len_buf, 1, 4, fin) == 4)
    {
        //转换为unsigned
        unsigned chunk_len = convert_uint(chunk_len_buf);
        //读取每个节的名称
        fread(chunk_name, 1, 4, fin);
        //读取每一节的数据
        fread(chunk_data, 1, chunk_len, fin);
        //跳过CRC校验部分
        fseek(fin, 4, SEEK_CUR);
        //节的名称比较,只解压IDAT节
        if(memcmp(chunk_name, "IDAT", 4) == 0)
        {
            //输入的数据
            zs.next_in = chunk_data;
            //输入的长度
            zs.avail_in = chunk_len;
            //执行解压
            inflate(&zs, Z_SYNC_FLUSH);
        }
    }
    //解压结束
    inflateEnd(&zs);
    //这里看了很长时间,查了资料才明白,1003×654是像素点的个数乘以4,转换为bits,最后加654,是因为1003除以4不整除,这里是字节对齐的处理。
    unsigned raw_png_len = 1003 * 654 * 4 + 654;
    //out_len要生成新文件(被隐藏的数据)的长度,申请的内存空间-剩余可用的内存空间-图片应有的长度
    unsigned out_len = sizeof(raw_data) - zs.avail_out - raw_png_len;
    //生成数据。
    fwrite(raw_data + raw_png_len, 1, out_len, fout);

    fclose(fin);
    fclose(fout);

    return 0;
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BCTF_海报探秘(300) 的相关文章

  • android4.0新控件Switch方法解析

    就是很像开关的那种控件 xff0c 它只有两个状态 xff1a on和off xff1a 在IOS中 xff0c 有个UISwitch控件 xff0c 其效果图 xff0c 如下 xff1a 在android4 0里面 xff0c 添加了一
  • Android Adb 源码分析(一)

    扭起屁股得意洋洋 最近 xff0c 我负责的项目因为临近量产 xff0c 把之前的userdebug版本关闭 xff0c 转成了user版本 xff0c 增加selinux的权限 xff0c 大家都洋溢在项目准备量产的兴奋和喜悦之中不能自拔
  • ADB源码分析(一)——ADB模块简述

    原文地址 http www apkbus com blog 50331 54609 html 感谢作者的分享 1 Adb 源码路径 system core adb 2 要想很快的了解一个模块的基本情况 xff0c 最直接的就是查看该模块的A
  • Git分支管理规范

    一 分支与角色说明 Git 分支类型 master 分支 xff08 主分支 xff09 稳定版本 develop 分支 xff08 开发分支 xff09 最新版本 release 分支 xff08 发布分支 xff09 发布新版本 hot
  • Kindeditor编辑器 jsp上传错误解决方法 与struts2冲突整合

    上传使用的是upload json jsp文件 xff0c 问题关键在于struts2对于struts2过滤访问的jsp时 xff0c 会改变reqeust的类型 xff0c 由HttpServletRequest变成MultiPartRe
  • Android中Dialog和Toast及其Snackbar的使用和区别

    一 Snackbar的使用 连接地址 http www jcodecraeer com a anzhuokaifa androidkaifa 2015 0714 3187 html 如果说Dialog和Toast是两个极端的话 xff0c
  • 国外SAP自由顾问的价格

    http scnblogs techweb com cn sapfreelancer archives 19 html 非常感谢我的一位在海外做SAP猎头的朋友 xff0c 他做SAP猎头已经七年了 xff0c 而且不久前刚刚离职 xff0
  • ping的详细过程

    ping是我们在Linux中测试网络连接的常用指令 首先ping是应用程序 xff0c 而不是协议 xff0c 它利用ICMP Internet control message protocol 因特网控制报文协议 报文检测网络连接 首先假
  • Android studio 之 Kotlin Not Configured

    Build报错 xff1a Index is not created for Stubs AndroidStudio 爆以下错误 xff1a com intellij ide plugins StartupAbortedException
  • ThreadPoolExecutor的的核心线程回收设置allowCoreThreadTimeOut

    如果你对ThreadPoolExecutor的执行还不了解 xff0c 可以参考有界 无界队列对ThreadPoolExcutor执行的影响这篇文章 在ThreadPoolExecutor类中有个allowCoreThreadTimeOut
  • C语言-数据结构-归并排序(merge sort)-递归 迭代-源代码及分析

    1 归并排序 归并排序 xff08 MERGE SORT xff09 是建立在归并操作上的一种有效的排序算法 该算法是采用分治法 xff08 Divide and Conquer xff09 的一个非常典型的应用 将已有序的子序列合并 xf

随机推荐