分类 杂记 下的文章

概述

很久很久以前(大约20年7月)写的一个奇奇怪怪的算法,当时的目的是为了从一堆动漫图片中获取其线稿用于描画练习
但是当时还没有现如今流行的各种大模型,根本做不到快速的本地抽出,所以就去尝试了解了一下一些简单的图像处理库
(当时还在用7300HQ老U,做不到基于纯图形或者推测的处理),后来就想了个办法,用色容差和反色+灰度来解决这个问题,出来的效果也暂且不算难看,用于描画练习则是绰绰有余了。
最近翻出来了当时的V1和V2版本代码,仔细阅读后发现写的属实非常烂,就直接尝试对其进行了直接的整体重构
以下为代码,编译时请携带好STB的头,用clang -Os -o OSE3 OSE3.C -lm来执行编译

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#define GRAYSCALE_RED_WEIGHT 0.3
#define GRAYSCALE_GREEN_WEIGHT 0.59
#define GRAYSCALE_BLUE_WEIGHT 0.11

void imgProcessGray(uint8_t *s, int sx, int sy, int stride, uint8_t *p, int gstride)
{
    for (int y=0; y<sy; y++) {
        for (int x=0; x<sx; x++) {
            p[x] = GRAYSCALE_RED_WEIGHT * s[x*3+0] + GRAYSCALE_GREEN_WEIGHT * s[x*3+1] + GRAYSCALE_BLUE_WEIGHT *s[x*3+2];
        }
        s += stride*3;
        p += gstride;
    }
}

void imgProcessDilate(uint8_t *s, int w, int h, int k, uint8_t *p)
{
    for (int y=1; y<h-1; y++) {
        for (int x=1; x<w-1; x++) {
            uint8_t uc = s[ (y+0)*w + (x+0) ];
            uint8_t ua = s[ (y-1)*w + (x+0) ];
            uint8_t ub = s[ (y+1)*w + (x+0) ];
            uint8_t ul = s[ (y+0)*w + (x-1) ];
            uint8_t ur = s[ (y+0)*w + (x+1) ];
            uint8_t ux = 0;
            if (uc > ux) ux = uc;
            if (ua > ux) ux = ua;
            if (ub > ux) ux = ub;
            if (ul > ux) ux = ul;
            if (ur > ux) ux = ur;
            p[ y*w + x ] = ux;
        }
    }
}

void imgProcessAbsdiff(uint8_t *s, uint8_t *s2, int w, int h, uint8_t *p)
{
    for (int n=0; n<w*h; n++) {
        *p++ = abs(*s++ - *s2++);
    }
}

void imgProcessReverse(uint8_t *s, int w, int h, uint8_t *p)
{
    for (int n=0; n<w*h; n++) {
        *p++ = 255 - *s++;
    }
}

int main(int argc, char* argv[])
{
    if (argc != 2) {
        fprintf(stderr, "Otaku Strokes Extractor v3\n");
        fprintf(stderr, "Usage: %s <image_path>\n", argv[0]);
        return 1;
    }

    char *name = argv[1];

    int w, h, bpp;
    uint8_t *pixels = stbi_load(name, &w, &h, &bpp, 3);
    if (!pixels) {
        fprintf(stderr, "Failed to load image: %s\n", name);
        return 1;
    }

    uint8_t *gray = (uint8_t*) malloc(w*h*4);
    if (!gray) {
        fprintf(stderr, "Failed to allocate memory for image processing.\n");
        stbi_image_free(pixels);
        return 1;
    }

    uint8_t *dilated = gray + w*h;
    uint8_t *diff = dilated + w*h;
    uint8_t *contour = diff + w*h;

    printf("Processing %s...\n", name);
    imgProcessGray(pixels, w, h, w, gray, w);
    imgProcessDilate(gray, w, h, 5, dilated);
    imgProcessAbsdiff(gray, dilated, w, h, diff);
    imgProcessReverse(diff, w, h, contour);
    stbi_write_jpg("result.jpg", w, h, 1, contour, 0);
    printf("Done for %s !\n", name);

    free(gray);
    stbi_image_free(pixels);

    return 0;
}

Windows体验版(使用MSYS2的gcc 11.3.0链静态构建)
OSE3_x64.exe

效果

原图
OSE3_Original
线稿
OSE3_Result
©版权所有者:クール教信者·双葉社/ドラゴン生活向上委員会

