File: A File to be Processed data. //文件
Start: Offset to Process data. //文件中处理数据的起始位置 (文件的开头位置为0)
Bytes: Bytes to Process. //要处理的字节数量 (如果输入0,则表示从Start开始到文件末尾)
/C: Copy Bytes from File to dstFile. //从源文件向目标文件复制数据
/I: Insert Bytes to dstFile from File. //从源文件向目标文件插入数据,插入数据后目标文件增加 Bytes个字节
dstFile: A File to Write Result data. //目标文件
Address: Offset to Write Result data. //目标文件中要复制或插入数据的位置 (如果目标文件不存在,该值被忽略)
STR
/D: Delete Bytes from File & Write Result to dstFile. //从源文件删除数据并结果写入目标文件
STR
/V: View File In Hex Style. //十六进制方式查看文件
/A: Show ASCII Value. //显示ASCII码
/P: Pause Echo Screen. //满屏暂停
STR :
Bytes: Must be 0. //必须为0
/F: Find String in File. //在文件中查找字符串
/Hex: Hex Style. //十六进制方式
/Asc: ASCII Style. //ASCII码方式
Value: Hex_Digital/ASCII String (40 Characters Maximum). //字符传真的值,最长40个字符 (如果是十六进制串长度应为双数)
/I: Ignore Case. //忽略大小写
/A: Process All Value in File. //在文件中查找所有满足要求的字符串(默认查找1次)
STR :
Bytes: Must be 0. //必须为0
/E: Edit File. //编辑文件
STR
Bytes: Must be 0. //必须为0
/R: Relace SrcString with DstString. //字符常替换
SrcString: :. //源串,可以使用十六进制或ASCII码串
DstString: :. //目标串,可以使用十六进制或ASCII码串
/A: Process All SrcString in File. //在文件中查找所有源字符串(默认替换1次)
说明:
1 使用 /C 和 /I 命令时,如果目的文件不存在,Adress 的值将被忽略,直接执行将源文件从 Start 开始的 Bytes 个字节写入到新创建的目的文件中
2 使用 /C 和 /I 命令时,如果目的文件存在,并且不输入 Address,则Address 默认为0,也就是文件的起始位置。
3 目前处理的单个文件大小不超过 2G
例子:
str 1.exe 0x100 0x10 /d 2.bin 执行将文件1.exe 从位置256开始的16个字节删除,并将结果写入到2.bin,文件2.bin的长度将比1.exe长度小16
str 1.exe 0x100 0x10 /c 2.bin 20 执行将文件1.exe 从位置256开始的16个字节写入到2.bin的20位置,也就是文件2.bin从位置20开始的16字节被覆盖
str 1.exe 0x100 0x10 /i 2.bin 20 执行将文件1.exe 从位置256开始的16个字节插入到2.bin的20位置,结果文件2.bin的长度将增加16字节
str 1.exe 0x100 0 /v /p /a 从文件偏移位置256开始在屏幕上显示文件内容,如果Bytes输入为0,则表示从Start开始至文件末尾。
str 1.exe 0x100 0 /e /hex:11223344 将文件偏移位置256开始的4个字节修改为,0x11,0x22,0x33,0x44。
str 1.exe 0x100 0 /e /asc:1234 将文件偏移位置256开始的4个字节修改为,1234, 也就是0x31,0x32,0x33,0x34
查找替换算法使用的是 KMP 算法,不重复计数,如文件 1.txt 的内容为10个字符0:
0000000000
如执行命令: str 1.txt 0 0 /f /asc:0000 /a
则执行结果为:
Find string At:
0 0x0
4 0x4
不会是:
Find string At:
0 0x0
1 0x1
2 0x2
3 0x3
4 0x4
5 0x5
6 0x6
压缩包中包含DOS版本和Win32版本
2008.12.14 修正替换字符串功能中存在的问题
2008.12.19 修正19楼存在问题
2009.2.15 测试版本在50楼
[ Last edited by 19951001 on 2020-11-16 at 17:01 ]
Gemini 解答
技术背景与功能实现解析
STR工具是一个针对 DOS 与 Win32 环境设计的命令行二进制文件处理器。在 2000 年代中后期的 DOS 技术社区中,这类工具常用于补丁制作、汉化修改、自动化脚本处理以及对二进制数据流的精确控制。1. 核心操作模式:复制、插入与删除
该工具通过区分
/C(Copy)、/I(Insert) 和/D(Delete) 三种模式,解决了二进制文件编辑中常见的对齐与位移问题:
- 覆盖模式 (/C):对应于传统的随机读写(Random Access)操作,使用
fseek定位后直接fwrite,目标文件长度仅在写入位置超过原文件末尾时才会增加。- 插入模式 (/I):这在低级语言实现中较为复杂。程序需要先将目标文件从
Address处起的后续数据向后移动Bytes个字节(通常在内存中缓存或通过临时文件交换),然后再写入源数据。- 删除模式 (/D):实质是文件的“裁剪”操作,将
Start之前和Start + Bytes之后的数据拼接并写入新文件。2. 文件大小限制与偏移量处理
帖子提到“处理单个文件大小不超过 2G”。这是由于工具在 32 位环境下开发,使用了符号化的 32 位整数(
signed long)来表示文件指针偏移量。在 C 标准库的fseek和ftell函数中,偏移量上限为 $2^{31}-1$ 字节,即 2,147,483,647 字节(2GB)。若要处理超过 2GB 的文件,在 DOS 环境下需依赖编译器特定的 64 位 I/O 函数(如_fseeki64)或直接调用中断/系统 API(如 DOS 的INT 21h, AX=4200h虽然也是 32 位,但某些扩展环境支持更大寻址)。3. 搜索算法:KMP 与不重复计数
作者明确指出使用了 KMP (Knuth-Morris-Pratt) 算法。
- 算法优势:KMP 算法在处理二进制搜索时具有 $O(m+n)$ 的时间复杂度,通过预处理模式串的“失配函数”(Partial Match Table),避免了在匹配失败时回溯主串指针,这对于大文件和磁盘 I/O 密集型操作具有显著的性能优势。
- 非重叠匹配逻辑:示例中提到的
0000匹配0000000000得到 0 和 4 的偏移位置。这符合工程实践中的“消耗性匹配”原则——一旦一个子串被匹配,搜索指针会跳转到该子串末尾之后开始下一次搜索。这与文本替换逻辑一致,防止了因重叠而导致的逻辑混淆或死循环替换。4. 字符串输入与十六进制转换
工具支持
/Hex和/Asc两种输入方式,这在 DOS 开发中是典型的需求。
- 十六进制处理:程序通常需要将输入的字符串(如
112233)按每两个字符一组转换为一个字节。作者提醒“十六进制串长度应为双数”,是为了确保字节对齐,防止在处理末尾孤立字符时产生歧义。- 大小写忽略 (/I):在二进制搜索中,
/I通常仅对/Asc模式有效。它在内部实现时,会将主串和模式串的字节统一转换为大写(或小写)后再进行比较。5. 环境兼容性:DOS 与 Win32
提供 DOS 版本通常意味着程序采用了 DJGPP(支持 32 位保护模式的 DPMI 环境)或 Turbo C/Borland C++(16 位实模式)进行编译。考虑到 2GB 文件的处理能力,该 DOS 版本极大概率是基于 DPMI 扩展的 32 位 DOS 程序,否则在 16 位实模式下,处理超过 64KB 的内存缓冲区或 2GB 的文件定位会面临显著的段寻址限制。
6. 异常处理与边界条件
- 目标文件不存在:工具在
/C或/I模式下若找不到dstFile会自动创建,此时Address失去偏移意义,等同于文件提取。- 十六进制查看 (/V):这是典型的 Hex Dump 实现,通常以 16 字节为一行,左侧显示十六进制码,右侧显示可打印的 ASCII 字符,不可打印字符则以点号
.代替。该工具是典型的 DOS 末期至 Windows 普及期过渡阶段的技术产物,强调对底层数据的直接操纵,而不依赖重型的十六进制编辑器界面,适合在批处理脚本中实现自动化部署。
