Reading contents of ESP8266 Flash from inside sketch
I think you're reading of flash is slightly wrong

while ESP.flashRead takes a unit32_t pointer for output data, the read "count" argument is in bytes - looking at Updater.cpp code it does this

uint8_t buff[128];
for(int i = 0; i &lt; binSize; i += sizeof(buff)) {
  ESP.flashRead(_startAddress + i, (uint32_t *)buff, sizeof(buff));
  .....
}


so, the the address and count are in bytes - given that SPI_FLASH_SEC_SIZE is 0x1000 or 4096, your code is doing the following


reading 4096 bytes into a 16384 buffer
writing 16384 bytes (so the last 12288 bytes are zero, or random, not sure)
adding 4096 to the address
subtracting 16384 from size
repeat until all read


So, the written size will be correct, but the data will be three quarters wrong :p

Therefore, your code should be

unsigned long addr = 0;
unsigned long rem = ESP.getSketchSize();
uint8_t *data = new uint8_t[SPI_FLASH_SEC_SIZE];
int sz = SPI_FLASH_SEC_SIZE;
File f = SPIFFS.open("/fw.bin", "w");

while (rem &gt; 0) {
    ESP.flashRead(addr, (uint32_t *)data, SPI_FLASH_SEC_SIZE);
    if (rem &lt; sz)
        sz = rem;
    f.write(data, sz);
    addr += SPI_FLASH_SEC_SIZE;
    rem -= sz;
    yield();
    Serial.println(rem);
}

f.flush();
f.close();