SDD
SDD

Reputation: 1451

How to debug driver load error?

I've made a driver for Windows, compiled it and tried to start it via SC manager, but I get the system error from the SC manager API:

ERROR_PROC_NOT_FOUND The specified procedure could not be found.

Is there a way to get more information about why exactly the driver fails to start? WinDbg or something? If I comment out all code in my DriverEntry routine, the driver starts.

The only thing I'm calling is a procedure in another source module (in my own project, though). I can comment out all external dependencies and I still get the same error.

Edit:
I've also tried different DDKs, i.e. 2003 DDK und Vista WDK (but not Win7 WDK)

Edit2: Here is my driver sour code file driver.cpp:

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <ntstrsafe.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include "../distorm/src/distorm.h"

void DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
}

#define MAX_INSTRUCTIONS 20

#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
 UNICODE_STRING pFcnName;

 // Holds the result of the decoding.
 _DecodeResult res;
 // Decoded instruction information.
 _DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
 // next is used for instruction's offset synchronization.
 // decodedInstructionsCount holds the count of filled instructions' array by the decoder.
 unsigned int decodedInstructionsCount = 0, i, next;
 // Default decoding mode is 32 bits, could be set by command line.
 _DecodeType dt = Decode32Bits;

 // Default offset for buffer is 0, could be set in command line.
 _OffsetType offset = 0;
 char* errch = NULL;

 // Buffer to disassemble.
 char *buf;
 int len = 100;

 // Register unload routine
 DriverObject->DriverUnload = DriverUnload;

 DbgPrint("diStorm Loaded!\n");

 // Get address of KeBugCheck
 RtlInitUnicodeString(&pFcnName, L"KeBugCheck");
 buf = (char *)MmGetSystemRoutineAddress(&pFcnName);
 offset = (unsigned) (_OffsetType)buf;

 DbgPrint("Resolving KeBugCheck @ 0x%08x\n", buf);
 // Decode the buffer at given offset (virtual address).

 while (1) {
  res = distorm_decode(offset, (const unsigned char*)buf, len, dt, decodedInstructions, MAX_INSTRUCTIONS, &decodedInstructionsCount);
  if (res == DECRES_INPUTERR) {
   DbgPrint(("NULL Buffer?!\n"));
   break;
  }

  for (i = 0; i < decodedInstructionsCount; i++) {
   // Note that we print the offset as a 64 bits variable!!!
   // It might be that you'll have to change it to %08X...
   DbgPrint("%08I64x (%02d) %s %s %s\n", decodedInstructions[i].offset, decodedInstructions[i].size, 
    (char*)decodedInstructions[i].instructionHex.p,
    (char*)decodedInstructions[i].mnemonic.p,
    (char*)decodedInstructions[i].operands.p);
  }

  if (res == DECRES_SUCCESS || decodedInstructionsCount == 0) {
   break; // All instructions were decoded.
  }

  // Synchronize:
  next = (unsigned int)(decodedInstructions[decodedInstructionsCount-1].offset - offset);
  next += decodedInstructions[decodedInstructionsCount-1].size;

  // Advance ptr and recalc offset.
  buf += next;
  len -= next;
  offset += next;
 }

 DbgPrint(("Done!\n"));
 return STATUS_SUCCESS;
}

#ifdef __cplusplus
}; // extern "C"
#endif

My directory structure is like this:

base_dir\driver\driver.cpp
        \distorm\src\all_the_c_files
        \distorm\distorm.h
        \distorm\config.h

My SOURCES file:

# $Id$
TARGETNAME=driver
TARGETPATH=obj
TARGETTYPE=DRIVER

# Additional defines for the C/C++ preprocessor
C_DEFINES=$(C_DEFINES) -DSUPPORT_64BIT_OFFSET

SOURCES=driver.cpp \
     distorm_dummy.c \
        drvversion.rc

INCLUDES=..\distorm\src;

TARGETLIBS=$(DDK_LIB_PATH)\ntdll.lib \
        $(DDK_LIB_PATH)\ntstrsafe.lib

You can download diStorm from here: http://ragestorm.net/distorm/dl.php?id=8

distorm_dummy is the same as the dummy.c from the diStorm lib.

Upvotes: 1

Views: 4274

Answers (5)

user273557
user273557

Reputation: 1

Build it with the 6000 WDK/DDK (because with the "actual" Build 7600... it links against wdfldr.sys, but under Windows Vista and XP Systems this sys file is not available). I don't know where you can download it officially but i did use a torrent...

Upvotes: 0

Daniel Goldberg
Daniel Goldberg

Reputation: 20518

Not surprisingly, you have all the information you need to solve this on your own.

ERROR_PROC_NOT_FOUND The specified procedure could not be found.

This, combined with your dependency Walker output, pretty much points to a broken Import Table

Why is your IT broken? I'm not sure, could be a problem with your build/linker settings, since rather obviously, HAL.DLL is right there in %windir%\system32.

Reasons for a broken load order are many and you'll have to track them down yourself.

Upvotes: 1

tyranid
tyranid

Reputation: 13318

Have you tried running Dependency Walker on the compiled .sys and see if there is actually some missing function imports?

Upvotes: 1

Johannes Passing
Johannes Passing

Reputation: 2805

Enable "Show loader snaps" using gflags -- in the debug output, you should find information about which import the loader is not able to resolve.

Upvotes: 2

Christopher
Christopher

Reputation: 8982

You can add deferred breakpoints in WinDbg.

If you specify a breakpoint, while the driver is not loaded (or with bu), it will be triggered, when the driver does get loaded and enters the function.

The command for specifiying breakpoints is :

bp <module_name>!<function_name>

e.g. :

bp my_driver!DriverEntry

Upvotes: -1

Related Questions