How To Guide The Definitive TTL patch

Search This thread

Zibri

Senior Member
Dec 10, 2010
359
114
My apologies. I just wanted confirmation before flashing since I only saw 4 lines of code.

I just tested it on my Galaxy Tab S5e and it works flawlessly. 55TTL on both device and client.


Thanks so much for your help!
hehehe my programs tend to be minimalistic... I know...
No need to apologize... I should have stated it somewhere.
With a fifth line of code it should become compatible with 99% of phones... but I prefer to do this in steps.
Please spread the link to this post on galaxy tab related forums or subforums.
 

Zibri

Senior Member
Dec 10, 2010
359
114
Really cool approach, I like how simple it is and that it's handled in kernel space.

I think with a little more effort we could patch
C:
u32 check = (__force u32)iph->check;
check += (__force u32)htons(0x0100);
iph->check = (__force __sum16)(check + (check>=0xFFFF));
return --iph->ttl;
to
C:
iph->ttl = 64;
ip_send_check(iph);
return iph->ttl;
and get behavior very similar to the xt_HL module. Would just require the patcher to search for the ip_send_check function address so the branch could be calculated.
It is very easy to patch it for a fixed TTL, but I personally dont like it.
Sometimes TTL is used to slow down tethered connections, not to block them.
In that case, it is useful sometimes to have a higher TTL for testing...
I don't like restrictions.
 

fddm

Senior Member
Feb 24, 2011
310
195
It looks like it works fine for ICMP, but testing with standard TCP web traffic, it only affects initial and final packets with the SYN and FIN flags. Suppose it might still trick some carrier DPI, idk. I also tried patching the decrements in ipv6_forward and ipv6_rthdr_rcv to no effect so far.
 

Zibri

Senior Member
Dec 10, 2010
359
114
It looks like it works fine for ICMP, but testing with standard TCP web traffic, it only affects initial and final packets with the SYN and FIN flags. Suppose it might still trick some carrier DPI, idk. I also tried patching the decrements in ipv6_forward and ipv6_rthdr_rcv to no effect so far.
I don't know why you say that.
TTL is just not decreased.
TTL is in ICMP and TCP packets.
I didn't patch ipv6 but it would be as easy as adding another 4 lines to the code.
 

fddm

Senior Member
Feb 24, 2011
310
195
I don't know why you say that.
TTL is just not decreased.
TTL is in ICMP and TCP packets.
I didn't patch ipv6 but it would be as easy as adding another 4 lines to the code.
I retested with with an older device that uses a 4.19 kernel and did not see the same behavior, all TCP packets look to have the expected TTL values with the patch applied. Seems to be some optimization in the 5.4 kernel where intermediate packets in a TCP flow do not take the same ip_forward -> ip_decrease_ttl code path. Toggling the 'Tethering hardware acceleration' option in Developer options had no effect in my testing.
 

Zibri

Senior Member
Dec 10, 2010
359
114
I retested with with an older device that uses a 4.19 kernel and did not see the same behavior, all TCP packets look to have the expected TTL values with the patch applied. Seems to be some optimization in the 5.4 kernel where intermediate packets in a TCP flow do not take the same ip_forward -> ip_decrease_ttl code path. Toggling the 'Tethering hardware acceleration' option in Developer options had no effect in my testing.
No idea.. on the latest MIUI 13 for redmi note 10 pro it just works perfectly.
And so it does on the other phones tested.
 

zuberuddinmd

New member
Feb 22, 2023
2
1
After trying nfqttl and failing, I decided to go on my way and, in the process, I found the definitive solution.

Steps:

1) unpack boot.img
2) patch kernel image
3) repack boot.img

Flash :D

the patch is simple:
In the linux kernet in ip_forward.c this function is called to decrease the TTL of every forwarded packet:
static __always_inline int ip_decrease_ttl(struct iphdr *iph)
{
u32 check = (__force u32)iph->check;
check += (__force u32)htons(0x0100);
iph->check = (__force __sum16)(check + (check >= 0xFFFF));
return --iph->ttl;
}

All I did is to patch the kernel not to do so.

return iph->ttl;

You can easily do it in this way:

Bash:
magiskboot unpack -h boot.img
magiskboot hexpatch kernel C9220039C816007968F24039E8002836 1F2003D51F2003D568F24039E8002836  # tested on Redmi Note 10 Pro
magiskboot hexpatch kernel A0160079A022403900040051A0220039 1F2003D5A0224039000400511F2003D5 # tested on Redmi 4X
magiskboot repack boot.img

