Users on tuts4you quite often ask questions like "Can you identify which obfuscator was used". When I was analyzing one such assembly, my CFF Explorer started to act erratically. New tabs would not open and on exit CFF Explorer crashed with access violation.
That's weird, I said to myself and decided to figure out what's causing it.
Uninitialized buffers and unchecked return values
First bug is a classic. In pseudo-code it looks like this:
bool ReadResourceHeader(ManagedResource resource, ResourcesInfo *info) { DWORD MagicNumber = ReadDword(); if (MagicNumber != RESOURCES_MAGIC_NUMBER) return FALSE; if (FAILED(ReadSomething(&xyz))) return FALSE; info.FieldX = xyz; ... return TRUE; } void BuggyFunction() { ResourcesInfo info; foreach (ManagedResource resource in exefile) { ReadResourceHeader(resource, &info); for (int i = 0; i < info.EntryCount; i++) { ... } } }
First issue is that nobody initialized ResourcesInfo structure, so all fields will initially contain random garbage. As soon as ReadResourceHeader fails to read or validate something, it returns, and lots of fields will still contain random garbage.
It wouldn't be a big problem, if Daniel checked the return value of the function. But his code just continues processing even if the data initialization failed. And, to make matters worse, it just hides all exceptions by putting try-except handlers around most of the code. No wonder CFF is occasionally acting weird! 🙂
This bug is quite hard to demonstrate, as it needs to have few lucky coincidences in the uninitialized data. But I'm sure that a skilled person would convert it into arbitrary code execution in no time. Not me, though... 🙂
Buffer overflow
Second bug is also a classic. In pseudo-code it looks like this:
WCHAR Str[MAX_PATH]; ZeroMemory(Str, MAX_PATH * sizeof (WCHAR)); if (!DecodeInt(ptr, &NameSize, &ValueSize)) return FALSE; memcpy(Str, ptr, NameSize);
So, what's wrong here? Daniel takes a fixed-size buffer and initializes it with all zeros (unlike previous case). Then he reads size of data (NameSize). And then he copies NameSize bytes into a fixed-size buffer - without checking if that's gonna overflow or not.. Yikes!
Example file demonstrating this bug: https://www.mediafire.com/?x4idsa21toh0t36 (you need to click on Resource Editor -> .NET Resources to trigger the buggy code. Afterwards, CFF Explorer will start acting weird).
Solution
Just like in a previous case where I added support for ConfuserEx and undocumented fields, I had to make few binary patches to CFF Explorer.
Fixed exe file is here: Please get latest version from this post
Have fun and stay safe!
Awesome job as always!
Thank you for all the details.
Best Regards,
Tony
Why doesn't the developer of CFF open-source CFF?
Or why you didn't report the issues to him so he can fix it and push an official update? 😮
He's said several times that CFF is old and unsupported tool - and hasn't released an update for 2.5 years. If you wish, you can nudge him via http://rcecafe.net/?p=250, but I doubt it will change anything.
BTW, making binary patches to closed-source software - that's an extra bit of fun! 😉
Hello kao,
Did this recent fix included the past fixes that already applied by you?
The very old bugs were fixed by CFF author in the release on which this patch is based.
So, this EXE includes 2 fixes:
1) fixes bugs with managed resources described in this article;
2) fixes undocumented field bug exploited by ConfuserEx, as described here: http://lifeinhex.com/improved-cff-explorer/
But if you find a file that CFF Explorer doesn't process correctly, let me know and I'll try to fix that. 🙂
Great job, kao.
Thanks
Nice work!
Mais la première équipe qui devrait monopoliser notre attention est celle de Luffy.