Well, we can always fall back to softdev's tool, which works perfectly fine with raw dumps and gcis and official cards. Only thing is that it is closed source (more accurately, source was never released, but it was going to) and that works on GC mode, but there's gamecube homebrew launcher...
BTW, the same gci recovered by softdev's tool and with gcmm+ has some differences (banner format and index bytes on gci header).
I've tested recovering to an unoficial card which never had any luigis mansion savegame, it works fine. Also worked deleting the savegame on oficial card, then restoring gci, but that's probably because the only written part was the directory part, actual game data wasn't written to card (but is is there, as deleting a savegame only deletes the directory entry, allowing to overwrite the actual data).
Here's a pic of diferences between softev's tool recovered gci (below) and gcmm+'s (above)
EDIT:
OK, index is always set to 32 :
/*** Block index does not matter, it won't be restored at the same spot ***/
gci.index = 32;
Seems a good reason.
But banner format is obtained as follows:
gci.banner_fmt = CardStatus->banner_fmt;
And the CardStatus struct is filled by a libogc function, so my guess is that libogc doesn't properly recover the banner_fmt byte.
That would explain those recovered GCI files which banner didn't work but the save still did.
EDIT2:
I've been looking at card.c and I think it would be better to use __cardgetstatusex insted of CardGetStatus function. The ex version works with the directory entry, which is exactly the GCI header, in fact we could just call the function with the gci header structure and it would be filled right away by memcopy.
Probably writing works fine, as the banner byte is written (and as I suspect, causing the banner to not be properly displayed in some games)
I'll try with ctr-gcs (easier to test coz it uses its own card.c)
I have to do more testing on official cards...I should get an official 59block card so I can compare with mu unoficial 59 block one