Then you can just boot it (for testing) or flash it directly.

fastboot boot new-boot.img
or
fastboot flash boot new-boot.img

result:
pinging google from the phone:
Bash:
$ ping google.com
PING google.com (142.250.179.142) 56(84) bytes of data.
64 bytes from ams17s10-in-f14.1e100.net (142.250.179.142): icmp_seq=1 ttl=106 time=115 ms

pinging google from windows connected to the phone (works both with wifi or usb tethering)
Code:
C:\>ping 142.250.179.142


Pinging 142.250.179.142 with 32 bytes of data:
Reply from 142.250.179.142: bytes=32 time=127ms TTL=106


As you can see the TTL is the same.
Before the patch it's one less, obviously.

Magisk module:

If you have magisk installed you can also just copy and paste this line of code in your adb shell:

Install patch:
Bash:
su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/customize.sh | sh"

Remove patch:
Bash:
su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/remove.sh | sh"
Hi Zibri,

Forgive me if I'm asking a silly question, but I've tried your solution and it's not working for me. I'm assuming I might've done something wrong because of which the TTL value is always decremented if I'm pinging the same IP address when tethered to my mobile.

I downloaded the TTL fix module for Magisk and installed it successfully. The installation was successful and the phone rebooted as well. However TTL value is still decremented.

Tried executing via bash script command and got the following response after a series of commands.
"<--[94m[!] Patch not installed. <--[39m"

I've currently installed Lineage OS 18.1 on my MI A2 using the boot.img and LOS 18.1 zip file from official Lineage OS Site. Upon checking the Kernel is of type Linux version 4.4.302.

Attaching the following files in the Drive. Kindly support in fixing the issue.
1. ADB shell error screenshot
2. boot.img file from Lineage OS Site
3. boot partition backups obtained via wanam app.


Regards
 

Attachments

  • ADB Shell error.PNG
    ADB Shell error.PNG
    22.8 KB · Views: 20
  • boot.img
    23 MB · Views: 5
  • boot_a_backup_2023-02-22_08-12-33.tar.gz
    22.5 MB · Views: 0
  • boot_b_backup_2023-02-22_08-12-33.tar.gz
    31.2 MB · Views: 3

Zibri

Senior Member
Dec 10, 2010
359
114
@zuberuddinmd Done.
I updated it. Now it supports also Lineage OS.
Please check the end of the first post, you can do this manually or redownload the new zip.
Please share this on Lineage OS related forums.
 
Last edited:
  • Like
Reactions: zuberuddinmd

Forelo

New member
Mar 4, 2023
1
0
In short, everything works, put it through magisk, samsung A01.

Крч всё работает, ставил через магиск, апарат samsung A01

Mod. edit: post translated. alecxs
 
Last edited by a moderator:

akubaek

Senior Member
Jun 5, 2013
137
6
C:\platform-tools>adb shell
[email protected]:/ $ su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/customize.sh | sh"
conv=4
131072+0 records in
131072+0 records out
67108864 bytes (64 M) copied, 0.260105 s, 246 M/s
Parsing boot image: [/data/local/tmp/ttl_fix/boot.img]
HEADER_VER [4]
KERNEL_SZ [21474710]
RAMDISK_SZ [484863]
PAGESIZE [4096]
CMDLINE []
KERNEL_FMT [lz4_legacy]
RAMDISK_FMT [lz4_legacy]
VBMETA
Patch @ 00EE10A0 [08050011C9220039C8160079687A4079] -> [080500111F2003D51F2003D5687A4079]
Parsing boot image: [/data/local/tmp/ttl_fix/boot.img]
HEADER_VER [4]
KERNEL_SZ [21474710]
RAMDISK_SZ [484863]
PAGESIZE [4096]
CMDLINE []
KERNEL_FMT [lz4_legacy]
RAMDISK_FMT [lz4_legacy]
VBMETA
Repack to boot image: [new.img]
HEADER_VER [4]
KERNEL_SZ [21474705]
RAMDISK_SZ [484863]
PAGESIZE [4096]
CMDLINE []
conv=4
131072+0 records in
131072+0 records out
67108864 bytes (64 M) copied, 7.020278 s, 9.1 M/s
[!] Patch installed.

i run the command through adb shell and its say connected my devices is pixel 6. but the hotspot still cannot access

C:\platform-tools>
 
Last edited:

dDoctar

