Despre Primo pe Windows Mobile si soluția "pda memory fixed"

victorpetroi
Moderator
Mesaje: 400
Membru din: Vin Dec 16, 2016 6:26 pm
7
Has thanked: 764 ori
Been thanked: 1209 ori

Moderare

#1

Dum Feb 25, 2018 8:41 am

Preluare de pe gpsforum.biz
Cititi cu atentie ce spunea genialul @raz12345, Atotputernicul, in data de 30 septembrie 2012 intr-o postare.


Totul a pornit de la executabilul 9.6.5.245577 titanic(exe-fixed)
► Show Spoiler
Citind "cu greu" postul de mai sus (topic redundant) și fără a stârni polemici și a polua forumul cu lucruri inutile care nu folosesc nimănui și plecând de la convingerea că fiecare are dreptul să-și exprime opinia fără îndoială, doar că, furnizând informații incorecte poate induce în eroare pe alții, vreau să fac anumite precizări / clarificări în ceea ce privește soluția "pda memory fixed".

Soluția nu-mi aparține nici mie, nici lui titanic(Titanic52) cum greșit se vehiculează prin diverse cercuri, ci lui madRat, care, mai exact a identificat problema și care a făcut publică o soluție la începutul acestui an pentru comunitatea de "pasionați GPS". Ulterior și eu și alții doar am implementat soluția în versiunile ulterior apărute pentru a funcționa pe device-urile care rulează Windows Mobile 5.x, respectiv 6.x.

Problema:

Windows CE 5.x / 6.x are implementat la nivelul nucleului(kernel - coredll.dll) funcțiile GetSystemMemoryDivision respectiv SetSystemMemoryDivision, funcții care în Windows Mobile 5.x / 6.x (care este DIFERIT atât la nivelul nucleului cât și la nivelele superioare față de Windows CE) nu funcționează, generând runtime error:


Fatal error occurred in main thread.

Address: 0x03fafa78

Exception: 0xc0000005

Funcția SetSystemMemoryDivision permite divizarea memoriei RAM în Storage Memory respectiv Program Memory în timpul execuției(runtime) prin specificarea numărului de pagini alocate pentru Storage Memory detalii aici (După cum și Microsoft precizează: "This function is deprecated" și "For Windows Mobile, this function will always fail").

In Windows CE în Control Panel > System > Memory se poate configura această divizare.

NNG folosește această funcție pentru a (re)aloca mai multa memorie de tip "Storage Memory", pentru a încăpea conținutul arhivei data.zip.

În versiunile Igo 8.x.x, Primo 1.0, 1.1, 1.2 (8.5.9, 8.5.11, 9.2.0, 9.2.1) subrutina in cadrul căreia se face apelul funcției SetSystemMemoryDivision verifica înainte de apel, dacă funcția este suportată sau nu și de aceea funcționează (nu dă eroare) pe Windows Mobile.

Mai jos subrutina în cauză din Primo 9.2.0.192885:

Cod: Selectaţi tot

