michaelyao
驱动牛犊
驱动牛犊
  • 注册日期2008-03-20
  • 最后登录2009-06-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
阅读:1155回复:4

新手请教关于驱动版的helloworld问题,请高手赐教!

楼主#
更多 发布于:2008-03-21 21:35
     小弟最近在学驱动,遇到很多迷茫的问题,在这跪求高手赐教。
1、怎么跟踪调试进入到sys文件?有什么具体点的方法,我只会在main.c中加个MessageBox,然后用softice断MessageBox,还是没办法走到sys里面
2、我跟踪进到main.c的DriverControl中,传入-start后,DeviceIoControl返回的是0,GetLastErr()返回的是87,这是哪出问题了呢?是不是进到DeviceIoControl中就会跳到驱动的Dispath函数?
 
下面是代码:
HelloWorld.c
#ifndef __HELLOWORLD_C__
#define __HELLOWORLD_C__

#define DEBUGMSG

#include <ntddk.h>

#define DEVICE_HELLO_INDEX 0x860

//2个IOCTL宏
#define START_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define STOP_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)

#define NT_DEVICE_NAME L"\\Device\\HelloWorld"     //设备名称
#define DOS_DEVICE_NAME L"\\DosDevices\\HelloWorld"   //符号连接

NTSTATUS HelloWorldDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);

VOID HelloWorldUnLoad (IN PDRIVER_OBJECT DriverObject);

//驱动入口
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
  NTSTATUS ntStatus=STATUS_SUCCESS;
  PDEVICE_OBJECT lpDeviceObject=NULL;     //指向设备对象的指针
  UNICODE_STRING DeviceNameString={0};     //设备名称
  UNICODE_STRING DeviceLinkString={0};     //符号连接

  //调试信息
  #ifdef DEBUGMSG
      DbgPrint("Starting DriverEntry()\n");
  #endif

  RtlInitUnicodeString(&DeviceNameString,NT_DEVICE_NAME); //初始化Unicode字符串
  //创建设备
  ntStatus=IoCreateDevice(DriverObject,0,&DeviceNameString,FILE_DEVICE_UNKNOWN,0,FALSE,&lpDeviceObject);

  //使用NT_SUCCESS宏检测函数调用是否成功
  if (!NT_SUCCESS(ntStatus))
  {
    #ifdef DEBUGMSG
          DbgPrint("IoCreateDevice() error reports 0x%08X\n",ntStatus);
    #endif
    return ntStatus;
  }

  RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
  //创建符号连接
  ntStatus=IoCreateSymbolicLink(&DeviceLinkString,&DeviceNameString);

  if (!NT_SUCCESS(ntStatus))
  {
    #ifdef DEBUGMSG
          DbgPrint("IoCreateSymbolicLink() error reports 0x%08X\n",ntStatus);
    #endif
    if (lpDeviceObject)
        IoDeleteDevice(lpDeviceObject);
    return ntStatus;
  }

  //设置IRP派遣例程和卸载例程
  DriverObject->MajorFunction[IRP_MJ_CREATE]=
  DriverObject->MajorFunction[IRP_MJ_CLOSE]=
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=HelloWorldDispatch;
  DriverObject->DriverUnload=HelloWorldUnLoad;

  return ntStatus;
}

NTSTATUS HelloWorldDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)
{
  NTSTATUS ntStatus=STATUS_SUCCESS;
  PIO_STACK_LOCATION IrpStack=NULL;   //IRP堆栈
  ULONG IoControlCodes=0;         //I/O控制代码

  //设置IRP状态
  pIrp->IoStatus.Status=STATUS_SUCCESS;
  pIrp->IoStatus.Information=0;

  #ifdef DEBUGMSG
      DbgPrint("Starting HelloWorldDispatch()\n");
  #endif

  IrpStack=IoGetCurrentIrpStackLocation(pIrp);   //得到当前调用者的IRP

  switch (IrpStack->MajorFunction)
  {
        case IRP_MJ_CREATE:
          #ifdef DEBUGMSG
                DbgPrint("IRP_MJ_CREATE\n");
          #endif
          break;

        case IRP_MJ_CLOSE:
          #ifdef DEBUGMSG
                DbgPrint("IRP_MJ_CLOSE\n");
          #endif
          break;

        case IRP_MJ_DEVICE_CONTROL:

          #ifdef DEBUGMSG
                DbgPrint("IRP_MJ_DEVICE_CONTROL\n");
          #endif

          //取得I/O控制代码
          IoControlCodes=IrpStack->Parameters.DeviceIoControl.IoControlCode;

          switch (IoControlCodes)
          {
                //启动
                case START_HELLPWORLD:
                    DbgPrint("Starting \"Hello World\"\n");
                    break;

                //停止
                case STOP_HELLPWORLD:
                    DbgPrint("Stoping \"Hello World\"\n");
                    break;

                default:
                    pIrp->IoStatus.Status=STATUS_INVALID_PARAMETER;
                    break;
          }

          break;

        default:
          break;
  }

  ntStatus=pIrp->IoStatus.Status;
  IoCompleteRequest(pIrp,IO_NO_INCREMENT);

  return ntStatus;
}

VOID HelloWorldUnLoad (IN PDRIVER_OBJECT DriverObject)
{
  UNICODE_STRING DeviceLinkString={0};
  PDEVICE_OBJECT DeviceObjectTemp1=NULL;
  PDEVICE_OBJECT DeviceObjectTemp2=NULL;

  #ifdef DEBUGMSG
        DbgPrint("Starting HelloWorldUnLoad()\n");
  #endif

  RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);

  if (DeviceLinkString.Buffer)
      IoDeleteSymbolicLink(&DeviceLinkString);

  if (DriverObject)
  {
      DeviceObjectTemp1=DriverObject->DeviceObject;

      while (DeviceObjectTemp1)
      {
          DeviceObjectTemp2=DeviceObjectTemp1;
          DeviceObjectTemp1=DeviceObjectTemp1->NextDevice;
          IoDeleteDevice(DeviceObjectTemp2);
      }
  }
}

