IME code injection (old)

I like clever and unusual tricks that are meant to fool sandboxes or evade malware analysis (and fool researchers). One of the very first one I came across many years ago was a SetWinEventHook trick used by mebroot which was loading the malicious DLL into Windows Explorer. Since then I tried to keep a track of all new tricks since I believe they are one of the most interesting aspects of reverse engineering work + often indicate the sample using the trick may be more interesting than the ‘run off the mill’ malware.

In today’s post I will describe a very unusual trick which – while not new – is not very well-known. I came across it in the past while checking my sandbox reports. When I discovered this trick, what caught my attention was the following API sequence:

  • FindWindowA … Program Manager
  • PostMessageA … WM_INPUTLANGCHANGEREQUEST … E0010409
  • PostMessageA … WM_INPUTLANGCHANGEREQUEST … 00000409

Apparently something was trying to get a window handle of the Program Manager and then force it to change its language input. Any malware looking for the window of Program Manager (shell) or any other shell window and then sending some messages to it immediately triggers alarm in my head, and it was a good catch.

The trick is not new and some researchers did mention it in the past – f.ex. here, here, and here, and while the trick was explained by others I still think it is useful to bring it back and describe the clever mechanism behind it.

The trick works like this:

  • The malware drops a temporary file in a system folder (a copy of itself with a DLL bit set)
  • It then adds a fake keyboard layout E0010409 under the registry key
    • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\E0010409
  • Notably, it only adds ‘Layout File’ and ‘Layout Text’ entries under this key, skipping the ‘Ime File’ entry (which normally points to the actual IME DLL)

ime0

  • It then hooks the NtQueryValueKey and ImmLoadLayout APIs.
  • The first API – NtQueryValueKey – is hooked so that it can provide the necessary value of ‘Ime File’ entry when the ImmLoadLayout API is called (ImmLoadLayout calls RegQueryValueExW which in turn calls NtQueryValueKey)
  • This is a neat trick to avoid writing a suspicious entry (pointing to a malicious / executable file) to Registry and instead, provide the value via a hooked API

ime1

  • The second hooked API is ImmLoadLayout
  • The only reason it is hooked seems to be to handle a situation when malware is running with the AV running in a background; the malware doesn’t seem to like 360tray.exe process – if it detects it, it uses the hooked ImmLoadLayout to remove the whole HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts key – it’s a bit strange and this could be a test code – prior to deletion, the malware exports this key to a text file using ‘reg export’
  • The core of the trick is that at some stage the ImmLoadLayout API will be called by the OS from kernel
  • As far as I can tell is it is called via user-mode callback triggered from kernel mode routine ClientImmLoadLayout, which will call KeUserModeCallback with the number 84 (on XP) which in turn will call __ClientImmLoadLayout callback inside user32.dll – this sequence will ensure that the data about the new IME layout is registered inside internal structures of the win32k.sys
  • Malware then calls the PostMessageA API with WM_INPUTLANGCHANGEREQUEST and the new keyboard layout E0010409 which forces explorer.exe to call the ImmLoadIME API, which will retrieve the cached information about the malicious IME file via ImmGetImeInfoEx and then call LoadLibraryW (on XP)
  • The whole process doesn’t inject any code into Windows Explorer directly and doesn’t even write a path pointing to the malicious file into Registry

Note: the trick is old, doesn’t work on newer versions of Windows.

Converting Shellcode to Portable Executable (32- and 64- bit)

Update 2023-12-22

Matthew pinged me about the Yasm links no longer working, so I have updated them to point to Yasm github repo, as he suggested. Thanks Matthew!

Old Post

Analyzing shellcodes is tricky so to simplify this process it’s really handy to convert them into executables which can be then analyzed with a debugger/IDA. Since a shellcode is a position-independent code, all we have to do is to build a simple executable that embeds the shellcode blob, and ensure the entry point of the executable points to the beginning of the embedded code.

Many people use different tricks to do it, some write C code, or use python.

Below, I present probably the simplest and shortest method – using assembly 😉

The following is a short tutorial on how to do it with 2 freely available tools – YASM and GoLink:

Global Start
Start:
incbin "shellcode.bin"
  • From a command line run the following command to assemble the code:
    • for 32-bit shellcode
      • yasm.exe -f win32 -o shellcode.obj shellcode.asm
    • for 64-bit shellcode
      • yasm.exe -f win64 -o shellcode.obj shellcode.asm
  • Now run the linker
    • golink /ni /entry Start shellcode.obj
  • The resulting file shellcode.exe can be debugged or analyzed with IDA

If it still sounds like a lot of steps, you can create a batch file to do all the work for you. Save it as shell2exe.bat and from now on, all you have to do is to run the following command:

shell2exe.bat 64 <shellcode file>

or

shell2exe.bat 32 <shellcode file>

depending on the shellcode architecture.

Here’s the shell2exe.bat file:

------------ shell2exe.bat ------------ 
@echo off
@if "%1"=="" goto help

@echo Global Start > shellcode.asm
@echo SECTION 'foo' write, execute,read >> shellcode.asm
@echo Start:       >> shellcode.asm
@echo incbin "%2"  >> shellcode.asm
@yasm.exe -f win%1 -o shellcode.obj shellcode.asm
@golink /ni /entry Start shellcode.obj
@del shellcode.asm
@del shellcode.obj
@dir shellcode.exe

@goto exit

@:help
@echo Converts a shellcode blob to an executable
@echo Required Arguments:
@echo - architecture: 32 or 64 (depending on the shellcode)
@echo - shellcode blob file name

@:exit
echo.
------------ shell2exe.bat ------------

And we really, really want to keep it supersimple here is the whole package for your convenience. It contains shell2exe.bat + GoLink.exe + 32-bit yasm.exe /for portability/.