Hacking API i Përkthimit Google

Google ofron API të Përkthimit Google me një strukturë kostoje të bazuar në përdorim si pjesë e Google Cloud. Ekziston edhe një API e padokumentuar që mund të përdoret pa një çelës , por që refuzon të funksionojë pas vetëm disa kërkesave. Kur përdorni funksionin e përkthimit të faqesinternet të Google Chrome, vërehet se faqet mund të përkthehen me cilësi shumë të mirë pa ndonjë kufizim të dukshëm.


Me sa duket modeli i përparuar nmt tashmë po përdoret këtu. Por cilin API përdor Google Chrome brenda për të përkthyer përmbajtjen dhe a mundet që ky API të adresohet drejtpërdrejt - madje edhe nga ana e serverit? Për të analizuar trafikun e rrjetit, rekomandohen mjete si Wireshark ose Telerik Fiddler , të cilat gjithashtu mund të analizojnë trafikun e koduar. Por Chrome madje sjell kërkesat që dërgon për përkthimin e faqes falas: Ato mund të shihen lehtësisht duke përdorur Chrome DevTools:

Nëse kryeni një përkthim, atëherë kapni kërkesën thelbësore POST tek https://translate.googleapis.com përmes "Kopjo> Kopjo si cURL (bash)" dhe ekzekutojeni atë në një mjet si Postman , për shembull, mund ta dërgoni përsëri kërkesën pa ndonjë problem:

Kuptimi i parametrave të URL-së është gjithashtu kryesisht i dukshëm:

CelësVlera ShembullKuptimi
anon3Modaliteti i shënimit (ndikon në formatin e kthimit)
klientte_libInformacioni i klientit (ndryshon, vlera është "webapp" përmes ndërfaqes së internetit të Google Translate; ka një efekt në formatin e kthimit dhe kufizimin e normës)
formatinhtmlFormati i vargut (i rëndësishëm për përkthimin e etiketave HTML)
v1.0Numri i versionit Google Përkthe
CelësAIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgwÇelësi API (shih më poshtë)
logldvTE_20200210_00Versioni i protokollit
sldeGjuha burimore
tlenGjuha e synuar
spnmtModeli ML
tc1i panjohur
sr1i panjohur
tk709408.812158Shenjë (shih më poshtë)
Modës1i panjohur

Disa kryefjalë të kërkesave janë vendosur gjithashtu - por këto kryesisht mund të injorohen. Pasi të keni zgjedhur manualisht të gjitha kokat, duke përfshirë ato nga agjenti i përdoruesit , zbulohet një problem i kodimit kur futni karaktere speciale (këtu kur përktheni " Hello World "):

Nëse riaktivizoni agjentin e përdoruesit (që zakonisht nuk bën ndonjë dëm), API sjell karaktere të koduar UTF-8:

A jemi tashmë atje dhe a i kemi të gjitha informacionet për të përdorur këtë API jashtë Google Chrome? Nëse ndryshoni vargun që do të përkthehet (fusha e të dhënave q e kërkesës POST) nga, për shembull, "Përshëndetje botë" në "Përshëndetje botë ! “, Ne kemi një mesazh gabimi:

Tani e përkthejmë këtë të modifikuar përsëri brenda Google Chrome duke përdorur funksionin e përkthimit të faqes në internet dhe zbulojmë se, përveç parametrit q , edhe parametri tk ka ndryshuar (të gjithë parametrat e tjerë kanë mbetur të njëjtë):

Me sa duket është një shenjë që varet nga vargu, struktura e së cilës nuk është e lehtë për tu parë. Kur filloni përkthimin e faqes në internet, skedarët e mëposhtëm ngarkohen:

  • 1 skedar CSS: translateelement.css
  • 4 grafikë: translate_24dp.png (2x), gen204 (2x)
  • 2 skedarë JS: main_de.js , element_main.js

Dy skedarët JavaScript janë të ngatërruar dhe të minifikuar. Mjete si JS Nice dhe de4js tani po na ndihmojnë t'i bëjmë këto skedarë më të lexueshëm. Në mënyrë që t'i korrigjojmë drejtpërdrejt nga ato, ne rekomandojmë Kërkesën për Zgjatje të Chrome , e cila tunelon skedarët e largët lokalisht në lëvizje:

Tani mund të korrigjojmë kodin ( CORS duhet së pari të aktivizohet në serverin lokal). Seksioni përkatës i kodit për gjenerimin e shenjës duket se është i fshehur në këtë seksion në skedarin element_main.js:

b7739bf50b2edcf636c43a8f8910def9

Këtu teksti është hashed me ndihmën e disa ndërrimeve të bitit . Por për fat të keq ende po na mungon një pjesë e enigmës: Përveç argumentit a (i cili është teksti që do të përkthehet), një argument tjetër b kalon në funksionin Bp () - një lloj farë që duket se ndryshon herë pas here dhe që gjithashtu përfshin derdhet në hashim. Por nga vjen ai? Nëse kalojmë në thirrjen e funksionit të Bp () , gjejmë seksionin e kodit vijues:

b7739bf50b2edcf636c43a8f8910def9

Funksioni Hq deklarohet paraprakisht si më poshtë:

b7739bf50b2edcf636c43a8f8910def9

Këtu Deobfuscater la ca mbeturina; Pasi të kemi zëvendësuar String.fromCharCode ('...') me vargjet përkatëse të karakterit, hiqni një () të vjetëruar dhe bashkoni funksionet thirrjet [c (), c ()] , rezultati është:

b7739bf50b2edcf636c43a8f8910def9

Ose edhe më lehtë:

b7739bf50b2edcf636c43a8f8910def9

Funksioni yq është përcaktuar më parë si:

b7739bf50b2edcf636c43a8f8910def9

Fara duket të jetë në objektin global google.translate._const._ctkk , e cila është në dispozicion gjatë kohës së ekzekutimit. Por ku është vendosur? Në skedarin tjetër, të ngarkuar më parë JS , main_de.js, të paktën është gjithashtu i disponueshëm në fillim. Shtojmë sa më poshtë në fillim:

b7739bf50b2edcf636c43a8f8910def9

Në tastierë ne në fakt marrim farën aktuale:

Kjo e lë vetë Google Chrome, i cili me sa duket siguron farën, si opsionin e fundit. Për fat të mirë, kodi burimor i tij (Chromium, përfshirë përbërësin Translate) është burim i hapur dhe për këtë arsye i disponueshëm për publikun. Ne tërheqim depon lokalisht dhe gjejmë funksionin TranslateScript :: GetTranslateScriptURL në skedarin translate_script.cc në dosjen e komponentëve / translate / core / browser:

b7739bf50b2edcf636c43a8f8910def9

Ndryshorja me URL përcaktohet fort në të njëjtën skedar:

b7739bf50b2edcf636c43a8f8910def9

Nëse tani e shqyrtojmënga afër skedarin element.js (pasi ta deobfuskojmë përsëri), gjejmë hyrjen e vendosur në c._ctkk - objekti google.translate është vendosur gjithashtu në përputhje me rrethanat dhe ngarkimi i të gjitha pasurive përkatëse (të cilat i kemi zbuluar tashmë më parë) shkaktohet:

b7739bf50b2edcf636c43a8f8910def9

Tani çelësi i parametrit mbetet për shqyrtim (me vlerën AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw). Duket se është një çelës gjenerik API i shfletuesit (i cili gjithashtu mund të gjendet në disa rezultate të Google ). Isshtë vendosur në Chromium në skedarin translate_url_util.cckomponentët e dosjes / translate / core / browser:

b7739bf50b2edcf636c43a8f8910def9

Çelësi gjenerohet në google_apis / google_api_keys.cc nga një vlerë bedel:

b7739bf50b2edcf636c43a8f8910def9

Sidoqoftë, një test tregon se thirrjet API funksionojnë njësoj pa këtë parametër kryesor. Nëse eksperimentoni me API, do të merrni përsëri kodin e statusit 200 nëse jeni të suksesshëm. Nëse më pas hasni një kufi, ju merrni kodin e statusit 411 përsëri me mesazhin " Kërkesat POST kërkojnë një kokë me gjatësi përmbajtje ". Prandaj është e këshillueshme që të përfshini këtë titull (i cili vendoset automatikisht si një titull i përkohshëm në Postman).

Formati i kthimit të vargjeve të përkthyera është i pazakontë kur ka disa fjali në një kërkesë. Fjalitë individuale janë të bashkangjitura nga etiketat i- / b-HTML:

Gjithashtu, Google Chrome nuk dërgon të gjithë HTML në API, por ruan vlera të atributeve të tilla si href në kërkesë (dhe në vend të kësaj vendos indekse në mënyrë që etiketat të mund të caktohen më vonë në anën e klientit):

Nëse ndryshoni vlerën e klientit të çelësit POST nga te_lib (Google Chrome) webapp ( Uebfaqja e Përkthimit Google ), ju merrni vargun përfundimtar të përkthyer:

Problemi është se keni shumë më shumë gjasa të hasni në kufizimin e normës sesa përmes te_lib (për krahasim: me webapp kjo arrihet pas 40,000 karakterësh, me te_lib nuk ka kufizim të normës). Pra, duhet të hedhim një vështrim më të afërt se si Chrome analizon rezultatin. Do ta gjejmë këtu në element_main.js:

b7739bf50b2edcf636c43a8f8910def9

Nëse dërgoni të gjithë kodin HTML në API, ai i lë atributet në përgjigjen e përkthyer. Prandaj, nuk duhet të imitojmë të gjithë sjelljen e analizës, por vetëm të nxjerrim vargun përfundimtar, të përkthyer nga përgjigja. Për ta bërë këtë, ne ndërtojmë një analizues të vogël të etiketave HTML që hedh poshtë etiketat më të jashtme <i> duke përfshirë përmbajtjen e tyre dhe heq etiketat më të jashtme <b>. Me këtë njohuri, ne mundemi tani (pas instalimit të varësive me kompozitorin, kërkojmë fzaninotto / faker vielhuber / stringhelper ) të ndërtojmë një version nga ana e serverit të API-së së përkthimit:

b7739bf50b2edcf636c43a8f8910def9

Më poshtë janë rezultatet e një prove fillestare që u krye në pesë sisteme të ndryshme me gjerësi bande dhe adresa IP të ndryshme:

KarakteriKarakteret për kërkesëKohëzgjatjaShkalla e gabimitKostoja përmes API zyrtar
13.064.662~25003: 36: 17h0%237,78€
24.530.510~25011: 09: 13h0%446,46€
49.060.211~25020: 39: 10h0%892,90€
99.074.487~100061: 24: 37h0%1803,16€
99.072.896~100062: 22: 20h0%1803,13€
Σ284.802.766~ Ø550Σ159: 11: 37h0%Σ 5183,41 €

Shënim: Ky post në blog duke përfshirë të gjitha skriptet është shkruar vetëm për qëllime testimi. Mos përdorni Scripts për përdorim produktiv, në vend që të punojë me zyrtare API Google Translation .

Mbrapa