2010-12-03 3 views
2

최근 OnGuard를 정직한 사람들이 그들의 원칙을 준수하는 데 도움이되는 방법으로 사용하는 방법을 살펴 보았습니다. 나는 라이센스 시스템이 귀하의 소프트웨어를 사용하고자하는 사람으로부터 귀하를 보호 할 것이고 비용을 지불하고 싶지 않다는 많은 사람들의 의견에 동의합니다. 다른 한편으로, 나는 다른 누군가가 내 프로그램을위한 유효한 키를 만드는 것을 너무 쉽게하지 않기를 바란다. OnGuard와의 라이센스

  1. 이를 사용하는 올바른 방법처럼 보이는가 :

    const 
        TheKey: TKey = ($4A,$62,$F3,$2B,$9C,$D2,$84,$BF,$CB,$04,$0A,$C3,$3D,$11,$47,$1A); 
    
    
    function TfrmMain1.MakeCode(sName, sNumber: String; dtExpiration: TDate): String; 
    var Key: TKey; 
        Code: TCode; 
        sCode: String; 
    begin 
        Key := TheKey; 
        InitRegCode(Key, sName + ' - ' + sNumber, dtExpiration, Code); 
        sCode := BufferToHex(Code, SizeOf(Code)); 
        Insert('-', sCode, 13); 
        Insert('-', sCode, 09); 
        Insert('-', sCode, 05); 
        Result := sCode 
    end; 
    
    function TfrmMain1.TestCode(sName, sNumber, sTestCode: String; dtExpiration: TDate): Boolean; 
    var Key: TKey; 
        Code: TCode; 
        sCode: String; 
    begin 
        sCode := MakeCode(sName, sNumber, dtExpiration); 
    
        Result := SameText(sCode, sTestCode); 
    end; 
    

    이 몇 가지 질문을 제공합니다 :

    은 설명서와 예제를 공부 한 후, 나는 내 기본 폼의 코드에 다음을 추가 ? 차라리 양식에 구성 요소를 추가하지 않을 것입니다.

  2. OnGuard 소스를 사용할 수 있기 때문에 해커가 리버스 엔지니어링을 통해 키를 선택하고 유효한 릴리스 코드를 생성 할 수 없습니까? 따라서 코드에 약간의 난독 화를 추가해야할까요 아니면 그냥 시스템을 약화시킬 수 있을까요?

  3. 키는 여기에서 상수로 설정됩니다. 연속 된 바이트로 코드에 나타나지 않고 복사하기 쉽지 않습니까?

  4. 내 프로그램에는 연간 업데이트가 필요하며 연간 가입으로 라이센스를 구입할 계획입니다. 내 프로그램에서 상수로 연도를 추가하고 해당 연도에 대한 사용자 항목을 몇 군데에서 테스트하는 것이 더 강력할까요?

밀접한 관련이 있고 매우 구체적인 4 가지 질문이 있습니다. 그것은 4 개의 분리 된 입장에서 그들에게 질문하는 것이 더 어색 할 것 같았고 문맥에 대한 참고 문헌을 추가해야만하는 것처럼 보였습니다. 그러나 그것이 바람직한 것이라면 나는 그것을 기꺼이 할 것입니다. 도와 줘서 고마워.

+2

정직한 사람들은 집행이없는 경우에도 여전히 원칙을 준수합니다. 그것이 그들이 정직하게 만드는 이유입니다. –

+1

당신이주의해야 할 것들은 얼마나 많은 라이센스를 사용하고 있는지를 알아야 할 필요가 있습니다. 왜냐하면 사용하는 라이센스 수를 추적 할 수 없기 때문입니다! –

답변