Member
Oct 21, 2022
11
7
sun, moonway
The patch already works for your kernel. You must patch boot.img not the init one.
Am I doing something wrong? I am currently using pixel 7 pro, feb 23 update on Radioactive kernel https://forum.xda-developers.com/t/...-2023-02-08-unified-pixel7-pixel7pro.4543551/ .
Successfully Flashed your mod using magisk as instructed, but hotspot speed on other devices are still being throttled. Tried first on stock kernel with nil result either. Can you please guide me if Im doing something wrong?
 

Zibri

Senior Member
Dec 10, 2010
359
114
Am I doing something wrong? I am currently using pixel 7 pro, feb 23 update on Radioactive kernel https://forum.xda-developers.com/t/...-2023-02-08-unified-pixel7-pixel7pro.4543551/ .
Successfully Flashed your mod using magisk as instructed, but hotspot speed on other devices are still being throttled. Tried first on stock kernel with nil result either. Can you please guide me if Im doing something wrong?
Sorry.. I can't support each and every kernel..
read the first post.
First connect with adb and try this:
Code:
su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/remove.sh | sh"
[the phone will reboot] or FAIL.
If it fails your kernel is not supported at the moment.
If it reboots, it worked.

then from adb ping an IP address (any) outside your lan.
then from another device connected to the hotspot on your phone try to ping the same ip address (not name!)
the TTL value should be the same.
 

yeagoer

New member
Apr 7, 2023
3
0
ive had zero luck with the oneplus 11 and this module. here is the boot.img if you need to reverse engeneer. i cant seem to find any of the hex patterns the scripts look for. im aware this if for a different device but the github doesnt allow any issues and there are no other threads.
 

Attachments

  • boot.img
    192 MB · Views: 7

fddm

