Tuesday, June 26, 2012

CreateRemoteThread vs. RtlCreateUserThread

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.

An example demonstrating how to use the "NtQuerySystemInformation" function as anti-attaching trick can be found here.

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

You can follow me on Twitter @waleedassar

Friday, June 22, 2012

IDA Pro And CodeView Debug Info Bug

In this post i will share with you another bug that i have found in IDA. This one is different from the previous one in that:

1) It is in code responsible for parsing CodeView debug info.
2) It crashes the current IDA instance with a minidump.

While trying to figure out how IDA reads various debug info, i found that old CodeView formats are also supported by IDA (Also, the demo version). So, i decided to give it a shot and try to find anything useful inside. Understanding the CodeView format was also kept in mind.

Code responsible for reading various debug info lies within dbg.ldw, a dynamic link library that resides in the "loaders" directory.

Since the CodeView format is not clearly documented, i tried to define structures myself. If you know any good reference, please let me know.

The CodeView debug info starts with a 4-character string referring to the CodeView version e.g. "NB10", "RSDS", "NB02", "NB11", etc..

NB10 and RSDS formats are handled by loading the IDA "pdb" plugin.

NB02, NB05, NB08, NB09, and NB11 are handled by dbg.ldw.

Here, i will take the format starting with "NB02". Debugging dbg.ldw, i could understand abit about CodeView format. In the image below, you will see some of my understanding of this format (still dirty, i know).
I will divide the image above into 2 structures. The first one (still incomplete) is as follows:
1) The first 4 bytes denote the CodeView signature or version. In this case, it is "NB02".
2) The second dword is the offset to the second structure.

The second structure is as follows:

1) At offset Zero, 0x10 is always found.
2) At offset 0x2 is the size of the "CV_INFO2" structure. I refer to it as "Incrementer".
3) At offset 0x4, is the number of CV_INFO2 structures. I refer to it as "NumberOfXX".
4) At offset 0x10  is an array of CV_INFO2 structures.

At 0x6000520C, dbg.ldw tries to make sure that the offset to the second structure is less than the size of the whole CodeView debug info (as found in the "IMAGE_DEBUG_DIRECTORY" structure).

If the check succeeds, dbg.ldw continues parsing CodeView debug info and reads members of the second structure e.g. it makes sure that the first word of the structure is 0x10.

I have noticed that code is vulnerable to "read beyond boundary" errors when reading members of the second structure. You can try this demo.

At 0x60005240, dbg.ldw has a loop that iterates through a number of CV_INFO2 structures equal to the "NumberOfXX" value. Each time, it increments the pointer to the current CV_INFO2 structure by the "Incrementer" value. It looks something like this in C code:
You can easily conclude from the two images above that if we set the "NumberOfXX" field to e.g. 0xFFFFFFFF and the "Incrementer" field to e.g. 0xFFFF, we can cause IDA to access violate.

Here you can find a demo tested on IDA 6.2 demo.

Any ideas or comments are very welcome.

You can follow me on Twitter @waleedassar

Monday, June 18, 2012

IDA Pro And COFF Debug Info

In this post i will share something that may be considered as a bug in IDA. The bug is as follows:

If we manipulate the value of the "NumberOfSymbols" field in the "IMAGE_COFF_SYMBOLS_HEADER" structure, we can force IDA to abort processing the whole PE and quickly terminate.

When manipulating this field, just make sure to set a compatible value for the "SizeOfData" field in the "IMAGE_DEBUG_DIRECTORY" structure and also have a compatible file size by appending null bytes to the file end.

When calculating the required memory size for symbol entries using the spoofed value, IDA detects an overflow.
After clicking the ok button in the image above, IDA quickly terminates.

You can find a demo here. It has the "NumberOfSymbols" field set to 0xE38EEDB5 and the "SizeOfData" fied set to 0xFFFFF. It has been tested on IDA 6.2 Demo version and IDA 6.3.

A quick workaround is to temporarily disable the "loaders\dbg.ldw" module.