2
constructor TLincenceManager.Create; 
    begin 
    FSpecialCode := TOgSpecialCode.Create(nil); 
    FSpecialCode.OnGetModifier := OgNetCodeGetModifier; 
    FSpecialCode.OnChecked := OgNetCodeChecked; 
    FSpecialCode.OnGetCode := OgNetCodeGetCode; 
    FSpecialCode.OnGetKey := OgNetCodeGetKey; 
    FSpecialCode.AutoCheck := False; 
    end; 

    function TLincenceManager.InitializeLicenceCode: Boolean; 
    begin 
    Result := FSpecialCode.CheckCode(True) = ogValidCode; 
    end; 

    procedure TLincenceManager.OgNetCodeChecked(Sender: TObject; Status: TCodeStatus); 
    begin 
    case Status of 
     ogValidCode : FMaxUsers := FSpecialCode.GetValue; 
     ogInvalidCode : FMaxUsers := 0; 
     ogPastEndDate : FMaxUsers := 0; 
     ogDayCountUsed : FMaxUsers := 0; 
     ogRunCountUsed : FMaxUsers := 0; 
     ogNetCountUsed : FMaxUsers := 0; 
     ogCodeExpired : FMaxUsers := 0; 
    else 
     FMaxUsers := 0; 
    end; 
    end; 

    procedure TLincenceManager.OgNetCodeGetCode(Sender: TObject; var Code: TCode); 
    var 
    FileName: string; 
    SerialData: string; 
    LicenceData: TStringList; 
    begin 
    FileName := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))); 
    FileName := FileName + cLicenseFileName; 
    SerialData := ''; 

    LicenceData := TStringList.Create; 
    try 
     if FileExists(FileName) then 
     begin 
     LicenceData.LoadFromFile(FileName); 
     SerialData := LicenceData.Values['Serial']; 
     end; 

     {convert to proper form} 
     HexToBuffer(SerialData, Code, SizeOf(Code)); 
    finally 
     LicenceData.Free; 
    end; 
    end; 

    procedure TLincenceManager.OgNetCodeGetKey(Sender: TObject; var Key: TKey); 
    const 
    CKey : TKey = ($4A,$62,$F3,$2B,$9C,$D2,$84,$BF,$CB,$04,$0A,$C3,$3D,$11,$47,$1A); 
    begin 
    Key := CKey; 
    end; 

    procedure TLincenceManager.OgNetCodeGetModifier(Sender: TObject; var Value: Integer); 
    begin 
    Value := GenerateMachineModifierPrim; 
    end; 
  1. 은 내가 그것을 할 방법을 게시했다. "시각적 인"구성 요소를 사용하지 않습니다. 내가하는 방식은 당신의 경우에는 날짜 수정자를 적용하는 것입니다. (기계 수정자를 가짐)

  2. 아니요, 이론적으로 아니오. 라이센스를 생성하는 핵심은 본질적입니다. 열쇠가 있으면 라이센스를 해독 할 수 있습니다. 하지만 코드만으로는 그럴 수 없습니다. 이것은 암호화 알고리즘과 같습니다. 알고리즘 작동 방식을 알 수 있지만 키가 없으면 크랙 할 수 없습니다. XTEA을보십시오. 그것은 매우 간단하지만 균열하기가 어렵습니다.

  3. 예 무슨 일을하는지 알면 이진에서 키를 추출 할 수 있습니다. 여기에 일종의 난독 화를 사용할 수 있습니다. 그러나 나는 신경 쓰지 않을 것이다. 대부분의 사람들은 이러한 보호가 충분하므로 다음 MS Office를 만들지 않는다면 걱정하지 않아도됩니다. 사람들은 그들의 제품에 대해 파라 나이드 (paranaoid)하는 방법입니다. 먼저 판매하고 나중에 이것에 대해 생각하십시오. 아, 그리고 문자열이 아니기 때문에 어쨌든 찾기가 조금 더 어렵습니다.

  4. 시간 제한 라이센스를 수행하는 방법을 알아보기 위해 onGuard와 함께 제공되는 평가판 데모를 살펴보십시오. 그러나 컴퓨터 시계를 조작하는 것만으로도 컴퓨터를 속일 수 있습니다. 내 견해로는 최상의 평가판 소프트웨어가 그러한데, 이는 필수적인 기능이 부족합니다 (버튼 저장 ...). 좋은 시간 재판은 내 의견으로는 매우 어렵습니다.

+0

완전하고 철저한 답변을 해주셔서 감사합니다. OnGuard를 사용하고자하는 다른 사람들에게 제공 한 코드가 유용 할 것입니다. 나는이 물건에 대해 너무 편집증적인 경향이 있다는 것에 동의한다. 도와 줘서 고마워. 나는 실제로 내 프로그램을 지금 판매 할 수있는 것에 더 가깝다. – jrodenhi

+0

아니요, 문제가있어서 기꺼이 도와 드리겠습니다. – Runner

2

