Analyzing a packer that uses Windows messages

in security •  7 years ago 

This is an adaptation for Steemit of ReversingMinds. if you want to have it in HTML format you can see it here.

OVERVIEW

SAMPLE MD5: 50d3cbd314e39b28bcd7938794e18c97

This sample is packed with a packer that drops a shellcode to decompress the
payload.

The packer uses a similar technique to “Process Hollowing”. In this case, after dropping the shellcode, the shellcode decodes the payload. Finally, the shellcode unmaps the packer and it maps the payload in the same memory address as the packer was.

The next image shows the different phases of unpacking process.

1.pngImage​ ​ 1:​ ​ Logic​ ​ summary​ ​ of​ ​ the​ ​ packer.

1. When the packer is in memory, after a process which I am going to describe later, it​ ​ drops​ ​ the​ ​ shellcode.
2. The shellcode drops encoded payload and decrypts it. After the decryption the payload​ ​ is​ ​ not​ ​ ready​ ​ yet​ ​ (red​ ​ color).
3.​ ​ The​ ​ shellcode​ ​ unmaps​ ​ the​ ​ packer.
4. The shellcode maps the decrypted payload at the same position as the packer was.
5.​ ​ The​ ​ shellcode​ ​ fixes​ ​ the​ ​ imports​ ​ addresses​ ​ which​ ​ will​ ​ be​ ​ used​ ​ by the​ ​ payload.
6.​ ​ Finally, ​ the​ ​ payload​ ​ is​ ​ executed.

UNPACKING PROCESS

I​ am​ going​ to​ explain​ in​ detail​ the​ 6 steps​ described​ above.

The​ first​ step​ (1)​ drops​ the​ shellcode​ using​ Windows​ messages.

2.pngImage​ 2:​​ ​ Main​ code of​ the​ packer.

The image 2 shows how the class named “needed” is registered. “needed” class has associated the subroutine “sub_4041A6” (The shellcode will be written by this subroutine).
After​ registering​ the​ class,​ the​ packer​ creates​ a ​ “needed”​ window.

The packer loops until it does not get more messages, at this moment the shellcode is​ ready​ to​ run​ (“image​ 2”,​ line​ 24).

“sub_4041A6” subroutine works as state machine. Depends on the received message, it jumps​ to​ one​ state​ or​ another.​ The​ next​ messages​ are​ the​ most​ important​ for​ the​ subroutine:

  • Message 0x111: This message manages the state machine, depends on lParam theprogram jumps to one state or another. The packer drops the shellcode after passing for all states.

Image 3 shows how the messages are managed by the window. If the message is different to 0x111 the program pass the message. In addition, if the message is 0x111 with value​ 0x579​ as​ lParam​ the​ window​ will​ start​ to​ drop​ the​ shellcode.

3.png
Image​ ​ 3:​ ​ Reading​ ​ 0x111​ ​ message.

  • Message 0x401: When this message is received, it will start to decode the shellcode. The wParam is the memory address to write from and the lParam is the address to​ write​ to.

4.png
Image​ ​ 4:​ ​ Message​ ​ 0x401​ ​ loop​ ​ which​ ​ is​ ​ responsible​ ​ for​ ​ decoding​ ​ the​ ​ shellcode.

The​ loop​ shown​ in​ the​ image​ 4,​ basically​ do​ the​ same​ as​ the​ next​ pseudo​ code.

dir_src​ = *wParam
dir\_to\_write​ = *wParam​ + 4
offset​ = lParam
for​ i in​ range(15):
    \[dir\_to\_write\]​ = \[dir_src​ + i\]
    dir\_to\_write​ = dirt\_to\_write​ + offset

This​ message​ is​ sent​ until​ the​ packer​ writes​ the​ shellcode.

When shellcode is executed, it decrypts itself at the beginning. After this decryption, the​ shellcode​ starts​ to​ work.

5.png
Image​ ​ 5:​ ​ Entry​ ​ point​ ​ of​ ​ the​ ​ shellcode​ ​ before​ ​ the​ ​ decryption.

6.png
Image​ ​ 6:​ ​ Piece​ ​ of​ ​ code​ ​ of​ ​ initial​ ​ decryption​ ​ just​ ​ before​ ​ calling​ ​ to​ ​ the​ ​ decrypted​ ​ shellcode.

7.png
Imagen​ ​ 7:​ ​ Entry​ ​ point​ ​ of​ ​ the​ ​ shellcode​ ​ after​ ​ the​ ​ decryption.

The shellcode allocates memory with VirtualAlloc function and starts to drop binary data​ which​ looks​ to​ be​ compressed.

8.png
Image​ ​ 8:​ ​ Uncompress​ ​ process.

After​ uncompressing​ data,​ we​ can​ find​ the​ payload.

9.png
Image​ ​ 9:​ ​ uncompressed,​ ​ payload.

Now we are at the third (3) step, the shellcode will unmap the packer and will map the​ decrypted​ payload​ in​ the​ same​ address​ as​ the​ packer​ was​ (4).

10.png
Image​ ​ 10:​ ​ Unmap/map​ ​ code.

Finally, the shellcode fixes up the import addresses of the payload and it passes the control​ to​ the​ payload.

11.png
Image​ ​ 11:​ ​ Fixing​ ​ up​ ​ the​ ​ imports​ ​ of​ ​ the​ ​ payload.

12.png
Image​ ​ 12:​ ​ Jump​ ​ to​ ​ OEP.

UPDATE:
The first command for starting the unpacking (in the subroutine associated with the "needed" registered class) is when the lParam is 0x38.

The firs state of the "needed" class is to get the system time. Once it has the current month (using GetSystemTime) it moves to lParam, the current month value (1 = January, 2 = February ... 11 = November, 12 = December) plus 0x27 and sends the message.

13.jpg

So, If it is not November It won't unpack =(

Author: @D00RT

If you like you can vote me as Witness, help me keep posting news about security

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Hi! I am a robot. I just upvoted you! I found similar content that readers might be interested in:
http://reversingminds-blog.logdown.com/posts/7359505-analyzing-a-packer-that-uses-windows-messages