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不知道是怎么通信的,他那读驱动里的信息可真好
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法