How to Hook Thiscall Functions?

October 6, 2012 Leave a comment

Yesterday I found a really interesting way to hook functions compiled with thiscall calling convention.
In the following post I will try to explain the method.

 A Bit About x86 Calling Conventions

According to Wikipedia:

Calling conventions describe the interface of called code:

  • The order in which atomic (scalar) parameters, or individual parts of a complex parameter, are allocated
  • How parameters are passed (pushed on the stack, placed in registers, or a mix of both)
  • Which registers may be used by the callee without first being saved (i.e. pushed)
  • How the task of setting up for and restoring the stack after a function call is divided between the caller and the callee

First, lets review some of the most important calling conventions:

  • stdcall – Parameters are pushed right-to-left. The callee is responsible for cleaning up the stack.
  • cdecl – Parameters are pushed right-to-left. The caller is responsible for cleaning up the stack.
  • thiscall – Parameters are pushed right-to-left. Either caller or callee is responsible for cleaning up the stack – depending if variable number of arguments is being used. A this pointer is passed in the ECX register.
  • fastcall – Passes the first two arguments(left-to-right) that fit into ECX and EDX. Remaining arguments are pushed onto the stack from right to left. The callee is responsible for cleaning up the stack.

Why it’s different to hook a thiscall function?

Well, let’s say you want to declare a function that will get called instead of the original detoured function.
You probably want your detour function prototype to be exactly the same as the original – so the stack won’t get corrupted. For example, let’s say we want to perform hook on a function with the following prototype:

char* __thiscall Foo(unsigned int firstParam, unsigned int secondParam);

One would try to declare a detour function that looks like this:

char* __thiscall myFoo(unsigned int firstParam, unsigned int secondParam);

But the problem is that VC++ won’t let you to explicitly define a thiscall function. If you’ll try to do it, the following error will be raised:

error C3865: '__thiscall' : can only be used on native member functions

This is rational – thiscall calling convention needs a “this” pointer which is available only when defining a method within a class.

So, how can we hook functions compiled with thiscall?

We can, of course, declare our function as __naked__  and write the function’s prologue and epilogue ourselves, but this is not fun at all – with every change to the function we’ll need to write assembly code to fix the stack.

But there is a better way to do it. Look again at the definition of thiscall: The this pointer should be passed in the ECX register and the callee should clean the stack.
Now, let’s look at the definition of fastcall: The two first parameters that fits into ECX and EDX are passed in these registers.
If we declare a function that uses the fastcall calling convention with the first parameter as This and the seconds parameter as a trash(not used) parameter, we could use this calling convention instead of thiscall, and the compiler won’t raise any error!
So, you can declare a function pointer(with a reference to the This pointer) and a detour function(with a reference to the This pointer and to a dummy seconds parameter), and the compiler will do all the rest for you:

typedef int (__thiscall *myFooPtr)(void*, unsigned int, unsigned int);
char* __fastcall myFoo(void* This, void* notUsed, unsigned int firstParam,
unsigned int secondParam) { }

The compiler will place the This pointer into ecx and the second dummy parmeter into EDX, as these are the first and the second parameters and we’re using fastcall calling convention.
The remaining parameters will be pushed into the stack.

This way, we can take advantage of the fastcall calling convention, and the compiler will do all the dirty stack work for us. Cool, huh? 🙂

Cy’a,

Categories: Uncategorized

Should we trust certificates?

February 25, 2012 Leave a comment

People often think that if a website is equipped with a certificate it is legitimate and secured.
Many people(and sadly, many AV vendors) also think that if an application is signed(once again, with a digital certificate) it is safe to run.

But wait, does it really that hard to acquire a digital certificate? And even if it is – are certificates so secure that we should trust them so much?

Modern certificates usually have a long encryption key and a well proven signing and encryption algorithms(SHA1/RSA), so breaking
them should be very hard. But there are some ways other than super computers and math geniuses to defeat strong certificates.

Comodo and Diginotar Incidents

Last year, a hacker broke into a server belonging to a reseller for Comodo, a well known security company and certificate authority. The attacker issued himself some certificates for site such as Gmail, Hotmail, Yahoo and others. With these certificates in his hands he could effectively disable the advantage of SSL and eavesdrop on users of those services. These certificates were revoked quickly.

Later that year, another attack was made(some say that even by the same attacker). This time the target wa the Dutch certificate authority DigiNotar. Several certificates  was issued, mainly for google.com and its subdomains. There were also some reports that these certificates was spotted in many man-in-the-middle attacks in Iran. DigitNoar has revoked the certificate several weeks after the attack.

So wait. You cant really handle sophisticated targeted attacks against root CA’s. It seems rational. Besides that, the certificates were revoked quickly and everything is back to be secured… Or is it?

OCSP

OCSP stands for Online Certificate Status Protocol. From Wikipedia:

The Online Certificate Status Protocol (OCSP) is an Internet protocol used for obtaining the revocation status of an X.509 digital certificate. It is described in RFC 2560 and is on the Internet standards track. It was created as an alternative to certificate revocation lists (CRL), specifically addressing certain problems associated with using CRLs in a public key infrastructure (PKI). Messages communicated via OCSP are encoded in ASN.1 and are usually communicated over HTTP. The “request/response” nature of these messages leads to OCSP servers being termed OCSP responders.

Just think about it for a minute. When an application uses a certificate(lets say, your browser) a revocation check is initiated to make sure that the certificate is still secure. It seems legitimate,
but what happens when the OCSP servers could not be reached?

Many companies and network are behind proxies and firewalls which allows only specific traffic to pass through, for example – only traffic to a certain server on specific ports. In such cases, the revocation check will fail. You might think that your browser will probably alert you about this serious problem, but you’ll be surprised to discover that most of the major browsers do almost nothing about this:

  • Microsoft’s Internet Explorer provides no indication at all about it.
  • Mozilla’s Firefox removes the EV(Extended Validation) marker. It’s pretty good, but 99% of the users won’t spot the difference between a site with Extended Validation and a site with only Domain Validation(DV).
  • Google’s Chrome does the most and puts a little triangle on the padlock icon. If you click on it, it says that chrome was “unable to check whether the certificate has been revoked”. Once again, 90% of the users won’t spot this. They’ve told that if the site starts with https and a padlock appears next to the site address, they are 100% secure…
Even if the user isn’t behind a firewall or a proxy, a sophisticated attacker can use one of the stolen certificates and actively prevent users from accessing OCSP servers(assuming he controls the network, as in the Iranian story).

Hey, I’m “Trustme Solutions inc.”, Give Me a Certificate Please

Many AV’s treat signed files as legitimate. Modern AV’s often uses heuristic algorithms that gives “trust grade” to files according to some predefined variables. Most of these AV’s gives a very high “trust” grade to files that are signed with certificates – even if the certificate is issued to an unknown company. As long as the certificate authority is legit, the file is considered to be safe(or at least a lot safer than it would be without certificate).

But what prevents a malicious attacker from creating a cover company with no real identity, and buy a certificate for his needs?
Yes, this procedure used to be complicated, but buying a certificate nowadays its not that hard.

So just think about it – certificates, in my opinion, are not that safe as some organization think.

Until next time,

NDIS may cause a BSOD when sending a large amount of very small packets

January 8, 2011 Leave a comment

During work on one of my latest projects I’ve encountered a very interesting problem when sending a huge amount of small packets through NDIS.

The problem began when a colleague of mine sent me a crashdump that probably caused by my driver. After a quick analysis I’ve verified that the BSOD indeed caused by my driver. The error code that presented the BSOD was the infamous IRQL_NOT_LESS_OR_EQUAL, but interestingly enough after a quick review of the crashed thread stack, it appears that the crash happened in the function ethFindMulticast, which  is part of NDIS itself.

IRQL_NOT_LESS_OR_EQUAL, as MSDN states, occurs when “An attempt was made to access a pageable (or completely invalid) address at an interrupt request level (IRQL) that is too high. THis is usually caused by drivers using improper addresses.”. In other words, this error might happen either by getting a page fault at IRQL>Passive Level, or by trying to access a completely invalid page.

The exact instruction that caused the BSOD was:
fc21f06a    8b7b02            mov    edi, dword ptr [ebx+2]

So to where ebx points, and why a read attempt to this address results in a BSOD?
fcaf5000     ?? ?? ?? ??  ?? ?? ?? ?? ?? ?? ?? ??  ?? ?? ?? ?? ?? ?? ?? ??  ?? ?? ?? ?? ?? ?? ?? ??  ?? ?? ?? ??

Ok. ethFindMulticast tried to access a page that is currently paged out or completely invalid, like we thought. But wait, one instruction earlier we used ebx and everything was fine. It means that we are currently on the edge of a page? The memory area that pointed by [ebx] was fine, but the memory area pointed by [ebx+2] wasn’t. Lets check it:
fcaf4ffe     f1 01 ?? ??  ?? ?? ?? ?? ?? ?? ?? ??  ?? ?? ?? ?? ?? ?? ?? ??  ?? ?? ?? ?? ?? ?? ?? ??  ?? ?? ?? ??

Nice! So now we know for sure that we are in a state where the last two bytes that we are about to check  are exactly on the end of an allocated page! We locked a MDL(a system-defined structure that describes a buffer by a set of physical addresses) on several pages, but in some rare cases we try to access outside of the last allocated page, as ethFindMulticast assumes that the given buffer is as long as a MAC address, i.e at least 6 bytes long! This assumption is ok, but I couldn’t find any documentation about it.

The interesting thing that happened here is that rare condition where we try to access a non allocated page. Remember that this BSOD occurs only after thousands of packet. Only after this amount of packets, we might be exactly on the edge of the last allocated page, where half of the packet is still on the allocated page, and the other half isn’t allocated at all.

Greetings

Categories: Windows, Windows Kernel