• 通过ODBC操作PostgreSQL

    • 我刚开始时, OLE DB Provider 连接PostgreSQL数据库, 连接成功了, 查询操作也是正常的.

      但是, 我用ADOQuery 添加数据时,出现"在行集中没有定义列",但是数据添加成功了.  郁闷中.

      后来通过ODBC DSN方式, 完全正常.. 不过PostgreSQL与MSSQL 有一些差别.

      如: delete table where id='1111'   (MSSQL 可以执行, 但是PGSQL就不行)

      更新记录时, update table set 名称='1221'  where id='1111'  (MSSQL可以执行,PGSQL要出错.)

      必须修改为: update table set  "名称"='1221'  where id='1111'  ,   哈哈...

      最后附上截图和PGSQL windows ODBC驱动安装包.


      odbcmanage.jpg

      odbc1.jpg

      odbc2.jpg

      odbc3.jpg

      psqlodbc.part1.rar

      psqlodbc.part2.rar

      psqlodbc.part3.rar

      psqlodbc.part4.rar

      psqlodbc.part5.rar

    • Delphi anti-loader

    • procedure   TForm1.FormCreate(Sender:   TObject);    
        var    
            isDebuggerPresent:   function:Boolean;    
            DllModule:   THandle;    
        begin    
            DllModule   :=   LoadLibrary('kernel32.dll');    
            isDebuggerPresent   :=   GetProcAddress(DllModule,   'IsDebuggerPresent');    
            if   isDebuggerPresent   then    
            begin    
                MessageBox(self.Handle,   '请不要调试我!',   '抗议',MB_OK   or   MB_ICONASTERISK);    
                Application.Terminate;    
            end;    
        end;    
         
        //anti-loader

    • 检测DEDE反编译器

    • Procedure   Anti_DeDe();//检测DEDE反编译器,只对2.5版本以后的起作用.  
        var  
            DeDeHandle:THandle;  
            i:integer;  
        begin  
            DeDeHandle:=FindWindow(nil,chr($64)+chr($65)+chr($64)+chr($65));  
            if   DeDeHandle<>0   then  
                begin  
                    For   i:=1   to   4500   do  
                        SendMessage(DeDeHandle,WM_CLOSE,0,0);  
                end;  
        end;  

    • Anti-Monitor Delphi反调试

    • //Anti-Monitor  
        Function   ABC39:   Boolean;   //检测Dump;  
        var  
            hFile:   Thandle;  
        Begin  
            Result:=   false;  
            hFile   :=   FindWindow(nil,'ProcDump32   (C)   1998,   1999,   2000   G-RoM,   Lorian   &   Stone');  
            if(   hFile   <>   0   )   then  
            begin  
                Result:=   TRUE;  
            end;  
        End;  
         
        Function   ABC40:   Boolean;   //检测RegMON;  
        var  
            hFile:   Thandle;  
        Begin  
            Result:=   false;  
            hFile   :=   FindWindow(nil,'Registry   Monitor   -   Sysinternals:   www.sysinternals.com');  
            if(   hFile   <>   0   )   then  
            begin  
                Result:=   TRUE;  
            end;  
        End;  
         
        Function   ABC41:   Boolean;stdcall;     //检测FileMON;  
        var  
            hFile:   Thandle;  
        Begin  
            Result:=   false;  
            hFile   :=   FindWindow(nil,'File   Monitor   -   Sysinternals:   www.sysinternals.com');  
            if(   hFile   <>   0   )   then  
            begin  
                Result:=   TRUE;  
            end;  
        End;  
         
        ////////////////////////////////////////////////////////////////////////////////  
        //Anti-loader  
        Function   ABC42():Boolean;   //检测调试器;  
        var  
            YInt,NInt:Integer;  
        begin  
            asm  
                mov   eax,fs:[30h]  
                movzx   eax,byte   ptr[eax+2h]  
                or   al,al  
                jz   @No  
                jnz   @Yes  
                @No:  
                    mov   NInt,1  
                @Yes:  
                    Mov   YInt,1  
            end;  
            if   YInt=1   then  
                Result:=True;  
            if   NInt=1   then  
                Result:=False;  
        end;  
         
        98下:  
        Function   IsSoftIce95Loaded:   boolean;         //声明一个检测SoftICE的boolean型变量    
        Var   hFile:   Thandle;    
        Begin    
            result   :=   false;    
            hFile   :=   CreateFileA('\\.\SICE',   GENERIC_READ   or   GENERIC_WRITE,    
                FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,    
                FILE_ATTRIBUTE_NORMAL,   0);    
            if(   hFile   <>   INVALID_HANDLE_VALUE   )   then   begin    
                CloseHandle(hFile);    
                result   :=   TRUE;    
            end;    
        End;    
         
        Function   IsSoftIceNTLoaded:   boolean;     //声明一个检测SoftIceNT的boolean型变量    
        Var   hFile:   Thandle;    
        Begin    
            result   :=   false;    
            hFile   :=   CreateFileA('\\.\NTICE',   GENERIC_READ   or   GENERIC_WRITE,    
                FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,    
                FILE_ATTRIBUTE_NORMAL,   0);    
            if(   hFile   <>   INVALID_HANDLE_VALUE   )   then   begin    
                CloseHandle(hFile);    
                result   :=   TRUE;    
            end;    
        End;    
         
        Function   IsTRWLoaded:   boolean;     //声明一个检测TRW的boolean型变量  
        Var   hFile:   Thandle;    
        Begin  
            result   :=   false;    
            hFile   :=   CreateFileA('\\.\TRWDEBUG',   GENERIC_READ   or   GENERIC_WRITE,    
                FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,    
                FILE_ATTRIBUTE_NORMAL,   0);    
            if(   hFile   <>   INVALID_HANDLE_VALUE   )   then   begin    
                CloseHandle(hFile);    
                result   :=   TRUE;    
            end;    
        End;  
         
        Function   IsTRW2000Loaded:   boolean;     //声明一个检测TRW2000的boolean型变量  
        Var   hFile:   Thandle;    
        Begin    
            result   :=   false;    
            hFile   :=   CreateFileA('\\.\TRW2000',   GENERIC_READ   or   GENERIC_WRITE,    
                FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,    
                FILE_ATTRIBUTE_NORMAL,   0);    
            if(   hFile   <>   INVALID_HANDLE_VALUE   )   then   begin    
                CloseHandle(hFile);    
                result   :=   TRUE;  
            end;    
        End;    
         
        Function   IsRegMONLoaded:   boolean;     //声明一个检测RegMON的boolean型变量   For   Windows98;  
        Var   hFile:   Thandle;    
        Begin    
            result   :=   false;    
            hFile   :=   CreateFileA('\\.\REGVXD',   GENERIC_READ   or   GENERIC_WRITE,    
                FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,    
                FILE_ATTRIBUTE_NORMAL,   0);    
            if(   hFile   <>   INVALID_HANDLE_VALUE   )   then   begin    
                CloseHandle(hFile);    
                result   :=   TRUE;    
            end;    
        End;    
         
        Function   IsNTRegMONLoaded:   boolean;     //声明一个检测RegMON的boolean型变量   For   Windows2000/xp;    
        Var   hFile:   Thandle;  
        Begin  
            result   :=   false;  
            hFile   :=   FindWindow(nil,'Registry   Monitor   -   Sysinternals:   www.sysinternals.com');  
            if(   hFile   <>   0   )   then  
            begin  
                result   :=   TRUE;  
            end;  
        End;  
         
        Function   IsFileMONLoaded:   boolean;         //声明一个检测FileMON的boolean型变量   For   Windows98;  
        Var   hFile:   Thandle;    
        Begin    
            result   :=   false;    
            hFile   :=   CreateFileA('\\.\FILEVXD',   GENERIC_READ   or   GENERIC_WRITE,    
                FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,    
                FILE_ATTRIBUTE_NORMAL,   0);    
            if(   hFile   <>   INVALID_HANDLE_VALUE   )   then   begin    
                CloseHandle(hFile);    
                result   :=   TRUE;    
            end;    
        End;    
         
        Function   IsBW2000Loaded:   boolean;     //声明一个检测冲击波2000的boolean型变量   加壳时说不定用的上  
        Var   hFile:   Thandle;  
        Begin  
            result   :=   false;  
            hFile   :=   CreateFileA('\\.\bw2k',   GENERIC_READ   or   GENERIC_WRITE,  
                FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,  
                FILE_ATTRIBUTE_NORMAL,   0);  
            if(   hFile   <>   INVALID_HANDLE_VALUE   )   then   begin  
                CloseHandle(hFile);  
                result   :=   TRUE;  
            end;  
        End;  
         
         
        上面的调用就是根据返回值True或者False来检测的.

    • 检测Win2000/XP下的SoftIce

    • Function   ABC38:Boolean;//检测Win2000/XP下的SoftIce  
        var  
            mark:Integer;  
            YesInt,NoInt:Integer;  
        begin  
            YesInt:=0;NoInt:=0;  
            mark:=0;  
            asm  
                push   offset   @handler  
                push   dword   ptr   fs:[0]  
                mov     dword   ptr   fs:[0],esp  
                xor     eax,eax  
                int   1  
                inc     eax  
                inc     eax  
                pop     dword   ptr   fs:[0]  
                add   esp,4  
                or       eax,eax  
                jz       @found  
                cmp   mark,   0  
                jnz       @found  
                jmp     @Nofound  
                @handler:  
                    mov   ebx,[esp+0ch]  
                    add   dword   ptr   [ebx+0b8h],02h  
                    mov   ebx,[esp+4]  
                    cmp   [ebx],   80000004h  
                    jz   @Table  
                    inc   mark  
                @Table:  
                    xor   eax,eax  
                  ret  
                @found:  
                    mov   YesInt,1  
                @Nofound:  
                    mov   NoInt,1  
            end;  
            if   Yesint=1   then  
                Result:=True;  
            if   NoInt=1   then  
                Result:=False;  
        end;   
         

    • 校验注册码时的技巧

    • 在进行注册码比较的时候要注意(En代表加密函数)  
        if   En(系列号)=En(注册码)   then  
            ShowMessage('注册成功!')  
        else  
            ShowMessage('注册失败');  
        如果是这样进行判断的话,那么注册码在内存当中就可以直接看到了。避免这样的情况发生.你可以对比较的值进行移位操作这样在内存中出现的值就不是真正的注册码.  
        if   ShlStr(En(系列号))=ShlStr(En(注册码))   then  
            ShowMessage('注册成功!')  
        else  
            ShowMessage('注册失败');  
        还有就是注册成功和注册失败的时候不要作任何的提示,只是可用和不可用功能.  
         
        移位的函数我给出一个,其实你自己可以写自己的移位函数,我只是给出一个参考的:   

        Function   ShlStr(Str:PChar):PChar;   //进行明码变换;  
        var  
            a:LongWord;  
            Int1,Int2:Integer;  
            j,j1:Integer;  
            sum:LongWord;  
            Str1:String;  
        begin  
                Str1:=StrPas(ABC44Str);  
                Int2:=Length(Str1);  
                for   j1:=1   to   Int2   do  
                    begin  
                        a:=ord(Str1[j1])   shl   7;  
                        sum:=sum+a;  
                    end;  
                Result:=PChar(IntToStr(sum));  
        end;  

    • 取MAC地址(集成网卡和非集成网卡)

    • 取MAC地址(集成网卡和非集成网卡):  
        uses  
            nb30;  
         
        type  
        PASTAT   =   ^TASTAT;  
            TASTAT   =   record  
                adapter   :   TAdapterStatus;  
                name_buf   :   TNameBuffer;  
            end;  
        function   Getmac:string;  
        var  
            ncb   :   TNCB;  
            s:string;  
            adapt   :   TASTAT;  
            lanaEnum   :   TLanaEnum;  
            i,   j,   m   :   integer;  
            strPart,   strMac   :   string;  
        begin  
        FillChar(ncb,   SizeOf(TNCB),   0);  
            ncb.ncb_command   :=   Char(NCBEnum);  
            ncb.ncb_buffer   :=   PChar(@lanaEnum);  
            ncb.ncb_length   :=   SizeOf(TLanaEnum);  
            s:=Netbios(@ncb);  
            for   i   :=   0   to   integer(lanaEnum.length)-1   do  
            begin  
                FillChar(ncb,   SizeOf(TNCB),   0);  
                ncb.ncb_command   :=   Char(NCBReset);  
                ncb.ncb_lana_num   :=   lanaEnum.lana[i];  
                Netbios(@ncb);  
                Netbios(@ncb);  
                FillChar(ncb,   SizeOf(TNCB),   0);  
                ncb.ncb_command   :=   Chr(NCBAstat);  
                ncb.ncb_lana_num   :=   lanaEnum.lana[i];  
                ncb.ncb_callname   :=   '*                               ';  
                ncb.ncb_buffer   :=   PChar(@adapt);  
                ncb.ncb_length   :=   SizeOf(TASTAT);  
                m:=0;  
                if   (Win32Platform   =   VER_PLATFORM_WIN32_NT)   then  
                m:=1;  
                if   m=1   then  
                begin  
                if   Netbios(@ncb)   =   Chr(0)   then  
                    strMac   :=   '';  
                    for   j   :=   0   to   5   do  
                    begin  
                        strPart   :=   IntToHex(integer(adapt.adapter.adapter_address[j]),   2);  
                        strMac   :=   strMac   +   strPart   +   '-';  
                    end;  
                    SetLength(strMac,   Length(strMac)-1);  
                end;  
            if   m=0   then  
                if   Netbios(@ncb)   <>   Chr(0)   then  
                begin  
                    strMac   :=   '';  
                    for   j   :=   0   to   5   do  
                    begin  
                        strPart   :=   IntToHex(integer(adapt.adapter.adapter_address[j]),   2);  
                        strMac   :=   strMac   +   strPart   +   '-';  
                    end;  
                    SetLength(strMac,   Length(strMac)-1);  
                end;  
            end;  
        result:=strmac;  
        end;  
         
        function   PartitionString(StrV,PrtSymbol:   string):   TStringList;  
        var  
            iTemp:   integer;  
        begin  
            result   :=   TStringList.Create;  
            iTemp   :=   pos(PrtSymbol,StrV);  
            while   iTemp>0   do   begin  
                if   iTemp>1   then   result.Append(copy(StrV,1,iTemp-1));  
                delete(StrV,1,iTemp+length(PrtSymbol)-1);  
                iTemp   :=   pos(PrtSymbol,StrV);  
            end;  
            if   Strv<>''   then   result.Append(StrV);  
        end;  
         
        function   MacStr():String;  
        var  
            Str:TStrings;  
            i:Integer;  
            MacStr:String;  
        begin  
            MacStr:='';  
            Str:=TStringList.Create;  
            Str:=PartitionString(Getmac,'-');  
            for   i:=0   to   Str.Count-1   do  
                MacStr:=MacStr+Str[i];  
            Result:=MacStr;  
        end;  
         
        调用:  
        Edit1.text:=MacStr;

    • 取MAC(非集成网卡):

    • 取MAC(非集成网卡):  
        usese  
            nb30;  
         
        function   NBGetAdapterAddress(a:   Integer):   string;  
        var  
            NCB:   TNCB;   //   Netbios   control   block   //NetBios控制块  
            ADAPTER:   TADAPTERSTATUS;   //   Netbios   adapter   status//取网卡状态  
            LANAENUM:   TLANAENUM;   //   Netbios   lana  
            intIdx:   Integer;   //   Temporary   work   value//临时变量  
            cRC:   Char;   //   Netbios   return   code//NetBios返回值  
            strTemp:   string;   //   Temporary   string//临时变量  
        begin  
            //   Initialize  
            Result   :=   '';  
            try  
                //   Zero   control   blocl  
                ZeroMemory(@NCB,   SizeOf(NCB));  
                //   Issue   enum   command  
                NCB.ncb_command   :=   Chr(NCBENUM);  
                cRC   :=   NetBios(@NCB);  
                //   Reissue   enum   command  
                NCB.ncb_buffer   :=   @LANAENUM;  
                NCB.ncb_length   :=   SizeOf(LANAENUM);  
                cRC   :=   NetBios(@NCB);  
                if   Ord(cRC)   <>   0   then  
                    exit;  
                //   Reset   adapter  
                ZeroMemory(@NCB,   SizeOf(NCB));  
                NCB.ncb_command   :=   Chr(NCBRESET);  
                NCB.ncb_lana_num   :=   LANAENUM.lana[a];  
                cRC   :=   NetBios(@NCB);  
                if   Ord(cRC)   <>   0   then  
                    exit;  
                //   Get   adapter   address  
                ZeroMemory(@NCB,   SizeOf(NCB));  
                NCB.ncb_command   :=   Chr(NCBASTAT);  
                NCB.ncb_lana_num   :=   LANAENUM.lana[a];  
                StrPCopy(NCB.ncb_callname,   '*');  
                NCB.ncb_buffer   :=   @ADAPTER;  
                NCB.ncb_length   :=   SizeOf(ADAPTER);  
                cRC   :=   NetBios(@NCB);  
                //   Convert   it   to   string  
                strTemp   :=   '';  
                for   intIdx   :=   0   to   5   do  
                    strTemp   :=   strTemp   +   InttoHex(Integer(ADAPTER.adapter_address[intIdx]),   2);  
                Result   :=   strTemp;  
            finally  
            end;  
        end;  

       调用:  
        edit1.Text:=NBGetAdapterAddress(12);  

    • 取CPU系列号

    •  CPU系列号:  
        FUNCTION   GetCPUID   :   TCPUID;   assembler;   register;  
        asm  
            PUSH         EBX                   {Save   affected   register}  
            PUSH         EDI  
            MOV           EDI,EAX           {@Resukt}  
            MOV           EAX,1  
            DW             $A20F               {CPUID   Command}  
            STOSD             {CPUID[1]}  
            MOV           EAX,EBX  
            STOSD                               {CPUID[2]}  
            MOV           EAX,ECX  
            STOSD                               {CPUID[3]}  
            MOV           EAX,EDX  
            STOSD                               {CPUID[4]}  
            POP           EDI             {Restore   registers}  
            POP           EBX  
        END;  
         
        function   GetCPUIDStr:String;  
        var  
            CPUID:TCPUID;  
        begin  
            CPUID:=GetCPUID;  
            Result:=IntToHex(CPUID[1],8)+IntToHex(CPUID[2],8)+IntToHex(CPUID[3],8)+IntToHex(CPUID[4],8);  
        end  
         
        调用:  
        Edit1.text:=GetCPUIDStr;  

    • 取硬盘系列号

    • 取硬盘系列号:  
        function   GetIdeSerialNumber:   pchar;     //获取硬盘的出厂系列号;  
            const   IDENTIFY_BUFFER_SIZE   =   512;  
        type  
              TIDERegs   =   packed   record  
                  bFeaturesReg:   BYTE;  
                  bSectorCountReg:   BYTE;  
                  bSectorNumberReg:   BYTE;  
                  bCylLowReg:   BYTE;  
                  bCylHighReg:   BYTE;  
                  bDriveHeadReg:   BYTE;  
                  bCommandReg:   BYTE;  
                  bReserved:   BYTE;  
            end;  
            TSendCmdInParams   =   packed   record  
                cBufferSize:   DWORD;  
                irDriveRegs:   TIDERegs;  
                bDriveNumber:   BYTE;  
                bReserved:   array[0..2]   of   Byte;  
                dwReserved:   array[0..3]   of   DWORD;  
                bBuffer:   array[0..0]   of   Byte;  
            end;  
            TIdSector   =   packed   record  
                wGenConfig:   Word;  
                wNumCyls:   Word;  
                wReserved:   Word;  
                wNumHeads:   Word;  
                wBytesPerTrack:   Word;  
                wBytesPerSector:   Word;  
                wSectorsPerTrack:   Word;  
                wVendorUnique:   array[0..2]   of   Word;  
                sSerialNumber:   array[0..19]   of   CHAR;  
                wBufferType:   Word;  
                wBufferSize:   Word;  
                wECCSize:   Word;  
                sFirmwareRev:   array[0..7]   of   Char;  
                sModelNumber:   array[0..39]   of   Char;  
                wMoreVendorUnique:   Word;  
                wDoubleWordIO:   Word;  
                wCapabilities:   Word;  
                wReserved1:   Word;  
                wPIOTiming:   Word;  
                wDMATiming:   Word;  
                wBS:   Word;  
                wNumCurrentCyls:   Word;  
                wNumCurrentHeads:   Word;  
                wNumCurrentSectorsPerTrack:   Word;  
                ulCurrentSectorCapacity:   DWORD;  
                wMultSectorStuff:   Word;  
                ulTotalAddressableSectors:   DWORD;  
                wSingleWordDMA:   Word;  
                wMultiWordDMA:   Word;  
                bReserved:   array[0..127]   of   BYTE;  
            end;  
            PIdSector   =   ^TIdSector;  
            TDriverStatus   =   packed   record  
                bDriverError:   Byte;  
                bIDEStatus:   Byte;  
                bReserved:   array[0..1]   of   Byte;  
                dwReserved:   array[0..1]   of   DWORD;  
            end;  
            TSendCmdOutParams   =   packed   record  
                cBufferSize:   DWORD;  
                DriverStatus:   TDriverStatus;  
                bBuffer:   array[0..0]   of   BYTE;  
            end;  
        var  
            hDevice:   Thandle;  
            cbBytesReturned:   DWORD;  
            SCIP:   TSendCmdInParams;  
            aIdOutCmd:   array[0..(SizeOf(TSendCmdOutParams)   +   IDENTIFY_BUFFER_SIZE-1)-1]   of   Byte;  
            IdOutCmd:   TSendCmdOutParams   absolute   aIdOutCmd;  
        procedure   ChangeByteOrder(var   Data;   Size:   Integer);  
        var  
            ptr:   Pchar;  
            i:   Integer;  
            c:   Char;  
        begin  
            ptr   :=   @Data;  
            for   I   :=   0   to   (Size   shr   1)   -   1   do   begin  
                c   :=   ptr^;  
                ptr^   :=   (ptr   +   1)^;  
                (ptr   +   1)^   :=   c;  
                Inc(ptr,   2);  
            end;  
        end;  
        begin  
        Result   :=   '';  
        if   SysUtils.Win32Platform   =   VER_PLATFORM_WIN32_NT   then   begin   //   Windows   NT,   Windows   2000  
        hDevice   :=   CreateFile('\\.\PhysicalDrive0',   GENERIC_READ   or   GENERIC_WRITE,  
        FILE_SHARE_READ   or   FILE_SHARE_WRITE,   nil,   OPEN_EXISTING,   0,   0);  
        end   else   //   Version   Windows   95   OSR2,   Windows   98  
        hDevice   :=   CreateFile('\\.\SMARTVSD',   0,   0,   nil,   CREATE_NEW,   0,   0);  
        if   hDevice   =   INVALID_HANDLE_VALUE   then   Exit;  
        try  
        FillChar(SCIP,   SizeOf(TSendCmdInParams)   -   1,   #0);  
        FillChar(aIdOutCmd,   SizeOf(aIdOutCmd),   #0);  
        cbBytesReturned   :=   0;  
        with   SCIP   do   begin  
        cBufferSize   :=   IDENTIFY_BUFFER_SIZE;  
        with   irDriveRegs   do   begin  
        bSectorCountReg   :=   1;  
        bSectorNumberReg   :=   1;  
        bDriveHeadReg   :=   $A0;  
        bCommandReg   :=   $EC;  
        end;  
        end;  
        if   not   DeviceIoControl(hDevice,   $0007C088,   @SCIP,   SizeOf(TSendCmdInParams)   -   1,  
        @aIdOutCmd,   SizeOf(aIdOutCmd),   cbBytesReturned,   nil)   then   Exit;  
        finally  
        CloseHandle(hDevice);  
        end;  
        with   PIdSector(@IdOutCmd.bBuffer)^   do   begin  
        ChangeByteOrder(sSerialNumber,   SizeOf(sSerialNumber));  
        (Pchar(@sSerialNumber)   +   SizeOf(sSerialNumber))^:=   #0;  
        Result   :=   Pchar(@sSerialNumber);  
        end;  
        end;  
         
        调用:  
        Edit1.Text:=strpas(GetIdeSerialNumber)  

Powered by Typecho)))   ICP:蜀ICP备05009250号