最近把很早以前购买的三星平板拿出来继续使用,其SoC是三星半导体自制的Exynos 9611,由于我买的是WIFI+LTE版本,其存在基带。很久以前用搭载Exynos4210的三星S2的时候,就对三星的奇怪的香农基带感到好奇。
历经快十年的对于逆向的爱好,最近再阅读了一些大牛写的代码和他们提供的Loader,成功的对目前最新的Exynos Shannon基带固件做到了解包,解压后可直接使用ShannonRE项目之中的Loader和静态分析工具进行分析。
当然如果你只是对三星的调试模式比较好奇的话,在我的解压工具中,其将自动从main区块中搜索AT指令,可通过终端模拟器连接到Samsung DM端口发送AT指令进行调试。

# siu.py v2
import struct
import re
import argparse
from contextlib import closing

class TOC:
    def __init__(self, fstream, fpos=None):
        try:
            if fpos is not None:
                fstream.seek(fpos)
            self.buf = fstream.read(32)
        except Exception as e:
            print(f"[!]ERROR Reading TOC Header: {e}")
            self.buf = bytearray(32)

    def unpack(self):
        try:
            self.name = self.buf[:12].rstrip(b"\x00").decode("utf-8")
            self.start = struct.unpack("i", self.buf[12:16])[0]
            self.size = struct.unpack("i", self.buf[20:24])[0]
            self.secdata = struct.unpack("i", self.buf[24:28])[0]
            self.queue = struct.unpack("i", self.buf[28:32])[0]
        except struct.error as e:
            print(f"[!]ERROR Unpacking TOC: {e}")
            raise

    def print_info(self):
        print(f"Block Name: {self.name}")
        print(f"Start Offset: 0x{self.start:08x}")
        print(f"Size: 0x{self.size:08x}")
        print(f"Sec Data: 0x{self.secdata:08x}")
        print(f"Queue: {self.queue}")


class IMG:
    def __init__(self, fstream, header):
        fstream.seek(header.start)
        self.buf = fstream.read(header.size)

    def unpack(self):
        pass

    def write(self, dst):
        with open(f"{dst}.bin", "wb") as f:
            f.write(self.buf)


class BOOT(IMG):
    def unpack(self):
        print('Done')


def unpack_toc(file_stream, name):
    header = TOC(file_stream)
    header.unpack()
    header.print_info()
    if header.name != name:
        raise ValueError(f"Unexpected TOC name. Expected {name}, got {header.name}")
    return header


def unpack_img(file_stream, header, img_type):
    img = img_type(file_stream, header)
    img.unpack()
    return img


def find_in_img(img, pattern, filename):
    strings = re.findall(rb'%s[^\x00]*' % pattern.encode(), img.buf)
    with open(f'{filename}.TXT', 'wb') as f:
        for s in strings:
            f.write(s + b'\n')
    print(f"Found {len(strings)} strings")
    return strings


def main():
    parser = argparse.ArgumentParser(description="SHANNON Image Unpacker v1.2 by Yuu/Idea from ShannonRE by grant-h")
    parser.add_argument('file', help='Path to the binary file')
    parser.add_argument('--at', action='store_true', help='Find AT strings')
    parser.add_argument('--ver', help='Find version strings for a given model')

    args = parser.parse_args()

    with closing(open(args.file, "rb")) as file_stream:
        toc_header = unpack_toc(file_stream, "TOC")
        boot_header = unpack_toc(file_stream, "BOOT")
        main_header = unpack_toc(file_stream, "MAIN")
        vss_header = unpack_toc(file_stream, "VSS")
        nv_header = unpack_toc(file_stream, "NV")
        offset_header = unpack_toc(file_stream, "OFFSET")

        boot_img = unpack_img(file_stream, boot_header, BOOT)
        boot_img.write("boot")

        main_img = unpack_img(file_stream, main_header, IMG)
        main_img.write("main")

        vss_img = unpack_img(file_stream, vss_header, IMG)
        vss_img.write("vss")

        nv_img = unpack_img(file_stream, nv_header, IMG)
        nv_img.write("nv")

        if args.at:
            find_in_img(main_img, 'AT+', 'AT')
        if args.ver:
            ver_strings = find_in_img(main_img, args.ver, 'VER')
            if ver_strings:
                print(f"Possible Version: {ver_strings[0].decode()}")


if __name__ == "__main__":
    main()

在开始之前,请确定你的设备型号是C1200 v1,以及备份好你的PPPoE账户和密码信息以及VLAN信息
由于马来西亚版本软件阉割了波束成形和AP功能,所以尝试将其刷成公开版。

