IDA text Execution

Update: some didnt like the fact a warning was spawned for execution. Since IDA users have python installed, a .py file can be used to bypass the dialog and run straight off the SMB share. In this case, the link is crafted to encourage a highlight for copy/paste. Be careful


When playing with IDA 6.5, I noticed it treating strings strangely. It would actually respect protocol handlers put on them in certain cases. A simple string of


when viewed in the disassembler would launch a webpage to if double clicked on in IDA View  (used for string highlighting). The “blah” is necessary for the string to be treated as a protocoled command by IDA (“blah” could be any string, just needs to be a string before our URL). I debug IDA to find where this protocol handler is being processed, which I assumed was MkParseDisplayName ( or something similar.

Debugging a bit, I found this was handled by the SHParseDisplayName API ( I figured this would be simple and get straight to code execution with “blah”.

It seems this protocol was ignored (among several other common ones). I did notice that the “file:” protocol worked, although the  “file:///” would be stripped out before being passed to SHParseDisplayName, making my string of

“blah file:///”



before being passed to SHParseDisplayName. This is a problem since we loose our ability to instruct Windows how to treat this string (as a protocoled command). I tried a few other techniques, but there simply was not a way around the fact it leaves a prepended ‘/’ character. Even when trying “file:///file:///”, I just get “/file:///” which is an invalid protocol of course.

It turned out to be simple, with a case change. This effectively bypassed the filter, which I didn’t even try because I thought surely it wouldn’t work…but it did, as we see the string argument to SHParseDisplayName.

Now when string is double clicked, this will be interpreted to execute (depending on file extension) meaning remote code execution can occur:

Code Execution via Insecure Synaptics Section Objects

Edit: Thanks for the comments, I realize this is NOT Lenovo specific problem, it just happened to come pre-loaded on my Lenovo machine.

Alex Ionescu did a cool talk a while back on exploiting unsecured shared memory objects. It sounded like an interesting attack vector to put to use, so I pulled up WinObj on my Lenovo machine and take a look for any ACL-less section objects (section objects are maps of memory that can be shared across applications – leave one of these unsecured and you are leaving yourself open to a 3rd party application able to read and write to it.)

My Lenovo had a memory map called “SynTPAPIMemMap”. Inspecting this via WinObj shows no ACLs – good place to start.

The owner of this memory map turned out to be SynTPEnh.exe, which is spawned at boot by the SynTPEnh service, a Lenovo touchpad utility.

Examining one of the SynTPEnh.exe .dlls in IDA, we can see it is responsible for creating and managing this memory map.

Since any app can read/write to this mapping, all one has to do is find all references made to this memory map and see what choke points best to attack. Out of all the references I found to it, the most promising one was the dll export “RegisterPluginW”, which seems to be called every time the user “clicks” and or even touches the mouse pad at times.


When RegisterPluginW is called, I noticed it will iterate over the memory map, setting of my memory breakpoints. The inner function responsible for this is the function I named “RespawnProc” (below).

Examining the RespawnProc function, I see it has the possibility to call the “CreateProcess” function, and whats even more incredible, is the cmdLine parameter for the CreateProcess, is pulled right from the memory map (rbx), which we can control!

To control execution flow where I want, we need to get “WindowCheck” function to return 0. Lets see how we do that…

Inside WindowCheck function

Looking at the function, its relying again on input from the same unsecured memory map. We can get this function to fail by writing invalid handles and invalid process IDs to the buffer its using to store them. This is probably a mechanism to relaunch this window process, in the event it died. Too bad their storing this in an unsecured memory map. To cause this to fail, we need to understand the format of the buffer, and what its all about.

After lightly reverse engineering the memory map, I found the buffer was an array of over 20 TPAPI objects. Highlighted in this memory below is one TPAPI object (Red) and a few important members.

The cmdline member in blue, is used as the CreateProcess parameter. It seems that it should be as simple as rewriting the cmdLine to a process I want to spawn, and setting invalid PID and/or Window Handle members to force the “WindowCheck” function to fail. I only have to worry about doing this to the first TPAPI object, since all will be iterated over upon touch/click and I dont need 27 calc.exe instances popping up.

Here is part of very simple code to trigger this execution.

We execute this code, and the second I move the mouse calc.exe instance is spawned from SynTPEnh process with inherited permissions.


What we have now, is the ability for any application able to write to this Lenovo section object to get code execution as the current user’s account, which can be a privilege escalation (depending where you are running from), or it can be an execution divert, in environments you dont want child processes under MS Word for example.

Stealth Process Hollowing (via Hotswapping Maps)

I’ve recently released a process hollowing packer: RISCyPacker ( This hollower technique is unique in the fact that it is able to hollow a process dynamically (without process suspension) and without using some of the more sketchy Win APIs. This means no WriteProcessMemory, QueueUserApc, CreateRemoteThread, SetThreadContext calls. While I didn’t get around to testing with all AV, this technique should go undetected. For you Reversers, I attached a POC binary packed by it (end of article), so you can see how it works.

If you are motivated enough to test with more AV, let me know, Id be interested to hear

How It Works

Most process hollowing techniques rely on suspension of process, writing to remote memorymanipulating context (SetThreadContext/CreateRemoteThread/QueueUserAPC) and Resuming. The RISCyPacker technique trims the fat by only using Memory Modification steps (NtUnMapViewOfSection/NtMapViewOfSection) to accomplish a hollow.

In order for this to work, we need to be establish a guarantee that our thread can Unmap/Map remote executable memory before the remote thread is scheduled. If we go half-cocked (ie: only an unmap), we will get crashes since the thread’s EIP will point to nothing when its scheduled. Luckily we can use some thread priority and affinity to help us:

Create local Thread with High Priority

Set Remote Process’ Thread to Low Priority

The Affinity settings are of course required, since multicore processors may affect up our desired scheduling priorities we set. By putting them both on the same core, with different priorities, we can properly queue them up, allowing manipulation of remote memory before remote thread can access it.

Conceptual steps on how this hollower works (example w/ ftp.exe)

The injected NOP sled happens to also contain shellcode to load and built the IAT for the injected process.


A few things this packer must keep in mind, is a set of processes that can support a non-suspension injection. Some processes you want to hollow into, will immediately exit upon start (ie: xcopy.exe w/ no arguments) and thus miss the injection opportunity. For now, I only tested with ping.exe which was a good candidate for this. In the event a proc early exits, the hotswap technique will still work, it will just require a suspension (does not require CREATE_SUSPENDED, but rather suspended after normal creation (more stealthy)

RISCyPacker does not currently support x64/TLS/Exports.

Proof of concept exe for reversers. Password is “notinfected”


Note on Stalled Apps

Some processes you hollow into may be in a blocking state (in a system library) by the time you hollow. This means it will not call back into it’s image base that we applied a NOP sled to. To get around this you can memswap libraries and externally trigger an enter. (For example, kernel32 can be unmapped/mapped and then a Kill process call to the hollowed process, this will force the stalling application to enter into kernel32/NOP sled you mapped).