patch_va39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
#!/usr/bin/env python3
"""
VA39 patch for the Antigravity linux_arm64 binary on Chromebook/Crostini.
Scans instruction patterns to patch TCMalloc for a 39-bit
virtual address space instead of the default 48-bit, fixing
the MmapAligned() crash. """
import
hashlib
import
shutil
import
struct
import
sys
from
pathlib
import
Path
src
Path ( sys . argv [ 1 ] if
len ( sys . argv )
1
else
"/usr/local/bin/agy"
) dst
Path ( str ( src ) +
".va39"
) if
not
src . exists
(): raise
SystemExit ( f"Input binary does not exist: { src } "
) print ( f"Input binary : { src } "
) print ( f"SHA256 in : { hashlib . sha256 ( src . read_bytes ()). hexdigest
()
}
\n "
) shutil . copyfile ( src , dst
) data
bytearray ( dst . read_bytes
()) def
get ( off
): return
struct . unpack_from ( "<I" , data , off )[ 0
] def
put ( off , word
): struct . pack_into ( "<I" , data , off , word
) lo , hi
0 , len ( data
) if
data [: 4
b" \x7f ELF" :
e_shoff
struct . unpack_from ( "<Q" , data , 40 )[ 0
] e_shentsize
struct . unpack_from ( "<H" , data , 58 )[ 0
] e_shnum
struct . unpack_from ( "<H" , data , 60 )[ 0
] e_shstrndx
struct . unpack_from ( "<H" , data , 62 )[ 0
] shstr_base
e_shoff
e_shstrndx
e_shentsize
shstr_off
struct . unpack_from ( "<Q" , data , shstr_base
24 )[ 0
] for
i
in
range ( e_shnum
): base
e_shoff
i
e_shentsize
sh_name
struct . unpack_from ( "<I" , data , base )[ 0
] sh_offset
struct . unpack_from ( "<Q" , data , base
24 )[ 0
] sh_size
struct . unpack_from ( "<Q" , data , base
32 )[ 0
] try :
nend
data . index ( b" \x00 " , shstr_off
sh_name
) section
data [ shstr_off
sh_name : nend ]. decode ( "utf-8"
) if
section
"google_malloc" :
lo , hi
sh_offset , sh_offset
sh_size
print ( f"Found google_malloc section: 0x { lo :x }
- 0x { hi :x } "
) break
except
ValueError :
pass
ubfx_count , lsl_count
0 , 0
for
off
in
range ( lo , hi , 4
): w
get ( off
) if ( w
&
0x7F800000
0x53000000 :
immr , imms
( w
16 ) &
0x3F , ( w
10 ) &
0x3F
if
immr
42
and
imms
44 :
put ( off , ( w
&
~ (( 0x3F
<<
16 ) | ( 0x3F
<<
10 ))) | ( 35
<<
16 ) | ( 37
<<
10
)) ubfx_count
+=
1
elif
immr
22
and
imms
21 :
put ( off , ( w
&
~ (( 0x3F
<<
16 ) | ( 0x3F
<<
10 ))) | ( 29
<<
16 ) | ( 28
<<
10
)) lsl_count
+=
1
(
f"[1] ubfx patches :
{
ubfx_count } \n
lsl patches :
{
lsl_count } "
) mask_count
0
for
off
in
range ( lo , hi
4 , 4
): if
get ( off
0x92D3800A
and
get ( off
4
0xF2E0000A :
put ( off , 0x9280000A
) put ( off
4 , 0xD35DFD4A
) mask_count
+=
1
(
f"[2] Random mask :
{
mask_count } "
) mmap_count
0
for
off
in
range ( lo , hi , 4
): if
get ( off
0xF2E00029 :
put ( off , 0xD3596129
) mmap_count
+=
1
(
f"[3] MmapAligned :
{
mmap_count } "
) word_rewrites
{ 0xD2C20009 : 0xD2C00409 , 0xD2C2000A : 0xD2C0040A , 0xF2C20008 : 0xF2DFF408 ,
0xF2C20009 : 0xF2DFF409 , 0xD2C10009 : 0xD2C00209 , 0xD2C1000A : 0xD2C0020A ,
0xF2C38008 : 0xF2DFF708 , 0xF2C38009 : 0xF2DFF709 , 0x92560A6C : 0x925D0A6C ,
0x92560A6A : 0x925D0A6A , 0xD2C3000D : 0xD2C0060D , 0xD2C3000C : 0xD2C0060C ,
0xD2C08008 : 0xD2C00108 ,
} counts
{ old : 0
for
old
in
word_rewrites
} for
off
in
range ( lo , hi , 4
): w
get ( off
) if
w
in
word_rewrites :
put ( off , word_rewrites [ w
]) counts [ w ] +=
1
(
f"[4] Tag constants:
{
sum ( counts . values
())
}
words rewritten"
) dst . write_bytes ( data
) dst . chmod ( 0o755
) print ( f" \n SHA256 out : { hashlib . sha256 ( dst . read_bytes ()). hexdigest
()
}
"
) print ( f"Output : { dst } \n "
) if
ubfx_count
0
or
mask_count
0 :
print ( "WARNING: No patches applied - binary structure may have changed."
) else :
print ( "Patch looks complete. To replace original and test:"
) print ( f" sudo mv { dst
}
{
src } "
)
print
(
f"
{
src
}
--version"
)