Search the Community
Showing results for tags 'run-time error 13'.
-
Acest tutorial este in legatura cu acest thread https://rstforums.com/forum/86916-run-time-error-13-type-mismatch.rst. L'am mutat aici fiind mai mult decat un simplu raspuns al thread-ului respectiv. Am explicat o posibila modalitate de rezolvare a erorilor de tip error-and-crash. Aplicatia exemplu este Youtube Viewer Am testat, la mine nu da eroare daca clipul are multe vizite (301+). Dar daca clipul are 20 de views atunci face o conexiune, face 1 view, si da Runtime Error 13: Type Mismatch Programul este foarte simplu, practic cu un socket face un requesturi spre YT folosind User agent Mozilla, cookiurile modificate ... si IPuri diferite fara a folosi proxy (?!). Type mismatch (13) apare, asa cum spunea @Ganav, atunci cand operanzii sunt incompatibili cu tipul operatiei. Un exemplu ar fi atunci cand o functie de conversie string-integer, care DEOBICEI intoarce un integer, nu poate converti valoarea de tip string. Astfel de 'bug'-uri apar frecvent in aplicatiile scrise de incepatori.. In cazul de fatza, ce se intampla concret nu e atat de important pe cat este rezolvarea problemei in sine. Aplicatia este practic un parser HTML. Face requestul, extrage valori din HTML pe care apoi le foloseste. Daca sursa site-ului se modifica, atunci evident extrage prost. Asta este motivul pentru care aplicatiile de tip crawler/parser dedicate trebuie actualizate mereu. Cred ca aplicatia vrea sa extraga numarul de views din pagina YT, dar scoate "50 views" in loc de "50", iar apoi crapa la conversia string-integer. Am explicat mai jos, pe cod. Am rulat atent si am observat ca eroarea apare imediat dupa ce apare notificarea in StatusBar: "Added view." Pornim OllyDBG, incarcam EXEul, debuger-ul ne duce pe EntryPoint, cautam dupa stringuri (clk dr, Search For-> All referenced text strings) si cautam "Added view". Il gasim la adresa 0041235F - undeva jos in lista. Dublu clk pe el si ajungem in cod exact acolo. ... ... 0041235F BA 10E64000 MOV EDX,40E610 ; UNICODE "Added view." 00412364 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18] 00412367 FF15 DC104000 CALL DWORD PTR DS:[4010DC] ; MSVBVM60.__vbaStrCopy 0041236D 8B16 MOV EDX,DWORD PTR DS:[ESI] 0041236F 8D45 BC LEA EAX,DWORD PTR SS:[EBP-44] 00412372 8D4D E8 LEA ECX,DWORD PTR SS:[EBP-18] 00412375 50 PUSH EAX 00412376 51 PUSH ECX 00412377 53 PUSH EBX 00412378 56 PUSH ESI ... ... Punem un brakepoint pe adresa 0041235F (F2), pentru ca debugerul sa opreasca aplicatia exact in locul ala, si rulam (F9). Aplicatia se incarca, apare formul, completam campul cu ID-ul video-ului care ne intereseaza, apasam pe START si asteptam eroarea. Debugerul ne opreste la adresa dorita (0041235F), chiar inainte sa primim eroarea. De aici putem rula Step-By-Step exact pana in locul unde va fi genereata eroarea. Ca sa economisim timp vom tine cont de ceea ce stim deja, si anume ca este o eroare tip Type Mismatch (13), care este generata de o functie MS; asadar cautam o functie de conversie din MSVBVM60.DLL Coboram (scrool) pana gasim: ... ... 00412496 8B95 4CFFFFFF MOV EDX,DWORD PTR SS:[EBP-B4] 0041249C 8B45 E8 MOV EAX,DWORD PTR SS:[EBP-18] 0041249F 50 PUSH EAX 004124A0 8B1A MOV EBX,DWORD PTR DS:[EDX] 004124A2 FF15 C8104000 CALL DWORD PTR DS:[4010C8] ; MSVBVM60.__vbaR8Str 004124A8 DC05 30114000 FADD QWORD PTR DS:[401130] 004124AE 83EC 08 SUB ESP,8 004124B1 DFE0 FSTSW AX 004124B3 A8 0D TEST AL,0D 004124B5 0F85 9E010000 JNZ 00412659 ; Youtubev.00412659 004124BB DD1C24 FSTP QWORD PTR SS:[ESP] 004124BE FF15 90104000 CALL DWORD PTR DS:[401090] ; MSVBVM60.__vbaStrR8 004124C4 8BD0 MOV EDX,EAX 004124C6 8D4D E4 LEA ECX,DWORD PTR SS:[EBP-1C] 004124C9 FF15 10114000 CALL DWORD PTR DS:[401110] ; MSVBVM60.__vbaStrMove 004124CF 8BCB MOV ECX,EBX 004124D1 8B9D 4CFFFFFF MOV EBX,DWORD PTR SS:[EBP-B4] 004124D7 50 PUSH EAX 004124D8 53 PUSH EBX ... ... Observam la adresa 004124A2 : 004124A2 FF15 C8104000 CALL DWORD PTR DS:[4010C8] ; MSVBVM60.__vbaR8Str Este prima functie de conversie care ar putea genera eroarea. Pentru ca debugerul sa se opreasca pe ea punem breakpoint. (click pe 004124A2 , apoi F2) si rulam (F9). Ajungem exact acolo, cu ochii pe valorile din registri EAX, EBX, ECX, EDX (dreapta sus in debuger) Observam cum se incarca nr. de views in EAX ("50 views") iar apoi urmeaza executia functiei de conversie. Teoretic de aici vom putea rula mai departe Step-by-Step (F7) fiindca suntem foarte aproape, dar stim ca eroarea apartine programatorului, nu functiilor API MS, asa ca vom folosi Step Over (F8) ca sa nu intram prin aceasta functie. Apasam F8 (Step Over) si observam ca am sarit in total alta parte: observam in titlu module USER32, in ECX ASCII "ViewsTube", in ESI avem USER32.MesageBoxIndirectA. Rulam in continuare (F8) si mai observam "Type Mismatch", ... deci e clar: eroarea s'a produs DEJA iar programul se pregateste sa ne afiseze un MessageBox cu titlul "ViewsTube" si mesajul "Type Mismatch".. ------------ CONCLUZIA: unul dintre registrii este incarcat cu o valoare incompatibila cu tipurile cerute de __vbaR8Str. Umpic de research pe google aflam ca __vbaR8Str este o functie nedocumentata de Microsoft, dar daca ne mai uitam putin prin cod (...) aflam ca foloseste o alta functie VarR8FromStr, care transforma un string in double: : (source MSDN) VarR8FromStr function Converts an OLECHAR string to a double value. HRESULT VarR8FromStr( _In_ LPCOLESTR strIn, _In_ LCID lcid, _In_ ULONG dwFlags, _Out_ DOUBLE *pdblOut ); Deci cu siguranta aplicatia vrea sa transforme stringul "50 views" in integer, ceea ce, evident, nu este posibil. ------------------ SOLUTIA: In acest caz eroarea apare la afisarea numarului de views efectuati, nu in functionalitate. Isi face treaba, dar crapa cand vrea sa ne afiseze numarul actual de views. Exista doua variante: - reparam "zona cu probleme" - ocolim "zona cu probleme" Daca nu e ceva foarte important sa trebuiasca reparat, si mai ales daca facem asta din pasiune si nu pe bani, vom prefera intotdeauna sa ocolim, aplicatia fiind FUNCTIONALA (chiar daca nu va mai arata corect nr. de views...). A repara o astfel de eroare implica mai mult timp si cunostinte, cum ar fi programarea ASM si injectiile suplimentare de cod. Deci vom ocoli zona folosind doar o simpla intructiune JMP (jump). Cum facem asta? Avem trei variante: - patch direct in debuger - scriem un patcher.exe - scriem un loader.exe Oricare varianta este buna, cea mai rapida fiind prima, pe care o prefer: Deschidem aplicatia dinnou in debuger, reluam toti pasii, sau punem direct un breakpoint pe adresa functiei cu probleme (004124A2): 004124A2 FF15 C8104000 CALL DWORD PTR DS:[4010C8] ; MSVBVM60.__vbaR8Str Rulam (F9), pana ajungem acolo. Folosind JMP putem sari practic oriunde, dar e de preferat sa ocolim cat mai putin pentru a nu pierde sectiuni functionale din cod. Adreasa 004124A2 fiind selectata apasam SPACE (sau clk dr.-> Assemble) stergem tot ce este acolo si introducem instructiunea JMP alaturi de noua adresa: JMP 004124F7 Bifam "Fill with NOP's" Apasam "Assemble" apoi "Cancel" Modificarile apar marcate cu alb si o sageata verticala de la 004124A2 spre noua 004124F7. Rulam (F9) si observam ca programul face un view dupa care se opreste in brakepoint-ul setat; mai rulam odata, inca odata, inca odata, ... face treaba, fara erori! Perfect: acum SALVAM noul EXE: clk. dr pe cod -> Copy -> Select All apoi Copy to executable -> All modifications -> Copy All Salvam noul EXE cu nume diferit: clk dr. Save File: youtubeviewer_patched.exe -> Save Rulam noul EXE, zambim, am mai invatat ceva Patched File URL: https://www.sendspace.com/file/d4tit2