나는 Runner가 제안한 클래스보다 낮은 수준의 OnGuard API를 사용합니다. 어느 것이 든 잘 동작 할 것이고, 어쨌든 더 낮은 레벨의 API를 호출하게 될 것이다. 다음은 이러한 저수준 API 메소드에 대한 래퍼 유틸리티 함수입니다.

{ Used by you to generate the unlock code you send to your customer, do not include in the customer software } 

function GenerateReleaseCode(const inAppKey : string; inExpiryDate : TDateTime; inRegCode : string) : string; 
(* inAppKey is the byte sequence key you already have 
    inRegCode can be anything, typically customers name 
    Returns the release code for the customer to type into the software *) 
var 
    releaseCode : TCode; 
    key : TKey; 
begin 
    HexToBuffer(inAppKey, key, SizeOf(TKey)); 
    InitRegCode(key, inRegCode, inExpiryDate, releaseCode); 
    Result := BufferToHex(unlockCode, SizeOf(releaseCode)); 
end; 

{ Used in your program to authenticate if the release code is valid - does not check for expiry } 

function AuthenticateReleaseCode(const inReleaseCodeHexString : string; const inAppKey : TKey) : Boolean; 
var 
    releaseCode : TCode; 
begin 
    HexToBuffer(inReleaseCodeHexString, releaseCode, SizeOf(releaseCode)); 
    Result := IsRegCodeValid(inAppKey, releaseCode); 
end; 

{ Used in your program to test if the license has expired } 

function UnlockCodeExpiryDate(const inReleaseCodeHexString : string; const inAppKey : TKey) : TDateTime; 
var 
    releaseCode : TCode; 
begin 
    HexToBuffer(inReleaseCodeHexString, releaseCode, SizeOf(releaseCode)); 
    Result := GetExpirationDate(inAppKey, releaseCode); 
end; 

저는 OnGuard를 광범위하게 사용하지만 불법 복제가 그다지 문제가되지 않는 엔터프라이즈 소프트웨어에만 사용합니다. 소비자 소프트웨어를 판매하고 불법 복제에 대해 걱정하고 있다면 exe를 암호화하는 상용 복사 방지 라이브러리와 같은 강력한 솔루션을 권합니다.

그럼에도 불구하고 크래커를 느리게 할 수는 있지만 중지 할 수는 없습니다.

+0

코드를 포함 해 주셔서 감사하며 사용하고자하는 제품에 대한 조언을 보내 주셔서 감사합니다. 나는 소비자 소프트웨어 시장이 소프트웨어 보호를위한 적대적인 장소 인 것처럼 보인다고 동의한다. 만료 된 부분이 만료 된 것 같아서 내가하는 일을 따라갈 것입니다. 귀하의 코드에 다시 한 번 감사드립니다. 사용 가능한 문서의 좋은 확장입니다. 내가 두 가지 대답을 받아 들일 수 있다고 표기 할 수 있다면, 나는 당신의 것을 포함시킬 것입니다. – jrodenhi

2

3) 키를 "분산"하고 어쩌면 일부를 계산해야합니다. 물론 키를 식별하는 것이 더 간단 할뿐 아니라 보호를 우회하는 것이 더 간단합니다. 그러나 적절한 위치에있는 간단한 JMP 명령어가 전체 보호 검사를 우회하면 복잡한 키조차도 쓸모가 없습니다. 그 수표는 둘 이상이어야하며 다시 흩어져 야합니다.

4) 이러한 종류의 라이선스에주의하십시오. 연간 요금이 일부 인식 된 값 (즉, 바이러스 백신이 업데이트 서명을 제공하거나 GPS 응용 프로그램이지도를 업데이트)을 제공하지 않는 한 일반적으로 사용자가 좋아하지 않습니다. 사용자가 매년 지불하도록 강요하는 것은 유용하지 않을 수도있는 새로운 기능을 추가하더라도 사용자에게는 좋지 않을 수 있지만 사용자에게는 적합하지 않을 수 있습니다. 응용 프로그램이 더 이상 작동하지 않는 경우. 그것은 동일한 기능을 가지고 있지만 연간 요금이없는 Windows 응용 프로그램을 사용할 수있게되었을 때 많은 유닉스 응용 프로그램을 죽인 문제 중 하나입니다. 나는 많은 기업들이 그 모델로 돌아갈 생각을하고 있음을 안다. 성공할 지 아직 보이지는 않는다.