2

I'm trying to figure out how to unpack the payload data made by NSISbi for of NSIS that adds support for installer size > 2GB. Here is an example installer: https://download.unity3d.com/download_unity/068178b99f32/Windows64EditorInstaller/UnitySetup64-2020.2.2f1.exe

Here are small examples of payloads between vanilla NSIS and NSISbi: https://www.dropbox.com/sh/jn4iyppbj1v8fmf/AAAsqlymn8AHgYhSPAG9iU7Ka?dl=1

7zip used to work on NSIS and forks but it cant open this one. So far I have figured out that there is some changes in signature match: 30000000EFBEADDE4E756C6C736F6674496E7374 (0 ï¾­ÞNullsoftInst) and the payload size that comes after signature (skipping 4 bytes) is now no longer int32 but int64 (since it is a native int to have support for larger address): enter image description here

Just doing these changes (removing extra 30 00 00 00 from signature and extra bytes form payload size) to payload results in 7zip being able to partially open the zlip/blip/lzma compressed data but a lot of entries are missing and some names broken.

1 Answer 1

3

thanks for using nsisbi, which is my fork of nsis. The source code for both is available, but most of what you are looking for is in 'Source\exehead\fileform.h', which I will summarize.

The first header has a flags int32, and I've added extra flags to specify what was configured at compile time so that it's easier to decompile. See the word 'NullsoftInst' in your example? Those are int32 3, 4 and 5 of the first header. The flags are the first int32, and the second int is the signature (0xDEADBEEF), which is backwards because of endianness in that hex dump of yours. Int32 6 is the length of the main header, and int32 7 is the length of all following data including the first header, the datablock and crc on the end.

The first header is 8 bytes longer, as it stores the total length of the datablock for external files. I just appended it to the end of the existing 7 int32 (low 4 bytes first, high 4 bytes second).

For the instruction fields, the size has been increased to 8 int32, instead of 6. For the file offset I just inserted the high int32 part after the existing int32 (which is now the low part), which means the fields got moved down one int32 (this is a fixed flag in nsisbi, which is always on). Also, most of the instructions that store data also use a slot for a crc32 value, which for most cases I appended to the end (the writeuninstaller instruction has 2 crcs).

In 7208, I added support for files bigger than 2GB, which means the 'first int' in the datablock varies in size (int32 or int64) when it was compiled by the C\C++ compiler. I added a flag for this in the header. This is on by default in 7208 and up (in previous versions it was always int32).

Hope this helps, JasonFriday13.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.