Any comments or ideas are very welcome.

You can follow me on Twitter @waleedassar

Friday, June 8, 2012

Loading COFF Symbols

In this post, i am going to share with you a case that i met while trying to debug a tiny webserver. In the beginning i have to clarify there is no security issue or anti-debug trick discussed here.

The first thing i did with this file was trying to resolve symbol names using IDA 6.2 Demo. Unfortunately,  few symbols were resolved and that was not satisfying at all. OllyDbg couldn't do anything with that, either.

The next thing i tried was opening the executable in Stud_PE. I was amazed to see the "PointerToSymbolTable" and "NumberOfSymbols" fields of the "_IMAGE_FILE_HEADER" structure set to valid values.

So, if COFF debug info exists why does not IDA read it?. Trying to answer this question, i built an executable with COFF debug info using MS VC++ 6 and loaded it in IDA. Strange enough, IDA successfully read COFF debug info from the MSVC-built executable.

Trying harder to solve that, i compared PE headers of both executables. I found that the MSVC-built executable has the "_IMAGE_DEBUG_DIRECTORY" structure set, while the executable of question does not.

Now i figured out that to have IDA reading COFF debug info i have to manually create the "_IMAGE_DEBUG_DIRECTORY" structure.

And here are the steps i followed to create the new "_IMAGE_DEBUG_DIRECTORY" structure:

1) Searching for any 0x1C unused bytes in any section of the executable.  
N.B. 0x1C is the sizeof(_IMAGE_DEBUG_DIRECTORY). A good candidate place is at the end of the resources section.

2) Filling the important fields of this structure with corresponding values. The structure is defined in winnt.h, see below.

The fields in question are:
a) Type. Set it to IMAGE_DEBUG_TYPE_COFF (0x1).

b) SizeOfData. Set it to ( (file size - PointerToSymbolTable) + 0x20 ).

N.B. 0x20 is sizeof(_IMAGE_COFF_SYMBOLS_HEADER). we will see that later.

c) PointerToRawData. Set it to the value of the "PointerToSymbolTable" field.
The rest of fields can be left zeros.
N.B. Coff debug info is usually tailing the executable.

3) Fill  the "VirtualAddress" and "Size" fields in the "_IMAGE_OPTIONAL_HEADER" structure.

4) Displace data at PointerToSymbolTable forward by 0x20 bytes to create gap for the "_IMAGE_COFF_SYMBOLS_HEADER" structure. This can be easily done using HexEditor Neo in the "insert mode".

5) Fill fields of the "_IMAGE_COFF_SYMBOLS_HEADER" structure so that first field is set to the number of COFF symbols (as found in the "NumberOfSymbols" field of the "_IMAGE_FILE_HEADER" structure) and second field is set to 0x20, sizeof(_IMAGE_COFF_SYMBOLS_HEADER). The rest are not important.

After the aforementioned five steps were taken, IDA read COFF debug info successfully.

Loading the fixed executable in OllyDbg v1.10, i again got no symbols resolved. To discover why, i debugged both IDA and OllyDbg v1.10 and found out that OllyDbg uses the "Dbghelp.SymLoadModule" function to read COFF debug info while IDA uses its own routine.

As you can see in the image above, the "Dbghelp.SymGetModuleInfo" function returned IMAGE_DEBUG_TYPE_UNKNOWN in the "SymType" field of the "IMAGEHLP_MODULE" structure and this is why OllyDbg cancelled symbol loading.

I quickly moved to XP SP3 and tried the fixed executable and again nothing. After renaming the dbghelp.dll residing in OllyDbg directory, OllyDbg loaded symbols like a charm.

So, the conclusion here is that Microsoft has dropped support for COFF symbols in newer versions of Dbghelp.dll.

N.B. For more info. about reading COFF debug info, you can refer to this link.

Any comments are very welcome. Also, if you see any mistake or misconception, please don't hesitate to contact me.

You can follow me on Twitter @waleedassar