A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #13005  by Tigzy
 Thu May 03, 2012 12:59 pm
Hello

I got a little problem with my driver...
With DeviceIOControl I call an IOCTL with buffer passed in argument, for both IN and OUT

In 90% of the runs, all is fine, and I keep the adresses of the fields of apiHookObj equals to what I have initialized.
But in some case, reported by some users, I got this in the log:
[00:08:0986] [SSDT] Iterate refApi : (0x9f0732c) 0x6456744e, refModule : (0x9f0712c) 0x6e6f436d
Here you can see the fields of the object passed to KM relocated up in the kernel (adresses with high ranges)
Normally, it should (and it does almost everytime) looks like this:
[00:08:0986] [SSDT] Iterate refApi : (0x9f0732c) 0x9f0732c, refModule : (0x9f0712c) 0x9f0712c
here's the code:
Code: Select all
typedef struct _API_HOOK_SSDT {

	PDWORD ApiIndex; 
	char* ApiName; 
	char* ModuleName; 
	PULONG ApiAdress;

} API_HOOK_SSDT, *PAPI_HOOK_SSDT;

Userland
Code: Select all
API_HOOK_SSDT apiHookObj = {0};

char Module[512] = "", ApiName[512] = "";
DWORD ApiIndex = 0; ULONG ApiAdress = 0x0;

// Init buffers
apiHookObj.ApiAdress = &ApiAdress;
apiHookObj.ApiIndex = &ApiIndex;
apiHookObj.ApiName = ApiName;
apiHookObj.ModuleName = Module;

while (DeviceIoControl( varEnv.driver.hDriver, IOCTL_SSDT, &apiHookObj, sizeof(API_HOOK_SSDT), &apiHookObj,  sizeof(API_HOOK_SSDT), &dwBytesRet, 0) && dwBytesRet)
{	
      printLog(L"[SSDT] Iterate refApi : (0x%x) 0x%x, refModule : (0x%x) 0x%x", (DWORD)ApiName, (DWORD)apiHookObj.ApiName, (DWORD)Module, (DWORD)apiHookObj.ModuleName);
      ...
}
KernelLand
Code: Select all

				case IOCTL_SSDT:
				{
					PAPI_HOOK_SSDT pBufferIn = pIrp->AssociatedIrp.SystemBuffer;					
										
					// Basically only a strcpy(pBufferIn->Field, "Something")
					ScanSSDT(pBufferIn);	
					
					//We got a hook left
					if (*pBufferIn->ApiAdress != 0x0)
					{
						pIrp->IoStatus.Information = 1;								
						retVal = STATUS_SUCCESS;
					}
					else
					{
						pIrp->IoStatus.Information = 0;
						retVal = STATUS_UNSUCCESSFUL;	
					}
					break;
				}
 #13011  by Vrtule
 Thu May 03, 2012 7:03 pm
Hello,

do you ever write any data to API_HOOK_SSDT buffer inside ScanSSDT routine?

By the way, it could be quite dangerous not to check validity of pointers to memory accessible from user mode. If you are using METHOD_BUFFERED the API_HOOK_SSDT structure is copied, however, the system does not (and cannot) make its deep copy.
 #13020  by Tigzy
 Fri May 04, 2012 5:55 am
Yes I do write inside the ScanSSDT routine.
Code: Select all
void ScanSSDT(PAPI_HOOK_SSDT pApiStruct)
{
        // Reinit buff
	strcpy(pApiStruct->ModuleName, "Unknown");
	strcpy(pApiStruct->ApiName, "Unknown");
	*pApiStruct->ApiIndex = 0;
	*pApiStruct->ApiAdress = 0x0;
        ...
}
I removed all the checks from the code before pasting it here to lower its size :)
This is better to understand it. basically the ckecks exits the routine when something goes wrong, so it's not the problem here

I thought about the possibility of having the IN buffer realocated inside the kernel, as here I pass the same pointer for both IN and OUT buffer.
Should I separate them?

What do you mean by "cannot makes its deep copy" ?
 #13023  by xdeadcode
 Fri May 04, 2012 8:46 am
Hi Tigzy,

What kind of method you use for passing params?
I understand that "..." inside ScanSSDT does not touch apistruct - right?
Are you 100% sure you don't have buffer overflow during strcpy operations?
What with rest of the fields of the api struct after deviceIoControl (I see that you are printing ApiName and ModuleName, maybe it would be worth to see what happens with rest of the fields).

Best regards.
 #13025  by Tigzy
 Fri May 04, 2012 11:51 am
Hi
What kind of method you use for passing params?
I'm not sure to understand, all the code is above :/
I understand that "..." inside ScanSSDT does not touch apistruct - right?
I only write into pointer's values. Normally.

I'm not sure for buffer overflow, I will securize my code and introduce a constant on both side to fix the max size of buffers. (it's 512 bytes, enough for 99,9% of the cases...)
But when you get overflow in the kernel about a userland buffer, what happen? Is it possible that the shared buffer is realocated elsewhere, and in our case in the kernel?

Rest of the fields are here :)
Code: Select all
*pApiStruct->ApiIndex = 0;
*pApiStruct->ApiAdress = 0x0;
 #13026  by xdeadcode
 Fri May 04, 2012 12:23 pm
Tigzy,

I understand that you use METHOD_BUFFERED in your code.
Here is how it is realized http://msdn.microsoft.com/en-us/library ... s.85).aspx

Since your pointer problems are not deterministic (as far as I understand) then I would suggest to use driver verifier and mark in options 'special pool'. This for sure it will find you eventual overflows/overruns/underruns.
Other options would probably find you other problems.

In last post I've asked about rest of fields to print it also in userland to see if something bad had happend with char* fields only or with other fields also.
 #13027  by Tigzy
 Fri May 04, 2012 12:53 pm
Thanks for the reply!
I changed every string manipulation function (strcpy, strcat, ...) with safe functions (RtlStringCbCopyA, ... ). We'll see what will going on.
I would suggest to use driver verifier and mark in options 'special pool'. This for sure it will find you eventual overflows/overruns/underruns.
Can you develop this please?
 #13028  by xdeadcode
 Fri May 04, 2012 1:34 pm
Tigzy,

Driver verifier is standard ms tool for verifying drivers when its loaded and running.
to run it simply win+r then lauch "verifier" - then choose options from menu and let your driver working.
When something very bad occur (like overrun) then you will see bsod with proper bugcheck code.

Best regards
 #13031  by GamingMasteR
 Fri May 04, 2012 3:17 pm
I think Vrtule meant by "deep copy" is that IO manager will only copy the passed structure but not the buffer it points to, try including the APINAME/MODULENAME buffers inside API_HOOK_SSDT instead of pointing to them.