Jump to content

dport

Members
  • Content Count

    15
  • Joined

  • Last visited

Posts posted by dport


  1. On 1/5/2024 at 6:56 AM, Dave Nottage said:

     

    I have a repo containing some ChatGPT "conversations" which might be of interest, and have just added this one:

     

    https://github.com/DelphiWorlds/HowTo/blob/main/ChatGPTConversations/DetectClonedApp.md

     

    The Delphi code is my conversion of the Java code. As per the warning here, always verify anything coming from ChatGPT, or me, for that matter 🙂

     

    Thank you for your answer. Unfortunately, when run from within the dualspace application, the getInstallerPackageName method always returns com.android.vending. Normally, when debugging the application, this value returns nil because it is not installed from Playstore. However, when you run your application compiled in debug mode from dualspace, this value returns as com.android.vending. Cloning apps manipulate all the parameters offered by the Android system to prevent cloning detection.

     

    var
      LInstallerPackage: JString;
    begin
      LInstallerPackage := TAndroidHelper.Context.getPackageManager.getInstallerPackageName(TAndroidHelper.Context.getPackageName);
      showmessage(JStringToString(LInstallerPackage));//always return com.android.vending in cloning application

    end;


  2. On 12/28/2023 at 11:24 AM, Fr0sT.Brutal said:

    Why would you need that? Just let the user install your app as it wants to. I'd throw away any app that would do such dirty things leaving 1-star review at market.

     

    On 12/28/2023 at 12:55 PM, Dave Nottage said:

    If there's a way to do it in Java or Kotlin, there's usually a way to do it in Delphi. Do you have any links discussing why this is a problem, and potential solutions?

    There are reasons such as preventing the user from opening more than one account and cheating in online games, and preventing punished players from logging in from parallel accounts and continuing to cause problems. We generally use device-specific serial numbers to prevent these situations. In the past, IMEI and MAC serial numbers could be used, but since this information is no longer provided, we provide this control by using different Unique IDs specific to the device. However, since the software that clones the device also clones these UniqueIDs, it is perceived as logging in from a completely different device. For this reason, if the application has been run through cloning, we want to prevent it from running.


  3. There is a solution that checks whether the cloning applications are installed on the phone, but it is not very applicable since there are hundreds of programs that do this job (it will also be necessary to introduce the programs that will be added later).

    function IsAppInstalled(const APackageName: string): Boolean;
    var
      LIntent: JIntent;
      LList: JList;
      LApplicationInfo: JApplicationInfo;
      I: Integer;
    begin
      Result := False;
      LIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_MAIN);
      LIntent.addCategory(TJIntent.JavaClass.CATEGORY_LAUNCHER);
      LIntent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK or TJIntent.JavaClass.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
      LList := TAndroidHelper.Context.getPackageManager.queryIntentActivities(LIntent, 0);
      for I := 0 to LList.size - 1 do
      begin
        LApplicationInfo := TJResolveInfo.Wrap(JObjectToID(LList.get(I))).activityInfo.applicationInfo;
        if (LApplicationInfo.flags and TJApplicationInfo.JavaClass.FLAG_SYSTEM) = 0 then
        begin
          if APackageName = JStringToString(LApplicationInfo.packageName) then
             exit(true);
        end;
      end;
    end;

    (Must be given query all packages permission to run)


  4. On 6/30/2023 at 7:46 PM, jerik said:

    Aha! Bad idea to place it in Form.Create.

    Thank you!

    Yes, there is this problem in the latest versions of Delphi. In the form create event, everything added to the webbrowser is deleted, not only that. It is also deleted when the parent changes.
    For example, when you move the WebBrowser parent to an object such as panel2, all the content is gone. I reported this on qualityprortal. Marco cantu wrote that this behavior is normal(!). So correction is not considered.


  5. With applications such as DualSpace available on Playstore, an application on the phone can be cloned and run as a completely different copy. Even if distinctive features such as androidId, FCM (Firebase Cloud Messaging) ID, MAC serial are used for device recognition, the cloned application can bypass the identification system by producing completely different IDs.
    Is there a way to tell if the app is a clone? Options such as PackageName control and Installation path control are suggested on the internet, but when I check as follows, the cloned application gets the PakageName like the original and shows the same installation path.
      showmessage(JStringToString(SharedActivityContext.getPackageName));
      showmessage(JStringToString(TAndroidHelper.Context.getPackageCodePath));
    Therefore, both of these methods do not work when detecting the cloned application.
    Another way is to check whether the application is running on the virtual machine, but I couldn't find how to check it.
    Is there a successful method in Delphi to detect a cloned application?


  6. I tried it on a bunch of android devices and it works fine (9003 different devices to be exact)

    And a correction below: (disabled   wvDrm:=tJMediaDrm.Create; row)

    function BytesToHex(const ABytes: TBytes): string;
    var
      I: Integer;
    begin
      Result := '';
      for I := Low(ABytes) to High(ABytes) do
        Result := Result + IntToHex(ABytes[I], 2);
    end;
    
    function get_media_drm_UNIQUE_ID:string;
    var
     wvDrm:JMediaDrm;
     str:String;
     UUID:JUUID;
     data : TJavaArray<Byte>;
     datab: TBytes;
     i:integer;
    begin
    //UUID:=TJUUID.JavaClass.fromString(stringtojstring('12107456-8629-b532-5c37-d8232ae2de13'));   //EJNIException with message 'android.media.UnsupportedSchemeException: Failed to instantiate drm object.
      UUID:=TJUUID.JavaClass.fromString(stringtojstring('edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'));//widevine_id
    
      //wvDrm:=tJMediaDrm.Create; //no need create
      wvDrm:=tJMediaDrm.JavaClass.init(UUID);
      try
       data:=wvDrm.getPropertyByteArray( TJMediaDrm.JavaClass.PROPERTY_DEVICE_UNIQUE_ID);
       if data <> nil then
       begin
          SetLength(datab, data.Length);
          for I := 0 to data.Length - 1 do
            datab[I] := data.Items[I];
          str:=BytesToHex(datab);
       end;
       result:=str;//length of str:64byte
      finally
       wvDrm.release;
      end;   
     end;
    
    procedure TForm1.Button3Click(Sender: TObject);
    begin
     memo1.Lines.add(get_media_drm_UNIQUE_ID);
    end;

     


  7. Delphi 11.1 on Android WebBrowser content disappears when parent is changed

     

     

    Add a WebBowser, GroupBox and three Button component on a form.

    Write this code to add a text to WebBrowser with EvaluateJavaScript method.

    procedure TForm1.Button1Click(Sender: TObject);

    begin
    webbrowser1.EvaluateJavaScript('document.write("hello");')
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    
    begin
    webbrowser1.EvaluateJavaScript('document.write("hello");')
    end;

    And add this code to change WebBrowser Parent to groupbox1

    procedure TForm1.Button2Click(Sender: TObject);
    begin
    webbrowser1.Parent :=groupbox1;
    end;

    And add this code to change WebBrowser Parent to form1.

    procedure TForm1.Button3Click(Sender: TObject);
    begin
    webbrowser1.Parent :=form1;
    end;


    Run on android and press Button1 to add Hello to WebBrowser1
    And Click Button2 to change WebBrowser parent to groupbox1
    And Click Button3 to change WebBrowser parent to form
    Webbowser content lost.

     

    https://quality.embarcadero.com/browse/RSP-38439?

     

     

     

    I found a difference with delphi 10.4 fmx.webbrowser.pas. 

    Embarcadero added this code to delphi 11 fmx.webbrowser.pas. 

    procedure TCustomWebBrowser.DoRootChanged;
    begin
      inherited;
      if csDesigning in ComponentState then
        Exit;
    
      if Root <> nil then
        RecreateWebBrowser;
    end;
    
    procedure TCustomWebBrowser.DoRootChanging(const NewRoot: IRoot);
    var
      WBService : IFMXWBService;
    begin
      inherited;
      if csDesigning in ComponentState then
        Exit;
    
      if (FWeb <> nil) and TPlatformServices.Current.SupportsPlatformService(IFMXWBService, WBService) then
      begin
        WBService.DestroyWebBrowser(FWeb);
        FWeb := nil;
        FWindowsBrowserProperties := nil;
      end;
    end;

    When parent change they destroy and recraete it. Why?


  8. 2 hours ago, mausmb said:

    B3B4BFBF67D02522F059BB610D9FA6A21D3042F2B45640C3E6A79AF2567B1327

     

    with 

     

    function ByteArrayToHexString(BA: TArray<Byte>; Sep: string = ''): string;
    var
      i, k: integer;
    begin
      result:='';

      if Sep='' then begin
         for i:=low(BA) to high(BA) do
           result := result + IntToHex(BA, 2);
      end else begin
         k:=high(BA);
         for i:=low(BA) to k do begin
            result:= result + IntToHex(BA, 2);
            if k<>i then result := result + Sep;
         end;
      end;
    end;

     

     

     

    thanks mausmb,

    sorry i forgot add BytesToHex function.

    edited my previous post.


  9. I translated to delphi

     

    function BytesToHex(const ABytes: TBytes): string;
    var
      I: Integer;
    begin
      Result := '';
      for I := Low(ABytes) to High(ABytes) do
        Result := Result + IntToHex(ABytes[I], 2);
    end;
    
    function get_media_drm_UNIQUE_ID:string;
    var
     wvDrm:JMediaDrm;
     str:String;
     UUID:JUUID;
     data : TJavaArray<Byte>;
     datab: TBytes;
     i:integer;
    begin
    //UUID:=TJUUID.JavaClass.fromString(stringtojstring('12107456-8629-b532-5c37-d8232ae2de13'));   //EJNIException with message 'android.media.UnsupportedSchemeException: Failed to instantiate drm object.
      UUID:=TJUUID.JavaClass.fromString(stringtojstring('edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'));//widevine_id
    
      wvDrm:=tJMediaDrm.Create;
      wvDrm:=tJMediaDrm.JavaClass.init(UUID);
      data:=wvDrm.getPropertyByteArray( TJMediaDrm.JavaClass.PROPERTY_DEVICE_UNIQUE_ID);
      if data <> nil then
      begin
          SetLength(datab, data.Length);
          for I := 0 to data.Length - 1 do
            datab[I] := data.Items[I];
          str:=BytesToHex(datab);
      end;
      result:=str;//length of str:64byte
     end;
    
    procedure TForm1.Button3Click(Sender: TObject);
    begin
     memo1.Lines.add(get_media_drm_UNIQUE_ID);
    end;

    result is for my phone: 42AAF4986AF6DA7F5CE736DDE4549F5D5BC44490646BCFA7A25B0C25B237C946

    If you can try and post the result, we can see if it's unique or not


  10. We are using the serial number for unique device identification. In android Q we can't access that device information. 

    https://stackoverflow.com/questions/58103580/android-10-imei-no-longer-available-on-api-29-looking-for-alternatives

    there is a solution is to use the MediaDrm API PROPERTY_DEVICE_UNIQUE_ID

     

    what is the delphi equivalent of the following code

    val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
        val id = MediaDrm(WIDEVINE_UUID)
            .getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)
        var encodedString: String = Base64.encodeToString(id,Base64.DEFAULT)
        Log.i("Uniqueid","Uniqueid"+encodedString)
    
     

  11. On 5/2/2022 at 2:23 PM, Dave Nottage said:

    It's possible there is. My question was: What are the steps to reproduce that the website will definitely show in dark mode? Then I can test that the code will force it into light mode

    I am creating dynamic webbrowser content like:

    WebBrowser1.EvaluateJavaScript('document.write("hello");');

    I add style section before html content to force light mode.

     

    WebBrowser1.EvaluateJavaScript('<html><head><meta name="color-scheme" content="light only"></head><style>:root {         color-scheme: light only;  }</style></head><body>');
    
    WebBrowser1.EvaluateJavaScript('document.write("hello");');

    I am looking a settings webbrowser force light mode or disable dark mode.


  12. I added head section html:

     

    <meta name="color-scheme" content="light only"></head>
    <style>
    :root {
             color-scheme: light only;
           }
    </style>

    I added it to the html codes but there must be a setting to force twebrowser

×