注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

回首望星辰

See you in the next world

 
 
 

日志

 
 

PPC上通过C#获取Sim卡串号(ICCID)  

2009-10-26 09:53:02|  分类: 手机开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
Sim卡的IMSI号码(每个卡唯一)和机器的IMEI号码(每个手机机器唯一)和Sim卡的ICCID(手机的串号,卡背面的20位数字,每个卡唯一)。
ICCID的获取
首先需要用到以下几个API:
[DllImport("cellcore.dll")]//初始化Sim卡列表,并返回一个可以操作的句柄lphSim
private static extern IntPtr SimInitialize(IntPtr dwFlags, IntPtr lpfnCallBack, IntPtr dwParam, out IntPtr lphSim);
开门用的,而且把门把手(lphSim)交给你掌握。

[DllImport("cellcore.dll")]//关闭Sim卡列表
private static extern IntPtr SimDeinitialize(IntPtr hSim);
出门后一定要记得不要留任何把柄在门把手上。

[DllImport("cellcore.dll")]//读取指定的记录
private static extern IntPtr SimReadRecord(IntPtr hSim, IntPtr dwAddress, IntPtr dwRecordType, IntPtr dwIndex, byte[] lpData, IntPtr dwBufferSize, ref IntPtr lpdwBytesRead);
进门后翻东西了呗。hSim,门把手记得不要留在外面,否则让人锁在屋里;dwAddress,要在哪拿东西;dwRecordType,拿什么东西;dwIndex,从哪开始拿;lpData,自己的兜;dwBufferSize,兜的大小;lpdwBytesRead,实际上拿了多少东西。

[DllImport("cellcore.dll")]//获取Sim卡指定记录的信息(数据结构)
private static extern IntPtr SimGetRecordInfo(IntPtr hSim, IntPtr dwAddress, ref SimRecord lpSimRecordInfo);
计划一下应该拿什么东西,用此门砖。hSim,门把手,不要丢;dwAddress,东西放在哪;lpSimRecordInfo,门砖是要回收地(沾满钻石的羊肉啊)。

//定义常量
const int EF_ICCID = 0x2FE2;//ICCID号码在Sim卡的存储地址
const int SIM_RECORDTYPE_TRANSPARENT = 0x00000001; //只获取单个记录

[StructLayout(LayoutKind.Sequential)]//Sim卡记录的数据结构
private struct SimRecord
{
    public IntPtr cbSize;
    public IntPtr dwParams;
    public IntPtr dwRecordType;
    public IntPtr dwItemCount;
    public IntPtr dwSize;
}

获取信息的过程如下:

//获取Sim卡的ICCID
IntPtr res, hSim;
//初始化Sim卡列表
res = SimInitialize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out hSim);
if (res != IntPtr.Zero)
    throw new Exception("Can not Initialize Sim.");

SimRecord rec = new SimRecord();
rec.cbSize = (IntPtr)Marshal.SizeOf(rec);
res = SimGetRecordInfo(hSim, (IntPtr)EF_ICCID, ref rec);//获取ICCID的数据结构信息
if (res != IntPtr.Zero)
    throw new Exception("Could not read the ICCID information from the SIM.");

byte[] bData = new byte[(int)rec.dwSize + 1];//这里多加了一个字节来扩充一下缓冲区
IntPtr dwBytesRead = IntPtr.Zero;
res = SimReadRecord(hSim, (IntPtr)EF_ICCID, rec.dwRecordType, IntPtr.Zero, bData, (IntPtr)bData.Length, ref dwBytesRead);
if (res != IntPtr.Zero)
    throw new Exception("Could not read the ICCID from the SIM");
SimDeinitialize(hSim);

string str="";
for (int i = 0; i < bData.Length - 1; i++)//这里当然要把前面多加的那个字节给去掉啦,否则会多些数据
{
    str = str + ReversByte(bData[i]);
}
Info.SimIccid = str;
Info.SimIccid = Info.SimIccid.Replace("\0", "");

ReversByte这个函数是个自己写的函数,具体的功能就是把一个byte的高4位和低4位的值颠倒过来(也就是把byte转成hex字符串之后吧第一位和第二位互换位置即可)。
从SimReadRecord读取到的数据是10个byte,转成hex之后大致会如下:98680055518014043250,把每个byte的高低位互转之后再组合起来就成了89860055150841003452,这个也就是Sim卡的ICCID了,每个卡背面的那唯一的20位数字。

为了防止人为的修改ICCID来达到混淆的目的,可以再获取IMSI号码(这个是移动侧数据库中的,人为一般不可能修改)和ICCID绑定并保存到服务器中来达到唯一识别客户的目的,如果还觉得不够,可以再获取客户的那个13×××××××××的号码或者15×××××××××的号码(不过我觉得这个没什么必要,之前那2个已经足够了)。

啊?手机号码的获取方式啊?随便发个短信就OK了,服务器拆包短信就可以知道了。具体解决方案看SMPP协议或者CMPP协议,里面讲的很明白了。

理论上如果知道Sim卡内各个参数的存储地址(dwAddress),就可以读、写Sim卡里面的所有可读写的信息,包括不用网上那个Tapi.dll。
  评论这张
 
阅读(4514)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017