Flag: Tornado! Hurricane!

Blogs >> waleedassar's Blog

Created: Saturday, June 30 2012 12:09.09 CDT Modified: Saturday, June 30 2012 12:13.40 CDT
Printer Friendly ...
CreateRemoteThread vs. RtlCreateUserThread
Author: waleedassar # Views: 9618

In this post i will shed the light on a slight difference between the "CreateRemoteThread" and "RtlCreateUserThread" functions. I will also show how this slight difference could affect your code, esp. if you are implementing an anti-attaching trick.

The difference is in the way the CONTEXT structure is initialized for the new thread. Let's first take the "CreateRemoteThread" function in disassembly.

On Windows XP SP3, at address 0x7C810550, We can see a call to the non-exported "_BaseInitializeContext@20" function which as its name implies sets initial values for registers of the CONTEXT structure.

Here, we focus on only two registers, EIP and EAX which are set in the following manner:

1) The EIP register is set to the address of  either "_BaseThreadStartThunk@8" or "_BaseProcessStartThunk@8" depending on the fifth parameter (in this case, the fifth parameter is set to TRUE and EIP is set to the address of "_BaseThreadStartThunk@8").

2) The EAX register is set to the user-defined entry point (User-defined here means the value passed to the "CreateRemoteThread" function in the "lpStartAddress" parameter).

Now the very first thing we conclude is that "BaseThreadStartThunk@8" later executes the user-defined entry point.

Now let's take the "RtlCreateUserThread" function in disassembly and see how the CONTEXT structure for the new thread is initialized.


As you can see in the image above, a different function, "RtlInitializeContext", is used for this task. Going into this function, we can see that it is as simple as setting :

1) The  EAX register to zero.

2) The EIP register to the user-defined entry point.

A question arises here!!. what is this useful for?

If a thread tries to query its own entry point by calling the "ZwQueryInformationThread" function with the "ThreadInformationClass" parameter set to ThreadQuerySetWin32StartAddress, then the initial value of EAX is the value returned in the "ThreadInformation" parameter. In most cases, this is okay since almost all threads are created by the "CreateRemoteThread" function and hence the user-defined entry point is always returned.

But threads created by the "RtlCreateUserThread" function (e.g. threads created by debuggers to attach to running processes) will not be able to query its own entry point using the "ZwQueryInformationThread" function, since the value returned in the "ThreadInformation" parameter will always be zero as the initial value for EAX was zero.

Imagine a TLS callback running in the context of the attaching thread and trying to query the thread's entry point by calling the "ZwQueryInformationThread" function as part of detecting the debugger, the entry point returned will be zero since the initial value of EAX was zero.

A good solution for this problem is using the "NtQuerySystemInformation" function with the "SystemInformationClass" parameter set to SystemProcessesAndThreadsInformation to get information about all current processes and threads, then locating the proper thread and its SYSTEM_THREAD_INFORMATION structure. Once the right structure is found, the thread entry point can easily be seen in the "StartAddress" member.

The code showing how to use the "NtQuerySystemInformation" function to extract threads entry points can be found here.
http://pastebin.com/2RpS08AC

An example demonstrating how to use the "NtQuerySystemInformation" function as anti-attaching trick can be found here.
http://code.google.com/p/ollytlscatch/downloads/detail?name=Query_Entrypoint.exe

N.B. This topic has been tested on Windows XP SP3.

You can follow me on Twitter @waleedassar




Add New Comment
Comment:









There are 31,314 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
hi!
Jul/01
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit