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
This commit is contained in:
fstat13 committed 2026-10-15 15:54:16 +02:00
1 parent edf3c4c6f2
commit d292d0fbf7
4 files changed
+54 -5

No files matched your search

+1
View File
@@ -14,3 +14,4 @@ _BOZZE/
# runtime
pscapture-app.log
pscapture.ini
dist/SHA256SUMS.txt
+14
View File
@@ -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
```
+12 -1
View File
@@ -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
+27 -4
View File
@@ -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();