确定版本

首先使用默认用户名和密码登录

默认用户名为admin,密码为TIME(主MAC地址后四位)
比如你的MAC地址为FF:FF:FF:FF:AA:C0,则对应密码是TIMEAAC0

TPTIME2EU_CheckVersion
首先在TIME旧固件下进入Advanced界面,向下滑动到最下方
TPTIME2EU_VersionCk
即可查看到当前的版本
TIME版本有一个特殊点就是完全没有任何关于系统更新的功能在前台,必须通过审查元素的方式才能调出。
而且只有1.0.0 Build 20180502 rel.45702 (EU)一个软件版本号,从来没有更新过

更新前准备

首先需要进入本来的管理页面,进入Advanced界面,在左侧找到Guest Network
TPTIME2EU_OriginalGuest
在Guest Network按钮上右键选择检查,进入DevTools
找到如下节点
TPTIME2EU_GuestPoint
改为
TPTIME2EU_DevTools_Moded
再次点击Guest Network,即可进入被隐藏的固件更新页面!
TPTIME2EU_UpdatePage

更新到中间固件

TP-LINK也不是傻瓜,不会让我们那么轻易的跨版本刷入固件开启更多功能,但是在2018年发布的46288 BETA版本中,这个版本没有刷写验证,所以我们就选择46288版本进行版本中继,继而就可以刷入正常的RELEASE版本。
TPTIME2EU_Flash46288
TPTIME2EU_Flash46288_Progress

更新到最新发布版固件

等待设备自动重启后,你会发现它的整个UI都大变样,同时也有BETA水印
TPTIME2EU_NewUi
直接设置好密码,进入新的页面
TPTIME2EU_NewBar
此时已经变成了公开版,所以也不再需要DevTools来打开固件更新页面了
TPTIME2EU_NewSidebar
直接进入Firmware Upgrade页面
选择2022年最新发布的58207版本,即可更新到RELEASE版本!
TPTIME2EU_Flash58207
TPTIME2EU_Flash58207_Progress

完成

享受波束成形和AP模式吧!
TPTIME2EU_Finish

固件下载

中转用BETA固件: C1200v1_eu_1.1.3_20180502_46288.bin
欧洲/东南亚区域最新版本固件: C1200v1_eu_1.1.4_20220517_58207.bin
美洲区域最新版本固件: C1200v1_us_1.1.3_20220517_58249.bin
TIME原版固件: C1200v1_time_1.0.0_20180502_45702.bin
注:如果需要刷回TIME版固件,请刷入一遍中转用BETA固件才可刷入TIME版固件

第一次尝试给Typecho写插件,其中利用到了Typecho1.2的新功能和比较新的PHP实现
这只是一个简单的小小作品,代码比较混杂,如果有什么建议和遇到问题可在评论区中提出
执行效果如下
CNYLtn_Yuu
动画基于CSS3和其自带的贝塞尔曲线实现进行绘制
同时又由于慢速互联网的存在,该插件会将代码插入到footer以避免影响页面的整体加载和渲染速度
将部分设置做了图形化界面,可以更快进行修改和匹配新的传统节日
CNYLtn_Settings
安装方式则与其他插件一样,解压下方提供的zip,将插件文件夹放入<网站根目录>/usr/plugins下,至Typecho后台启用即可。

更新日志与下载

1.2R->1.3R
<FEB.14-2023>
CNYLtn_1.3R.zip
1.添加调试模式,开启后可在前台控制台中输出调试信息
2.整体结构优化

1.1R->1.2R
<JAN.11-2023>
CNYLtn_1.2R.zip
1.修复在英文版Windows系统和MacOS下的默认字体回归问题
2.修改组件动画显示
3.修改字体大小为3em并在灯笼中居中

1.0R->1.1R
<JAN.04-2023>
CNYLtn_1.1R.zip
1.修复移动端检测无效的问题

1.0R
<JAN.03-2023>
未公开发布的Release版本

注于230214:今年已经更新结束,功能新增将在来年进行更新,Bug修复则可继续提出并等待修复

有的时候我会去分析一些奇奇怪怪的嵌入式系统或者设备,积攒下来一些特征,在此公开出来,也许对大家有用!
适配于binwalk,可直接放入~/.config/binwalk/magic中使用
此文章将长期更新

