日期:2014-05-16 浏览次数:20697 次
//GetIP.h
// GetIP.h
// 解析纯真IP数据库文件
//
#pragma once
#ifndef _QQWRY_DAT_IP_
#define _QQWRY_DAT_IP_
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
extern DWORD LeftMov[4];
#pragma pack(push,1)
// 查找IP块结构
typedef struct _IP_FIND
{
DWORD SessionStartAddr; // 开始的IP地址
DWORD offset:24; // 指向IP_RECORD,结束IP
}IP_FIND, *PIP_FIND;
// QQwry.dat文件头
typedef struct _IP_HEADER
{
PIP_FIND StartIp; // 开始IP地址
PIP_FIND EndIp; // 最后一个IP地址
}IP_HEADER,* PIP_HEADER;
// IP地址
typedef struct _IP_ADDR
{
char flags[1]; // 0x01 表明指向IP_ADDR, 0x02 ,其他表示后面是地名
DWORD offset:24; // 指向下一个IP_ADDR结构,相对文件头偏移
}IP_ADDR,* PIP_ADDR;
// IP记录
typedef struct _IP_RECORD
{
DWORD SessionEndAddr; // 本段结束IP值
IP_ADDR addr;
}IP_RECORD, *PIP_RECORD;
// 保存IP信息
typedef struct _IP_SAVE
{
DWORD FindIP; // 要查找的IP
DWORD StartIP; // 起始IP
DWORD EndIP; // 终止IP
PSTR Country; // 国名
PSTR City; // 城市名
}IP_SAVE, *PIP_SAVE;
#pragma pack(pop)
class CDWYIP
{
public:
CDWYIP(LPVOID point); // point qqwry.dat 文件内存首地址
VOID FindIP(DWORD); // 查找IP (DWORD型) 值对应的地理位置
VOID FindIP(PTSTR); // 查找IP对应地理
VOID FindADDr(PSTR); // 查找地面对应IP
VOID show(BOOL showip = TRUE); // 显示数据
const IP_SAVE * GetSaveInfo(); //得到IP_SAVE结构指针
// 各种Get函数添加处
// ...
~CDWYIP();
protected:
DWORD ShortFindIP(PIP_FIND, PIP_FIND, DWORD ); // 二分查找
DWORD szIP2ulIP(PTSTR szIP); // 点分十进制的字符串IP变成DWORD值
PTSTR ulIP2szIP(DWORD ulIP); // DWORD值变成点分十进制IP
VOID GetAddress(PIP_ADDR addr ,int mode); // 根据mode得到数据
VOID GetAddress(PIP_RECORD addr);
private:
TCHAR szbuf[20]; // 用户存储IP地址,不可重入
PIP_HEADER iphead; // 目的:保存qqwry.dat首地址
IP_SAVE ip; // IP对应信息记录块
};
#endif //_QQWRY_DAT_IP_
// Getip.cpp
// GetIP.cpp
// 解析纯真IP数据库文件
//
#include "GetIP.h"
DWORD LeftMov[4] = {24, 16, 8, 0};
CDWYIP::CDWYIP(LPVOID point)
{
iphead = (PIP_HEADER)point;
ZeroMemory((LPVOID)&ip, sizeof(ip));
}
// mode 1 得到国家、城市名, 2 得到国家名
// 3 得到地区名
VOID CDWYIP::GetAddress(PIP_ADDR addr ,int mode)
{
switch(addr->flags[0])
{
case 0x1:
GetAddress((PIP_ADDR)(addr->offset + (DWORD)iphead) , mode);
break;
case 0x2:
if (mode == 1)
{
GetAddress( (PIP_ADDR) (addr->offset + (DWORD)iphead) , 2);
GetAddress( (PIP_ADDR) ((DWORD)addr + 4) , 3);
}
else
{
GetAddress((PIP_ADDR) (addr->offset + (DWORD)iphead) , mode);
}
break;
// 找到字符串
default:
if (mode == 1)
{
ip.Country = addr->flags;
GetAddress((PIP_ADDR)( addr->flags + strlen(addr->flags) + 1 ), 3);
}
else if(mode == 2)
{
ip.Country = addr->flags;
}
else
{
ip.City = addr->flags;
}
}
}
VOID CDWYIP::GetAddress(PIP_RECORD Record)
{
ip.EndIP = Record->SessionEndAddr;
switch(Record->addr.flags[0])
{
case 0x1:
GetAddress((PIP_ADDR)(Record->addr.offset + (DWORD)iphead) , 1) ;
break;
case 0x2:
GetAddress( (PIP_ADDR) (Record->addr.offset + (DWORD)iphead), 2);
GetAddress( (PIP_ADDR)&Record->addr.flags[4], 3);
break;
default:
ip.Country = Record->addr.flags;
GetAddress((PIP_ADDR) (Record->addr.flags + strlen(Record->addr.flags) + 1), 3);
}
}
// 根据DWORD型IP值得到地址
VOID CDWYIP::FindIP(DWORD Address)
{
DWORD offset = 0;
ip.FindIP = Address;
PIP_FIND Front = (PIP_FIND)( (DWORD)iphead->StartIp + (DWORD)iphead );
do
{
if (Address >= 0xFFFFFF00)
{
Front = (PIP_FIND)( (DWORD)iphead->EndIp + (DWORD)iphead );
ip.StartIP = Front->SessionStartAddr;
offset = Front->offset;
break;
}
ip.StartIP = Front->SessionStartAddr;
offset = Front->offset;
Front = (PIP_FIND)((DWORD)Front + 7); // 7 = sizeof(IP_FIND)
}while(Front->SessionStartAddr <= Address);
GetAddress((PIP_RECORD)(offset + (DWORD)iphead ));
}
// 将字符串IP转为DWORD,继而调用 VOID CDWYIP::FindIP(DWORD Address)