06 Feb

Updated Molebox unpacker

During last year, the most common complaint on this blog was "your Molebox unpacker cannot unpack this crazy big EXE of MMORPG game X, Y or Z."

Sounds like an easy problem to fix, right? Well, that's not true - but I finally did it!

TL;DR - new version of unpacker is here: https://www.mediafire.com/?t3xw46s554it5fp

In the rest of the post I'll describe the obstacles I had to overcome while solving this seemingly simple problem.

Delphi TMemoryStream limitation

First, unpacker is written using classic (non-.NET) Delphi and compiled as x86 executable. And standard Delphi streams are retarded. TMemoryStream uses GetMem - which ends up somewhere in Delphi memory manager and VirtualAlloc. That doesn't work well with 800+MB files.

I ended up with implementing custom stream backed by temporary file (CreateFile with FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE).

Pointer magic

Since the original unpacker was using TMemoryStream, the whole file was loaded in memory as a continuous memory block and I could easily read/write each byte of file using pointers. Something like this:

Guess what? Files don't work that way.. sad I had to do a full and complete rewrite of all those methods.

Zlib conflicts

Original unpacker was compiled with Delphi 3. Delphi 3 didn't have Zlib library, so you had to supply your own Zlib implementation. But it won't compile with new versions of Delphi, giving error message

Unit Graphutil was compiled with a different version of zlib.TZDecompressionStream.

The solution was to get rid of my Zlib implementation and rewrite all methods that deal with decompression.

ANSI strings

In Delphi 3 all strings were ANSI. Starting from Delphi 2007, strings are Unicode. Since Molebox internally uses ANSI, it required changing quite a few structure definitions and rewriting several string manipulation routines. It's a lot of fun (and source of the most obscure bugs), trust me!

Conclusion

I hope you find this unpacker useful. But if it doesn't work for you, please send me an error report with all the details you can and I'll try to fix it. Have fun!

Download link: see https://lifeinhex.com/yet-another-update-to-molebox-unpacker/ for an updated version.

01 Feb

Moving to a new host

Last week MaxXor suggested that I should add HTTPS support to my blog. My existing free host (bplaced) doesn't offer HTTPS, so I decided to finally switch to paid hosting. After thinking a bit, reading customer references, I chose Active24 - and so far the experience has been overwhelmingly positive.

  • Webhost was set up within minutes, including self-signed HTTPS certificate;
  • As soon as you update your DNS entries, Let's Encrypt certificate is issued automatically. You don't need to do anything yourself!
  • Unlimited disk space;
  • Unlimited traffic;
  • Unlimited cron jobs;
  • And everything "just works™";

