During the past few days, we found many malware samples using complex anti-debug methods.
The beginning of some functions looks like this. You can easily see the junk code:
The malware will push meaningless parameters and call some GUI APIs to bypass AV’s virtual machine emulator. Please refer to below snapshot:
Since the parameters for LBItemFromPt() are meaningless, LBItemFromPt() will report an error code. The following function COMCTL32.#14 is WSAGetLastError(). Malware call this function to get the error code generated by LBItemFromPt(). Then compare it with 578 which is the correct error code. But in common AV’s emulators, the emulated WSAGetLastError() can only get certain error codes which means AV’s emulators won’t get 578 in this case, so the malware will continue in the wrong process while running in the emulator.
If the malware in running in real environment, it will trigger an exception to continue with malicious behavior.
The stack view is as follows. SHE handler is 0x00405650
Address of handler is 0x00402FDF. We can see similar junk code there. Also a new thread will be created.
Now what’s interesting. Malware will install an UnhandledExceptionFilter in this thread.
Actually, if we use a debugger, we could not run into the filter function due to windows’ exception handling process. So we have to patch UnhandledExceptionFilter code. We shall change ‘je kernel32.7c862cc1’ into ‘ jmp kernel32.7c862cc1’.
Now we can run into the filter function installed by malware. But that’s not the end. In the filter function, we find that the malware would manually modify current thread context. It will change the EIP in the context into 0x004027D2. Why?
At the end of the filter function, we know the reason. The filter function will return ‘EXCEPTION_CONTINUE_EXECUTION’. Windows’ exception handling process will check the filter function’s return code to check how to continue. If it finds the ‘EXCEPTION_CONTINUE_EXECUTION ‘ return code, it will continue running with the EIP set in the thread context.
So after the filter function, this malware will go to 0x004027D2 where the real malicious behavior will happen.
To summarize it all, malware first uses certain API’s error code to escape from detection by AV’s emulators. Second, they will set up an own exception filter function. Then trigger an exception by itself. If we run a debugger, we could not run into the exception filter function. Third, malwares will modify the EIP in thread context. Then return ‘EXCEPTION_CONTINUE_EXECUTION’ to let CPU go to the EIP address to change the process.
Stanley Zhu & Franklin Zhao
Leave a reply