程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 我的第一個偏移量補丁程序

我的第一個偏移量補丁程序

編輯:Delphi

我的第一個偏移量補丁程序 

  前些天分析了啟明公司的口語光盤,同時也用Delphi編寫了個補丁程序。以往的補丁程序原理是利用了資源釋放形式進行,因此,最終生成的補丁程序會奇大無比(=自身體積加上目標破解文件的體積),就拿啟明光盤的破解補丁說吧,生成出來並壓縮後仍然有800K左右。但考慮到補丁原理只是修改了一個偏移量的值,如此大動干戈地把破解後的文件制作成資源文件來進行覆蓋,實在是下策,有沒有更好的辦法呢。肯定有!!!於是就有了自己的偏移量補丁程序模塊啦。畢竟作為注冊機或補丁程序的話,體積越小自然越好,因此,考慮用純API編寫,這樣生成的程序可以很小很小,以下就是源代碼,生成的程序僅有54K,壓縮後只有40多K,太可愛啦!!但界面一樣。(如果不使用GUI界面而只使用關鍵破解代碼的話,生成出來的文件只有7K。呵呵。這才是真正意義上的補丁哦。

   //******************** 以下是需要修改的常量或變量    ****************

   (*主對話框界面*)

    szMainCaption = '海浪輕風偏移量補丁程序V1.0';
    szName = '啟明英語口語考試系統'; //目標破解文件名
    szBy = '[email protected]'; //軟件開發者
    szCracker = '海浪輕風'; //解密人
    szCrackeremail = 'mailto:[email protected]'; //解密人email
    szLink = 'http://hi.baidu.com/beyond0769'; //主頁地址
    szTime = '2008-03-18'; //破解時間
    szCopyright = '本程序只作研究學習用,禁止非法用途';
    szKeyGenName = '海浪輕風偏移量補丁程序';
    szScroll = '海浪輕風偏移量補丁程序' + #$0A + #$0A
        + '本模塊用純API函數編寫,界面構建'+ #$0A#$0A
        + '利用了資源文件形式,大大節省了'+ #$0A#$0A
        + '生成後的文件體積,壓縮後只有'+ #$0A#$0A
        + '41k左右。同時加入了uFMOD單元' + #$0A#$0A
        + '實現背景音樂循環播放。 ' + #$0A#$0A + #$0A

        + '特別鳴謝:' + #$0A + #$0A
        + 'you_know[FCG]'+ #$0A+ #$0A
        + '看雪學院的Delphi牛人們' + #$0A+ #$0A
        + '以及uFMOD的程序員'+ #$0A+ #$0A
        + '感謝一直在背後默默支持我的琴兒' + #$0A + #$0A
        + '補丁使用方法:'+ #$0A + #$0A
        + '把補丁復制到目標文件相同目錄下'+ #$0A + #$0A
        + '運行,點擊“應用補丁”即可。 '+ #$0A + #$0A
        + '本程序只作研究學習用' + #$0A#$0A
        + '禁止一切非法商業用途' + #$0A#$0A
        + '程序破解 by 海浪輕風(黃仁來)' + #$0A#$0A
        + '程序編程 by 海浪輕風(黃仁來) + #$0A#$0A
        + '[email protected]' + #$0A + #$0A
        + 'http://beyond-0769.blog.163.com/' + #$0A + #$0A
        + '2008-03-18';
var
    FileName: PChar = 'SpokenEngMain.exe'; //破解目標文件完整名稱
    IntFileSize: Cardinal = 2731008; //破解目標文件的大小字節
     RBuffer: array[0..1] of Byte = ($75, $0C);   //目標破解文件原有的偏移量
     WBuffer: array[0..1] of Byte = ($EB, $0C);   //修改後的偏移量
     OffsetPos: TOVERLAPPED = (Internal: 0; InternalHigh: 0; Offset: $000EE089; OffsetHigh: 0; hEvent: 0);
    CommandLine: PChar; //                                           ↑↑以上是物理地址,通過W32DSM可以查到
    hwndname: HWND;
    hFile: THANDLE;
    Numb: DWord;
    Buffer: array[0..1] of Byte;
    nType: DWord;
    pMsg: string;

  ////////////////////

   //全局變量數據聲明 ******************** 以下常量或變量基本上無需要修改 ******************8

   ////////////////////

    h_Icon: HICON; //實例句柄
    h_Inst: HMODULE;
    h_Cur: hCursor;
    h_Brush: HBRUSH;
    sRectL, sRectM, sRectA: TRect;
    //RegName,RegCode:Array[1..256] of Byte; //原版數據;下句是修改後的
    RegName, RegCode: string;
    h_ScrollParent, h_Scroll: HWND;
    ScrollWidth, ScrollHeight: Word;
    xCount: Integer;
    LineCount: Word;
const

   ////////////////

   //資源常量定義//

    ////////////////

    MAINICON = 100;
    LINKCURSOR = 112;

    IDD_LICENSEDLG = 1000;
    IDD_MAINDLG = 2000;
    IDD_ABOUTDLG = 3000;

    LICENSE_YES = 1001;
    LICENSE_NO = 1002;
    LICENSE_CLOSE = 1004;

    MAIN_CALC = 2001; //計算按鈕控件ID(本實例已經去掉)
    MAIN_EXIT = 2002; //退出按鈕控件ID
    MAIN_ABOUT = 2003; //關於按鈕控件ID
    MAIN_CLOSE = 2004; //關閉按鈕控件ID

    ABOUT_OK = 3001;
    ABOUT_CLOSE = 3002;

   //++++++++++++++++++ 關鍵的爆破過程 ++++++++++++++++++++

procedure PatchFile;
var
Res:boolean;
begin
    Setfileattributes(FileName, FILE_ATTRIBUTE_NORMAL + FILE_ATTRIBUTE_ARCHIVE); //設置文件的屬性為正常
    hFile := CreateFile(FileName, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or
        FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    try
        if hFile <> INVALID_HANDLE_VALUE then
        begin
            if GetFileSize(hFile,nil)<>IntFileSize then
            begin
                nType := MB_OK or MB_ICONINFORMATION;
                pMsg := '文件校驗出錯:'+#13+'文件大小不一致,目標文件(英語口語主程序:' + FileName + ')可能已經被修改,拒絕打補丁!';
                exit;
            end;
            ReadFile(hFile, Buffer, 2, Numb, @OffsetPos); //如果讀出的偏移數據是已經打上補丁的數據,則提示已經打上補丁。
            if Word(Buffer[0]) = Word(WBuffer[0]) then begin
                nType := MB_OK or MB_ICONINFORMATION;
                pMsg := '錯誤提示:'+#13+'目標程序(' + FileName + ')已經打過補丁了,還想怎樣? ^_^';
                Res:=True;
                exit;
            end;
            if Word(Buffer[0]) = Word(RBuffer[0]) then {// 讀取偏移是否正確;} begin
                CopyFile(FileName, PChar('備份' + FileName), False); //備份破解目標文件;
                if WriteFile(hFile, WBuffer, 2, Numb, @OffsetPos) then
                begin
                    nType := MB_OK or MB_ICONINFORMATION;
                    pMsg := '成功打上補丁! Enjoy it^_^' + #13 +#13+
                            'Cracked & Coded by 海浪輕風(黃仁來)'; ; //成功補丁;
                    Res:=True;
                end else
                begin // 寫入出錯。
                    nType := MB_OK or MB_ICONERROR;
                    pMsg := '錯誤提示:'+#13+':請檢查目標文件(' + FileName + ')是否已經被打開,請先將其關閉再嘗試。';
                end;
            end else {//偏移不正確則提示出錯;}
            begin
                nType := MB_OK or MB_ICONWARNING;
                pMsg := '錯誤提示:'+#13+'目標文件(' + FileName + ')偏移量不符,拒絕打補丁!'+#13+'更多問題請到個人主頁反映。';
                ShellExecute(0, nil, szLink, nil, nil, 0);
            end;
        end else {//文件被打開或文件找不到}
        begin
            nType := MB_OK or MB_ICONERROR;
            pMsg := '補丁出錯 :-( 可能原因如下:' + #13 +
                '  1.目標文件找不到:(英語口語主程序:' + FileName + '),請把本程序復制到同一個目錄下再運行。' + #13 +
                '  2.目標文件已經被打開,請先將其關閉再嘗試。';
        end;
    finally
        CloseHandle(hFile);
        MessageBox(0, PChar(pMsg), PChar('海浪輕風溫馨提示:'), nType);
        if Res then ShellExecute(0, nil, szLink, nil, nil, 0);
    end;
end;

 //+++++++++++++++++ 以下為構造程序主窗口所需的函數過程 ++++++++++++++

Function CountCRLF(Str:String):Word; 
Var 
   Count:Word; 
   i:Word; 
Begin 
   Count:=1; 
   For i:=1 to Length(Str) Do 
     Begin 
       If Str[i]=#$0A Then Inc(Count); 
     End; 
   CountCRLF:=Count; 
End; 
Procedure DialogInit(hDlg:HWND); 
Var 
   RECT:TRect; 
   X,Y:Word; 
   i:Word; 
   Rgn:HRGN; 
Begin 
   ShowWindow(hDlg,SW_HIDE); 
   GetWindowRect(hDlg,RECT); 
   X:=(RECT.Right-RECT.Left) DIV 2; 
   Y:=(RECT.Bottom-RECT.Top) DIV 2; 
   
   For i:=1 to RECT.Right DIV 2 do 
     Begin 
       Rgn:=CreateRectRgn(X-i,Y-i,X+i,Y+i); 
       SetWindowRgn(hDlg,Rgn,True); 
       ShowWindow(hDlg,SW_SHOW); 
       DeleteObject(Rgn); 
     End; 
End; 
Procedure ItemDraw(lpDIS:PDrawItemStruct); 
Var 
   Str:Array[1..11] of Byte; 
Begin 
   FillRect(lpDIS^.hDC,lpDIS^.rcItem,h_Brush); 
   SetTextColor(lpDIS^.hDC,$A0A0A0); 
   //SetTextColor(lpDIS^.hDC,$03FF09); //綠色 
   SetBkMode(lpDIS^.hDC,TRANSPARENT); 
   DrawEdge(lpDIS^.hDC,lpDIS^.rcItem,BDR_RAISEDOUTER,BF_RECT); 
   GetWindowText(lpDIS^.hwndItem,@Str,10); 
   DrawText(lpDIS^.hDC,@Str,-1,lpDIS^.rcItem,DT_SINGLELINE OR DT_VCENTER OR DT_CENTER); 
   
   If lpDIS^.itemState MOD 2=1 Then 
     Begin 
       SetTextColor(lpDIS^.hDC,$03FF09);   //按下 綠色 
       DrawText(lpDIS^.hDC,@Str,-1,lpDIS^.rcItem,DT_SINGLELINE OR DT_VCENTER OR DT_CENTER); 
       DrawEdge(lpDIS^.hDC,lpDIS^.rcItem,BDR_SUNKENOUTER,BF_RECT); 
     End; 
End; 
Procedure Paint(dc:HDC;Icon:hIcon;Caption:PChar;BeginRGB:DWORD;EndRGB:DWord;Rect:TRect); 
Var 
   LogBrush:TLogBrush; 
   LRect,rc:TRect; 
   LhBR:HBRUSH; 
   R,G,B,Ri,Gi,Bi,Rt,Gt,Bt:Word; 
   LFont:HFONT; 
   Width:Word; 
   i:Word; 
Begin 
   LRect:=Rect; 
   
   B:=EndRGB AND $FF; 
   G:=(EndRGB SHR 8) AND $FF; 
   R:=(EndRGB SHR 16) AND $FF; 
   Bi:=BeginRGB AND $FF; 
   Gi:=(BeginRGB SHR 8) AND $FF; 
   Ri:=(BeginRGB SHR 16) AND $FF; 
   Width:=(LRect.right-LRect.left) DIV 2; 
   rc.top:=0; 
   rc.bottom:=LRect.bottom-LRect.top; 
   LogBrush.lbStyle:=0; 
   LogBrush.lbHatch:=0; 
   If Width>=0 Then 
     Begin 
       For i:=0 To (Width AND $FF) Do 
         Begin 
             rc.left:=1; 
             rc.right:=i+1; 
             Bt:=MulDiv(i,Bi,Width)+B; 
             Gt:=MulDiv(i,Gi,Width)+G; 
             Rt:=MulDiv(i,Ri,Width)+R; 
             If Bt>$FF Then Bt:=$FF; 
             If Gt>$FF Then Gt:=$FF; 
             If Rt>$FF Then Rt:=$FF; 
             LogBrush.lbColor:=(Rt SHL 16) OR (Gt SHL 8) OR (Bt); 
             LhBR:=CreateBrushIndirect(LogBrush); 
             FillRect(dc,rc,LhBR); 
             rc.left:=Rect.right-Rect.left-i; 
             rc.right:=Rect.right-Rect.left-i-1; 
             FillRect(dc,rc,LhBR); 
             DeleteObject(LhBR); 
         End; 
     End; 
   LogBrush.lbColor:=$9E6A54;     //標題欄顏色 
   LhBR:=CreateBrushIndirect(LogBrush); 
   FrameRect(dc,Rect,LhBR); 
   DeleteObject(LhBR); 
   SetTextColor(dc,$05E8FC); 
   SetBkMode(dc,TRANSPARENT); 
   Rect.left:=2; 
   Rect.top:=2; 
   Dec(Rect.bottom,2); 
   LFont:=CreateFont(-$C,0,0,0,$2BC,0,0,0,1,0,0,0,0,'宋體'); 
   SelectObject(dc,LFont); 
   If Icon<>0 Then 
     Begin 
       DrawIconEx(dc,2,2,Icon,$10,$10,0,0,3); 
       Rect.left:=$14; 
     End; 
   DrawText(dc,Caption,-1,Rect,$24); 
   DeleteObject(LFont); 
End;

 //////////////////////////////////////////////////////////////////

//滾動文本函數 
Function ScrollProc(hDlg:HWND;Msg,wParam,lParam:DWord):LRESULT;stdcall; 
Var 
   sRect:TRect; 
   sPaint:PAINTSTRUCT; 
   DC:HDC; 
   LFont:HFONT; 
Begin 
   If Msg=WM_PAINT Then 
     Begin 
       DC:=BeginPaint(hDlg,sPaint); 
       GetClIEntRect(hDlg,sRect); 
       //SetTextColor(DC,$A0A0A0); 
       SetTextColor(DC,$03FF09);   //滾動字幕呈 綠色 
       SetBkMode(DC,TRANSPARENT); 
       LFont:=CreateFont(-$C,0,0,0,0,0,0,0,1,0,0,0,0,'宋體'); 
       SelectObject(DC,LFont); 
       DrawText(DC,szScroll,-1,sRect,DT_CENTER); 
       EndPaint(hDlg,sPaint); 
       DeleteObject(LFont); 
     End 
   Else 
     Begin 
       CallWindowProc(Pointer(GetWindowLong(hDlg,GWL_USERDATA)),hDlg,Msg,wParam,lParam); 
     End; 
   Result:=1; 
End;

  //////////////////////////////////////////////////////////////////

  //關於對話框過程函數

Function AboutProc(hDlg:HWND;Msg,wParam,lParam:DWord):LRESULT;stdcall; 
Var 
   sRect:TRect; 
   sPaint:PAINTSTRUCT; 
   sPoint:TPoint; 
Begin 
   Result:=0; 
   Case Msg of 
     WM_COMMAND: 
       Begin 
         Case wParam of 
           ABOUT_OK: 
             Begin 
               KillTimer(hDlg,$A8); 
               EndDialog(hDlg,0); 
             End; 
           ABOUT_CLOSE: 
             Begin 
               KillTimer(hDlg,$A8); 
               EndDialog(hDlg,0); 
             End; 
         End; 
       End; 
     WM_PAINT: 
       Begin 
         Paint(BeginPaint(hDlg,sPaint),h_Icon,szMainCaption,$767676,0,sRectA); 
         EndPaint(hDlg,sPaint); 
       End; 
     WM_DRAWITEM: 
       Begin 
         ItemDraw(PDrawItemStruct(lParam)); 
         Result:=0; 
       End; 
     WM_INITDIALOG: 
       Begin 
         GetClIEntRect(hDlg,sRectA); 
         sRectA.Bottom:=sRectA.Top+$14; 
         h_ScrollParent:=GetDlgItem(hDlg,$BBD); 
         SendMessage(GetDlgItem(hDlg,$BBB),WM_SETFONT,CreateFont(-$C,0,0,0,$2BC,0,0,0,1,0,0,0,0,'宋體'),0); 
         SetDlgItemText(hDlg,$BBB,szKeyGenName); 
         SetDlgItemText(hDlg,$BBC,szCracker); 
         SetWindowText(hDlg,'關於'); 
         GetClIEntRect(h_ScrollParent,sRect); 
         ScrollWidth:=sRect.right-sRect.left; 
         ScrollHeight:=sRect.bottom-sRect.top; 
         xCount:=ScrollHeight; 
         LineCount:=CountCRLF(szScroll); 
         h_Scroll:=CreateWindowEx(WS_EX_LEFT,'Static','',WS_CHILD OR WS_VISIBLE OR SS_CENTER,0,ScrollHeight,ScrollWidth,LineCount*12,h_ScrollParent,0,h_Inst,nil); 
         SetWindowLong(h_Scroll,GWL_USERDATA,SetWindowLong(h_Scroll,GWL_WNDPROC,LongWord(@ScrollProc))); 
         DialogInit(hDlg); 
         SetTimer(hDlg,$A8,60,NIL); 
         Result:=1; 
       End; 
     WM_CTLCOLORDLG: 
       Begin 
         SetTextColor(wParam,$A0A0A0); 
         SetBkMode(wParam,TRANSPARENT); 
         Result:=h_Brush; 
       End; 
     WM_CTLCOLORSTATIC: 
       Begin 
         //SetTextColor(wParam,$FE248B); //關於對話框 題目 顏色 
         SetTextColor(wParam,$FC77B5); 
         SetBkMode(wParam,TRANSPARENT); 
         Result:=h_Brush; 
       End; 
     WM_LBUTTONDOWN: 
       Begin 
         sPoint.x:=lParam AND $FFFF; 
         sPoint.y:=lParam SHR 16; 
         If PtInRect(sRectA,sPoint) Then 
           Begin 
             PostMessage(hDlg,WM_NCLBUTTONDOWN,2,0); 
           End; 
       End; 
     WM_TIMER: 
       Begin 
         Sleep(20); 
         Dec(xCount); 
         SetWindowPos(h_Scroll,HWND_TOP,0,xCount,ScrollWidth,LineCount*12,0); 
         If xCount<(0-LineCount*12) Then 
           Begin 
             xCount:=ScrollHeight; 
           End; 
       End; 
   End; 
End;

//////////////////////////////////////////////////////////////////

  //超連接函數

Function LinkProc(hDlg:HWND;Msg,wParam,lParam:DWord):LRESULT;stdcall; 
Begin 
   Result:=1; 
   Case Msg of 
     WM_SETCURSOR: 
       Begin 
         SetCursor(h_Cur); 
       End; 
     WM_NCHITTEST: 
       Begin 
         Result:=1; 
       End; 
     WM_LBUTTONUP: 
       Begin 
         ShellExecute(0,nil,'http://17339836.qzone.QQ.com',nil,nil,0);//偷了點懶 
       End; 
     Else 
       Begin 
         CallWindowProc(Pointer(GetWindowLong(hDlg,GWL_USERDATA)),hDlg,Msg,wParam,lParam); 
       End; 
   End; 
End; 
//_____________________________________________________________

  //主窗口過程函數

Function MainProc(hDlg:HWND;Msg,wParam,lParam:DWord):LRESULT;stdcall; 
Var 
   sPaint:PAINTSTRUCT; 
   sPoint:TPoint; 
   LFont:HFONT; 
   LinkHWND:HWND; 
   SetLongRet:Longint; 
Begin 
   Result:=0; 
   
   Case Msg of 
     WM_CTLCOLOREDIT: 
       Begin 
         SetTextColor(wParam,$A0A0A0); 
         SetBkMode(wParam,TRANSPARENT); 
         Result:=h_Brush; 
       End; 
     WM_COMMAND: 
       Begin 
         Case wParam AND $FFFF of 
           MAIN_CALC: 
             Begin 
               GetDlgItemText(hDlg,$7DA,@RegName,255); 
               //GetRegCode;   // 計算注冊碼過程 
               PatchFile; //打補丁過程 
               SetDlgItemText(hDlg,$7D9,@RegCode); 
             End; 
           MAIN_EXIT: 
             Begin 
               EndDialog(hDlg,0); 
             End; 
           MAIN_ABOUT: 
             Begin 
               MessageBeep(0); 
               DialogBoxParam(h_Inst,LPCTSTR(IDD_ABOUTDLG),hDlg,@AboutProc,0); 
             End; 
           MAIN_CLOSE: 
             Begin 
               EndDialog(hDlg,0); 
             End; 
           $7DA://就是RegName的ID 
             Begin 
               Case wParam SHR 16 of 
                 EN_CHANGE:   // 在用戶名中輸入數據時,捕獲消息,立即進行計算。過程相當於按下“計算”按鍵過程。 
                   Begin 
                     GetDlgItemText(hDlg,$7DA,@RegName,255); 
                     //GetRegCode; 
                     PatchFile; //打補丁過程;; 
                     SetDlgItemText(hDlg,$7D9,@RegCode); 
                   End; 
               End; 
             End; 
         End; 
       End; 
     WM_PAINT: 
       Begin 
         Paint(BeginPaint(hDlg,sPaint),h_Icon,szMainCaption,$767676,0,sRectM); 
         EndPaint(hDlg,sPaint); 
       End; 
     WM_DRAWITEM: 
       Begin 
         ItemDraw(PDrawItemStruct(lParam)); 
         Result:=0; 
       End; 
     WM_INITDIALOG: 
       Begin 
         GetClIEntRect(hDlg,sRectM); 
         sRectM.Bottom:=sRectM.Top+$14; 
         SetDlgItemText(hDlg,2011,szLink); 
         SetDlgItemText(hDlg,2008,szTime); 
         SetDlgItemText(hDlg,2005,szName); 
         SetDlgItemText(hDlg,2006,szCracker); 
         SetDlgItemText(hDlg,2007,szBy); 
         SetDlgItemText(hDlg,2012,szCopyright); 
         SetWindowText(hDlg,szMainCaption); //任務欄顯示名稱; 
         LFont:=CreateFont(-$C,0,0,0,$2BC,0,1,0,1,0,0,0,0,'宋體'); 
         LinkHWND:=GetDlgItem(hDlg,2011); 
         SendMessage(LinkHWND,WM_SETFONT,LFont,0);//設置字體 
         SetLongRet:=SetWindowLong(LinkHWND,GWL_WNDPROC,LongWord(@LinkProc)); 
         SetWindowLong(LinkHWND,GWL_USERDATA,SetLongRet); 
         DialogInit(hDlg); 
       End; 
     WM_CTLCOLORDLG: 
       Begin 
         SetTextColor(wParam,$A0A0A0); 
         SetBkMode(wParam,TRANSPARENT); 
         Result:=h_Brush; 
       End; 
     WM_CTLCOLORSTATIC: 
       Begin 
         SetTextColor(wParam,$A0A0A0); 
         SetBkMode(wParam,TRANSPARENT); 
         Result:=h_Brush; 
       End; 
     WM_LBUTTONDOWN: 
       Begin 
         sPoint.x:=lParam AND $FFFF; 
         sPoint.y:=lParam SHR 16; 
         If PtInRect(sRectM,sPoint) Then 
           Begin 
             PostMessage(hDlg,WM_NCLBUTTONDOWN,2,0); 
           End; 
       End; 
   End; 
End;

  //程序運行時從這裡開始執行代碼;

begin 
   h_Inst:=GetModuleHandle(nil); 
   h_Brush:=CreateSolidBrush($1F1F1F); 
   h_Cur:=LoadCursor(h_Inst,MAKEINTRESOURCE(LINKCURSOR)); 
   h_Icon:=LoadIcon(h_Inst,MAKEINTRESOURCE(MAINICON)); 
   DialogBox(h_Inst,LPCTSTR(IDD_MAINDLG),0,@MainProc); //顯示主窗口 
   DeleteObject(h_Brush);   // 刪除窗體 
   ExitProcess(0);   //退出程序 
end.






  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved