其中函数AllocSelector(Selector) 是保护模式下物理内存访问的关键,Selector是分配空选择器的段寄存器模板,可以利用GlobalAlloc()函数分配内存,再利用GlobalHandleToSel()函数将内存句柄转换为相应选择器,内存单元访问结束后再利用GlobalFree()释放分配的内存。最简单的方法就是将系统的数据段寄存器__DS直接作为模板参数,这个参数在一般应用程序中完全可以正常使用。然后利用SetSelectorBase()和SetSelectorLimit( )函数分别设置内存的物理起始地址和访问界限值,利用正常的指针操作*pt=Value和Value=*pt访问物理内存单元,访问结束后必须使用FreeSelector()函数释放分配的选择器,因为WINDOWS 并不自动释放无用的选择器,而且系统的选择器共享资源是非常有限,只有8192个供使用。根据以上原理及注册机中的注册源和注册码算法,就不难实现共享软件内部注册码函数: 代码:
| UINT ImeCmpkey(void) { //共享软件内部注册码产生函数 static unsigned int sum; static BOOL flag; static unsigned int far *pt; static UINT Sel1,Sel2; static WORD Seg,Off,Start; static DWORD Bas,Lim; flag=TRUE; sum=0x1234; __asm mov Sel1,ds;//将DS作为模板 Sel2=AllocSelector(Sel1);//分配一个新选择符 if(Sel2==NULL){ flag=FALSE; pt=(unsigned int far*)0xf000fff0L; } else { Seg=0xffff; //绝对地址段址 Off=0x10; //绝对地址偏移 Start=0x0; Bas=((unsigned long)Seg)<<4|Start; Lim=(unsigned long)Off-1; SetSelectorBase(Sel2,Bas); SetSelectorLimit(Sel2,Lim); pt=(unsigned int far*)((((unsigned long)Sel2)<<16)|Start); } for(j=0;j<4;j++){//形成16位注册码 for(i=0;i<5;i++) sum+=(*(pt+3+i)+0x1818)^0x5858;//形成前4位 sum^=0x1234<<j;//进行移位异或处理 wsprintf((LPSTR)sImeG.ImeKey+4*j,(LPSTR)"%04x",sum); } if(flag==TRUE) FreeSelector(Sel2); sImeG.ImeKey[16]=0;//对注册码本身加密 for(i=16;i>0;i--) sImeG.ImeKey[16-i]^=(unsigned char)i; for(i=0;i<16;i++){ //判断注册码 if(sImeG.ImeKey[i]!=lpImeL->ZcMyOk[i]) break; } if(i==16){ sImeG.ZcFlag=FALSE; sImeG.ZcCount=0x0; lpImeL->UseNum=0x0; for(i=0;i<16;i++) sImeG.ImeKey[i]=0x0; return(0); } else { sImeG.ZcFlag=TRUE; sImeG.ZcCount=0x0; sImeG.iSel = 1; sImeG.FScrCz = TRUE; lstrcpy(sImeG.szSel[0],(LPSTR)"注册:_________________"); sImeG.szSel[0][6]=0x11; sImeG.szSel[0][23]=0x0; UpdateInList(); return(~0); } } |
|