首页
社区
课程
招聘
[旧帖] [求助]关于拦截IE重定向的问题 0.00雪花
发表于: 2011-5-3 03:40 2147

[旧帖] [求助]关于拦截IE重定向的问题 0.00雪花

2011-5-3 03:40
2147
最近需要一个工具实现拦截系统中的IE访问,将访问拦截后发送到指定的代理服务器去处理。
我是通过将一个dll注入到iexplore.exe程序中的。成功的注入进去了。但是我发现并没有拦截到HTTP的数据,在DLL中这样实现对于HTTP协议的拦截,准确的说是TCp拦截:
(本段代码来自网络,主要输出拦截的数据)
#include "stdafx.h"
#include "windows.h"
#include "winnt.h"

PVOID pNtDeviceIoControl  = NULL ; 
//

#define AFD_RECV 0x12017

#define AFD_SEND 0x1201f


typedef struct AFD_WSABUF{
  UINT  len ;
  PCHAR  buf ;
}AFD_WSABUF , *PAFD_WSABUF;

typedef struct AFD_INFO {
  PAFD_WSABUF  BufferArray ; 
  ULONG  BufferCount ; 
  ULONG  AfdFlags ;
  ULONG  TdiFlags ;
} AFD_INFO,  *PAFD_INFO;
typedef LONG NTSTATUS;

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

const CHAR GetXX[] = "GET ";
const CHAR PostXX[] = "POST ";
const CHAR HttpXX[] = "HTTP";
//////////////////////////////////////////////////////////////////////////
//
// LookupSendPacket
// 检查Send包
// 目前实现了过滤HTTP请求(GET AND POST)
//
//////////////////////////////////////////////////////////////////////////

BOOL LookupSendPacket(PVOID Buffer , ULONG Len)
{
  if (Len < 5)
  {
    return FALSE ; 
  }

  //外层已有异常捕获

  if (memcmp(Buffer , GetXX , 4) == 0 
    ||
    memcmp(Buffer , PostXX , 5) == 0 )
  {
    return TRUE ; 
  }
  return FALSE ; 
}  
//////////////////////////////////////////////////////////////////////////
//
// LookupRecvPacket
//
// 检查Recv包
// 在这里可以实现Recv包查字典功能
// 目前实现了过滤HTTP返回数据包的功能
//
//
///////////////////////////////////////////////////////////////////////////
BOOL LookupRecvPacket(PVOID Buffer , ULONG Len)
{
  if (Len < 4)
  {
    return FALSE ; 
  }

  if (memcmp(Buffer , HttpXX , 4) == 0 )
  {
    return TRUE ; 
  }

  return FALSE ; 
}
//hook函数

//////////////////////////////////////////////////////////////////////////
//
// NtDeviceIoControlFile的HOOK函数 
// ws2_32.dll的send , recv最终会调用到mswsock.dll内的数据发送函数
// mswsock.dll会调用NtDeviceIoControlFile向TDI Client驱动发送Send Recv指令
// 我们在这里做拦截,可以过滤所有的TCP 收发包(UDP之类亦可,不过要更改指令)
//
//////////////////////////////////////////////////////////////////////////

NTSTATUS __stdcall NewNtDeviceIoControlFile(
             HANDLE FileHandle,
             HANDLE Event OPTIONAL,
             PVOID ApcRoutine OPTIONAL,
             PVOID ApcContext OPTIONAL,
             PVOID IoStatusBlock,
             ULONG IoControlCode,
             PVOID InputBuffer OPTIONAL,
             ULONG InputBufferLength,
             PVOID OutputBuffer OPTIONAL,
             ULONG OutputBufferLength
    )
{
  
  //先调用原始函数

  LONG stat ; 
  __asm
  {
    push  OutputBufferLength
    push  OutputBuffer
    push  InputBufferLength
    push  InputBuffer 
    push  IoControlCode
    push  IoStatusBlock 
    push  ApcContext
    push  ApcRoutine
    push  Event
    push  FileHandle
    call  pNtDeviceIoControl
    mov    stat ,eax
  }

  //如果原始函数失败了(例如RECV无数据)

  if (!NT_SUCCESS(stat))
  {
    return stat ; 
  }

  //检查是否为TCP收发指令

  if (IoControlCode != AFD_SEND && IoControlCode != AFD_RECV)
  {
    return stat ; 
  }


  //访问AFD INFO结构,获得SEND或RECV的BUFFER信息
  //这里可能是有问题的BUFFER,因此我们要加TRY EXCEPT
  //

  __try
  {
    //从InputBuffer得到Buffer和Len

    PAFD_INFO AfdInfo = (PAFD_INFO)InputBuffer ; 
    PVOID Buffer = AfdInfo->BufferArray->buf ; 
    ULONG Len = AfdInfo->BufferArray->len;

    if (IoControlCode == AFD_SEND)
    {
      /*if (LookupSendPacket(Buffer , Len))
      {
        //输出包内容
        //这里输出调试信息,可以用DbgView查看,如果有UI可以做成SendMessage形式~
		// MessageBox(NULL,(char*)Buffer,NULL,MB_OK);
        OutputDebugString("SendPacket!\n");    
        OutputDebugString((char*)Buffer);
      }
	  */
		MessageBox(NULL,"You Attached",NULL,MB_OK);	
    }
    else
    {
      if (LookupRecvPacket(Buffer , Len))
      {
        OutputDebugString("RecvPacket!\n");
        OutputDebugString((char*)Buffer);
      }
    }
  }
  __except(EXCEPTION_EXECUTE_HANDLER)
  {
    return stat ; 
  }

  return stat ; 
   




  
}