Senior Member
Feb 24, 2011
310
195
I got a patch request in my PMs, so I'm sharing the patcher I wrote so people can do it themselves. It's a generic patcher that should work for the vast majority of devices, but only supports ARM64 little-endian kernels. This does the TTL 64 patch rather than the decrement patch from the OP. Run the patcher with Python 3 in the same directory you unpacked your boot image with magiskboot to patch. You can do this on your computer or with the Termux app from F-Droid after installing the python3 package.
Code:
$ python3 ttl_patcher.py
Opening file 'kernel' for patching...
ip_send_check signature matched - 0x1054680 - ['1f140079', '08400091', '0a004039', '093040a9']
ip_decrease_ttl signature matched - 0x1052ecc - ['678a4179', 'a0ff9f52', '1601078b', 'c3164079', 'c1224039', '7f00006b', '6094831a', '02040011', '
23040051', 'c2160079', 'c3220039']
678a4179a0ff9f521601078bc3164079c12240397f00006b6094831a0204001123040051c2160079c3220039
678a41791601078b08088052e00316aac8220039e80500941f2003d51f2003d51f2003d51f2003d51f2003d5
File patched! Saved to 'kernel.patched'
It generates the byte patches found and a patched kernel named 'kernel.patched'. Rename it to 'kernel' before repacking. It will patch 5.x kernels without complaining, but only partially works in my testing.
Edit: improved patch generation
 

Attachments

  • ttl_patcher.zip
    2.7 KB · Views: 15
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 2
    After searching through the source code, I found that starting with Android 12 they added IPv4 decrement to the tethering eBPF program here. I think the bpf iptables rules could probably be removed so it's only handled in the kernel or the bytecode could be patched in /system/apex/com.android.tethering/etc/bpf/offload.o
    Code:
    const int sz2 = sizeof(__be16);
    const __be16 old_ttl_proto = *(__be16 *)&ip->ttl;
    const __be16 new_ttl_proto = old_ttl_proto - htons(0x0100);
    bpf_l3_csum_replace(skb, ETH_IP4_OFFSET(check), old_ttl_proto, new_ttl_proto, sz2);
    bpf_skb_store_bytes(skb, ETH_IP4_OFFSET(ttl), &new_ttl_proto, sz2, 0);
    From the source level, we could patch new_ttl_proto to something like this
    Code:
    const __be16 new_ttl_proto = htons(0x4000) + (old_ttl_proto & 0xff)
    But that probably needs too many bytes so instead the entire function could be replaced with
    Code:
    const int sz2 = sizeof(__u8);
    const __u8 new_ttl_proto = 0x40
    bpf_skb_store_bytes(skb, ETH_IP4_OFFSET(ttl), &new_ttl_proto, sz2, BPF_F_RECOMPUTE_CSUM);
    This is also where the HL decrement is and probably why overriding from the kernel has never worked for TCP/UDP traffic.
  • 8
    After trying nfqttl and failing, I decided to go on my way and, in the process, I found the definitive solution.

    Steps:

    1) unpack boot.img
    2) patch kernel image
    3) repack boot.img

    Flash :D

    the patch is simple:
    In the linux kernet in ip_forward.c this function is called to decrease the TTL of every forwarded packet:
    static __always_inline int ip_decrease_ttl(struct iphdr *iph)
    {
    u32 check = (__force u32)iph->check;
    check += (__force u32)htons(0x0100);
    iph->check = (__force __sum16)(check + (check >= 0xFFFF));
    return --iph->ttl;
    }

    All I did is to patch the kernel not to do so.

    return iph->ttl;

    You can easily do it in this way:

    Bash:
    magiskboot unpack -h boot.img
    magiskboot hexpatch kernel C9220039C816007968F24039E8002836 1F2003D51F2003D568F24039E8002836  # tested on Redmi Note 10 Pro
    magiskboot hexpatch kernel A0160079A022403900040051A0220039 1F2003D5A0224039000400511F2003D5 # tested on Redmi 4X
    magiskboot repack boot.img

    Then you can just boot it (for testing) or flash it directly.

    fastboot boot new-boot.img
    or
    fastboot flash boot new-boot.img

    result:
    pinging google from the phone:
    Bash:
    $ ping google.com
    PING google.com (142.250.179.142) 56(84) bytes of data.
    64 bytes from ams17s10-in-f14.1e100.net (142.250.179.142): icmp_seq=1 ttl=106 time=115 ms

    pinging google from windows connected to the phone (works both with wifi or usb tethering)
    Code:
    C:\>ping 142.250.179.142
    
    
    Pinging 142.250.179.142 with 32 bytes of data:
    Reply from 142.250.179.142: bytes=32 time=127ms TTL=106


    As you can see the TTL is the same.
    Before the patch it's one less, obviously.

    Magisk module:

    If you have magisk installed you can also just copy and paste this line of code in your adb shell:

    Install patch:
    Bash:
    su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/customize.sh | sh"

    Remove patch:
    Bash:
    su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/remove.sh | sh"
    3
    if you have magisk installed, you can also just download an run only the script:

    Install patch:
    Bash:
    su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/customize.sh | sh"

    Remove patch:
    Bash:
    su -c "curl -s https://raw.githubusercontent.com/Zibri/ttl_fix/master/remove.sh | sh"

    (it's even easier)

    And merry Christmas to everybody!

    if you get "[!] Patch not applied." it can mean 2 things:
    1) you already applied it.
    2) your phone is not yet supported.
    in that case you can send me in a private message your "boot.img" which you will find in /data/local/tmp/ttl_fix/boot.img and I can add a patch for your phone.
    3
    I got a patch request in my PMs, so I'm sharing the patcher I wrote so people can do it themselves. It's a generic patcher that should work for the vast majority of devices, but only supports ARM64 little-endian kernels. This does the TTL 64 patch rather than the decrement patch from the OP. Run the patcher with Python 3 in the same directory you unpacked your boot image with magiskboot to patch. You can do this on your computer or with the Termux app from F-Droid after installing the python3 package.
    Code:
    $ python3 ttl_patcher.py
    Opening file 'kernel' for patching...
    ip_send_check signature matched - 0x1054680 - ['1f140079', '08400091', '0a004039', '093040a9']
    ip_decrease_ttl signature matched - 0x1052ecc - ['678a4179', 'a0ff9f52', '1601078b', 'c3164079', 'c1224039', '7f00006b', '6094831a', '02040011', '
    23040051', 'c2160079', 'c3220039']
    678a4179a0ff9f521601078bc3164079c12240397f00006b6094831a0204001123040051c2160079c3220039
    678a41791601078b08088052e00316aac8220039e80500941f2003d51f2003d51f2003d51f2003d51f2003d5
    File patched! Saved to 'kernel.patched'
    It generates the byte patches found and a patched kernel named 'kernel.patched'. Rename it to 'kernel' before repacking. It will patch 5.x kernels without complaining, but only partially works in my testing.
    Edit: improved patch generation
    2
    how to run/execute? :
    magiskboot unpack -h boot.img
    magiskboot hexpatch kernel C9220039C816007968F24039E8002836 1F2003D51F2003D568F24039E8002836
    magiskboot repack boot.img
    i try via adb but failed.
    here you go...
    magisk module just made.. please tell me if there are any problems.