For now HTTPS is optional (try https://lifeinhex.com/), I'll start enforcing HTTPS in a few days after fixing all the mixed-content warnings. smile

Have fun and stay safe (and let me know if you notice any issues)!

26 Jan

Abusing Microsoft-signed executables

This morning I noticed an article from Cylance named "Graftor Variant Leveraging Signed Microsoft Executable". It's a nice article, so I can really recommend you read it.

TL;DR version: Graftor authors are using DLL hijacking in SrcTool.exe to load their own dbghelp.dll. If antimalware solution trusts executable that's signed by Microsoft (most of them do!) and doesn't check all the DLLs it loads, malicious code will not be detected.

Other vulnerable files

I decided to look for other Microsoft-signed files that could be abused in a similar manner. One quick search for EXE files in folder C:\Program Files (x86)\Windows Kits that also contain string dbghelp.dll and here's the result:

  • agestore.exe
  • cdb.exe
  • dbh.exe
  • kd.exe
  • mftrace.exe
  • ntkd.exe
  • ntsd.exe
  • srctool.exe
  • symchk.exe*
  • symstore.exe
  • tlist.exe
  • tracefmt.exe
  • tracepdb.exe

*symchk.exe also requires SymbolCheck.dll.

All these files are statically linked to dbghelp.dll and therefore vulnerable to DLL hijacking. agestore.exe, mftrace.exe, srctool.exe, symstore.exe, tlist.exe, tracefmt.exe and tracepdb.exe are the best targets - if you don't pass any command-line to them, they load dbghelp.dll but don't call any of its APIs and therefore will not crash.

Demo time

Here's a small fake dbghelp.dll you can use for testing: https://www.mediafire.com/?yx677bhxtyc13pu

Place it in the folder with vulnerable EXE lies and run the EXE. If a "DLL Hijacking" messagebox shows up, the EXE is vulnerable. smile Something like this:

Have fun and keep it safe!

18 Jan

Blog not dead

I just noticed that I haven't published a full-length post for almost 2 months already. sad Let me assure you, this blog is not dead, I just had a peaceful Christmas vacation. Here's what else is new..

Domain renewal

I'm still having fun writing this blog. So, I've renewed the domain for one more year. Since I'm using a free shared hosting, HTTPS is not an option. But if you would really like to see that (or any other improvements to the site), please let me know in the comments.

WordPress update

As you probably have noticed, this blog is running on WordPress. And since my webhost has really tough restrictions on what can be done with shared hosting accounts, automatic update of WordPress is not possible. So, I updated the engine manually to the latest version 4.7.1.

Last night there was some short outage but it was more likely caused by maintenance on the webhost. But please do let me know if you notice any issues with the site!

Improved Enigma Virtual Box unpacker

One of the most requested features for Enigma Virtual Box unpacker was support for large files. I had to rewrite quite a lot of stuff to make it happen but now it works fine for files up to 4GB (and possibly more). wink It's finished but I need to test the unpacker properly before making it public.

Improved Molebox unpacker

Again, one of the most requested features is to support huge files (500MB+). Since the original unpacker was written in 2009, compiled only with Delphi 4 and was intended to unpack regular EXE files, I had to rewrite pretty much everything from scratch - so I'm happy to say that it's 90% done. I should be able to wrap it up in a few weeks and then make it public.

Blog post about video-to-exe DRM protections

Every once in a while someone in Tuts4You asks about video-to-exe or pdf-to-exe "protections". Every single one I've seen so far has been just a snake oil. In the article I'll document the methods used by these "protections" to encrypt video/PDF and prevent user from extracting original file out of EXE. You won't believe how much time and effort goes into preparing a single technical blog post - so don't expect it to be finished any time soon. wink

Have fun and talk to you all later!

02 Dec

Deobfuscating AutoIt scripts

Every once in a while, someone posts an interesting challenge concerning protected or obfuscated AutoIt scripts. Today I'd like to show some basic approaches to AutoIt deobfuscation. As a target I'll use a very simple protection called AutoGuardIt and the crackme from Tuts4You thread. If you don't have access to Tuts4You, here is the alternative download link: https://www.mediafire.com/?qs52emp7tkk472g

In general, there is nothing hard in decompiling AutoIt scripts. The Autoit script interpreter is designed in such a way that it's really easy to convert P-Code back to the script form. There's also a tidy.exe utility which takes ugly hand-written script and reformats it to make it really pretty. All of this makes writing deobfuscators much easier because you can start with well-formatted AutoIt script and your deobfuscator can consist of simple regexps and string replaces. It will not be very pretty code but it will work.

While I was preparing this blog post, SmilingWolf came up with a full-featured solution written in Python. It's a nice solution but it doesn't explain how or why it works. So, in this article I will explain how the protection works, show the basic techniques and sample source code to defeat each of the protection steps. Making a full-featured deobfuscator is left as an exercise for the reader.

Required tools

  • C# compiler. All my examples were tested under Visual Studio 2010 but any recent version should do
  • MyAutToExe. I'm using my personal modification of myAutToExe. You can download it from Bitbucket: https://bitbucket.org/kao/myauttoexe
  • Tool for testing regexps. I'm using http://regexr.com/
  • Some brains. You can't become a reverser if you can't think for yourself.

Decompiling the script

There are 2 public tools for extracting compiled AutoIt script: MyAutToExe and Exe2Aut.

Exe2Aut uses dynamic approach for obtaining script - it runs the file and gets decrypted and decompressed script from process memory. That's usually the easiest way but you really don't want to run the malware on your computer.

MyAutToExe uses static approach - it analyzes file and tries to locate, decrypt and decompress the script on its own. That's more safe approach but it's easier to defeat using different packers, modified script markers and so on. To extract script from this crackme, I used my own MyAutToExe (see "Required tools" section above).

Analyzing the obfuscation

Once the script is extracted and decompiled, it looks quite strange and unreadable:

Let's look at each of the obfuscation techniques and see how it works and how it can be defeated.

Integer decomposition

AutoGuardIt takes constants and converts them to series of math operations. Example:

Deobfuscator should be able to take the expression, evaluate it and replace the expression with the correct value.

The biggest problem here is the precedence of operations (multiply and divide should be processed before addition and subtraction), so you can't start from the beginning of line and do it one step at a time. This would be wrong:

After some thinking and few Google searches, I found a LoreSoft.MathExpressions library that does all the heavy lifting for me. smile

The following C# code snippet will find all math expressions, extract them, evaluate them and replace expression with the actual value:

Pseudo-random integers

This is quite strange protection that relies on a fact that AutoIt's Random function is actually pseudo-random number generator. If you seed it with the same seed, you get the same results. Example:

In general, it's a very bad idea because there's no guarantee that random number generator will not change in the next version of AutoIt. But for now it works..

Since I was already using myAutToExe, I decided to use RanRot_MT.dll from the package.

a = StringLen("xyz")

Small integers can be obfuscated by using function StringLen:

To clean them up, a simple regex can be used:

End result:

Chr(x)

Some strings in the executable are split into bytes, and each byte is then encoded as call to Chr function:

Another simple regex will kill all of those:

The result will be valid but still hardly readable string:

And one more simple search-replace will fix that:

End result:

If 1 Then

Once you remove the integer obfuscations, you'll see a lot of useless statements like this:

This condition is always true, so we can remove both If and EndIf lines and improve readability.

The problem here is that If's can be nested and you can't just remove first EndIf that you encounter. Consider this example:

Taking all that into account, I came up with this ugly but working* code:

* - see below for some scenarios where this code might fail.

If a = a Then

Variation of previous protection. In such cases, using regexp is much more efficient than simple string comparison

Do Until 1

It's pretty much the same protection as If 1 Then and it can be defeated the exact same way.

While 1 / ExitLoop / WEnd

Another protection of the same kind, just uses 3 lines of code instead of 2. Same approach, just make sure you match the correct lines and remove all 3 of them.

For $random=0 to 123.456 / ExitLoop / Next

Another protection, very similar to previous ones.

Here one must be very careful not to remove the real for cycles from program, so it's better to use regexps. Apart from that, it's pretty much the same code again.

Assign/Execute

This type of protection relies on AutoIt's Assign function. First, an alias to a function is defined:

Later, alias is used to call the function:

Deobfuscation is a simple operation: find all calls to Assign, extract the variable name and the function name, then replace all references to the variable with the function name:

BinaryToString

As you can see in the example above, some strings in the script are replaced with calls to BinaryToString. Here's a another example of the same protection where part of code is replaced with BinaryToString + call to Execute.

Merging all 3 lines into one and converting hex strings to bytes gives us the following code:

which using the methods described earlier can be deobfuscated as:

Functions returning constants

Some strings are not only encoded using BinaryToString but also moved to a separate function.

Deobfuscated code will look like this:

It's quite tricky to find the correct return value for each function and replace function calls with correct values. In addition to that, regexes aren't really suitable for such tasks. smile The code I wrote is really ugly, so I'm not going to show it. Go, figure it out yourself! smile

Switch control-flow obfuscation

This is actually the hardest one of them all. The example code looks like this:

You must find the initial value of the variable. Then you must find the correct start/end of the Switch, all the switch cases and all other assignments to the control variable. Then you'll be able to reorder all the code. It's a moderately hard problem for which I don't have a pretty solution. smile

Here's my code which seems to work:

After cleanup, the deobfuscated code looks like this:

Unused variable assignments

There are random variable assignments sprinkled all over the code.

They are only assigned once and never used. To clean them up, one can locate the assignments using regex, count how many times this variable appears in the code and remove it, if it's only assigned once. Something like this:

You can remove string and integer assignments using very similar regex.

Lather, rinse, repeat

If you run each of the mentioned deobfuscations only once, you'll end up with half-deobfuscated code. Also, there isn't one specific order in which the deobfuscations should be applied. Of course, you could just run the entire loop 100 times, but it's just ugly.

Therefore, I prefer to run the code in the loop like this:

It will run all the deobfuscations until there's nothing left to clean up. Then run tidy.exe on the output and you'll get a nicely readable script.. smile

Possible problems and gotchas

Deobfuscators based on string matching are very easy to implement. However, one must be very careful to write correct regular expressions and string comparisons. My example code works very well on this specific crackme. However, it will mess up with code like this:

You can work around such issues by using more specific regexes with anchors. During my research, I used http://regexr.com/ a lot, and I find it really helpful. Give it a try!

Conclusion

In this article I showed basic approaches that can be used to deobfuscate (not only) AutoIt scripts. They are extremely simple and work well for one-time tasks. For more complex tasks, deobfuscators based on abstract syntax trees or disassembled P-Code are much more efficient but more time-consuming to create.

Have fun!

15 Nov

Why morons shouldn’t be writing about security, part 2

I read Kotaku's article called "FBI Says Alleged Hackers Used FIFA To Steal Millions From EA" this morning. And it reminded me of the crap articles Catalin Cimpanu writes at Softpedia.

What's wrong with Kotaku's article?

Well, pretty much everything.

First, this group did not steal from Electronic Arts. If fact, not a single penny of real currency was taken from EA.

According to an unsealed FBI indictment, Clark and his co-defendants allegedly built a tool that would send false signals to EA’s servers to spoof matches, generating these FIFA coins at a rapid rate. The FBI alleges that Clark and crew then sold the coins to third-party sellers, earning millions.

Exactly! Guys received FIFA coins from EA (it's an in-game currency) which they later sold on underground sites. Money came from persons entirely unrelated to Electronic Arts and it was given voluntarily. And that, by definition, is not a theft.

The article continues with a plenty of other funny statements like

.. worked with the defendants to get Xbox development kits and reverse-engineer a pirated copy of FIFA 14 using a program called Interactive Disassembler. This process took several months, Alcala said, but it allowed them to create a tool for mining FIFA coins.

I just love the IDA reference in here. bigsmile These guys used disassembler, they must be real evil hackers! All in all, this article is a fun read but it got all the basic facts wrong.

Mr. Jason Schreier, please stop writing about things you have no clue about. Stick to your video game reviews or something.

What is really happening?

Thankfully, UK journalists have much better idea of what's happening in US courts, and they wrote a much better article. According to the indictment, the charges are "conspiracy to commit wire fraud", a stupid catch-all term used in US courts for pretty much everything done over the Internet.

That document is equally funny read and shows how desperate the prosecutors must be to make any charges stick. Let's see:

  • the defendant assisted in creating a program (...) which sent electronic messages to EA's servers fraudulently representing that thousands of FUT matches had been completed in the EA's FIFA video game. EA's servers materially relied on the completed match messages and credited various accounts maintained by the defendant and his co-conspirators with FIFA coins. - this is the only part of the indictment that actually makes sense. Kinda. There's one teeny tiny detail - RANE Developments got virtual goods from EA. And the legal status of virtual goods is very unclear in the United States. If virtual goods are not "money or property" in the eyes of law, then there was no fraud.
  • the defendant and co-conspirators continued to create and execute new methods to circumvent the security measures by EA in EA's effort to prevent fraudulent activity associated with the company's FIFA video game. - that might be a breach of EULA but not a crime;
  • executed their "application" through a video game console, which they modified to circumvent security and copyright protections, and on game development kits, which they obtained from unlicensed sources. - we're getting desperate, let's charge them with modding their consoles!
  • executed their "application" through cloud computer servers, which allowed them to run more copies of the software and obtain significantly more FIFA coins. - if nothing else helps, let's charge them with renting cloud computer servers! Oh, wait, what? smile

Naturally, the defendant has pled not guilty to the charge. And if his lawyer is any good, I'm guessing he'll walk out of the court as a free man.

07 Nov

About FLARE 2016 contest

This year's FLARE reverse engineering contest is over. I managed to finish it on time - but I really had to force myself to keep going several times. This graph tells it all:
flare2016-progress

You can get all the challenges from the official site (password: flare) and there are already a number of writeups all over the web.

I'm not going to reinvent the wheel, so here's just my take on few of the challenges. smile

#1 - Challenge1

Time spent: 9 mins. Not much to say, it's designed to be a warmup.. Custom Base64, that's it.

#2 - DudeLocker

Time spent: 1h 20mins. The buzzword for year 2016 is "ransomware". Every self-respecting reversing challenge has to have one. It was fun and kinda easy for me - but in my opinion it was too hard for level 2.

#3 - unknown

Time spent: 7h 45mins. Since challenge starts at 3AM in Europe, one needs to get some sleep..

As for the task - reverser has to figure out the correct filename from PDB entry and then the challenge becomes solvable. No, it doesn't have anything to do with actual reversing, just a random crap obstacle thrown into your way.

#4 - flareon2016challenge

Time spent: 1h 20mins. "Play me a song, have me play along.." Given a DLL, one must figure out the correct order in which to call exported functions to play a song. Original idea, kinda refreshing.. smile

#5 - smokestack

Time spent: 1h 45mins. And, of course, every challenge has to have custom Virtual Machine. This one was just the right difficulty and offering several ways to break it. Nice.

#6 - khaki

Time spent: 2h 20mins. Obfuscated python bytecode. Considering that it was my first time directly patching python bytecode, I enjoyed it a lot. In my opinion, one of the most interesting of challenges this year.

Fun fact - opcode for nop in Python is 0x09.

#7 - hashes

Time spent: 5days 2h 22mins. This is where I got really annoyed and stopped playing.

Not only they throw in a Linux challenge into the mix, they use Go programming language and compile binary in a way that requires libgo.so.7 - which is not available on certain Linux distributions (like Debian).

So, one has to figure out which bloody Linux distribution has support for it, install that in a Virtual Machine, then find a way to install Go language, then fight with SELinux - and all that just to be able to debug the binary provided by challenge. That's just frigging stupid. How hard it is to tell the OS requirements before the challenge starts? angry

Once I got over my enrage and disgust, it was actually pretty easy. My "solution" generated ~60GB of data files - just because I let my hash generation code run while still analyzing the challenge code.. wink

#8 - CHIMERA

Time spent: 2h 10mins. The actual check was hidden in the DOS stub. There were some nice hints and neat and clean code, I loved everything about this challenge! smile

The fact that I got to boot up my Windows XP virtual machine and use debug.exe - that was just an icing on the cake.

#9 - GUI

Time spent: 1h 35mins. Mandatory .NET assembly thrown in the mix. Apparently FLARE team was running out of ideas, so they just used ConfuserEx. Three times.

To solve it, all you need to know is that DNSpy exists. I have no idea why this challenge was put as #9, difficulty wise it was more appropriate as #3..#5.

#10 - flava

Time spent: 35.5 days. Difficulty: 9, fun factor: 0.

This was just frigging stupid. I know, it's a final challenge. But it required so much of a very specialized knowledge, that it's insane.

First you need to get through 3 layers of JavaScript obfuscation. Hard but doable. Then you'll arrive at some serious crypto. Normal person can't know this is bugged Diffie-Hellman key exchange which was used by Angler exploit kit and got broken by Kaspersky Labs. So, if you're not a crypto wizard or you don't focus on exploit kit research, you're screwed.

Once you figure out this crap, you still have to get through 3 layers of Flash. First SWF is easy but second one is obfuscated and solving involves a lot of guesswork. You're supposed to guess that RC4 key is reused and decrypting other binary data with the same key stream will get you the required values to get to 3rd layer. How you're supposed to figure that one out? Well, just "do some random stuff and hope it works™".

The final layer has slightly obfuscated ActionScript code but nothing JPEXS can't handle. It is there just to generate the answer.

Conclusion

If I compare this year's FLARE with LabyREnth, LabyREnth wins hands down. In my opinion LabyREnth's Windows track was much more fun and tasks were much more reverse engineering related. But that's just my opinion..

I wish to express my deepest gratitude to fellow reversers who kept me going when I got really angry and upset: Extreme Coders, fasya and Levis. Your hints were invaluable, thank you so much!

27 Sep

Why I’m not using x64dbg

x64dbg is (probably) the most user-friendly x64 debugger right now. It's pretty, it's open-source and it usually works. But I find it very hard to switch from WinDbg to x64dbg for several reasons. Some of them are purely emotional (don't worry, I'm not going to bore you to death explaining those) but most of them are technical and related to the way x64dbg is being developed.

So, here goes slightly exaggerated but still serious list of my grievances. smile

Insane system requirements

Both DNSpy and x64dbg suffer from this disease. They love to use the "latest and greatest" of technologies, meaning Visual Studio 2017, .NET 4.6 and what not. That's perfectly fine when you're writing normal software. But debugger is not a normal software.

If I have a customer with a software crashing on his production servers, I can't tell him "You need to install Windows 7 SP2 and 3 different VS redistributables and reboot your machine twice just for me to run my debugger". No, I really can't.

Debugger must run on any and all systems out-of-the box. Olly does that. WinDbg does that. And it wouldn't be hard to link x64bdg with static VS runtime libs and target WinXP while using all the modern goodies. But for some reason it's not done that way.

Updated 30-Sep-2016: Mr. eXoDia let me know that now x64dbg is distributed together with the necessary runtime DLLs. We can remove this grievance off of my list. Hooray! smile

Uncertain direction and feature bloat

Antoine de Saint Exupery said:

Perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away

These are really wise words and Olly is designed that way. It does all the basic stuff and has stable SDK that enables plugin authors to implement all the extras.

On the contrary, Mr. eXoDia is adding features left and right and the direction of x64dbg development looks more like this:
BrownianMovement

For example, why does a debugger need 3 (yes, three!) different assembler engines?
assemble

Want another example? Let's just look at the latest weekly digest.. How about this:

... change to the info box. Basically the pointer values in the instruction were not resolved (so if the instruction contained qword ptr ds:[rsp+30] it would not show the value of rsp+30). Personally this is quite useless

Yes, Mr. eXoDia, you're right. It is useless for everyone but few people.

And how about:

The commands plugload and plugunload have been added. This is useful for plugin developers who want to test plugins without having to restart x64dbg all the time.

How many people in the entire world will actually benefit from that? 5? 10?

So, why add such bloat? Once you add something, that something must be maintained. And it's very hard to remove stuff later, as it might break something else. So, please don't..

Broken features

When I am on a job and need to debug something, last thing I want to spend my time on, is fighting with debugger bugs. And my customers certainly don't want to pay me for doing that.

Oleh Yuschuk got it exactly right with the OllyDbg. There were few releases - but they were properly tested and rock solid. From what I can see, x64dbg is going the other way:
compiles_ship_it

Frequent commits like "Fixed search for constant references", "Fixed intermodular calls in module", "Fixed FS/GS memory branch destinations" is not something you want to see in any software, let alone a debugger.

Well, it wouldn't matter much, if there was some known-stable version I could put in my tool collection and use it anytime anywhere. But no, Mr. eXoDia thinks that "No more excuses to not update every day!" is a way to go. Instead of using tried-and-tested version, I should use a probably buggy and unstable one? Dafuq?

Conclusion

So, those are my 3 biggest complaints about x64dbg. I'd love to love x64dbg. I'd love to use x64dbg for everything. But right now I just can't.

How about you?

21 Sep

IDA bug in PE export processing

Hi, I'm back from vacation. And now I'm catching up on all the things that have happened during that time. So, here's a short writeup regarding publicly-known IDA bug and how it will (not) affect reversers.

It was supposed to be a long post showing how to use PatchDiff to locate patched code and then backport it. But, as you'll see later, that's not necessary at all. Maybe another time..

Initial research by Palo Alto

When checking my RSS feed, I stumbled upon the article by Palo Alto researchers called "The Dukes R&D Finds a New Anti-Analysis Technique". It stated:

Using the exported functions by ordinal meant the exported function name was unnecessary, which allowed the developer of this DLL to leave the names for the exported functions blank ... The less obvious reason is that it takes advantage of a bug in the popular IDA disassembler that was recently fixed in the latest version of IDA.

Bug in IDA?! How nice, I want to test this!

Testing the bug

Palo Alto report contained most of the information to reproduce the issue. But IDA 6.95 changelog was even more detailed about what was fixed:

BUGFIX: PE: IDA would not detect DLL exports with empty names
BUGFIX: PE: IDA would show no exports if the export directory's DLL name was an empty string

Armed with the detailed description, I used MASM32 package and their Examples to build a DLL file.

Empty DLL name

First, I took hex editor and changed DLL name in export directory.
export_dll_name_1
export_dll_name_2
Now the exported DLL name is 0-length string. Let's see what IDA does..

I started with IDA 6.95 Demo you can download from official site. No surprises here, the bug is fixed:
export_dll_name_IDA695

Then I took legit copy of IDA 6.90. As already demonstrated by Palo Alto, it's buggy:
export_dll_name_IDA690

Naturally, I wanted to see how old this bug is. So, I took a copy of IDA 6.80. Surprise, surprise, it's not buggy!
export_dll_name_IDA680
So, it looks like this bug was introduced in IDA 6.90.

Empty export name

For completeness sake, I repeated the experiment with empty exported API name.
export_api_name_1
export_api_name_2
The results were identical, the bug is only present in IDA 6.90.

How it affects you?

If you're using IDA Free, latest version is 6.95. You're good.
If you're using legit IDA, you have received the updated version 6.95. You're good.
If you're using the latest publicly leaked version of IDA (6.80), it didn't have the bug. So, you're good, too.

To sum it up - it's a fun bit of information but no one is really affected. Good news, I guess. smile

Example DLL files if you want to verify your tools: https://www.mediafire.com/?c9t6hm4icd3kk46