//////////////////////////////////////////////////////////////////////////
//
//  Hook mswsock.dll导出表的Ntdll!NtDeviceIoControlFile
//  并过滤其对TDI Cilent的请求来过滤封包
//  稳定,隐蔽,RING3下最底层的包过滤~
//
//////////////////////////////////////////////////////////////////////////
void SuperHookDeviceIoControl()
{
  //得到ws2_32.dll的模块基址
  HMODULE hMod = LoadLibrary("mswsock.dll");
  if (hMod == 0 )
  {
    return ;
  }

  //得到DOS头

  PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hMod ; 

  //如果DOS头无效
  if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  {
    return ; 
  }

  //得到NT头

  PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG)hMod + pDosHeader->e_lfanew);

  //如果NT头无效
  if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
  {
    return ; 
  }

  //检查输入表数据目录是否存在
  if (pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 ||
    pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0 )
  {
    return ; 
  }
  //得到输入表描述指针

  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)hMod + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

  PIMAGE_THUNK_DATA ThunkData ; 

  //检查每个输入项
  while(ImportDescriptor->FirstThunk)
  {
    //检查输入表项是否为ntdll.dll

    char* dllname = (char*)((ULONG)hMod + ImportDescriptor->Name);
    
    //如果不是,则跳到下一个处理

    if (stricmp(dllname , "ntdll.dll") !=0)
    {
      ImportDescriptor ++ ; 
      continue;
    }
    
    ThunkData = (PIMAGE_THUNK_DATA)((ULONG)hMod + ImportDescriptor->OriginalFirstThunk);

    int no = 1;
    while(ThunkData->u1.Function)
    {
      //检查函数是否为NtDeviceIoControlFile

      char* functionname = (char*)((ULONG)hMod + ThunkData->u1.AddressOfData + 2);
      if (stricmp(functionname , "NtDeviceIoControlFile") == 0 )
      {
        //
        //如果是,那么记录原始函数地址
        //HOOK我们的函数地址
        //
        ULONG myaddr = (ULONG)NewNtDeviceIoControlFile;
        ULONG btw ; 
        PDWORD lpAddr = (DWORD *)((ULONG)hMod + (DWORD)ImportDescriptor->FirstThunk) +(no-1);
        pNtDeviceIoControl = (PVOID)(*(ULONG*)lpAddr) ; 
        WriteProcessMemory(GetCurrentProcess() , lpAddr , &myaddr , sizeof(ULONG), &btw );
        return ; 

      }

      no++;
      ThunkData ++;
    }
    ImportDescriptor ++;
  }
  return ; 
}


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
           )
{
  //当加载DLL时,进行API HOOK

  if (ul_reason_for_call == DLL_PROCESS_ATTACH)
  {  
    //HOOK API
    SuperHookDeviceIoControl();
  }
    return TRUE;
}

最后通过dgbview查看却没有任何信息,只有当IE进程退出后有一个dll卸载信息。不知道怎么回事。请大家帮忙看看怎么回事

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 1149
活跃值: (888)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
2
这段代码 写的很是工整...
2011-5-3 11:02
0
雪    币: 233
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这是准备做木马??
2011-5-3 11:19
0
雪    币: 45
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
不是做木马,是研究代理方面的问题。
2011-5-4 17:27
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
IE使用的是wininet API,没有直接使用socket吧。
2011-5-5 12:31
0
雪    币: 410
活跃值: (214)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
7
hook send吧。和谐一切
2011-5-5 13:04
0
雪    币: 45
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
  //得到ws2_32.dll的模块基址
  HMODULE hMod = LoadLibrary("mswsock.dll");
这些API不都是在这个dll里面?
我只拦截里面的send和recv
2011-5-6 01:57
0
雪    币: 45
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
可以给点思路?见谅不要使用驱动层的吧。谢谢。资料也行
2011-5-6 01:58
0
雪    币: 65
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
有一个疑问,你这个hook成功没有呢?在中途出错了没有?错误调试信息都没有一个。

那么多的hook代码你可以借鉴来用用。
2011-5-6 10:53
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
你没明白我的意思。我是说IE使用了A来访问网络,你hook了B,所以收不到信息。
wininet API和socket没有关系。
2011-5-6 11:33
0
雪    币: 45
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
这样啊,谢谢,那么我应该如何来处理这个问题,或者说应该hook那个?
2011-5-6 22:12
0
雪    币: 45
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
程序的编译和调试都正常,但是没有任何的HTTP数据包输出,dbgview
2011-5-6 22:14
0
游客
登录 | 注册 方可回帖
返回
//