首页
社区
课程
招聘
[求助]mickeylan老大的方法,我怎么就学不会,请大家赐教啊!
发表于: 2009-1-7 09:27 3920

[求助]mickeylan老大的方法,我怎么就学不会,请大家赐教啊!

2009-1-7 09:27
3920
mickeylan老大在Delphi研究之驱动开发篇(七)--利用共享内存与用户模式程序通讯,我基本上和他的是一样的,不知道我这就是不行,请大家帮忙看看,谢谢!
驱动功能是把与本机通信的IP全部传到应用程序
驱动部分代码:
IO_CTL:buffered模式;
DISPATCH里:
inputBuffer   = Irp->AssociatedIrp.SystemBuffer;
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
case GET_EVENT:
{                               
  OBJECT_HANDLE_INFORMATION objHandleInfo;
  HANDLE hEvent = *(HANDLE *)inputBuffer;
                               
  Irp->IoStatus.Status =ObReferenceObjectByHandle(hEvent,GENERIC_ALL,NULL,                                KernelMode, &gpEventObject,&objHandleInfo);                        

  if(gpEventObject)
  {
    DbgPrint("got gpEventObject\n");                                       
    psharememory = ExAllocatePoolWithTag(NonPagedPool, sizeof(PKT_BUFFER),'MhSp');
     CreateShareMemory(psharememory,sizeof(Monitor_Message));       
    MapSharedMemory(psharememory);
    DbgPrint("psharememory->UserBaseAddress:%d\n",psharememory->UserBaseAddress);       
            DbgPrint("shared memory\n");                                       
   }
       break;
}

case MONITOR_INFO:
{
   if (outputBufferLength== sizeof(PVOID))
  {
    DbgPrint("sending info\n");
    *((PVOID *)outputBuffer)  = psharememory->UserBaseAddress;
    Irp->IoStatus.Information = sizeof(PVOID);                               
    }
   break;
}

case IO_DEREFERENCE_EVENT:
{
  if(gpEventObject)
  ObDereferenceObject(gpEventObject);       
                                       
  if(psharememory)
  {
     (psharememory->KernelBaseAddress))->name);        
    UnmapSharedMemory(psharememory);
    DestroyShareMemory(psharememory);
   }
   DbgPrint("IO_DEREFERENCE_EVENT OVER\n");
   break;
  }
其它的辅助函数:
BOOLEAN CreateShareMemory(PPKT_BUFFER PktBuffer, ULONG Size)
{
  PktBuffer->KernelBaseAddress = ExAllocatePoolWithTag(NonPagedPool, Size,'MpaM');
 if(!PktBuffer->KernelBaseAddress)
  return FALSE;
//
// Allocate and initalize an MDL that describes the buffer
//
  PktBuffer->BufferMdl = IoAllocateMdl(PktBuffer->KernelBaseAddress, Size, FALSE, FALSE,NULL);
  if(!PktBuffer->BufferMdl)
 {
  ExFreePool(PktBuffer->KernelBaseAddress);
  PktBuffer->KernelBaseAddress =NULL;
  return FALSE;
  }
 MmBuildMdlForNonPagedPool(PktBuffer->BufferMdl); //页面用这个:MmProbeAndLockPages
  return TRUE;
}

BOOLEAN MapSharedMemory(PPKT_BUFFER PktBuffer)
{
 if(!PktBuffer->BufferMdl)
   return FALSE;
//
// The preferred V5 way to map the buffer into user space
//
 PktBuffer->UserBaseAddress = MmMapLockedPagesSpecifyCache(PktBuffer->BufferMdl, // MDL
                                UserMode, // Mode
                                            MmCached, // Caching
                                            NULL, // Address
                                            FALSE, // Bugcheck?
                                            NormalPagePriority); // Priority
 if(!PktBuffer->UserBaseAddress)
    return FALSE;
 return TRUE;
}
相关结构:
typedef struct _PKT_BUFFER
{
        PMDL BufferMdl;
        PVOID UserBaseAddress;
        PVOID KernelBaseAddress;
}PKT_BUFFER, *PPKT_BUFFER;
相关说明:
驱动运行在IRQL=2级,驱动获得事件对像后像不停的给应用程序信号,不停地速度很快地向应用程序发送。

应用程序:
  TThreadPara=packed record
    ctrlcode:integer;
    ListItem:TListItem;
  end;
procedure TFireWallFrm.BtnMonitorAllStartClick(Sender: TObject);
var
  para:TThreadPara;
  id:dword;
begin
  para.ctrlcode:=MONITOR_INFO;
  para.ListItem:=self.LVMonitorAll.Items.Add;
  threadhandle:=CreateThread(nil,0,@GetMonitorInfo,@para,0,id);   
end;

function GetMonitorInfo(var para:TThreadPara):dword;stdcall;
var
  pinfo:PMonitorMessage;
  pSend:PULONG;
begin  
  if MainFrm.bFWStart then
  begin
    if eventhandle=0 then
    begin
      eventhandle:=CreateEvent(nil,false,false,nil);
      GetMem(pSend,sizeof(Thandle));
      Copymemory(pSend,@eventhandle,sizeof(eventhandle));
      MainFrm.IpWall.WriteIo(GET_EVENT,pSend,sizeof(eventhandle));
      freemem(pSend);
    end;
    Getmem(pinfo,sizeof(TMonitorMessage));
    while(true) do
    begin
      WaitForSingleObject(eventhandle, INFINITE);
      MainFrm.IpWall.ReadIo(para.ctrlcode,@pinfo,sizeof(pointer));
  showmessage(inttostr(ULONG (pinfo)));//这里显示的地址是UserBaseAddress一样的           
      para.ListItem.SubItems.Add(iptostring(pinfo^.ip));//程序运行到这出现访问内存错误,我想应该是共享内存不对,可是又想不出问题,因为DBG显示的UserBaseAddress和我用showmessage显示的一样      
  para.ListItem.SubItems.Add(inttostr(htons(pinfo^.port)));
      case pinfo.protocol of
        6:para.ListItem.SubItems.Add('TCP');
        17:para.ListItem.SubItems.Add('UDP');
        1:para.ListItem.SubItems.Add('ICMP');
      end;
      if pinfo^.send then
        para.ListItem.SubItems.Add('发送')
      else
        para.ListItem.SubItems.Add('接收');
      para.ListItem.SubItems.Add(inttostr(pinfo^.size));
    end;
  end;
end;

请各位前辈指点啊!windbg不知道是怎么通信的,他那读驱动里的信息可真好

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 215
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我想知道为什么DDDK/KmdKit4D编译驱动,同单元里定义的函数都不能随便用,一用就蓝,必须连接为_XXX@a模式
但是我用omf2d和rmcoff都不行,rmcoff提示我没有函数被导出,明明我导出了的

哦omf2d自己添加参数是可以转换,但是太麻烦,KmdKit4D就是为这个而设计的,但是我没搞懂rmcoff的用法
2009-1-8 17:21
0
游客
登录 | 注册 方可回帖
返回
//