var_60	       = -0x60
 var_5C	       = -0x5C
 var_58	       = -0x58
 TotalNumberOfFreeBytes= -0x54
 TotalNumberOfBytes= -0x4C
 FreeBytesAvailableToCaller= -0x44
 Buffer	       = -0x3C

		       STMFD   SP!, {R4-R9,LR}
		       SUB     SP, SP, #0x44
		       LDR     R0, =aCoredll_dll_0 ; "coredll.dll"
		       BL      LoadLibraryW
		       LDR     R1, =aGetsystemmemor ; "GetSystemMemoryDivision"
		       MOV     R7, R0
		       BL      GetProcAddressW
		       LDR     R1, =aSetsystemmemor ; "SetSystemMemoryDivision"
		       MOV     R4, R0
		       MOV     R0, R7	       ; hModule
		       BL      GetProcAddressW
		       MOVS    R8, R0
		       BEQ     loc_7499F8
		       CMP     R4, #0
		       BEQ     loc_7499F8
		       ADD     R2, SP, #0x60+var_58
		       ADD     R1, SP, #0x60+var_5C
		       ADD     R0, SP, #0x60+var_60
		       MOV     LR, PC
		       MOV     PC, R4
		       CMP     R0, #0
		       BEQ     loc_7499F8
		       ADD     R0, SP, #0x60+Buffer ; lpBuffer
		       BL      GlobalMemoryStatus
		       ADD     R3, SP, #0x60+TotalNumberOfFreeBytes ; lpTotalNumberOfFreeBytes
		       ADD     R2, SP, #0x60+TotalNumberOfBytes	; lpTotalNumberOfBytes
		       ADD     R1, SP, #0x60+FreeBytesAvailableToCaller	; lpFreeBytesAvailableToCaller
		       MOV     R0, #0	       ; lpDirectoryName
		       BL      GetDiskFreeSpaceExW
		       LDR     R2, [SP,#0x60+TotalNumberOfFreeBytes]
		       LDR     R3, [SP,#0x60+TotalNumberOfBytes]
		       LDR     R6, [SP,#0x60+Buffer.dwAvailVirtual]
		       LDR     R1, [SP,#0x60+Buffer.dwTotalVirtual]
		       SUB     R3, R3, R2
		       LDR     R2, =byte_828FE7
		       ADD     R3, R3, #0xF00
		       MOV     R9, #0x8100000
		       LDRB    R5, [R2]
		       LDR     R4, [SP,#0x60+var_5C]
		       ADD     R0, R3, #0xFF
		       SUB     R1, R1, R6
		       ORR     R3, R9, #0x100
		       ADD     R3, R1, R3
		       CMP     R5, #0
		       RSB     R1, R4, R3,LSR#12
		       LDRNE   R3, =dword_83165C
		       LDR     LR, [SP,#0x60+FreeBytesAvailableToCaller]
		       MOV     R2, R0,LSR#12
		       LDRNE   R3, [R3]
		       ADD     R0, R2, #0x40
		       MOV     LR, LR,LSR#12
		       CMPNE   R3, #0xB
		       MOVNE   R2, #0x200
		       MOVEQ   R2, #0x40
		       CMP     R1, #0
		       BLE     loc_7499F8
		       ADD     R3, R2, R1
		       CMP     R3, LR
		       LDR     R3, [SP,#0x60+var_60]
		       BCS     loc_7499E8
		       SUB     R0, R3, R1
		       MOV     LR, PC
		       MOV     PC, R8
		       B       loc_7499F8
 ; ---------------------------------------------------------------------------
 loc_7499E8			       ; CODE XREF: sub_7498E8+ECj
		       ADD     R0, R2, R0
		       CMP     R0, R3
		       MOVCC   LR, PC
		       MOVCC   PC, R8

 loc_7499F8			       ; CODE XREF: sub_7498E8+30j
					       ; sub_7498E8+38j ...
		       MOV     R0, R7	       ; hLibModule
		       BL      FreeLibrary
		       ADD     SP, SP, #0x44
		       LDMFD   SP!, {R4-R9,PC}
 ; End of	function sub_7498E8
 
În versiunile mai noi de Primo 2.0.x (9.6.2.209584, 9.6.5.214202, 9.6.5.216230, 9.6.5.221194, 9.6.5.245577) dar și în Primo 1.1 (8.5.11.209632 - Apontador ), cât și în Becker Transit50 (9.6.1.215570) au modificat rutina în cauză, ne mai verificând dacă este suportată funcția SetSystemMemoryDivision, pornind probabil de la premiza că dezvoltă produsul doar pentru PNA–uri care rulează Windows CE implicit.

Mai jos subrutina din Primo 9.6.5.245577:

Cod: Selectaţi tot

var_64	       = -0x64
 var_60	       = -0x60
 var_5C	       = -0x5C
 TotalNumberOfFreeBytes= -0x58
 TotalNumberOfBytes= -0x50
 FreeBytesAvailableToCaller= -0x48
 Buffer	       = -0x40

		       STMFD   SP!, {R4-R10,LR}
		       SUB     SP, SP, #0x44
		       MOV     R4, R0
		       LDR     R1, =aGetsystemmemor ; "GetSystemMemoryDivision"
		       BL      GetProcAddressW
		       LDR     R1, =aSetsystemmemor ; "SetSystemMemoryDivision"
		       MOV     R5, R0
		       MOV     R0, R4	       ; hModule
		       BL      GetProcAddressW
		       MOVS    R8, R0
		       BEQ     loc_859830
		       CMP     R5, #0
		       BEQ     loc_859830
		       ADD     R2, SP, #0x64+var_60
		       ADD     R1, SP, #0x64+var_5C
		       ADD     R0, SP, #0x64+var_64
		       MOV     LR, PC
		       MOV     PC, R5
		       CMP     R0, #0
		       BEQ     loc_859830
		       ADD     R3, SP, #0x64+TotalNumberOfFreeBytes ; lpTotalNumberOfFreeBytes
		       ADD     R2, SP, #0x64+TotalNumberOfBytes	; lpTotalNumberOfBytes
		       ADD     R1, SP, #0x64+FreeBytesAvailableToCaller	; lpFreeBytesAvailableToCaller
		       MOV     R0, #0	       ; lpDirectoryName
		       BL      GetDiskFreeSpaceExW
		       CMP     R0, #0
		       BEQ     loc_859830
		       ADD     R0, SP, #0x64+Buffer ; lpBuffer
		       BL      GlobalMemoryStatus
		       LDR     R2, [SP,#0x64+TotalNumberOfFreeBytes]
		       LDR     R3, [SP,#0x64+TotalNumberOfBytes]
		       LDR     R5, [SP,#0x64+var_60]
		       LDR     R1, =__imp__rt_udiv
		       SUB     R3, R3, R2
		       ADD     R3, R3, R5
		       LDR     R2, [R1]
		       SUB     R1, R3, #1
		       MOV     R0, R5
		       MOV     LR, PC
		       MOV     PC, R2
		       LDR     R3, =__imp__rt_udiv
		       LDR     R1, [SP,#0x64+FreeBytesAvailableToCaller]
		       MOV     R10, R0
		       MOV     R0, R5
		       MOV     LR, PC
		       LDR     PC, [R3]
		       LDR     R3, =byte_94693A
		       LDR     R7, =dword_951310
		       LDR     R1, [SP,#0x64+Buffer.dwAvailPhys]
		       LDRB    R3, [R3]
		       MOV     R2, #0x8100000
		       MOV     R9, R0
		       CMP     R3, #0
		       LDRNE   R3, [R7,#(dword_951428 -	0x951310)]
		       MOV     R0, R5
		       CMPNE   R3, #0xB
		       LDR     R3, =_rt_sdiv
		       MOVNE   R6, #0x200
		       MOVEQ   R6, #0x40
		       LDR     R4, [R3]
		       ORR     R3, R2, #0x100
		       ADD     R2, R6, R10
		       ADD     R5, R2, #0x40
		       RSB     R1, R1, R3
		       MOV     LR, PC
		       MOV     PC, R4
		       CMP     R0, #0
		       BLE     loc_859830
		       ADD     R3, R0, R6
		       CMP     R3, R9
		       LDR     R3, [SP,#0x64+var_64]
		       SUBCC   R5, R3, R0
		       BCC     loc_8597CC
		       CMP     R5, R3
		       BCS     loc_859830

 loc_8597CC			       ; CODE XREF: sub_8596A0+120j
		       CMP     R5, #0
		       BEQ     loc_859830
		       MOV     R0, R5
		       MOV     LR, PC
		       MOV     PC, R8
		       CMP     R0, #0
		       BEQ     loc_859830
		       CMP     R0, #1
		       BEQ     loc_85981C
		       CMP     R0, #3
		       BEQ     loc_859810
		       LDR     R1, =aUnknownErrorDO ; "Unknown error (%d)\noccured setting the "...

 loc_8597FC			       ; CODE XREF: sub_8596A0+178j
		       MOV     R2, R0
		       MOV     R0, #0	       ; lpBuffer
		       BL      wsprintfW
		       MOV     R1, #0
		       B       loc_859820
 ; ---------------------------------------------------------------------------

 loc_859810			       ; CODE XREF: sub_8596A0+154j
		       BL      GetLastError
		       LDR     R1, =aTheNumberOfSto ; "The number of storage pages\ncould not b"...
		       B       loc_8597FC
 ; ---------------------------------------------------------------------------

 loc_85981C			       ; CODE XREF: sub_8596A0+14Cj
		       LDR     R1, =aTheNumberOfS_0 ; "The number of storage pages\ncould not b"...

 loc_859820			       ; CODE XREF: sub_8596A0+16Cj
		       LDR     R2, =aError_1   ; "ERROR"
		       LDR     R0, [R7]
		       MOV     R3, #0
		       BL      sub_1F968

 loc_859830			       ; CODE XREF: sub_8596A0+28j
					       ; sub_8596A0+30j ...
		       ADD     SP, SP, #0x44
		       LDMFD   SP!, {R4-R10,PC}
 ; End of	function sub_8596A0
Deși poate nu am dezasamblat codul 100% corect se pot sesiza diferențele. Soluția: Soluția propusă de madRat este una extrem de simplă și constă în redenumirea funcției SetSystemMemoryDivision din tabela de simboluri (din .rdata - segmentul de date). Astfel primo ne mai găsind funcția SetSystemMemoryDivision, "ignoră" operația de "memory division" şi se scapă astfel de eroare. În soluția lui madRat se schimbă numele din SetSystemMemoryDivision în UnkSystemMemoryDivision prin hexaedit în fișierul exe (se poate schimba în orice alt nume, păstrând numărul de caractere din numele funcţiei - valorile sunt Unicode). Ex: pentru primo 9.6.5.245577 - 06.07.2012 (md5: 2fda803beb128ebcceb74aee198d70a6) modificările sunt următoarele:

Cod: Selectaţi tot

offset 91575c: 53 -> 55
offset 91575e: 65 -> 6e
offset 915760: 74 -> 6b
Obs.
Confuzia cum că unele versiuni de Primo 2.0.x funcționează şi pe Windows CE şi pe Windows Mobile fără a aplica soluţia de mai sus provine din faptul că cei care au modificat executabilul (tratat / vaccinat), au modificat şi numele funcției SetSystemMemoryDivision astfel că atunci când au ”lansat” noua versiune au lansat-o cu soluția de mai sus gata integrată.

Deci fără aceasta modificare, nici o versiune oficială de primo 2.0.x NU funcționează pe Windows Mobile.

Aceasta este soluţia "PDA memory fixed" şi nicidecum "optimizări" sau "modificări" pentru device-uri cu memorie mai redusă, cum eronat se vehiculează prin diverse posturi / forumuri.
Scrie răspuns

Înapoi la “Tutoriale iGO”