---
# System prepended metadata

title: Flutter bypass ssl pinning
tags: [pentest android]

---

# Flutter bypass ssl pinning

Tải app tại 
- https://github.com/NVISOsecurity/disable-flutter-tls-verification

truy cập app và thực hiện gửi request bị ssl pinning thấy burp suite không thể bắt request 


![image](https://hackmd.io/_uploads/Hkpo5Hqjbx.png)

![image](https://hackmd.io/_uploads/SJoa5rqsZx.png)


![image](https://hackmd.io/_uploads/ByfwoHcibg.png)



## Bypass bằng frida 
- https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/
Decomply app bằng apktool hoặc apk studio

![image](https://hackmd.io/_uploads/HJ2mrV5oWx.png)

Các file libflutter.so khác nhau chỉ do kiến trúc CPU (ABI) thôi, không phải nội dung logic khác nhau (về cơ bản cùng code nhưng compile cho từng kiến trúc):

📂 Cụ thể:
- arm64-v8a/libflutter.so → cho ARM 64-bit (đa số máy Android thật hiện nay)
- armeabi-v7a/libflutter.so → cho ARM 32-bit
- x86_64/libflutter.so → cho giả lập Android Studio (AVD) dùng CPU Intel/AMD 64-bit

libflutter.so chủ yếu là Flutter engine

chúng ta đang chạy trên máy ảo android studio nên chạy với `lib/x86_64/libflutter.so`



![image](https://hackmd.io/_uploads/HJd0LVco-x.png)


![image](https://hackmd.io/_uploads/BJzCLV9o-g.png)


![image](https://hackmd.io/_uploads/H1kALEqjWl.png)

- https://github.com/google/boringssl/blob/main/ssl/handshake.cc#L390-L393


![image](https://hackmd.io/_uploads/rk8unE5sZg.png)

Luồng kiểm tra cert phải qua hàm x509
- `Search → For Strings` và tìm ssl_x509

![image](https://hackmd.io/_uploads/Hy_vkSqs-e.png)



![image](https://hackmd.io/_uploads/HystJBqoZg.png)



![image](https://hackmd.io/_uploads/ByXoJH5s-x.png)


![image](https://hackmd.io/_uploads/HJV-lS9obx.png)
![image](https://hackmd.io/_uploads/ry1NgH9sbe.png)


![image](https://hackmd.io/_uploads/BkIReS9jZx.png)
    
![image](https://hackmd.io/_uploads/BJZQ-rqobe.png)

![image](https://hackmd.io/_uploads/S1JV-S9jZe.png)

chọn option này để hiện thị tất cả reference

![image](https://hackmd.io/_uploads/Bk8lUS9iZx.png)


click chọn phân tích tất cả 

![image](https://hackmd.io/_uploads/ByhbIHqoWx.png)

![image](https://hackmd.io/_uploads/H1G4LB9iZx.png)

![image](https://hackmd.io/_uploads/Hk5DISqibg.png)

![image](https://hackmd.io/_uploads/HJLtIHqs-g.png)

![image](https://hackmd.io/_uploads/rk_iISqsWl.png)



![image](https://hackmd.io/_uploads/Hk02wBqibe.png)


```cpp

ulong FUN_0050e711(long param_1,long *param_2,undefined1 *param_3)

{
  long *plVar1;
  long lVar2;
  long lVar3;
  long lVar4;
  undefined1 uVar5;
  int iVar6;
  long lVar7;
  long *plVar8;
  undefined8 uVar9;
  long lVar10;
  ulong uVar11;
  long lVar12;
  char *pcVar13;
  long lVar14;
  long *local_30;
  
  *param_3 = 0x50;
  plVar1 = *(long **)(param_1 + 0xa8);
  if ((plVar1 == (long *)0x0) || (*plVar1 == 0)) {
    uVar11 = 0;
    goto LAB_0050e8ef;
  }
  lVar10 = *param_2;
  lVar2 = *(long *)(lVar10 + 0x68);
  lVar7 = 0;
  if ((*(byte *)(lVar10 + 0xa4) & 1) == 0) {
    lVar14 = *(long *)(*(long *)(lVar10 + 0x30) + 0x110);
    lVar12 = 0;
    lVar7 = 0;
    if (lVar14 != 0) {
      lVar7 = 0;
      lVar12 = 0;
      if (*(int *)(*(long *)(lVar10 + 0x30) + 0xd0) == 2) {
        lVar12 = *(long *)(lVar14 + 0x5f0);
        lVar7 = *(long *)(lVar12 + 0x20);
        lVar12 = *(long *)(lVar12 + 0x28);
      }
    }
  }
  else {
    lVar12 = 0;
  }
  lVar14 = *(long *)(lVar2 + 0x60);
  lVar3 = *(long *)(*(long *)(param_2[1] + 0x20) + 0x58);
  lVar4 = *(long *)plVar1[1];
  plVar8 = (long *)FUN_004e807e();
  local_30 = plVar8;
  if (plVar8 == (long *)0x0) {
LAB_0050e8cc:
    FUN_004b812d(0x10,0xb,"../../third_party/boringssl/src/ssl/ssl_x509.cc",399);
LAB_0050e8e3:
    uVar11 = 0;
  }
  else {
    if (lVar3 != 0) {
      lVar14 = lVar3;
    }
    uVar9 = FUN_004e814c(plVar8,lVar14,lVar4,(long)plVar1);
    if ((int)uVar9 == 0) goto LAB_0050e8cc;
    uVar9 = FUN_004c0804(plVar8 + 0x1c,0,lVar10);
    if ((int)uVar9 == 0) goto LAB_0050e8cc;
    pcVar13 = "ssl_client";
    if ((*(byte *)(lVar10 + 0xa4) & 1) == 0) {
      pcVar13 = "ssl_server";
    }
    lVar10 = FUN_004ea63a(pcVar13);
    if (lVar10 == 0) goto LAB_0050e8cc;
    uVar9 = FUN_004ea256(plVar8[4],lVar10);
    if ((int)uVar9 == 0) goto LAB_0050e8cc;
    lVar10 = plVar8[4];
    lVar14 = *(long *)(param_2[1] + 0x10);
    uVar11 = *(ulong *)(lVar10 + 0x10);
    *(ulong *)(lVar10 + 0x10) = uVar11 | 1;
    uVar9 = FUN_004ea256(lVar10,lVar14);
    *(ulong *)(lVar10 + 0x10) = uVar11;
    if ((int)uVar9 == 0) goto LAB_0050e8cc;
    if (lVar12 != 0) {
      uVar9 = FUN_004ea580(plVar8[4],lVar7,lVar12);
      if ((int)uVar9 == 0) goto LAB_0050e8cc;
    }
    if (*(long *)(param_2[1] + 0x28) != 0) {
      plVar8[7] = *(long *)(param_2[1] + 0x28);
    }
    if (*(code **)(lVar2 + 0xb8) == (code *)0x0) {
      iVar6 = FUN_004e672e(plVar8);
    }
    else {
      iVar6 = (**(code **)(lVar2 + 0xb8))(plVar8,*(undefined8 *)(lVar2 + 0xc0));
    }
    lVar10 = (long)(int)plVar8[0x16];
    *(long *)(param_1 + 0xb8) = lVar10;
    if ((iVar6 < 1) && (*(char *)(param_2[1] + 0xe8) != '\0')) {
      uVar5 = 0x2e;
      if (lVar10 - 1U < 0x42) {
        uVar5 = *(undefined1 *)(&DAT_0028da08 + lVar10 * 2);
      }
      *param_3 = uVar5;
      goto LAB_0050e8e3;
    }
    FUN_004b80cb();
    uVar11 = CONCAT71((int7)((ulong)plVar8 >> 8),1);
  }
  FUN_0050e22e((long *)&local_30);
LAB_0050e8ef:
  return uVar11 & 0xffffffff;
}


```

để bypass thay đổi giá trị trả về của hàm thành 1 => biến `uVar11` thành 1

![image](https://hackmd.io/_uploads/BkyDhH5ibl.png)












```
frida -U -f eu.nviso.flutter_pinning -l .\test.js
```




```java
function hook_ssl_verify_result(address) {
  Interceptor.attach(address, {
    onEnter: function (args) {
      console.log('Disabling SSL validation');
    },
    onLeave: function (retval) {
      console.log('Retval: ' + retval);
      retval.replace(0x1);
    },
  });
}
function disablePinning() {
  var m = Process.findModuleByName('libflutter.so');
  var pattern =
    '55 41 57 41 56 41 55 41 54 53 48 83 ec 38 c6 02 50 48 8b af a8 00 00 00';
  var res = Memory.scan(m.base, m.size, pattern, {
    onMatch: function (address, size) {
      console.log('[+] ssl_verify_result found at: ' + address.toString());

      hook_ssl_verify_result(address.add(0x00));
    },
    onError: function (reason) {
      console.log('[!] There was an error scanning memory');
    },
    onComplete: function () {
      console.log('All done');
    },
  });
}
setTimeout(disablePinning, 1000);
```


![image](https://hackmd.io/_uploads/SyMVcS5jWg.png)


![image](https://hackmd.io/_uploads/SJOv5r5jZe.png)



Đoạn code khác tổng quát hơn 


```java
/**

A Frida script that disables Flutter's TLS verification

This script works on Android x86, Android x64 and iOS x64. It uses pattern matching to find [ssl_verify_peer_cert in handshake.cc](https://github.com/google/boringssl/blob/master/ssl/handshake.cc#L323)

If the script doesn't work, take a look at https://github.com/NVISOsecurity/disable-flutter-tls-verification#warning-what-if-this-script-doesnt-work 


*/

// Configuration object containing patterns to locate the ssl_verify_peer_cert function for different platforms and architectures.
var config = {
    "ios":{
        "modulename": "Flutter",
        "patterns":{
            "arm64": [
                // First pattern is actually for macos
                "FF 83 01 D1 FA 67 01 A9 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 FD 7B 05 A9 FD 43 01 91 F4 03 00 AA 68 31 00 F0 08 01 40 F9 08 01 40 F9 E8 07 00 F9",
                "FF 83 01 D1 FA 67 01 A9 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 FD 7B 05 A9 FD 43 01 91 F? 03 00 AA ?? 0? 40 F? ?8 ?? 40 F9 ?? ?? 4? F9 ?? 00 00",
                "FF 43 01 D1 F8 5F 01 A9 F6 57 02 A9 F4 4F 03 A9 FD 7B 04 A9 FD 03 01 91 F3 03 00 AA 14 00 40 F9 88 1A 40 F9 15 E9 40 F9 B5 00 00 B4 B6 46 40 F9"

            ],
        },
    },
    "android":{
        "modulename": "libflutter.so",
        "patterns":{
            "arm64": [
                "F? 0F 1C F8 F? 5? 01 A9 F? 5? 02 A9 F? ?? 03 A9 ?? ?? ?? ?? 68 1A 40 F9",
                "F? 43 01 D1 FE 67 01 A9 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 13 00 40 F9 F4 03 00 AA 68 1A 40 F9",
                "FF 43 01 D1 FE 67 01 A9 ?? ?? 06 94 ?? 7? 06 94 68 1A 40 F9 15 15 41 F9 B5 00 00 B4 B6 4A 40 F9",
                "FF C3 01 D1 FD 7B 01 A9 6A A1 0B 94 08 0A 80 52 48 00 00 39 1A 50 40 F9 DA 02 00 B4 48 03 40 F9"
            ],
            "arm": [
                "2D E9 F? 4? D0 F8 00 80 81 46 D8 F8 18 00 D0 F8",
            ],
            "x64": [
                "55 41 57 41 56 41 55 41 54 53 50 49 89 F? 4? 8B ?? 4? 8B 4? 30 4C 8B ?? ?? 0? 00 00 4D 85 ?? 74 1? 4D 8B",
                "55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FF 48 8B 1F 48 8B 43 30 4C 8B A0 28 02 00 00 4D 85 E4 74",
                "55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FE 4C 8B 27 49 8B 44 24 30 48 8B 98 D0 01 00 00 48 85 DB"
            ],
            "x86":[
                "55 89 E5 53 57 56 83 E4 F0 83 EC 20 E8 00 00 00 00 5B 81 C3 2B 79 66 00 8B 7D 08 8B 17 8B 42 18 8B 80 88 01"
            ]

        }
    },
    "windows": {
        "modulename": "flutter_windows.dll",
        "patterns":{
            "x64":[
                "41 57 41 56 41 55 41 54 56 57 53 48 83 EC 40 4? 89 CF 48 8B 05 ?? ?? ?? 00 48 31 E0 48 89 44 24 38 4? 8B 31 4? 8B",
                "41 57 41 56 41 55 41 54 56 57 55 53 48 83 EC 38 48 89 CF 48 8B 05 20 45 C6 00 48 31 E0 48 89 44 24 30 48 8B 31 48",
            ]
        }
    },
    "linux":{
        "modulename": "libflutter_linux_gtk.so",
        "patterns":{
            "x64":[
                // This one actually matches android x64 too
                "55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FE 4C 8B 27 49 8B 44 24 30 48 8B 98 D0 01 00 00 48 85 DB"
            ]
        }
    }
};

console.log("[+] Pattern version: Jan 26 2026")
console.log("[+] Arch:", Process.arch)
console.log("[+] Platform: ", Process.platform)
// Flag to check if TLS validation has already been disabled
var TLSValidationDisabled = false;
var flutterLibraryFound = false;
var tries = 0;
var maxTries = 5;
var timeout = 1000;
var androidBypass = false;
disableTLSValidation();


// Main function to disable TLS validation for Flutter
function disableTLSValidation() {

    // Stop if ready
    if (TLSValidationDisabled) return;

    tries ++;
    if(tries > maxTries && !androidBypass){
        console.warn(`\n`)
        console.warn('[!] Flutter library not found. Possible reasons:');
        console.warn('[!] - The application does not use Flutter');
        console.warn('[!] - The application has not loaded the Flutter library yet');
        console.warn('[!] - You are using an emulator + gadget (https://github.com/NVISOsecurity/disable-flutter-tls-verification/issues/43)');
        console.warn('[!] The script will continue, but is likely to fail');
        console.warn(`\n`)
        androidBypass = true;
    }else{
        // No module found yet
        if(m == null){
            if(androidBypass){
                // But we are in bypass mode and are looking for the ssl_verify_peer_certy anyway
                console.log(`[ ] Locating ssl_verify_peer_cert (${tries}/${maxTries})`)
            }
            else{
                // Still looking for flutter lib
                console.log(`[ ] Locating Flutter library ${tries}/${maxTries}`);
            }
        }
        else
        {
            // Module has been located
            console.log(`[ ] Locating ssl_verify_peer_cert (${tries}/${maxTries})`)
        }
    }
    

    // Figure out which patterns to use
    var platformConfig = {}
    if(Java.available){
        platformConfig = config["android"]
    }
    else if(Java.available || Swift.available){
        platformConfig = config["ios"]
    }
    else if(Process.platform in config){
        platformConfig = config[Process.platform]
    }
    else{
        console.log(`[!] Platform not supported: ${Process.platform}`)
    }

    var m = Process.findModuleByName(platformConfig["modulename"]);

    if (m === null && !androidBypass) {
        setTimeout(disableTLSValidation, timeout);
        return;
    }
    else{
        if(!androidBypass){
            console.log(`[+] Flutter library located`)
        }
        // reset counter so that searching for ssl_verify_peer_cert also gets x attempts
        if(flutterLibraryFound == false){
            flutterLibraryFound = true;
            tries = 0;
        }
    }

    if (Process.arch in platformConfig["patterns"])
    {
        var ranges;
        if(Java.available){
            // On Android, getting ranges from the loaded module is buggy, so we revert to Process.enumerateRanges
            ranges = Process.enumerateRanges({protection: 'r-x'}).filter(isFlutterRange)
        }else{
            // On iOS, there's no issue
            ranges = m.enumerateRanges('r-x')
        }

        findAndPatch(ranges, platformConfig["patterns"][Process.arch], Java.available && Process.arch == "arm" ? 1 : 0);
    }
    else
    {
        console.log('[!] Processor architecture not supported: ', Process.arch);
    }

    if (!TLSValidationDisabled)
    {        
        if (tries == maxTries)
        {
            if(androidBypass){
                console.warn(`\n`)
                console.warn(`[!] No function matching ssl_verify_peer_cert could be found.`)
                console.warn(`[!] If you are sure that the application is using Flutter, please open an issue:`)
                console.warn(`[!] https://github.com/NVISOsecurity/disable-flutter-tls-verification/issues`)
                console.warn(`\n`)
            }else{
                console.warn(`\n`)
                console.error(`[!] libFlutter was found, but ssl_verify_peer_cert could not be located`)
                console.error(`Please open an issue at https://github.com/NVISOsecurity/disable-flutter-tls-verification/issues`);
                console.warn(`\n`)
            }
            // Not really, but we give up
            TLSValidationDisabled = true
        }
    }
}

// Find and patch the method in memory to disable TLS validation
function findAndPatch(ranges, patterns, thumb) {
   
    ranges.forEach(range => {
        patterns.forEach(pattern => {
            var matches = Memory.scanSync(range.base, range.size, pattern);
            matches.forEach(match => {
                // CHỈ SỬA TẠI ĐÂY: Loại bỏ DebugSymbol.fromAddress để tránh crash SIGSEGV
                console.log(`[+] ssl_verify_peer_cert found at location: ${match.address}`);
                
                TLSValidationDisabled = true;
                hook_ssl_verify_peer_cert(match.address.add(thumb));
                console.log('[+] ssl_verify_peer_cert has been patched')
    
            });
            if(matches.length > 1){
                console.log('[!] Multiple matches detected. This can have a negative impact and may crash the app. Please open a ticket')
            }
        });
    });
    
    // Try again. disableTLSValidation will not do anything if TLSValidationDisabled = true
    setTimeout(disableTLSValidation, timeout);
}

function isFlutterRange(range){
    if(androidBypass) return true;

    var address = range.base;
    // Thay vì dùng DebugSymbol, ta kiểm tra trực tiếp qua tên Module nếu có thể
    var module = Process.findModuleByAddress(address);
    if (module != null && module.name.toLowerCase().includes("flutter")) {
        return true;
    }
    return false;
}

// Replace the target function's implementation to effectively disable the TLS check
function hook_ssl_verify_peer_cert(address) {
    Interceptor.replace(address, new NativeCallback((pathPtr, flags) => {
        return 0;
    }, 'int', ['pointer', 'int']));
}
```


```java
/**

A Frida script that disables Flutter's TLS verification

This script works on Android x86, Android x64 and iOS x64. It uses pattern matching to find [ssl_verify_peer_cert in handshake.cc](https://github.com/google/boringssl/blob/master/ssl/handshake.cc#L323)

If the script doesn't work, take a look at https://github.com/NVISOsecurity/disable-flutter-tls-verification#warning-what-if-this-script-doesnt-work 


*/

// Configuration object containing patterns to locate the ssl_verify_peer_cert function for different platforms and architectures.
var config = {
    "ios":{
        "modulename": "Flutter",
        "patterns":{
            "arm64": [
                // First pattern is actually for macos
                "FF 83 01 D1 FA 67 01 A9 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 FD 7B 05 A9 FD 43 01 91 F4 03 00 AA 68 31 00 F0 08 01 40 F9 08 01 40 F9 E8 07 00 F9",
                "FF 83 01 D1 FA 67 01 A9 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 FD 7B 05 A9 FD 43 01 91 F? 03 00 AA ?? 0? 40 F? ?8 ?? 40 F9 ?? ?? 4? F9 ?? 00 00",
                "FF 43 01 D1 F8 5F 01 A9 F6 57 02 A9 F4 4F 03 A9 FD 7B 04 A9 FD 03 01 91 F3 03 00 AA 14 00 40 F9 88 1A 40 F9 15 E9 40 F9 B5 00 00 B4 B6 46 40 F9"

            ],
        },
    },
    "android":{
        "modulename": "libflutter.so",
        "patterns":{
            "arm64": [
                "F? 0F 1C F8 F? 5? 01 A9 F? 5? 02 A9 F? ?? 03 A9 ?? ?? ?? ?? 68 1A 40 F9",
                "F? 43 01 D1 FE 67 01 A9 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 13 00 40 F9 F4 03 00 AA 68 1A 40 F9",
                "FF 43 01 D1 FE 67 01 A9 ?? ?? 06 94 ?? 7? 06 94 68 1A 40 F9 15 15 41 F9 B5 00 00 B4 B6 4A 40 F9",
                "FF C3 01 D1 FD 7B 01 A9 6A A1 0B 94 08 0A 80 52 48 00 00 39 1A 50 40 F9 DA 02 00 B4 48 03 40 F9"
            ],
            "arm": [
                "2D E9 F? 4? D0 F8 00 80 81 46 D8 F8 18 00 D0 F8",
            ],
            "x64": [
                "55 41 57 41 56 41 55 41 54 53 50 49 89 F? 4? 8B ?? 4? 8B 4? 30 4C 8B ?? ?? 0? 00 00 4D 85 ?? 74 1? 4D 8B",
                "55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FF 48 8B 1F 48 8B 43 30 4C 8B A0 28 02 00 00 4D 85 E4 74",
                "55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FE 4C 8B 27 49 8B 44 24 30 48 8B 98 D0 01 00 00 48 85 DB"
            ],
            "x86":[
                "55 89 E5 53 57 56 83 E4 F0 83 EC 20 E8 00 00 00 00 5B 81 C3 2B 79 66 00 8B 7D 08 8B 17 8B 42 18 8B 80 88 01"
            ]

        }
    },
    "windows": {
        "modulename": "flutter_windows.dll",
        "patterns":{
            "x64":[
                "41 57 41 56 41 55 41 54 56 57 53 48 83 EC 40 4? 89 CF 48 8B 05 ?? ?? ?? 00 48 31 E0 48 89 44 24 38 4? 8B 31 4? 8B",
                "41 57 41 56 41 55 41 54 56 57 55 53 48 83 EC 38 48 89 CF 48 8B 05 20 45 C6 00 48 31 E0 48 89 44 24 30 48 8B 31 48",
            ]
        }
    },
    "linux":{
        "modulename": "libflutter_linux_gtk.so",
        "patterns":{
            "x64":[
                // This one actually matches android x64 too
                "55 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 89 FE 4C 8B 27 49 8B 44 24 30 48 8B 98 D0 01 00 00 48 85 DB"
            ]
        }
    }
};

console.log("[+] Pattern version: Jan 26 2026")
console.log("[+] Arch:", Process.arch)
console.log("[+] Platform: ", Process.platform)
// Flag to check if TLS validation has already been disabled
var TLSValidationDisabled = false;
var flutterLibraryFound = false;
var tries = 0;
var maxTries = 5;
var timeout = 1000;
var androidBypass = false;
disableTLSValidation();


// Main function to disable TLS validation for Flutter
function disableTLSValidation() {

    // Stop if ready
    if (TLSValidationDisabled) return;

    tries ++;
    if(tries > maxTries && !androidBypass){
        console.warn(`\n`)
        console.warn('[!] Flutter library not found. Possible reasons:');
        console.warn('[!] - The application does not use Flutter');
        console.warn('[!] - The application has not loaded the Flutter library yet');
        console.warn('[!] - You are using an emulator + gadget (https://github.com/NVISOsecurity/disable-flutter-tls-verification/issues/43)');
        console.warn('[!] The script will continue, but is likely to fail');
        console.warn(`\n`)
        androidBypass = true;
    }else{
        // No module found yet
        if(m == null){
            if(androidBypass){
                // But we are in bypass mode and are looking for the ssl_verify_peer_certy anyway
                console.log(`[ ] Locating ssl_verify_peer_cert (${tries}/${maxTries})`)
            }
            else{
                // Still looking for flutter lib
                console.log(`[ ] Locating Flutter library ${tries}/${maxTries}`);
            }
        }
        else
        {
            // Module has been located
            console.log(`[ ] Locating ssl_verify_peer_cert (${tries}/${maxTries})`)
        }
    }
    

    // Figure out which patterns to use
    var platformConfig = {}
    if(Java.available){
        platformConfig = config["android"]
    }
    else if(Java.available || Swift.available){
        platformConfig = config["ios"]
    }
    else if(Process.platform in config){
        platformConfig = config[Process.platform]
    }
    else{
        console.log(`[!] Platform not supported: ${Process.platform}`)
    }

    var m = Process.findModuleByName(platformConfig["modulename"]);

    if (m === null && !androidBypass) {
        setTimeout(disableTLSValidation, timeout);
        return;
    }
    else{
        if(!androidBypass){
            console.log(`[+] Flutter library located`)
        }
        // reset counter so that searching for ssl_verify_peer_cert also gets x attempts
        if(flutterLibraryFound == false){
            flutterLibraryFound = true;
            tries = 0;
        }
    }

    if (Process.arch in platformConfig["patterns"])
    {
        var ranges;
        if(Java.available){
            // On Android, getting ranges from the loaded module is buggy, so we revert to Process.enumerateRanges
            ranges = Process.enumerateRanges({protection: 'r-x'}).filter(isFlutterRange)
        }else{
            // On iOS, there's no issue
            ranges = m.enumerateRanges('r-x')
        }

        findAndPatch(ranges, platformConfig["patterns"][Process.arch], Java.available && Process.arch == "arm" ? 1 : 0);
    }
    else
    {
        console.log('[!] Processor architecture not supported: ', Process.arch);
    }

    if (!TLSValidationDisabled)
    {        
        if (tries == maxTries)
        {
            if(androidBypass){
                console.warn(`\n`)
                console.warn(`[!] No function matching ssl_verify_peer_cert could be found.`)
                console.warn(`[!] If you are sure that the application is using Flutter, please open an issue:`)
                console.warn(`[!] https://github.com/NVISOsecurity/disable-flutter-tls-verification/issues`)
                console.warn(`\n`)
            }else{
                console.warn(`\n`)
                console.error(`[!] libFlutter was found, but ssl_verify_peer_cert could not be located`)
                console.error(`Please open an issue at https://github.com/NVISOsecurity/disable-flutter-tls-verification/issues`);
                console.warn(`\n`)
            }
            // Not really, but we give up
            TLSValidationDisabled = true
        }
    }
}

// Find and patch the method in memory to disable TLS validation
function findAndPatch(ranges, patterns, thumb) {
   
    ranges.forEach(range => {
        patterns.forEach(pattern => {
            var matches = Memory.scanSync(range.base, range.size, pattern);
            matches.forEach(match => {
                var info = DebugSymbol.fromAddress(match.address)
                if(info.name){
                    console.log(`[+] ssl_verify_peer_cert found at offset: ${info.name || match.address}`);
                }else{

                    console.log(`[+] ssl_verify_peer_cert found at location: ${match.address}`);
                }
                TLSValidationDisabled = true;
                hook_ssl_verify_peer_cert(match.address.add(thumb));
                console.log('[+] ssl_verify_peer_cert has been patched')
    
            });
            if(matches.length > 1){
                console.log('[!] Multiple matches detected. This can have a negative impact and may crash the app. Please open a ticket')
            }
        });
        
    });
    
    // Try again. disableTLSValidation will not do anything if TLSValidationDisabled = true
    setTimeout(disableTLSValidation, timeout);
}

function isFlutterRange(range){
    if(androidBypass) return true;

    var address = range.base
    var info = DebugSymbol.fromAddress(address)
    if(info.moduleName != null){
        if(info.moduleName.toLowerCase().includes("flutter")){
            return true;
        }
    }
    return false;
}

// Replace the target function's implementation to effectively disable the TLS check
function hook_ssl_verify_peer_cert(address) {
    Interceptor.replace(address, new NativeCallback((pathPtr, flags) => {
        return 0;
    }, 'int', ['pointer', 'int']));
}
```




Hoặc dùng đoạn code share sau 

```
frida -U --codeshare TheDauntless/disable-flutter-tls-v1 -f eu.nviso.flutter_pinning
```


```
PS E:\Learn\learn\flutter> frida -U --codeshare TheDauntless/disable-flutter-tls-v1 -f eu.nviso.flutter_pinning
     ____
    / _  |   Frida 16.1.4 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to Android Emulator 5554 (id=emulator-5554)
Spawning `eu.nviso.flutter_pinning`...
Hello! This is the first time you're running this particular snippet, or the snippet's source code has changed.

Project Name: disable-flutter-tls-v1
Author: @TheDauntless
Slug: TheDauntless/disable-flutter-tls-v1
Fingerprint: 3bab62e72ec01060a0b5e81a5e894641e35ac6cb1b8f96a4f94444625dbf35a2
URL: https://codeshare.frida.re/@TheDauntless/disable-flutter-tls-v1

Are you sure you'd like to trust this project? [y/N] y
Adding fingerprint 3bab62e72ec01060a0b5e81a5e894641e35ac6cb1b8f96a4f94444625dbf35a2 to the trust store! You won't be prompted again unless the code changes.
[+] Pattern version: Jan 26 2026
[+] Arch: x64
[+] Platform:  linux
[ ] Locating Flutter library 1/5
Spawned `eu.nviso.flutter_pinning`. Resuming main thread!
[Android Emulator 5554::eu.nviso.flutter_pinning ]-> [ ] Locating Flutter library 2/5
[+] Flutter library located
[+] ssl_verify_peer_cert found at offset: 0x3faec6
[+] ssl_verify_peer_cert has been patched
[Android Emulator 5554::eu.nviso.flutter_pinning ]->
[Android Emulator 5554::eu.nviso.flutter_pinning ]->
```

## Bypass bằng reflutter

- https://github.com/Impact-I/reFlutter
```
pip3 install reflutter==0.8.6
reflutter .\pinning.apk

```

![image](https://hackmd.io/_uploads/r1nytUqj-l.png)

cấu hình theo như chỉ dẫn

![image](https://hackmd.io/_uploads/SJHVYLqsbx.png)

![image](https://hackmd.io/_uploads/rkq_YLqs-l.png)

tải uber
https://github.com/patrickfav/uber-apk-signer/releases/tag/v1.2.1


![image](https://hackmd.io/_uploads/S1Sm9Lqobl.png)

![image](https://hackmd.io/_uploads/rk-Uh85sZe.png)

tải file `release.RE-aligned-debugSigned.apk` và thấy với case này thì:
✅ Phải dùng Frida hook runtime
❌ reFlutter không đủ

![image](https://hackmd.io/_uploads/Hkpo5Hqjbx.png)

![image](https://hackmd.io/_uploads/SJoa5rqsZx.png)