From c5fc081977300966198a090ad394ea5f0aa6a65d Mon Sep 17 00:00:00 2001 From: Leonmmcoset Date: Sat, 28 Feb 2026 19:24:02 +0800 Subject: [PATCH] =?UTF-8?q?hex=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BuildTime.txt | 2 +- GitCommit.txt | 2 +- docs/cmleonos/docs/commands.md | 54 ++++++ shell/CommandList.cs | 3 + shell/Commands/Help/Help.cs | 6 + shell/Commands/Utility/HexCommand.cs | 49 +++++ shell/Commands/Utility/HexEditor.cs | 258 +++++++++++++++++++++++++++ shell/Shell.cs | 7 +- 8 files changed, 378 insertions(+), 3 deletions(-) create mode 100644 shell/Commands/Utility/HexCommand.cs create mode 100644 shell/Commands/Utility/HexEditor.cs diff --git a/BuildTime.txt b/BuildTime.txt index 737410b..e206e17 100644 --- a/BuildTime.txt +++ b/BuildTime.txt @@ -1 +1 @@ -2026-02-28 16:28:03 \ No newline at end of file +2026-02-28 19:13:47 \ No newline at end of file diff --git a/GitCommit.txt b/GitCommit.txt index 2a68d5c..1ecd060 100644 --- a/GitCommit.txt +++ b/GitCommit.txt @@ -1 +1 @@ -02ff829 \ No newline at end of file +58df162 \ No newline at end of file diff --git a/docs/cmleonos/docs/commands.md b/docs/cmleonos/docs/commands.md index 1c06c71..7683804 100644 --- a/docs/cmleonos/docs/commands.md +++ b/docs/cmleonos/docs/commands.md @@ -329,6 +329,60 @@ nano nano myfile.txt ``` +### hex +使用16进制编辑器编辑二进制文件。 + +**用法:** +```bash +hex +``` + +**示例:** +```bash +hex test.bin +hex kernel.sys +``` + +**控制键:** +- `↑ ↓ ← →` - 移动光标 +- `Page Up / Page Down` - 滚动视图 +- `0-9, A-F` - 编辑字节值 +- `S` - 保存文件 +- `Q` - 退出编辑器 + +**说明:** +- 显示文件的16进制字节值和对应的ASCII字符 +- 每行显示16个字节,分为8个字节一组 +- 显示每行的偏移地址(8位16进制) +- 光标位置用白色背景高亮显示 +- 文件修改后显示 [MODIFIED] 标记 +- 支持查看和编辑任意大小的二进制文件 +- 按 S 键保存修改到文件 +- 按 Q 键退出编辑器(不保存修改) + +**界面示例:** +``` +==================================== + Hex Editor +==================================== + +File: test.bin +Size: 256 bytes [MODIFIED] + +00000000 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 00 00 00 |Hello World.....| +00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| + +Cursor: 0x00000000 (0) +Value: 0x48 + +Controls: + Arrow Keys - Move cursor + Page Up/Down - Scroll view + 0-9, A-F - Edit byte + S - Save file + Q - Quit +``` + ## 用户管理命令 ### user diff --git a/shell/CommandList.cs b/shell/CommandList.cs index 3ee5a2f..8abbb7e 100644 --- a/shell/CommandList.cs +++ b/shell/CommandList.cs @@ -214,6 +214,9 @@ namespace CMLeonOS.shell case "snake": shell.PlaySnake(); break; + case "hex": + shell.EditHexFile(args); + break; case "alias": shell.ProcessAlias(args); break; diff --git a/shell/Commands/Help/Help.cs b/shell/Commands/Help/Help.cs index bc7d2a7..abf43ae 100644 --- a/shell/Commands/Help/Help.cs +++ b/shell/Commands/Help/Help.cs @@ -296,6 +296,12 @@ namespace CMLeonOS.Commands Description = "Search text in file" }, new CommandInfo + { + Command = "hex", + Parameters = "", + Description = "Hexadecimal file editor" + }, + new CommandInfo { Command = "ping", Parameters = "", diff --git a/shell/Commands/Utility/HexCommand.cs b/shell/Commands/Utility/HexCommand.cs new file mode 100644 index 0000000..9b4de40 --- /dev/null +++ b/shell/Commands/Utility/HexCommand.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; + +namespace CMLeonOS.Commands.Utility +{ + public static class HexCommand + { + public static void EditHexFile(string args) + { + try + { + if (string.IsNullOrWhiteSpace(args)) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Usage: hex "); + Console.WriteLine("Example: hex test.bin"); + Console.WriteLine(); + Console.WriteLine("Controls:"); + Console.WriteLine(" Arrow Keys - Move cursor"); + Console.WriteLine(" Page Up/Down - Scroll view"); + Console.WriteLine(" 0-9, A-F - Edit byte"); + Console.WriteLine(" S - Save file"); + Console.WriteLine(" Q - Quit"); + Console.ResetColor(); + return; + } + + string filePath = args.Trim(); + + if (!File.Exists(filePath)) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"File not found: {filePath}"); + Console.ResetColor(); + return; + } + + var editor = new HexEditor(filePath); + editor.Run(); + } + catch (Exception ex) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"Error opening hex editor: {ex.Message}"); + Console.ResetColor(); + } + } + } +} diff --git a/shell/Commands/Utility/HexEditor.cs b/shell/Commands/Utility/HexEditor.cs new file mode 100644 index 0000000..770925a --- /dev/null +++ b/shell/Commands/Utility/HexEditor.cs @@ -0,0 +1,258 @@ +using System; +using System.IO; + +namespace CMLeonOS.Commands.Utility +{ + public class HexEditor + { + private byte[] data; + private int cursorPosition; + private int viewOffset; + private int bytesPerLine = 16; + private int bytesPerGroup = 2; + private string filePath; + private bool modified; + private bool running; + + public HexEditor(string path) + { + filePath = path; + if (File.Exists(path)) + { + data = File.ReadAllBytes(path); + } + else + { + data = new byte[256]; + } + cursorPosition = 0; + viewOffset = 0; + modified = false; + running = true; + } + + public void Run() + { + Console.Clear(); + Console.WriteLine("===================================="); + Console.WriteLine(" Hex Editor"); + Console.WriteLine("===================================="); + Console.WriteLine(); + Console.WriteLine("File: " + filePath); + Console.WriteLine("Size: " + data.Length + " bytes"); + Console.WriteLine(); + Console.WriteLine("Controls:"); + Console.WriteLine(" Arrow Keys - Move cursor"); + Console.WriteLine(" Page Up/Down - Scroll view"); + Console.WriteLine(" 0-9, A-F - Edit byte"); + Console.WriteLine(" S - Save file"); + Console.WriteLine(" Q - Quit"); + Console.WriteLine(); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(true); + + while (running) + { + Display(); + HandleInput(); + } + } + + private void Display() + { + Console.Clear(); + Console.WriteLine("===================================="); + Console.WriteLine(" Hex Editor"); + Console.WriteLine("===================================="); + Console.WriteLine(); + Console.WriteLine("File: " + filePath); + Console.WriteLine("Size: " + data.Length + " bytes"); + if (modified) + { + Console.Write(" [MODIFIED]"); + } + Console.WriteLine(); + Console.WriteLine(); + + int lines = (int)Math.Ceiling((double)data.Length / bytesPerLine); + int startLine = viewOffset / bytesPerLine; + int endLine = Math.Min(startLine + 20, lines); + + for (int line = startLine; line < endLine; line++) + { + int offset = line * bytesPerLine; + if (offset >= data.Length) break; + + Console.Write(offset.ToString("X8") + " "); + + for (int i = 0; i < bytesPerLine; i++) + { + int byteOffset = offset + i; + if (byteOffset >= data.Length) + { + Console.Write(" "); + } + else + { + byte b = data[byteOffset]; + bool isCursor = (byteOffset == cursorPosition); + + if (isCursor) + { + Console.BackgroundColor = ConsoleColor.White; + Console.ForegroundColor = ConsoleColor.Black; + } + + Console.Write(b.ToString("X2") + " "); + + if (isCursor) + { + Console.ResetColor(); + } + + if ((i + 1) % bytesPerGroup == 0) + { + Console.Write(" "); + } + } + } + + Console.Write(" |"); + + for (int i = 0; i < bytesPerLine; i++) + { + int byteOffset = offset + i; + if (byteOffset >= data.Length) + { + Console.Write(" "); + } + else + { + byte b = data[byteOffset]; + bool isCursor = (byteOffset == cursorPosition); + + if (isCursor) + { + Console.BackgroundColor = ConsoleColor.White; + Console.ForegroundColor = ConsoleColor.Black; + } + + char c = (b >= 32 && b <= 126) ? (char)b : '.'; + Console.Write(c); + + if (isCursor) + { + Console.ResetColor(); + } + } + } + + Console.WriteLine("|"); + } + + Console.WriteLine(); + Console.WriteLine("Cursor: 0x" + cursorPosition.ToString("X8") + " (" + cursorPosition + ")"); + Console.WriteLine("Value: 0x" + data[cursorPosition].ToString("X2")); + Console.WriteLine(); + Console.WriteLine("Controls:"); + Console.WriteLine(" Arrow Keys - Move cursor"); + Console.WriteLine(" Page Up/Down - Scroll view"); + Console.WriteLine(" 0-9, A-F - Edit byte"); + Console.WriteLine(" S - Save file"); + Console.WriteLine(" Q - Quit"); + } + + private void HandleInput() + { + var key = Console.ReadKey(true); + + switch (key.Key) + { + case ConsoleKey.UpArrow: + cursorPosition = Math.Max(0, cursorPosition - bytesPerLine); + break; + case ConsoleKey.DownArrow: + cursorPosition = Math.Min(data.Length - 1, cursorPosition + bytesPerLine); + break; + case ConsoleKey.LeftArrow: + cursorPosition = Math.Max(0, cursorPosition - 1); + break; + case ConsoleKey.RightArrow: + cursorPosition = Math.Min(data.Length - 1, cursorPosition + 1); + break; + case ConsoleKey.PageUp: + viewOffset = Math.Max(0, viewOffset - (bytesPerLine * 20)); + break; + case ConsoleKey.PageDown: + viewOffset = Math.Min(data.Length - 1, viewOffset + (bytesPerLine * 20)); + break; + case ConsoleKey.D0: + case ConsoleKey.D1: + case ConsoleKey.D2: + case ConsoleKey.D3: + case ConsoleKey.D4: + case ConsoleKey.D5: + case ConsoleKey.D6: + case ConsoleKey.D7: + case ConsoleKey.D8: + case ConsoleKey.D9: + int digit = key.KeyChar - '0'; + EditByte(digit); + break; + case ConsoleKey.A: + EditByte(10); + break; + case ConsoleKey.B: + EditByte(11); + break; + case ConsoleKey.C: + EditByte(12); + break; + case ConsoleKey.D: + EditByte(13); + break; + case ConsoleKey.E: + EditByte(14); + break; + case ConsoleKey.F: + EditByte(15); + break; + case ConsoleKey.S: + SaveFile(); + break; + case ConsoleKey.Q: + running = false; + break; + } + } + + private void EditByte(int value) + { + if (cursorPosition >= 0 && cursorPosition < data.Length) + { + data[cursorPosition] = (byte)value; + modified = true; + } + } + + private void SaveFile() + { + try + { + File.WriteAllBytes(filePath, data); + modified = false; + Console.WriteLine(); + Console.WriteLine("File saved successfully!"); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(true); + } + catch (Exception ex) + { + Console.WriteLine(); + Console.WriteLine("Error saving file: " + ex.Message); + Console.WriteLine("Press any key to continue..."); + Console.ReadKey(true); + } + } + } +} diff --git a/shell/Shell.cs b/shell/Shell.cs index 5742dfe..f89cc4b 100644 --- a/shell/Shell.cs +++ b/shell/Shell.cs @@ -409,7 +409,7 @@ namespace CMLeonOS "cpass", "hostname", "ipconfig", "setdns", "setgateway", "nslookup", "ping", "wget", "ftp", "tcpserver", "tcpclient", "lua", "lua2cla", "cla", "branswe", "beep", "env", "whoami", "uptime", "alias", - "unalias", "base64", "testgui", "ps", "kill" + "unalias", "base64", "testgui", "ps", "kill", "hex" }; } @@ -1066,6 +1066,11 @@ namespace CMLeonOS Commands.System.KillCommand.KillProcess(args, ShowError, ShowWarning); } + public void EditHexFile(string args) + { + Commands.Utility.HexCommand.EditHexFile(args); + } + public void CreateFTP() { Console.WriteLine("====================================");