#endif



Main.c
#define DEBUGMSG

#include <windows.h>
#include <winioctl.h>
#include <stdio.h>

#define DEVICE_FILTER_INDEX 0x860

#define START_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_FILTER_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define STOP_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_FILTER_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)

#define erron GetLastError()

#define MY_DEVICE_NAME "\\\\.\\HelloWorld\\sys\\i386\\HelloWorld.sys"

#define MY_DEVICE_START "-start"
#define MY_DEVICE_STOP "-stop"

BOOL DriverControl (TCHAR *Maik);

void Usage (TCHAR *Paramerter);

int main (int argc,TCHAR *argv[])
{
  if (argc!=2)
  {
    Usage(argv[0]);
    return 0;
  }

  if (strcmpi(argv[1],MY_DEVICE_START)==0 || strcmpi(argv[1],MY_DEVICE_STOP)==0)
    DriverControl(argv[1]);
  else
  {
    Usage(argv[0]);
    return 0;
  }

  return 0;
}

BOOL DriverControl (TCHAR *Maik)
{
  HANDLE hDevice=NULL; //设备句柄
 Dword BytesReturn;

  //获得设备句柄
  hDevice=CreateFile(MY_DEVICE_NAME,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

  if (hDevice==INVALID_HANDLE_VALUE)
  {
      #ifdef DEBUGMSG
          printf("CreateFile() GetLastError reports %d\n",erron);
      #endif
      return FALSE;
  }

  //启动
  if (strcmpi(Maik,MY_DEVICE_START)==0)
  {
      //传递启动的I/O控制代码
      if (!(DeviceIoControl(hDevice,START_HELLPWORLD,NULL,0,NULL,0,&BytesReturn,(LPOVERLAPPED)NULL)))
      {
        #ifdef DEBUGMSG
            printf("DeviceIoControl() GetLastError reports %d\n",erron);
        #endif
        CloseHandle(hDevice);
        return FALSE;
      }
  }

  //停止
  if (strcmpi(Maik,MY_DEVICE_STOP)==0)
  {
      //传递停止的I/O控制代码
      if (!(DeviceIoControl(hDevice,STOP_HELLPWORLD,NULL,0,NULL,0,,&BytesReturn,,(LPOVERLAPPED)NULL)))
      {
        #ifdef DEBUGMSG
            printf("DeviceIoControl() GetLastError reports %d\n",erron);
        #endif
        CloseHandle(hDevice);
        return FALSE;
      }
  }

  if (hDevice)
      CloseHandle(hDevice); //关闭句柄

  return TRUE;
}

void Usage (TCHAR *Paramerter)
{
  fprintf(stderr,"============================================================================\n"
        "     驱动版Hello World\n"
        "作者:dahubaobao[E.S.T]\n"
        "主页:http://www.eviloctal.com/\n"
        "OICQ:382690\n\n"
        "%s -start\t启动\n"
        "%s -stop \t停止\n\n"
        "本程序只是用做代码交流,如有错误,还请多多包含!\n"
        "============================================================================\n"
        ,Paramerter,Paramerter);
}
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2008-03-22 13:53
lpBytesReturned
[out] Pointer to a variable that receives the size of the data stored in the output buffer, in bytes.
If the output buffer is too small to receive any data, the call fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, and lpBytesReturned is zero.

If the output buffer is too small to hold all of the data but can hold some entries, some drivers will return as much data as fits. In this case, the call fails, GetLastError returns ERROR_MORE_DATA, and lpBytesReturned indicates the amount of data received. Your application should call DeviceIoControl again with the same operation, specifying a new starting point.

If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even when an operation returns no output data and lpOutBuffer is NULL, DeviceIoControl makes use of lpBytesReturned. After such an operation, the value of lpBytesReturned is meaningless.

If lpOverlapped is not NULL, lpBytesReturned can be NULL. If this parameter is not NULL and the operation returns data, lpBytesReturned is meaningless until the overlapped operation has completed. To retrieve the number of bytes returned, call GetOverlappedResult. If hDevice is associated with an I/O completion port, you can retrieve the number of bytes returned by calling GetQueuedCompletionStatus.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
michaelyao
驱动牛犊
驱动牛犊
  • 注册日期2008-03-20
  • 最后登录2009-06-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-03-22 14:33
引用第1楼wowocock于2008-03-22 13:53发表的  :
lpBytesReturned
[out] Pointer to a variable that receives the size of the data stored in the output buffer, in bytes.
If the output buffer is too small to receive any data, the call fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, and lpBytesReturned is zero.

If the output buffer is too small to hold all of the data but can hold some entries, some drivers will return as much data as fits. In this case, the call fails, GetLastError returns ERROR_MORE_DATA, and lpBytesReturned indicates the amount of data received. Your application should call DeviceIoControl again with the same operation, specifying a new starting point.
.......


DeviceIoControl的倒数第二个参数改为非0也不行呀。请具体指点下
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2008-03-22 15:08
参考DDK 里的例子,初学者最好的老师.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
michaelyao
驱动牛犊
驱动牛犊
  • 注册日期2008-03-20
  • 最后登录2009-06-09
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-03-22 15:47
我就是看了半天看不明白,请指点下吧
游客

返回顶部