Blog

  • Windows 下vcpkg 与bindiff

    vcpkg 是 微软的一种包管理方式,对于curl之类的库,目前看使用 vcpkg可能是比较好的下载安装方式,比自己编译简单太多。

    遇到了一个需要逆向的程序,经过人肉特征分析,程序里发现使用了 curl 的一个老版本,这个版本的二进制已经不提供下载了,虽然通过 web.archive.org 拿到了要的版本,但是是 mingw 的,而且没有调试信息用起来不方便。

    于是,记录一下 vcpkg 操作的过程。

    下载不提了,假设安装完 vcpkg 后,在一个空白的工作目录,建立 vcpkg.json

    {
       "name": "curl-test",
        "dependencies": [ "curl", "libsodium" ],
        "overrides": [
            { "name": "curl", "version": "8.0.0" }
        ]
    }

    然后在这个目录执行 (我要分析的程序静态链接了curl,而且是32位的)

    ..\vcpkg\vcpkg.exe install --triplet x86-windows

    上边这个配置文件的例子其实是成功不了的,错误提示是

    error: C:\Work\packages\vcpkg.json was rejected because it uses "overrides" and does not have a "builtin-baseline". This can be fixed by removing the uses of "overrides" or adding a "builtin-baseline".
    See `vcpkg help versioning` for more information.

    我没找到正确姿势,但是看到这个baseline 跟git版本疑似有关,偷懒但是生效了

    第一步,加一个 "builtin-baseline":"HEAD",再次执行,报错变成了

    the top-level builtin-baseline (HEAD) was not a valid commit sha: expected 40 hexadecimal characters.You can use the current commit as a baseline, which is:
            "builtin-baseline": "61f610845fb206298a69f708104a51d651872877"
    note: updating vcpkg by rerunning bootstrap-vcpkg may resolve this failure.

    直接改json。

    接下来,bindiff的问题。

    一般程序不可能静态链接一个 debug 版本的库,所以直接用 ida pro分析 release 版本的二进制,而 vcpkg 的目录里带了调试信息,在 match的时候会比较简单。

    #EOF

  • 记录一个软件 API Monitor

    http://www.rohitab.com/apimonitor

    找了好长时间,终于找到了。

    需求是找一个工具记录软件的 DeviceIOControl 的调用,用来查设备驱动被哪个用户软件调用,且最好能找到调用的参数或者内容。

    在找到这个之前,试过了nirsoft / deviceioview、MartinDrab / IRPMon、zodiacon / DriverMon、Fyyre / DrvMon、DynamoRIO / drmemory,很遗憾,各种问题都用不了。

    而这个工具能记录目标程序的具体哪个DLL、哪个线程调用了哪些调用,相当神器。

    遇到的问题:记录数据不全,设置限制了最大的数据抓取4096字节,且输入长度最大4个字符。

    解决的方案:半解决吧,patch了程序。用 4096 搜立即数,找到了限制最大值的代码,逐个改成 0x400000;搜 EM_SETLIMITTEXT,看到定义是 0xC5,当立即数搜索,查找 SendMessageW 的调用,定位了两个框的限制,改成了8。

  • Protected: 某驱动调试手记(更新中)

    This content is password protected. To view it please enter your password below:

  • Protected: 北京联通F4610 管理员登录

    This content is password protected. To view it please enter your password below:

  • 基于 USB/IP 的USB劫持实验

    环境:服务端 usbipd (Linux,用的是 PVE),客户端 usbip(Linux,用的是 ubuntu 22.04虚拟机),测试设备 SanDisk U盘(一开始用的是海康的 R36C,遇到了 UAS 的问题,后边说),中间机 mac + mitmproxy。

    思路:

    1. 服务端 usbipd 起服务
    2. 服务端插上 U 盘,usbip bind
    3. 中间机器开 mitmproxy 反向代理,加载插件
    4. 客户端连中间机器的端口
    5. 客户端挂载分区,写入文件
    6. 验证写入文件是否被劫持

    可能用到的命令

    客户端

    usbip --tcp-port 2021 list -r 192.168.11.33
    usbip --tcp-port 2021 attach -r 192.168.11.33 -b 6-2.1
    lsblk
    mount -o rw,noatime,noauto,sync /dev/sdb1 /mnt/
    echo helloabcdefghijk > /mnt/1.txt
    umount /mnt
    usbip detach -p 8

    中间机器

    mitmdump --mode reverse:tcp://192.168.11.5:3240@2021 -s usbip.py 

    usbip.py 只做了一件事情,就是把 abcdefg 换成 xyzabcd。

    结果:正常操作下来,从服务端挂载 U 盘后

    root@wpve:~# cat /mnt/1.txt 
    helloxyzabcdhijk

    证明写入的数据确实是被修改过的。

    但是客户机在写入后立即读,读到的还是原始尝试写入的内容,这个缓存不知道怎么关,但是不重要了。

    UAS 的问题,硬盘挂载上dmesg报错

    [48408.638543] usb 14-1: USB controller vhci_hcd.0 does not support streams, which are required by the UAS driver.
    [48408.638550] usb 14-1: Please try an other USB controller if you wish to use UAS.
    [48408.638553] usb-storage 14-1:1.0: USB Mass Storage device detected
    [48408.639125] scsi host2: usb-storage 14-1:1.0

    找到了一篇文章https://leo.leung.xyz/wiki/How_to_disable_USB_Attached_Storage_(UAS)

    按说明在客户端配置了 quirks,不报错,但是没有 /dev下的 sdx,手动触发 udev

    udevadm trigger -v

    但是看不到分区,所以换了小U盘。

  • PN53 PVE 显卡直通踩坑记

    PN53 6900HX + 64GB内存,用了半年多的 Win11,每次干点啥都 WSL,但是WSL 有些时候太麻烦了,而使用 VMware 太慢。所以想着换个硬盘来搞一下 Proxmox VE,把原来的 Windows 变成虚拟机,但是后来,硬盘买到手,改变主意了,直接踢掉原装的 512GB 镁光,换上国产 2T。

    (more…)
  • WSL Docker 迁移 Volume 到 Linux

    看了一堆 Volume 迁移的教程,麻烦死。其实操作逻辑很简单,找到源主机的 docker volume 目录(一般在 /var/docker/volumes/ ),在目标端建立同名的volume,停掉两端的docker,从源把目录 rsync 到目标。

    Windows 11 + WSL2 + Docker。

    操作步骤如下

    1 找到 Docker 的数据盘 VHDX。

    我自己的磁盘被迁移到了 D盘,如果不知道在哪儿,一般在用户目录,例如 C:\Users\sskaje\AppData\Local\Docker,这个目录下 distro 是程序的镜像,data是数据的镜像。

    如果还不在这里,Windows 11 可以使用任务管理器 -> 性能 右上角… -> 资源监视器 -> CPU,在关联的句柄里搜索 vhdx,然后操作docker,例如 系统托盘退出docker 再打开,或者打开docker-desktop 的界面,乱点点。

    2 退出 Docker Desktop。

    3 在 WSL 里 手动加载 Docker Desktop 的数据盘。

    wsl.exe -d Debian --mount --vhd D:/WSL/Docker/data/ext4.vhdx --bare --name docker-data-1

    参考 https://www.sskaje.me/2023/08/13/wsl-mount-external-vhdx-disk/,找到 docker 数据盘可能的磁盘,我这里是 sdd,直接挂载。

    mkdir docker-data
    mount /dev/sdd docker-data/

    于是,在 docker-data/data/docker/volumes 里能找到正常 docker volumes 目录里的所有文件。

    cd docker-data/data/docker/volumes

    4 (新terminal窗口)在目标主机上建立对应的volumes,然后关掉 docker。

    以 gogs-data 为例,在目标主机上执行

    docker volume create gogs-data
    /etc/init.d/docker stop

    5 从源 WSL 里,rsync 目录

    rsync -av gogs-data root@192.168.11.11:/var/lib/docker/volumes/

    执行完成后,在目标主机上启动 docker

    /etc/init.d/docker start

    如果有多个volume要迁移,迁移完所有的volume之后再start。

    6 目标 Linux 启动对应的docker。

    例如我的 gogs

    docker run --detach --name=gogs -p 10022:22 -p 10880:3000 -v gogs-data:/data gogs/gogs

    再用浏览器访问 192.168.11.11:10880,用之前的凭据登录,一切正常。

    7 收拾残局。

    很遗憾,WSL 2 我不知道怎么正确地 unmount Disk ,我尝试 linux 里 umount 再从外边 wsl --unmount DISK,失败,只能用 wsl --unmount 卸载全部。

  • OpenWRT Auto Bind USB Device to USBIP

    OpenWRT 加载设备自动执行脚本使用的是 hotplug,官方文档在

    https://openwrt.org/docs/guide-user/base-system/hotplug

    一般 Linux 可能要使用 udev。

    此方案的设计目标是,使支持 OpenWRT 的随身路由,通过 USB/IP,改造成车载CAN采集终端,并可以支持远程实时采集、刷写。

    简单的脚本如下。(此处只使用了 ETAS 的产品的 USB VID,其他诸如 Vector,IntrepidCS,Peak 等的,修改 if 的条件即可。)

    /etc/hotplug/usb/99-usbcan

    #!/bin/sh
    
    # ETAS 58x
    #    108c/168/*) # es582.1
    #    108c/169/*) # es584.1
    #    108c/15a/*) # es583.1
    #    108c/159/*) # es581.4
    #    108c/15b/*) # es581.4
    
    if [ "${ACTION}" = "bind" ]; then
        if [[ "${PRODUCT}" =~ "108c/.*" ]]; then
          usbip bind -b ${DEVICENAME}
        fi
    fi
    
    if [ "${ACTION}" = "remove" ]; then
        if [[ "${PRODUCT}" =~ "108c/.*" ]]; then
          usbip unbind -b ${DEVICENAME}
        fi
    fi

    附上记录的日志,内容格式

    "$PRODUCT detected, Action=${ACTION}, DEVICENAME=${DEVICENAME}, DEVICE_TTY=${DEVICE_TTY}, DEVPATH=${DEVPATH}"

    插拔 ES582.1 的日志

    
    108c/168/100 detected, Action=add, DEVICENAME=3-1, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1
    108c/168/100 detected, Action=add, DEVICENAME=3-1:1.0, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1/3-1:1.0
    108c/168/100 detected, Action=add, DEVICENAME=3-1:1.1, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1/3-1:1.1
    108c/168/100 detected, Action=bind, DEVICENAME=3-1, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1
    
    108c/168/100 detected, Action=remove, DEVICENAME=3-1:1.0, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1/3-1:1.0
    108c/168/100 detected, Action=remove, DEVICENAME=3-1:1.1, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1/3-1:1.1
    108c/168/100 detected, Action=unbind, DEVICENAME=3-1, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1
    108c/168/100 detected, Action=remove, DEVICENAME=3-1, DEVICE_TTY=, DEVPATH=/devices/platform/usbdrd3_0/fc000000.usb/xhci-hcd.6.auto/usb3/3-1

    其他已知的 USB VIDs:

    Vector: 0x1248
    Peak System: 0x0C72
    Kvaser: 0x0BFD

    也可以从Linux 内核源码里找 https://github.com/torvalds/linux/tree/master/drivers/net/can/usb

  • USBIP + Windows

    测试环境:Linux(PVE) + Windows 10

    软件 https://github.com/vadimgrn/usbip-win2

    使用设备 ETAS ES582.1

    服务端安装

    # 安装
    apt update
    apt install usbip
    # 加载
    modprobe usbip-host
    modprobe usbip-core
    modprobe vhci-hcd
    # 查看列表,查找到 bus id
    usbip list -l
    # bind 设备
    usbip bind -b 1-3
    # 启动服务端
    usbipd -D

    启动后,服务端会打开 TCP 3240 端口。

    客户端,Windows,安装二进制,按要求重启。

    管理员模式 CMD 允许自定义驱动,执行完再重启

    bcdedit.exe /set testsigning on

    usbip.exe 被加到了 %PATH% 里,我是用的 0.9.5.5 版,命令行需要使用 usbip.exe ,如果使用 usbip 会无响应。

    >usbip.exe list -r 192.168.8.254
    Exportable USB devices
    ======================
        1-3    : Robert Bosch GmbH : unknown product (108c:0168)
               : /sys/devices/pci0000:00/0000:00:14.0/usb1/1-3
               : (Defined at Interface level) (00/00/00)
               :  0 - Communications/Multi-Channel/? (02/04/01)
               :  1 - (Defined at Interface level) (00/00/00)
    >usbip.exe attach -r 192.168.8.254 -b 1-3
    succesfully attached to port 1

    使用 ETAS HSP,设备能正常识别。

    Linux 端,tcpdump 抓包,数据能抓到,但是 WireShark 自带的 dissector 暂时有问题,解析不完整。

    理论上到了 tcp/ip 的这条路,做个 mitm 应该就好搞了。