From d292d0fbf7434d1aeda50103911e4d2a18266b85 Mon Sep 17 00:00:00 2001 From: fstat13 Date: Thu, 15 Oct 2026 15:54:16 +0200 Subject: [PATCH] fix: harden FTP/send paths and driver registration (audit round) - send_all(): full send loop for the elfldr payload push and the FTP STOR (a single send() can legally transfer less than requested) - PASV: check command result and zero the buffer before parsing (no more parsing of uninitialized stack on FTP failure) - DllRegisterServer: verify the per-user key was actually written and return a real HRESULT instead of unconditional S_OK - README: 'Verify the download' section with release checksums --- .gitignore | 1 + README.md | 14 ++++++++++++++ pc/ps5cam.c | 13 ++++++++++++- pc/pscapture.c | 31 +++++++++++++++++++++++++++---- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 41db072..f827305 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ _BOZZE/ # runtime pscapture-app.log pscapture.ini +dist/SHA256SUMS.txt diff --git a/README.md b/README.md index acc2173..619fcac 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,20 @@ IP — the app retries by itself every 2 seconds. 🔧 What the app does under the hood when you press Start: [`docs/INSTALLER.md`](docs/INSTALLER.md). +## 🔒 Verify the download + +The release binaries are built from this repository's sources. Every release +carries a `SHA256SUMS.txt` — check it before running the exe: + +``` +certutil -hashfile pscapture.exe SHA256 (Windows) +sha256sum -c SHA256SUMS.txt (Linux/macOS) +``` + +And you never have to trust any binary: the whole toolchain is documented in +[`docs/BUILD.md`](docs/BUILD.md) — rebuild `pscapture.exe` from the sources +yourself and compare. + ## 📦 Repository layout ``` diff --git a/pc/ps5cam.c b/pc/ps5cam.c index f7d7df1..5dff530 100644 --- a/pc/ps5cam.c +++ b/pc/ps5cam.c @@ -2545,11 +2545,22 @@ __declspec(dllexport) HRESULT WINAPI DllRegisterServer(void) { WCHAR dll[MAX_PATH]; + WCHAR p[512]; + WCHAR guid[64]; + HKEY k; if(!GetModuleFileNameW(g_hinst_ps5cam, dll, MAX_PATH)) return E_FAIL; registra(HKEY_CURRENT_USER, dll); /* niente admin */ registra(HKEY_LOCAL_MACHINE, dll); /* se siamo admin, meglio */ - return S_OK; + /* il risultato si verifica davvero: se almeno la chiave per-utente e' + * leggibile la registrazione e' utilizzabile (HKCR unisce HKCU+HKLM) */ + StringFromGUID2(&CLSID_Ps5Cam, guid, 64); + wsprintfW(p, L"Software\\Classes\\CLSID\\%s\\InprocServer32", guid); + if(RegOpenKeyExW(HKEY_CURRENT_USER, p, 0, KEY_READ, &k) == ERROR_SUCCESS) { + RegCloseKey(k); + return S_OK; + } + return E_FAIL; } __declspec(dllexport) HRESULT WINAPI diff --git a/pc/pscapture.c b/pc/pscapture.c index 841afcc..c534990 100644 --- a/pc/pscapture.c +++ b/pc/pscapture.c @@ -243,6 +243,22 @@ ftp_cmd(int c, const char *cmd, char *risp, int sz) return buf[0] == '2' || buf[0] == '3' || buf[0] == '1' ? 0 : -1; } +/* invio completo: TCP non garantisce che una singola send() trasferisca + * tutti i byte richiesti */ +static int +send_all(int s, const char *d, int len) +{ + int off = 0; + + while(off < len) { + int n = send((SOCKET)s, d + off, len - off, 0); + + if(n <= 0) return -1; + off += n; + } + return 0; +} + static int ftp_leggi_file(const char *ip, const char *file, char *out, int outsz) { @@ -251,7 +267,8 @@ ftp_leggi_file(const char *ip, const char *file, char *out, int outsz) int n; if(c < 0) return -1; - ftp_cmd(c, "PASV\r\n", buf, sizeof(buf)); + memset(buf, 0, sizeof(buf)); + if(ftp_cmd(c, "PASV\r\n", buf, sizeof(buf))) goto ko; { char *p = strchr(buf, '('); unsigned h1, h2, h3, h4, p1, p2; @@ -292,7 +309,8 @@ ftp_manda_file(const char *ip, const char *remoto, const unsigned char *d, char buf[4096]; if(c < 0) return -1; - ftp_cmd(c, "PASV\r\n", buf, sizeof(buf)); + memset(buf, 0, sizeof(buf)); + if(ftp_cmd(c, "PASV\r\n", buf, sizeof(buf))) goto ko; { char *p = strchr(buf, '('); unsigned h1, h2, h3, h4, p1, p2; @@ -310,7 +328,7 @@ ftp_manda_file(const char *ip, const char *remoto, const unsigned char *d, if(recv((SOCKET)c, buf, sizeof(buf) - 1, 0) <= 0 || buf[0] != '1') goto ko; } - if(send((SOCKET)ds, (const char *)d, len, 0) != len) goto ko; + if(send_all(ds, (const char *)d, len)) goto ko; closesocket((SOCKET)ds); ds = -1; recv((SOCKET)c, buf, sizeof(buf) - 1, 0); @@ -575,7 +593,12 @@ lavoro_deploy(LPVOID p) free(elf); return 1; } - send((SOCKET)s, (const char *)elf, len, 0); + if(send_all(s, (const char *)elf, len)) { + logUI("ERRORE: invio payload all'elfldr incompleto"); + closesocket((SOCKET)s); + free(elf); + return 1; + } /* 3) leggi lo stream di log per qualche secondo */ { DWORD t0 = GetTickCount();