0       string  NORTi(c)MiSPO   MISPO NORTi uITRON RTOS
0       string  HI7700          HITACHI HI7700/4 ITRON RTOS
0       string  Installer       YAMAHA Firmware Update Package for TRON
0       string  SIMBMPMDSB      YAMAHA Firmware Update Package for TRON
0       string     Boot\x20Program\x20  YAMAHA TRON Bootloader Program
0       string  Emi-dos YAMAHA uITRON for EMI
0       string  DSPX09  YAMAHA DSP Firmware or Parameter
0       string  XPFH    YAMAHA Voice and Style Expansion Package or Data
0       string  XPIH    YAMAHA Voice and Style Expansion Config
0       string  onSSC   Roland SSC SoC Application (Renesas SH-4A Platform)
0       string  onESC2  Roland ESC DSP Application
0       string  ExP\x00V01      Medeli Extension Pack
0       string  SHFOTA          RedBend LZMA FOTA Package (SHARP/AES Encrypted)
0       string  RedBendEFDPackage       RedBend LZMA FOTA Package (Original)
0       string  \x02\x50\x40\x01\x00\x80\x38\x01\x00\xc0\x00\x00\x90\x04        RedBend LZMA FOTA Package (KYOCERA)
0       string  FOTA_UPDATE_FILE\x20BaseSwVer=  RedBend LZMA FOTA Package (Fujitsu)
# [UPD]Aug.18-2022:Add TRON EXE and SHOKO Magic
0       string  \xE0\xFF\x06\x00\x00\x00\x02\x00\x21\x01\xE3\xFF\x18    BTRON Shoko Archive File
0       string  \xFD\xFF\xFF\xFF        TRON Executable File
# [UPD]Aug.24-2022:Add Roland XV Series ROM Magic
0       string  MIIG    Roland XV-30/5080 ROM Code (Renesas SH-2A Platform)
# [UPD]Sep.12-2022:Add SKHynix NVMe SSD Controller Firmware Magic
0       string  EBINCEP2        SK Hynix SSD Controller Firmware
# [UPD]Sep.15-2022:Add MEDELI Firmware Magic
0       string  MEDELI          Medeli Update Package
0       string  ROLAND          Medeli Update Package (Roland ODM)
# [UPD]Sep.20-2022:Add Panasonic Venus Firmware Magic
0       string  UPD\x00\x00\x02\x00\x00\x00\x02\x00\x00 Panasonic Venus Camera Firmware
>12     string  x       \b, model"%s"
# [UPD]Sep.24-2022:Add Ricoh Camera Firmware Magic
0       string  RICOH           RICOH Camera Firmware Upgrade Package
>8      string  x       \b, model "%s"{many}
# [UPD]Sep.25-2022:Add Fujifilm Camera and Lens Firmware Magic
0       string  \x06\x00\x00\x00\x33\x30\x33\x30\x33\x30\x33    Fujifilm Camera Firmware
0       string  \x05\x00\x00\x00\x34\x63        Fujifilm Lens Firmware
# [UPD]Sep.25-2022:Add Akai EWI-5000 OS Magic
0       string  \xF0\x47\x7F\x20\x00\x00\x02\x1E\x00\x00\x50\x1E\x2D\x5B\x33\x41        AKAI EWI-5000 OS Update Package
# [UPD]Sep.25-2022:Add SONY Camera Product Upgrade Package
0       string  \x89\x55\x46\x55\x0D\x0A\x1A\x0A        SONY Camera Product Firmware Upgrade Package
# [UPD]Nov.17-2022:Add Roland E-X30/50 Style Extension Pack
0       string  MSF\x20V02\x00InfS        Roland E-X30/50 Style Extension Pack
# [UPD]Apr.27-2023:Add Medeli V2 Extension Pack
0       string  ExP\x00V02        Medeli Extension Pack V2
# [UPD]May.07-2023:Add CASIO Extension Pack
0       string  \x00ZPKGX30        CASIO Extension Pack for MZ Series
# [UPD]Jun.26-2023:Add Roland EZSTL Style
0       string  Roland EZ-Format 1.00        Roland EZSTL Style File
# [UPD]Dec.12-2023:Add Thine ISP Firmware
0       string \x54\x48\x69\x6E\x65        THINE THP7312/7212 ISP Firmware
# [UPD]Jan.01-2024:Add SEC XSR
0       string XSR2        Samsung XSR2 Flash Translation Layer Software
0       string XSRPARTI        Samsung XSR2 Partition