diff --git a/CODE/desktop/input.c b/CODE/desktop/input.c index 2b714b1..f28b241 100644 --- a/CODE/desktop/input.c +++ b/CODE/desktop/input.c @@ -130,6 +130,21 @@ void cursor_restore_bg(void) { } void cursor_draw(int mx, int my) { + /* 白色指针 + 黑色描边:描边 = 空心像素且 8 邻域有实心(不出保存区) */ + for (int r = 0; r < CURSOR_SIZE; r++) { + for (int c = 0; c < CURSOR_SIZE; c++) { + if (cursor_shape[r][c]) continue; + int near = 0; + for (int dy = -1; dy <= 1 && !near; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int rr = r + dy, cc = c + dx; + if (rr < 0 || rr >= CURSOR_SIZE || cc < 0 || cc >= CURSOR_SIZE) continue; + if (cursor_shape[rr][cc]) { near = 1; break; } + } + } + if (near) du_pixel(&g_fb, mx + c, my + r, 0xFF000000u); + } + } for (int r = 0; r < CURSOR_SIZE; r++) { for (int c = 0; c < CURSOR_SIZE; c++) { if (cursor_shape[r][c]) { diff --git a/CODE/firstInit/main.c b/CODE/firstInit/main.c index 98e53fd..e713c9c 100644 --- a/CODE/firstInit/main.c +++ b/CODE/firstInit/main.c @@ -499,8 +499,8 @@ static void cursor_draw(u32 *fb, i64 mx, i64 my) { cursor_bg_valid = 1; cursor_cur_x = mx; cursor_cur_y = my; - /* draw cursor shape(全白指针,深色描边改白) */ - u32 white = 0xFFFFFFFF, dark = 0xFFFFFFFF; + /* draw cursor shape(白色指针 + 纯黑描边,'X'=描边 'O'=填充) */ + u32 white = 0xFFFFFFFF, dark = 0xFF000000; for (i64 y = 0; y < CUR_H; y++) { i64 py = my + y; if (py < 0 || (u64)py >= fb_h) continue; diff --git a/CODE/login/main.c b/CODE/login/main.c index 75c993f..a8c849a 100644 --- a/CODE/login/main.c +++ b/CODE/login/main.c @@ -350,6 +350,27 @@ static void cursor_restore_bg(u32 *fb) { static void cursor_draw(u32 *fb, int mx, int my) { u32 fg = 0xFFFFFFFF; /* 白色指针 */ + /* 黑色描边:空心像素且 8 邻域有实心 */ + for (int r = 0; r < CURSZ; r++) { + for (int c = 0; c < CURSZ; c++) { + if (cursor_shape[r][c]) continue; + int near = 0; + for (int dy = -1; dy <= 1 && !near; dy++) { + for (int dx = -1; dx <= 1; dx++) { + int rr = r + dy, cc = c + dx; + if (rr < 0 || rr >= CURSZ || cc < 0 || cc >= CURSZ) continue; + if (cursor_shape[rr][cc]) { near = 1; break; } + } + } + if (near) { + int x = mx + c, y = my + r; + if (x >= 0 && (u64)x < fb_w && y >= 0 && (u64)y < fb_h) { + u32 *line = (u32 *)((u8 *)fb + (u64)y * fb_p); + line[x] = 0xFF000000u; + } + } + } + } for (int r = 0; r < CURSZ; r++) { for (int c = 0; c < CURSZ; c++) { if (!cursor_shape[r][c]) continue; diff --git a/CODE/login/patch_login_hash.ps1 b/CODE/login/patch_login_hash.ps1 index 6641efb..518ee86 100644 --- a/CODE/login/patch_login_hash.ps1 +++ b/CODE/login/patch_login_hash.ps1 @@ -1,36 +1,34 @@ -# patch_login_hash.ps1 — login.elf .text 防篡改哈希补丁 -# 用法: powershell -File patch_login_hash.ps1 -# 计算 .text 段的 SHA256,写入 .hashseg 段(__expected_hash,32 字节)。 -param([Parameter(Mandatory=$true)][string]$ElfPath) +# patch_login_hash.ps1 - patch login.elf .text SHA256 into .hashseg +# usage: powershell -File patch_login_hash.ps1 [login.elf] +param([string]$ElfPath = "..\..\SYSTEM\system\user\use\login.elf") -if (-not (Test-Path $ElfPath)) { Write-Error "not found: $ElfPath"; exit 1 } +if (-not (Test-Path $ElfPath)) { Write-Error ("not found: " + $ElfPath); exit 1 } $bytes = [System.IO.File]::ReadAllBytes($ElfPath) # ELF64 header: e_shoff @ 0x28 (u64), e_shentsize @ 0x3A (u16), e_shnum @ 0x3C (u16) -function U64($b, $o) { [UInt64]$b[$o] -bor ([UInt64]$b[$o+1] -shl 8) -bor ([UInt64]$b[$o+2] -shl 16) -bor ([UInt64]$b[$o+3] -shl 24) -bor ([UInt64]$b[$o+4] -shl 32) -bor ([UInt64]$b[$o+5] -shl 40) -bor ([UInt64]$b[$o+6] -shl 48) -bor ([UInt64]$b[$o+7] -shl 56) } -function U16($b, $o) { [UInt32]$b[$o] -bor ([UInt32]$b[$o+1] -shl 8) } -function U32($b, $o) { [UInt32]$b[$o] -bor ([UInt32]$b[$o+1] -shl 8) -bor ([UInt32]$b[$o+2] -shl 16) -bor ([UInt32]$b[$o+3] -shl 24) } +function U64([byte[]]$b, [int]$o) { [UInt64]$b[$o] -bor ([UInt64]$b[$o+1] -shl 8) -bor ([UInt64]$b[$o+2] -shl 16) -bor ([UInt64]$b[$o+3] -shl 24) -bor ([UInt64]$b[$o+4] -shl 32) -bor ([UInt64]$b[$o+5] -shl 40) -bor ([UInt64]$b[$o+6] -shl 48) -bor ([UInt64]$b[$o+7] -shl 56) } +function U16([byte[]]$b, [int]$o) { [UInt32]$b[$o] -bor ([UInt32]$b[$o+1] -shl 8) } +function U32([byte[]]$b, [int]$o) { [UInt32]$b[$o] -bor ([UInt32]$b[$o+1] -shl 8) -bor ([UInt32]$b[$o+2] -shl 16) -bor ([UInt32]$b[$o+3] -shl 24) } $shoff = U64 $bytes 0x28 $shentsize = U16 $bytes 0x3A $shnum = U16 $bytes 0x3C $textOff = 0; $textSize = 0; $hashOff = 0 +$shstr = $null for ($i = 0; $i -lt $shnum; $i++) { $sh = $shoff + $i * $shentsize - $nameIdx = U32 $bytes $sh $shType = U32 $bytes ($sh + 4) $shOffset = U64 $bytes ($sh + 24) $shSize = U64 $bytes ($sh + 32) - # sh_name indexes .shstrtab; resolve names via that section lazily - if ($shType -eq 3 -and -not $shstr) { $shstrOff = $shOffset; $shstrSize = $shSize; $shstr = $bytes[$shstrOff..($shstrOff+$shstrSize-1)] } + if ($shType -eq 3 -and -not $shstr) { $shstr = $bytes[[int]$shOffset..[int]($shOffset+$shSize-1)] } } -function Get-Name([int]$idx) { +function Get-SectName([byte[]]$strtab, [int]$idx) { $end = $idx - while ($shstr[$end] -ne 0) { $end++ } - [System.Text.Encoding]::ASCII.GetString($shstr, $idx, $end - $idx) + while ($strtab[$end] -ne 0) { $end++ } + [System.Text.Encoding]::ASCII.GetString($strtab, $idx, $end - $idx) } for ($i = 0; $i -lt $shnum; $i++) { @@ -39,7 +37,7 @@ for ($i = 0; $i -lt $shnum; $i++) { $shType = U32 $bytes ($sh + 4) $shOffset = U64 $bytes ($sh + 24) $shSize = U64 $bytes ($sh + 32) - $nm = Get-Name $nameIdx + $nm = Get-SectName $shstr $nameIdx if ($nm -eq '.text' -and $shType -eq 1) { $textOff = $shOffset; $textSize = $shSize } if ($nm -eq '.hashseg') { $hashOff = $shOffset } } @@ -53,5 +51,6 @@ $hash = $sha.ComputeHash($textBytes) [Array]::Copy($hash, 0, $bytes, [int]$hashOff, 32) [System.IO.File]::WriteAllBytes($ElfPath, $bytes) -Write-Host "[patch_login_hash] .text($textSize B) SHA256 -> .hashseg @ $hashOff : $(($hash[0..3] | ForEach-Object { $_.ToString('x2') }) -join '')..." +$hex = ($hash[0..3] | ForEach-Object { $_.ToString('x2') }) -join '' +Write-Host (".text(" + $textSize + " B) SHA256 -> .hashseg @ " + $hashOff + " : " + $hex + "...") exit 0