Nytro Posted June 5, 2011 Report Posted June 5, 2011 This will be picked up as a virus(rootkit), most rootkits use ssdt hooking to hide files\processes. I had to configure my AV.Source Files: http://www.ucdownloads.com/downloads...o=file&id=4211 If there is anything you'd like me to explain more, please post about it.Writing drivers to perform kernel-level SSDT hooking The goal of the reader is to perform the the below points while following the tutorial. The tutorial describes how to do this step by step. Write a console application to load, and send commands to the driverHave the driver process commandsHave the driver perform according SSDT hooks, or execute the received command.There are several chapters to this tutorial. The are as described below. Installing the Driver Development Kit, and setting up your working folder.Creating a basic console application to load and start driver services, as well as perform IO to IO Devices.Building a basic driverSetting up driver major functions and basic IOCreating a message protocol.Getting access to protected memory using MDLs.Writing the hook. Before we begin the tutorial please note the following: If you get any linking errors regarding unresolved external symbols, assure you have all your source files defined in SOURCES(you will learn about SOURCES later in this tutorial)For debugging the driver, run the drivers in a VM, setting up DbgView client on VM, and then connecting to it on the host machine. This will give you the last debug messages recived before the driver crashed the host machine. And you can easily narrow down errors this way.This is not worth your time if you plan to write a simple hook with it.This driver is written in C, there are some big differences between C and C++, they will be noted as you follow the tutorial. If you know C++, you should have no problems following this tutorial.Any errors, overflows, exceptions, etc will cause a BSOD, and could possibly damage your OS. And thus, when these drivers are being tested it is highly recommended you do testing on a virtual machine.All drivers written with this tutorial should NOT be installed as services that startup with the operating system. If there are errors in the driver, it can prevent you from starting your computer, to fix this you can boot in to safe mode and manually remove the service.The drivers you write using this tutorial will most likely be picked up as rootkits, disable your anti-virus during the whole tutorial, or configure it accordingly. This is because hooking the service dispatch table is a common technique used by rootkits to hide processes or files.I don't know what UC's status is on including drivers in your hacks, so be sure to consult them about it before using this technique in hacking.Lastly, for whatever you're trying to achive with a driver, will probably be achiveable by user-level hooking, so be sure you take advantage of user-level hooks before kernel-level hooks.Installing the Driver Development Kit, and setting up your working folder Now lets start to setup our DDK, and our development environment. We're actually going to be installing WDK, which contains the DDK. The DDK contains many useful headers and libraries, as well as the binaries we're going to be using to build our driver. I will start off by saying, Microsoft has successfully made this thee most difficult development kit to acquire(thanks Microsoft). How to Get the WDK1. Register a hotmail account if you don't already acquire one.2. Login at Microsoft Products Accepting Bugs and Suggestions | Microsoft Connect3. After logging in, there will be tabs on the top of the page, select Connection Directory.4. To the left of the page, there is a navigation menu, select Developer Tools. 5. Search for : Windows Driver Kit (WDK) and Windows Driver Framework (WDF) and apply. 6. Now select 'Your Dashboard' on the top navigation menu. 7. Select Windows Driver Kit (WDK) and Windows Driver Framework (WDF).8. Finally, press the download link under the text "The download package for this release is:"8. After that download, either mount the downloaded ISO file, or extract it. Then install it.After the installation, if you go to start->All Programs->Windows Driver Kits->WDK (version number)->Build Environments->Your OS->You will see two executables. One is a free build environment, and the other is checked. If you build your driver in the checked environment, your driver will not be optimized, and if it is done in a free environment, it will be optimized. Optimization can sometimes cause errors. And thus drivers should be built in checked, then when they're completed, tested, built, and distributed in free. Throughout this tutorial we'll be using a checked environment.And there you go, DDK should be located in InstalledDrive:\WinDDK\VersionNumber\ You can setup the DDK to MSVS, but it's not recommended, the staff over at MSDN are saying it wasn't built to compile drivers. There really isn't a need to use VS anyway, the console and notepad will do just fine. I tried setting it up with MSVS and I got a ton of errors. Not worth it for me. Create a folder in either of your harddisks. Make it easy to access and without spaces. Ex: C:\hack\, not C:\my hack\. Also make it short, because you'll be navigating to it quite oftenly. In that folder you'll need to create two files:SOURCESMAKEFILENo extensions. SOURCES should contain the following: Code: TARGETNAME=MYDRIVER TARGETPATH=OUTPUT TARGETTYPE=DRIVER TARGETLIBS= $(BASEDIR)\lib\w2k\i386\ndis.lib SOURCES= TARGETNAME: Name of file to output file, excluding .sys extention.TARGETPATH: The path, from the current directory, where the compiled file will be stored.TARGETTYPE: The type of file source code is being compiled into.TARGETLIBS: A list to all the libraries to include in the project. Where $(BASEDIR) is the base directory of wherever you installed the DDK. Usually this is InstalledDriver:\WinDDK\VersionNumber\ SOURCES: defines all the c files to compile and link in the project. Be sure to update this when you create a new source file. This is currently blank, and will be filled in later on in this tutorial.And MAKEFILE should contain: Code: !INCLUDE $(NTMAKEENV)\makefile.def Which essentially redirects to the makefile provided in the ddk. All drivers will share the same makefile.Last but not least, download DebugView, which will allow you to view debug output messages from your driver. When you're debugging, you'll want to be viewing the output remotely. You can do this by starting the DebugView client(giving DebugView /c command argument when starting it) on the VM you'll be testing the driver is, then starting DebugView without any arguments on the host machine, and connecting to the local client by going to computer->connect-> and inserting the target machine's IP Address. After you've got that, you're ready to continue to the next step. Creating a basic console application to load and start driver services, as well as perform IO to IO Devices This is probably the easiest part of the tutorial and won't be explained too much. For this part of the tutorial we'll be using C++.To keep your code neat and organized, start by creating a source file, called serviceTools.h. We want to have a function load a driver using two parameters, the service name, and the path of it's corresponding executable. Notice this code may be modifed by it's parent tags, and thus refer to download for valid source file. PHP Code: #pragma once #include <stdio.h> #include <windows.h> int createService(char* serviceName, char* executablePath, bool relative); int startService(char* serviceName); int stopService(char* serviceName); int deleteService(char* serviceName); And the corresponding source file: Notice this code may be modifed by it's parent tags, and thus refer to download for valid source file. PHP Code: #include "stdafx.h" #include "serviceTools.h" int createService(char* serviceName, char* executablePath, bool relative) { char pathBuffer[200]; if(relative) { GetCurrentDirectory(200, pathBuffer); strcat(pathBuffer, "\\"); } strcat(pathBuffer, executablePath); printf("Creating service %s ", serviceName); SC_HANDLE sh = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if(sh == INVALID_HANDLE_VALUE) { printf("Error opening handle to Service Manager.\n"); return -1; } SC_HANDLE hService = CreateService(sh, serviceName, serviceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, pathBuffer, 0, 0, 0, 0, 0); CloseServiceHandle(sh); if(hService == 0) { printf("Error creating service.\n"); return -1; } printf("Service has been created under the display name of %s\n", serviceName); CloseServiceHandle(hService); return 1; } int startService(char* serviceName) { SC_HANDLE hService; SC_HANDLE sh = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if(!sh) { printf("Error opening service handler handle\n"); return -1; } hService = OpenService(sh, serviceName, SERVICE_ALL_ACCESS); CloseServiceHandle(sh); if(!hService) { printf("Error opening service handle\n"); return -1; } if(StartService(hService, 0, 0) != 0) printf("Service started.\n"); else { unsigned long eCode = GetLastError(); printf("Error starting service.(%d)\n", eCode); CloseServiceHandle(hService); return -1; } CloseServiceHandle(hService); return 1; } int stopService(char* serviceName) { SC_HANDLE hService; SC_HANDLE sh = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if(!sh) { printf("Error opening service handler handle\n"); return -1; } hService = OpenService(sh, serviceName, SERVICE_ALL_ACCESS); CloseServiceHandle(sh); if(!hService) { printf("Error opening service handle\n"); return -1; } SERVICE_STATUS srvStatus; if(ControlService(hService, SERVICE_CONTROL_STOP, &srvStatus) != 0) printf("Service stopped.\n"); else { printf("Error stopping service.\n"); CloseServiceHandle(hService); return -1; } CloseServiceHandle(hService); return 1; } int deleteService(char* serviceName) { SC_HANDLE hService; SC_HANDLE sh = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if(!sh) { printf("Error opening service handler handle\n"); return -1; } hService = OpenService(sh, serviceName, SERVICE_ALL_ACCESS); CloseServiceHandle(sh); if(!hService) { printf("Error opening service handle\n"); return -1; } if(DeleteService(hService) != 0) printf("Service deleted.\n"); else { printf("Error deleting service.\n"); CloseServiceHandle(hService); return -1; } CloseServiceHandle(hService); } The above code is pretty simple, but I will go over createService, after that, the rest are pretty much the same.First we notify the user a driver is being loaded printf("Creating service %s ", serviceName); Then we can go ahead and open a handle to the service control manager. SC_HANDLE sh = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); The first two parameters are optional, the first being the name of the target machine, in our case we want to open the SC Manager of the local machine, and thus this can be set to null. The second parameter is the name of the SC Manager database. MSDN states this should be set to SERVICES_ACTIVE_DATABASE definition, if it is null it is set to this by default.Now we can create our service. Code: SC_HANDLE hService = CreateService(sh, serviceName, serviceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, pathBuffer, 0, 0, 0, 0, 0); I don't plan to go through all of these parameters, they're all defined at MSDN library. Notice though, that the dwServiceType parameter is set to SERVICE_KERNEL_DRIVER definition. This API will create our service, and then return a handle to the newly created service.Then we dispose of the handles using CloseServiceHandle, CloseHandle cannot be used when it comes to service related handles, instead CloseServiceHandle is used.Now that that's over with, lets start writing the IO portion of the code. The objective of this code is to open handles to an IO device, and write to it. Create a new header file, call it deviceIo.h. We want a method to open a handle to an IO device, another to write to it, we wont need to read from the IO device in this tutorial. PHP Code: #pragma once #include <windows.h> HANDLE GetHandleToIo(char* deviceName); int CloseIoHandle(HANDLE hIo); int WriteToDevice(HANDLE hDevice, char* inBuffer); And the corresponding source file PHP Code: #include "stdafx.h" #include "deviceIo.h" HANDLE GetHandleToIo(char* deviceName) { return (HANDLE)CreateFile(deviceName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); } int CloseIoHandle(HANDLE hIo) { if(hIo == INVALID_HANDLE_VALUE) return -1; else CloseHandle(hIo); return 1; } int WriteToDevice(HANDLE hDevice, char* inBuffer) { WriteFile(hDevice, inBuffer, strlen(inBuffer) + 1, 0, 0); return 1; } Pretty simple. No need to go into any details. If you need help with this portion of code, just say so and I will document it a bit more.Lastly, we need to process all the commands thrown into our console. To do so, we're going to create yet another file called commandProcessor.h. PHP Code: #pragma once #define CMD_UNKNOWN_COMMAND 0 #define CMD_SETUP_SERVICE 1 #define CMD_DELETE_SERVICE 2 #define CMD_START_SERVICE 3 #define CMD_STOP_SERVICE 4 #define CMD_WRITE 5 #define CMD_OPEN 6 #define CMD_CLOSE 7 #include "serviceTools.h" #include "deviceIo.h" unsigned int translateCommand(char* command); int processCommand(char* command); And the corresponding source file: PHP Code: #include "stdafx.h" #include "commandProcessor.h" const unsigned long CMD_ID_TABLE[] = {CMD_SETUP_SERVICE, CMD_DELETE_SERVICE, CMD_START_SERVICE, CMD_STOP_SERVICE, CMD_WRITE, CMD_OPEN, CMD_CLOSE, CMD_QUIT}; const char* CMD_NAME_TABLE[] = {"ss" , "ds" , "start", "stop" , "write", "open", "close", "quit"}; unsigned int translateCommand(char* command) { int tblCmdSize = sizeof(CMD_ID_TABLE) / sizeof(unsigned long); int tblCmdName = sizeof(CMD_NAME_TABLE) / sizeof(char*); for(unsigned int i = 0; i < tblCmdSize && i < tblCmdName; i++) if(!strcmp(command, CMD_NAME_TABLE[i])) return CMD_ID_TABLE[i]; return CMD_UNKNOWN_COMMAND; } int processCommand(char* command) { static HANDLE hFileHandle = INVALID_HANDLE_VALUE; char buffer[200]; ZeroMemory(&buffer, 200); switch(translateCommand(command)) { case CMD_SETUP_SERVICE: scanf("%s", buffer); createService("MYDRIVER", buffer, true); break; case CMD_DELETE_SERVICE: scanf("%s", buffer); deleteService(buffer); break; case CMD_START_SERVICE: scanf("%s", buffer); startService(buffer); break; case CMD_STOP_SERVICE: scanf("%s", buffer); stopService(buffer); break; case CMD_OPEN: scanf("%s", buffer); hFileHandle = GetHandleToIo(buffer); break; case CMD_CLOSE: CloseIoHandle(hFileHandle); break; case CMD_WRITE: scanf("%[^\n\t]s", buffer); WriteToDevice(hFileHandle, buffer); break; case CMD_QUIT: return 0; break; default: printf("Unknown command inserted..\n"); } return 1; } Lets tie this all together into main.cpp PHP Code: // tutDriverConsole.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "commandProcessor.h" int main(int argc, char* argv[]) { char buffer[200]; int ret; do { printf("\n >>"); scanf("%200s", buffer); ret = processCommand(buffer); }while(ret); return 0; } Commands for console: Quote: ss- Setup Serviceds- Delete servicestart - start servicestop - stop serviceopen - open handle to IO deviceclose - close current IO handlewrite - write to opened IO handlequit - quit Be sure to close your handle to the IO device, before attempting to stop and delete the service.And that's about it for the console application. Now lets dive right into creating our first driver.Este doar o parte din tutorial.Articolul complet: [Tutorial] Writing drivers to perform kernel-level SSDT hooking.PDF: MEGAUPLOAD - The leading online storage and file delivery serviceDownload Writing drivers to perform kernel-level SSDT hooking.pdf for free on uploading.com2shared - download Writing drivers to perform kernel-level SSDT hooking.pdf Quote