├── .gitignore ├── .gitmodules ├── DumpWrapper ├── DumpWrapper.sln └── DumpWrapper │ ├── Config.cs │ ├── DefineConstants.cs │ ├── DumpData.cs │ ├── DumpWrapper.cs │ ├── DumpWrapper.csproj │ └── Properties │ └── AssemblyInfo.cs ├── Il2cppSpy ├── application.py ├── bin │ └── Release │ │ ├── DumpWrapper.dll │ │ ├── Il2CppDumper.exe │ │ ├── Mono.Cecil.dll │ │ └── config.json ├── data │ └── repository │ │ ├── assembly_repository.py │ │ ├── file_repository.py │ │ └── il2cpp_repository.py ├── domain │ ├── model │ │ └── dump_data.py │ ├── repository │ │ ├── abstract_assembly_repository.py │ │ ├── abstract_file_repository.py │ │ └── abstract_il2cpp_repository.py │ └── use_case │ │ ├── compare_files_use_case.py │ │ └── open_file_use_case.py ├── presentation │ ├── presenter │ │ └── action_presenter.py │ └── view │ │ ├── explorer_view.py │ │ ├── tab_item_view.py │ │ └── tab_view.py ├── ui │ ├── file.png │ ├── folder.png │ ├── mainwindow.ui │ ├── resources.qrc │ ├── resources_rc.py │ ├── tabitemwindow.ui │ ├── ui_color.py │ ├── ui_mainwindow.py │ └── ui_tabitemwindow.py └── utils │ └── file_utils.py ├── LICENSE ├── Pipfile ├── Pipfile.lock ├── README.md ├── docs └── images │ ├── diff.png │ ├── logo.png │ └── open.gif ├── scripts ├── Il2cppSpy.spec ├── build.sh └── icons │ ├── icon.icns │ └── icon.ico └── setup.cfg /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/macos,python,csharp 3 | # Edit at https://www.gitignore.io/?templates=macos,python,csharp 4 | 5 | ### Csharp ### 6 | ## Ignore Visual Studio temporary files, build results, and 7 | ## files generated by popular Visual Studio add-ons. 8 | ## 9 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 10 | 11 | # User-specific files 12 | *.rsuser 13 | *.suo 14 | *.user 15 | *.userosscache 16 | *.sln.docstates 17 | 18 | # User-specific files (MonoDevelop/Xamarin Studio) 19 | *.userprefs 20 | 21 | # Mono auto generated files 22 | mono_crash.* 23 | 24 | # Build results 25 | # [Dd]ebug/ 26 | [Dd]ebugPublic/ 27 | # [Rr]elease/ 28 | [Rr]eleases/ 29 | x64/ 30 | x86/ 31 | [Aa][Rr][Mm]/ 32 | [Aa][Rr][Mm]64/ 33 | bld/ 34 | # [Bb]in/ 35 | [Oo]bj/ 36 | [Ll]og/ 37 | 38 | # Visual Studio 2015/2017 cache/options directory 39 | .vs/ 40 | # Uncomment if you have tasks that create the project's static files in wwwroot 41 | #wwwroot/ 42 | 43 | # Visual Studio 2017 auto generated files 44 | Generated\ Files/ 45 | 46 | # MSTest test Results 47 | [Tt]est[Rr]esult*/ 48 | [Bb]uild[Ll]og.* 49 | 50 | # NUnit 51 | *.VisualState.xml 52 | TestResult.xml 53 | nunit-*.xml 54 | 55 | # Build Results of an ATL Project 56 | [Dd]ebugPS/ 57 | [Rr]eleasePS/ 58 | dlldata.c 59 | 60 | # Benchmark Results 61 | BenchmarkDotNet.Artifacts/ 62 | 63 | # .NET Core 64 | project.lock.json 65 | project.fragment.lock.json 66 | artifacts/ 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.vspscc 94 | *.vssscc 95 | .builds 96 | *.pidb 97 | *.svclog 98 | *.scc 99 | 100 | # Chutzpah Test files 101 | _Chutzpah* 102 | 103 | # Visual C++ cache files 104 | ipch/ 105 | *.aps 106 | *.ncb 107 | *.opendb 108 | *.opensdf 109 | *.sdf 110 | *.cachefile 111 | *.VC.db 112 | *.VC.VC.opendb 113 | 114 | # Visual Studio profiler 115 | *.psess 116 | *.vsp 117 | *.vspx 118 | *.sap 119 | 120 | # Visual Studio Trace Files 121 | *.e2e 122 | 123 | # TFS 2012 Local Workspace 124 | $tf/ 125 | 126 | # Guidance Automation Toolkit 127 | *.gpState 128 | 129 | # ReSharper is a .NET coding add-in 130 | _ReSharper*/ 131 | *.[Rr]e[Ss]harper 132 | *.DotSettings.user 133 | 134 | # JustCode is a .NET coding add-in 135 | .JustCode 136 | 137 | # TeamCity is a build add-in 138 | _TeamCity* 139 | 140 | # DotCover is a Code Coverage Tool 141 | *.dotCover 142 | 143 | # AxoCover is a Code Coverage Tool 144 | .axoCover/* 145 | !.axoCover/settings.json 146 | 147 | # Visual Studio code coverage results 148 | *.coverage 149 | *.coveragexml 150 | 151 | # NCrunch 152 | _NCrunch_* 153 | .*crunch*.local.xml 154 | nCrunchTemp_* 155 | 156 | # MightyMoose 157 | *.mm.* 158 | AutoTest.Net/ 159 | 160 | # Web workbench (sass) 161 | .sass-cache/ 162 | 163 | # Installshield output folder 164 | [Ee]xpress/ 165 | 166 | # DocProject is a documentation generator add-in 167 | DocProject/buildhelp/ 168 | DocProject/Help/*.HxT 169 | DocProject/Help/*.HxC 170 | DocProject/Help/*.hhc 171 | DocProject/Help/*.hhk 172 | DocProject/Help/*.hhp 173 | DocProject/Help/Html2 174 | DocProject/Help/html 175 | 176 | # Click-Once directory 177 | publish/ 178 | 179 | # Publish Web Output 180 | *.[Pp]ublish.xml 181 | *.azurePubxml 182 | # Note: Comment the next line if you want to checkin your web deploy settings, 183 | # but database connection strings (with potential passwords) will be unencrypted 184 | *.pubxml 185 | *.publishproj 186 | 187 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 188 | # checkin your Azure Web App publish settings, but sensitive information contained 189 | # in these scripts will be unencrypted 190 | PublishScripts/ 191 | 192 | # NuGet Packages 193 | *.nupkg 194 | # NuGet Symbol Packages 195 | *.snupkg 196 | # The packages folder can be ignored because of Package Restore 197 | **/[Pp]ackages/* 198 | # except build/, which is used as an MSBuild target. 199 | !**/[Pp]ackages/build/ 200 | # Uncomment if necessary however generally it will be regenerated when needed 201 | #!**/[Pp]ackages/repositories.config 202 | # NuGet v3's project.json files produces more ignorable files 203 | *.nuget.props 204 | *.nuget.targets 205 | 206 | # Microsoft Azure Build Output 207 | csx/ 208 | *.build.csdef 209 | 210 | # Microsoft Azure Emulator 211 | ecf/ 212 | rcf/ 213 | 214 | # Windows Store app package directories and files 215 | AppPackages/ 216 | BundleArtifacts/ 217 | Package.StoreAssociation.xml 218 | _pkginfo.txt 219 | *.appx 220 | *.appxbundle 221 | *.appxupload 222 | 223 | # Visual Studio cache files 224 | # files ending in .cache can be ignored 225 | *.[Cc]ache 226 | # but keep track of directories ending in .cache 227 | !?*.[Cc]ache/ 228 | 229 | # Others 230 | ClientBin/ 231 | ~$* 232 | *~ 233 | *.dbmdl 234 | *.dbproj.schemaview 235 | *.jfm 236 | *.pfx 237 | *.publishsettings 238 | orleans.codegen.cs 239 | 240 | # Including strong name files can present a security risk 241 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 242 | #*.snk 243 | 244 | # Since there are multiple workflows, uncomment next line to ignore bower_components 245 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 246 | #bower_components/ 247 | 248 | # RIA/Silverlight projects 249 | Generated_Code/ 250 | 251 | # Backup & report files from converting an old project file 252 | # to a newer Visual Studio version. Backup files are not needed, 253 | # because we have git ;-) 254 | _UpgradeReport_Files/ 255 | Backup*/ 256 | UpgradeLog*.XML 257 | UpgradeLog*.htm 258 | ServiceFabricBackup/ 259 | *.rptproj.bak 260 | 261 | # SQL Server files 262 | *.mdf 263 | *.ldf 264 | *.ndf 265 | 266 | # Business Intelligence projects 267 | *.rdl.data 268 | *.bim.layout 269 | *.bim_*.settings 270 | *.rptproj.rsuser 271 | *- [Bb]ackup.rdl 272 | *- [Bb]ackup ([0-9]).rdl 273 | *- [Bb]ackup ([0-9][0-9]).rdl 274 | 275 | # Microsoft Fakes 276 | FakesAssemblies/ 277 | 278 | # GhostDoc plugin setting file 279 | *.GhostDoc.xml 280 | 281 | # Node.js Tools for Visual Studio 282 | .ntvs_analysis.dat 283 | node_modules/ 284 | 285 | # Visual Studio 6 build log 286 | *.plg 287 | 288 | # Visual Studio 6 workspace options file 289 | *.opt 290 | 291 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 292 | *.vbw 293 | 294 | # Visual Studio LightSwitch build output 295 | **/*.HTMLClient/GeneratedArtifacts 296 | **/*.DesktopClient/GeneratedArtifacts 297 | **/*.DesktopClient/ModelManifest.xml 298 | **/*.Server/GeneratedArtifacts 299 | **/*.Server/ModelManifest.xml 300 | _Pvt_Extensions 301 | 302 | # Paket dependency manager 303 | .paket/paket.exe 304 | paket-files/ 305 | 306 | # FAKE - F# Make 307 | .fake/ 308 | 309 | # CodeRush personal settings 310 | .cr/personal 311 | 312 | # Python Tools for Visual Studio (PTVS) 313 | __pycache__/ 314 | *.pyc 315 | 316 | # Cake - Uncomment if you are using it 317 | # tools/** 318 | # !tools/packages.config 319 | 320 | # Tabs Studio 321 | *.tss 322 | 323 | # Telerik's JustMock configuration file 324 | *.jmconfig 325 | 326 | # BizTalk build output 327 | *.btp.cs 328 | *.btm.cs 329 | *.odx.cs 330 | *.xsd.cs 331 | 332 | # OpenCover UI analysis results 333 | OpenCover/ 334 | 335 | # Azure Stream Analytics local run output 336 | ASALocalRun/ 337 | 338 | # MSBuild Binary and Structured Log 339 | *.binlog 340 | 341 | # NVidia Nsight GPU debugger configuration file 342 | *.nvuser 343 | 344 | # MFractors (Xamarin productivity tool) working folder 345 | .mfractor/ 346 | 347 | # Local History for Visual Studio 348 | .localhistory/ 349 | 350 | # BeatPulse healthcheck temp database 351 | healthchecksdb 352 | 353 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 354 | MigrationBackup/ 355 | 356 | ### macOS ### 357 | # General 358 | .DS_Store 359 | .AppleDouble 360 | .LSOverride 361 | 362 | # Icon must end with two \r 363 | Icon 364 | 365 | # Thumbnails 366 | ._* 367 | 368 | # Files that might appear in the root of a volume 369 | .DocumentRevisions-V100 370 | .fseventsd 371 | .Spotlight-V100 372 | .TemporaryItems 373 | .Trashes 374 | .VolumeIcon.icns 375 | .com.apple.timemachine.donotpresent 376 | 377 | # Directories potentially created on remote AFP share 378 | .AppleDB 379 | .AppleDesktop 380 | Network Trash Folder 381 | Temporary Items 382 | .apdisk 383 | 384 | ### Python ### 385 | # Byte-compiled / optimized / DLL files 386 | *.py[cod] 387 | *$py.class 388 | 389 | # C extensions 390 | *.so 391 | 392 | # Distribution / packaging 393 | .Python 394 | build/ 395 | develop-eggs/ 396 | dist/ 397 | downloads/ 398 | eggs/ 399 | .eggs/ 400 | lib/ 401 | lib64/ 402 | parts/ 403 | sdist/ 404 | var/ 405 | wheels/ 406 | pip-wheel-metadata/ 407 | share/python-wheels/ 408 | *.egg-info/ 409 | .installed.cfg 410 | *.egg 411 | MANIFEST 412 | 413 | # PyInstaller 414 | # Usually these files are written by a python script from a template 415 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 416 | *.manifest 417 | # *.spec 418 | 419 | # Installer logs 420 | pip-log.txt 421 | pip-delete-this-directory.txt 422 | 423 | # Unit test / coverage reports 424 | htmlcov/ 425 | .tox/ 426 | .nox/ 427 | .coverage 428 | .coverage.* 429 | .cache 430 | nosetests.xml 431 | coverage.xml 432 | *.cover 433 | .hypothesis/ 434 | .pytest_cache/ 435 | 436 | # Translations 437 | *.mo 438 | *.pot 439 | 440 | # Django stuff: 441 | local_settings.py 442 | db.sqlite3 443 | db.sqlite3-journal 444 | 445 | # Flask stuff: 446 | instance/ 447 | .webassets-cache 448 | 449 | # Scrapy stuff: 450 | .scrapy 451 | 452 | # Sphinx documentation 453 | docs/_build/ 454 | 455 | # PyBuilder 456 | target/ 457 | 458 | # Jupyter Notebook 459 | .ipynb_checkpoints 460 | 461 | # IPython 462 | profile_default/ 463 | ipython_config.py 464 | 465 | # pyenv 466 | .python-version 467 | 468 | # pipenv 469 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 470 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 471 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 472 | # install all needed dependencies. 473 | #Pipfile.lock 474 | 475 | # celery beat schedule file 476 | celerybeat-schedule 477 | 478 | # SageMath parsed files 479 | *.sage.py 480 | 481 | # Environments 482 | .env 483 | .venv 484 | env/ 485 | venv/ 486 | ENV/ 487 | env.bak/ 488 | venv.bak/ 489 | 490 | # Spyder project settings 491 | .spyderproject 492 | .spyproject 493 | 494 | # Rope project settings 495 | .ropeproject 496 | 497 | # mkdocs documentation 498 | /site 499 | 500 | # mypy 501 | .mypy_cache/ 502 | .dmypy.json 503 | dmypy.json 504 | 505 | # Pyre type checker 506 | .pyre/ 507 | 508 | # End of https://www.gitignore.io/api/macos,python,csharp 509 | 510 | # vscode 511 | .vscode/ 512 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Il2CppDumper"] 2 | path = Il2CppDumper 3 | url = git@github.com:Perfare/Il2CppDumper.git 4 | -------------------------------------------------------------------------------- /DumpWrapper/DumpWrapper.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DumpWrapper", "DumpWrapper\DumpWrapper.csproj", "{961C4433-2E3D-4927-938E-A10EBC9D69F6}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Il2CppDumper", "..\Il2CppDumper\Il2CppDumper\Il2CppDumper.csproj", "{379715D4-4B7B-41F2-B78A-8B18D86320E2}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {961C4433-2E3D-4927-938E-A10EBC9D69F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {961C4433-2E3D-4927-938E-A10EBC9D69F6}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {961C4433-2E3D-4927-938E-A10EBC9D69F6}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {961C4433-2E3D-4927-938E-A10EBC9D69F6}.Release|Any CPU.Build.0 = Release|Any CPU 18 | {379715D4-4B7B-41F2-B78A-8B18D86320E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {379715D4-4B7B-41F2-B78A-8B18D86320E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {379715D4-4B7B-41F2-B78A-8B18D86320E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {379715D4-4B7B-41F2-B78A-8B18D86320E2}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | EndGlobal 24 | -------------------------------------------------------------------------------- /DumpWrapper/DumpWrapper/Config.cs: -------------------------------------------------------------------------------- 1 | // From Config.cs 2 | 3 | namespace Wrapper 4 | { 5 | public class Config 6 | { 7 | public bool DumpMethod = true; 8 | public bool DumpField = true; 9 | public bool DumpProperty = false; 10 | public bool DumpAttribute = false; 11 | public bool DumpFieldOffset = true; 12 | public bool DumpMethodOffset = true; 13 | public bool DumpTypeDefIndex = true; 14 | public bool DummyDll = true; 15 | public bool MakeFunction = false; 16 | public bool ForceIl2CppVersion = false; 17 | public int ForceVersion = 16; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /DumpWrapper/DumpWrapper/DefineConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | // From DefineConstants.cs 5 | 6 | namespace Wrapper 7 | { 8 | static class DefineConstants 9 | { 10 | /* 11 | * Field Attributes (21.1.5). 12 | */ 13 | public const int FIELD_ATTRIBUTE_FIELD_ACCESS_MASK = 0x0007; 14 | public const int FIELD_ATTRIBUTE_COMPILER_CONTROLLED = 0x0000; 15 | public const int FIELD_ATTRIBUTE_PRIVATE = 0x0001; 16 | public const int FIELD_ATTRIBUTE_FAM_AND_ASSEM = 0x0002; 17 | public const int FIELD_ATTRIBUTE_ASSEMBLY = 0x0003; 18 | public const int FIELD_ATTRIBUTE_FAMILY = 0x0004; 19 | public const int FIELD_ATTRIBUTE_FAM_OR_ASSEM = 0x0005; 20 | public const int FIELD_ATTRIBUTE_PUBLIC = 0x0006; 21 | 22 | public const int FIELD_ATTRIBUTE_STATIC = 0x0010; 23 | public const int FIELD_ATTRIBUTE_INIT_ONLY = 0x0020; 24 | public const int FIELD_ATTRIBUTE_LITERAL = 0x0040; 25 | 26 | /* 27 | * Method Attributes (22.1.9) 28 | */ 29 | public const int METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK = 0x0007; 30 | public const int METHOD_ATTRIBUTE_COMPILER_CONTROLLED = 0x0000; 31 | public const int METHOD_ATTRIBUTE_PRIVATE = 0x0001; 32 | public const int METHOD_ATTRIBUTE_FAM_AND_ASSEM = 0x0002; 33 | public const int METHOD_ATTRIBUTE_ASSEM = 0x0003; 34 | public const int METHOD_ATTRIBUTE_FAMILY = 0x0004; 35 | public const int METHOD_ATTRIBUTE_FAM_OR_ASSEM = 0x0005; 36 | public const int METHOD_ATTRIBUTE_PUBLIC = 0x0006; 37 | 38 | public const int METHOD_ATTRIBUTE_STATIC = 0x0010; 39 | public const int METHOD_ATTRIBUTE_FINAL = 0x0020; 40 | public const int METHOD_ATTRIBUTE_VIRTUAL = 0x0040; 41 | 42 | public const int METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK = 0x0100; 43 | public const int METHOD_ATTRIBUTE_REUSE_SLOT = 0x0000; 44 | public const int METHOD_ATTRIBUTE_NEW_SLOT = 0x0100; 45 | 46 | public const int METHOD_ATTRIBUTE_ABSTRACT = 0x0400; 47 | 48 | public const int METHOD_ATTRIBUTE_PINVOKE_IMPL = 0x2000; 49 | 50 | /* 51 | * Type Attributes (21.1.13). 52 | */ 53 | public const int TYPE_ATTRIBUTE_VISIBILITY_MASK = 0x00000007; 54 | public const int TYPE_ATTRIBUTE_NOT_PUBLIC = 0x00000000; 55 | public const int TYPE_ATTRIBUTE_PUBLIC = 0x00000001; 56 | public const int TYPE_ATTRIBUTE_NESTED_PUBLIC = 0x00000002; 57 | public const int TYPE_ATTRIBUTE_NESTED_PRIVATE = 0x00000003; 58 | public const int TYPE_ATTRIBUTE_NESTED_FAMILY = 0x00000004; 59 | public const int TYPE_ATTRIBUTE_NESTED_ASSEMBLY = 0x00000005; 60 | public const int TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM = 0x00000006; 61 | public const int TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM = 0x00000007; 62 | 63 | 64 | public const int TYPE_ATTRIBUTE_INTERFACE = 0x00000020; 65 | 66 | public const int TYPE_ATTRIBUTE_ABSTRACT = 0x00000080; 67 | public const int TYPE_ATTRIBUTE_SEALED = 0x00000100; 68 | 69 | public const int TYPE_ATTRIBUTE_SERIALIZABLE = 0x00002000; 70 | 71 | /* 72 | * Flags for Params (22.1.12) 73 | */ 74 | public const int PARAM_ATTRIBUTE_OUT = 0x0002; 75 | public const int PARAM_ATTRIBUTE_OPTIONAL = 0x0010; 76 | 77 | 78 | public static readonly Dictionary TypeString = new Dictionary 79 | { 80 | {1,"void"}, 81 | {2,"bool"}, 82 | {3,"char"}, 83 | {4,"sbyte"}, 84 | {5,"byte"}, 85 | {6,"short"}, 86 | {7,"ushort"}, 87 | {8,"int"}, 88 | {9,"uint"}, 89 | {10,"long"}, 90 | {11,"ulong"}, 91 | {12,"float"}, 92 | {13,"double"}, 93 | {14,"string"}, 94 | {19,"T"}, 95 | {22,"System.TypedReference"}, 96 | {24,"IntPtr"}, 97 | {25,"UIntPtr"}, 98 | {28,"object"}, 99 | {30,"T"}, 100 | }; 101 | 102 | public static Version Unity20183 = new Version(2018, 3); 103 | public static Version Unity20191 = new Version(2019, 1); 104 | } 105 | 106 | static class ElfConstants 107 | { 108 | public const int DT_PLTGOT = 3; 109 | public const int DT_STRTAB = 5; 110 | public const int DT_SYMTAB = 6; 111 | public const int DT_RELA = 7; 112 | public const int DT_RELASZ = 8; 113 | public const int DT_REL = 17; 114 | public const int DT_RELSZ = 18; 115 | public const int DT_INIT_ARRAY = 25; 116 | public const int DT_INIT_ARRAYSZ = 27; 117 | 118 | public const int R_ARM_ABS32 = 2; 119 | 120 | public const int R_386_32 = 1; 121 | 122 | public const int R_AARCH64_ABS64 = 257; 123 | public const int R_AARCH64_RELATIVE = 1027; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /DumpWrapper/DumpWrapper/DumpData.cs: -------------------------------------------------------------------------------- 1 | namespace Wrapper 2 | { 3 | public class DumpType 4 | { 5 | public string Namespace { get; set; } 6 | public DumpAttribute[] Attributes { get; set; } 7 | public string Modifier { get; set; } 8 | public string TypeStr { get; set; } 9 | public string Name { get; set; } 10 | public string[] Extends { get; set; } 11 | public DumpField[] Fields { get; set; } 12 | public DumpProperty[] Properties { get; set; } 13 | public DumpMethod[] Methods { get; set; } 14 | } 15 | 16 | public class DumpAttribute 17 | { 18 | public string Name { get; set; } 19 | public ulong Address { get; set; } 20 | } 21 | 22 | public class DumpField 23 | { 24 | public DumpAttribute[] Attributes { get; set; } 25 | public string Modifier { get; set; } 26 | public string TypeStr { get; set; } 27 | public string Name { get; set; } 28 | public string ValueStr { get; set; } 29 | } 30 | 31 | public class DumpProperty 32 | { 33 | public DumpAttribute[] Attributes { get; set; } 34 | public string Modifier { get; set; } 35 | public string TypeStr { get; set; } 36 | public string Name { get; set; } 37 | public string Access { get; set; } 38 | } 39 | 40 | public class DumpMethod 41 | { 42 | public DumpAttribute[] Attributes { get; set; } 43 | public string Modifier { get; set; } 44 | public string TypeStr { get; set; } 45 | public string Name { get; set; } 46 | public string[] Parameters { get; set; } 47 | public ulong Address { get; set; } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /DumpWrapper/DumpWrapper/DumpWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Web.Script.Serialization; 8 | using Il2CppDumper; 9 | using static Wrapper.DefineConstants; 10 | 11 | namespace Wrapper 12 | { 13 | public static class DumpWrapper 14 | { 15 | private const string CONFIG_JSON = "{\"DumpMethod\":true,\"DumpField\":true,\"DumpProperty\":true,\"DumpAttribute\":true,\"DumpFieldOffset\":true,\"DumpMethodOffset\":true,\"DumpTypeDefIndex\":true,\"DummyDll\":true,\"MakeFunction\":true,\"ForceIl2CppVersion\":false,\"ForceVersion\":16}"; 16 | 17 | private static Metadata metadata; 18 | private static Il2Cpp il2cpp; 19 | private static Config config; 20 | private static Dictionary methodModifiers = new Dictionary(); 21 | private static Dictionary typeDefImageIndices = new Dictionary(); 22 | 23 | public static DumpType[] Dump(string metadataPath, string il2cppPath, string stringVersion) 24 | { 25 | // From Program.cs 26 | 27 | config = new JavaScriptSerializer().Deserialize(CONFIG_JSON); 28 | 29 | var metadataBytes = File.ReadAllBytes(metadataPath); 30 | var il2cppBytes = File.ReadAllBytes(il2cppPath); 31 | 32 | var sanity = BitConverter.ToUInt32(metadataBytes, 0); 33 | if (sanity != 0xFAB11BAF) 34 | { 35 | throw new Exception("ERROR: Metadata file supplied is not valid metadata file."); 36 | } 37 | float fixedMetadataVersion; 38 | var metadataVersion = BitConverter.ToInt32(metadataBytes, 4); 39 | if (metadataVersion == 24) 40 | { 41 | var versionSplit = Array.ConvertAll(Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries), int.Parse); 42 | var unityVersion = new Version(versionSplit[0], versionSplit[1]); 43 | if (unityVersion >= Unity20191) 44 | { 45 | fixedMetadataVersion = 24.2f; 46 | } 47 | else if (unityVersion >= Unity20183) 48 | { 49 | fixedMetadataVersion = 24.1f; 50 | } 51 | else 52 | { 53 | fixedMetadataVersion = metadataVersion; 54 | } 55 | } 56 | else 57 | { 58 | fixedMetadataVersion = metadataVersion; 59 | } 60 | Console.WriteLine("Initializing metadata..."); 61 | metadata = new Metadata(new MemoryStream(metadataBytes), fixedMetadataVersion); 62 | //判断il2cpp的magic 63 | var il2cppMagic = BitConverter.ToUInt32(il2cppBytes, 0); 64 | var isElf = false; 65 | var isPE = false; 66 | var is64bit = false; 67 | var isNSO = false; 68 | switch (il2cppMagic) 69 | { 70 | default: 71 | throw new Exception("ERROR: il2cpp file not supported."); 72 | case 0x304F534E: 73 | isNSO = true; 74 | is64bit = true; 75 | break; 76 | case 0x905A4D: //PE 77 | isPE = true; 78 | break; 79 | case 0x464c457f: //ELF 80 | isElf = true; 81 | if (il2cppBytes[4] == 2) //ELF64 82 | { 83 | is64bit = true; 84 | } 85 | break; 86 | case 0xCAFEBABE: //FAT Mach-O 87 | case 0xBEBAFECA: 88 | // To 64bit 89 | case 0xFEEDFACF: // 64bit Mach-O 90 | is64bit = true; 91 | break; 92 | case 0xFEEDFACE: // 32bit Mach-O 93 | break; 94 | } 95 | 96 | var version = config.ForceIl2CppVersion ? config.ForceVersion : metadata.version; 97 | if (isNSO) 98 | { 99 | var nso = new NSO(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages); 100 | il2cpp = nso.UnCompress(); 101 | } 102 | else if (isPE) 103 | { 104 | il2cpp = new PE(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages); 105 | } 106 | else if (isElf) 107 | { 108 | if (is64bit) 109 | il2cpp = new Elf64(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages); 110 | else 111 | il2cpp = new Elf(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages); 112 | } 113 | else if (is64bit) 114 | il2cpp = new Macho64(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages); 115 | else 116 | il2cpp = new Macho(new MemoryStream(il2cppBytes), version, metadata.maxMetadataUsages); 117 | Console.WriteLine("Searching..."); 118 | try 119 | { 120 | // Select Auto(Plus) 121 | bool flag = il2cpp.PlusSearch(metadata.methodDefs.Count(x => x.methodIndex >= 0), metadata.typeDefs.Length); 122 | if (!flag) 123 | throw new Exception(); 124 | } 125 | catch 126 | { 127 | throw new Exception("ERROR: Can't use this mode to process file, try another mode."); 128 | } 129 | 130 | Console.WriteLine("Dumping..."); 131 | //dump type 132 | var dumpTypes = new List(); 133 | for (var imageIndex = 0; imageIndex < metadata.imageDefs.Length; imageIndex++) 134 | { 135 | try 136 | { 137 | var imageDef = metadata.imageDefs[imageIndex]; 138 | var typeEnd = imageDef.typeStart + imageDef.typeCount; 139 | for (int idx = imageDef.typeStart; idx < typeEnd; idx++) 140 | { 141 | var dumpType = new DumpType(); 142 | var typeDef = metadata.typeDefs[idx]; 143 | typeDefImageIndices.Add(typeDef, imageIndex); 144 | var isStruct = false; 145 | var isEnum = false; 146 | var extends = new List(); 147 | if (typeDef.parentIndex >= 0) 148 | { 149 | var parent = il2cpp.types[typeDef.parentIndex]; 150 | var parentName = GetTypeName(parent); 151 | if (parentName == "ValueType") 152 | isStruct = true; 153 | else if (parentName == "Enum") 154 | isEnum = true; 155 | else if (parentName != "object") 156 | extends.Add(parentName); 157 | } 158 | //implementedInterfaces 159 | if (typeDef.interfaces_count > 0) 160 | { 161 | for (int i = 0; i < typeDef.interfaces_count; i++) 162 | { 163 | var @interface = il2cpp.types[metadata.interfaceIndices[typeDef.interfacesStart + i]]; 164 | extends.Add(GetTypeName(@interface)); 165 | } 166 | } 167 | dumpType.Namespace = metadata.GetStringFromIndex(typeDef.namespaceIndex); 168 | var dumpTypeAttributes = new List(); 169 | var typeAttributes = GetCustomAttributes(imageDef, typeDef.customAttributeIndex, typeDef.token); 170 | if (typeAttributes != null) 171 | { 172 | dumpTypeAttributes.AddRange(typeAttributes); 173 | } 174 | if (config.DumpAttribute && (typeDef.flags & TYPE_ATTRIBUTE_SERIALIZABLE) != 0) 175 | dumpTypeAttributes.Add(new DumpAttribute { Name = "[Serializable]" }); 176 | dumpType.Attributes = dumpTypeAttributes.ToArray(); 177 | var visibility = typeDef.flags & TYPE_ATTRIBUTE_VISIBILITY_MASK; 178 | switch (visibility) 179 | { 180 | case TYPE_ATTRIBUTE_PUBLIC: 181 | case TYPE_ATTRIBUTE_NESTED_PUBLIC: 182 | dumpType.Modifier += "public "; 183 | break; 184 | case TYPE_ATTRIBUTE_NOT_PUBLIC: 185 | case TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM: 186 | case TYPE_ATTRIBUTE_NESTED_ASSEMBLY: 187 | dumpType.Modifier += "internal "; 188 | break; 189 | case TYPE_ATTRIBUTE_NESTED_PRIVATE: 190 | dumpType.Modifier += "private "; 191 | break; 192 | case TYPE_ATTRIBUTE_NESTED_FAMILY: 193 | dumpType.Modifier += "protected "; 194 | break; 195 | case TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM: 196 | dumpType.Modifier += "protected internal "; 197 | break; 198 | } 199 | if ((typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0 && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0) 200 | dumpType.Modifier += "static "; 201 | else if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) == 0 && (typeDef.flags & TYPE_ATTRIBUTE_ABSTRACT) != 0) 202 | dumpType.Modifier += "abstract "; 203 | else if (!isStruct && !isEnum && (typeDef.flags & TYPE_ATTRIBUTE_SEALED) != 0) 204 | dumpType.Modifier += "sealed "; 205 | dumpType.Modifier.TrimEnd(); 206 | if ((typeDef.flags & TYPE_ATTRIBUTE_INTERFACE) != 0) 207 | dumpType.TypeStr = "interface"; 208 | else if (isStruct) 209 | dumpType.TypeStr = "struct"; 210 | else if (isEnum) 211 | dumpType.TypeStr = "enum"; 212 | else 213 | dumpType.TypeStr = "class"; 214 | var typeName = GetTypeName(typeDef); 215 | dumpType.Name = $"{typeName}"; 216 | if (extends.Count > 0) 217 | dumpType.Extends = extends.ToArray(); 218 | //dump field 219 | var dumpFields = new List(); 220 | if (config.DumpField && typeDef.field_count > 0) 221 | { 222 | var fieldEnd = typeDef.fieldStart + typeDef.field_count; 223 | for (var i = typeDef.fieldStart; i < fieldEnd; ++i) 224 | { 225 | //dump_field(i, idx, i - typeDef.fieldStart); 226 | var dumpField = new DumpField(); 227 | var fieldDef = metadata.fieldDefs[i]; 228 | var fieldType = il2cpp.types[fieldDef.typeIndex]; 229 | var fieldDefaultValue = metadata.GetFieldDefaultValueFromIndex(i); 230 | var fieldAttributes = GetCustomAttributes(imageDef, fieldDef.customAttributeIndex, fieldDef.token); 231 | if (fieldAttributes != null) 232 | { 233 | dumpField.Attributes = fieldAttributes; 234 | } 235 | var access = fieldType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK; 236 | switch (access) 237 | { 238 | case FIELD_ATTRIBUTE_PRIVATE: 239 | dumpField.Modifier += "private "; 240 | break; 241 | case FIELD_ATTRIBUTE_PUBLIC: 242 | dumpField.Modifier += "public "; 243 | break; 244 | case FIELD_ATTRIBUTE_FAMILY: 245 | dumpField.Modifier += "protected "; 246 | break; 247 | case FIELD_ATTRIBUTE_ASSEMBLY: 248 | case FIELD_ATTRIBUTE_FAM_AND_ASSEM: 249 | dumpField.Modifier += "internal "; 250 | break; 251 | case FIELD_ATTRIBUTE_FAM_OR_ASSEM: 252 | dumpField.Modifier += "protected internal "; 253 | break; 254 | } 255 | if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0) 256 | { 257 | dumpField.Modifier += "const "; 258 | } 259 | else 260 | { 261 | if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0) 262 | dumpField.Modifier += "static "; 263 | if ((fieldType.attrs & FIELD_ATTRIBUTE_INIT_ONLY) != 0) 264 | dumpField.Modifier += "readonly "; 265 | } 266 | dumpField.TypeStr = GetTypeName(fieldType); 267 | dumpField.Name = metadata.GetStringFromIndex(fieldDef.nameIndex); 268 | if (fieldDefaultValue != null && fieldDefaultValue.dataIndex != -1) 269 | { 270 | var pointer = metadata.GetDefaultValueFromIndex(fieldDefaultValue.dataIndex); 271 | if (pointer > 0) 272 | { 273 | var fieldDefaultValueType = il2cpp.types[fieldDefaultValue.typeIndex]; 274 | metadata.Position = pointer; 275 | object val = null; 276 | switch (fieldDefaultValueType.type) 277 | { 278 | case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: 279 | val = metadata.ReadBoolean(); 280 | break; 281 | case Il2CppTypeEnum.IL2CPP_TYPE_U1: 282 | val = metadata.ReadByte(); 283 | break; 284 | case Il2CppTypeEnum.IL2CPP_TYPE_I1: 285 | val = metadata.ReadSByte(); 286 | break; 287 | case Il2CppTypeEnum.IL2CPP_TYPE_CHAR: 288 | val = BitConverter.ToChar(metadata.ReadBytes(2), 0); 289 | break; 290 | case Il2CppTypeEnum.IL2CPP_TYPE_U2: 291 | val = metadata.ReadUInt16(); 292 | break; 293 | case Il2CppTypeEnum.IL2CPP_TYPE_I2: 294 | val = metadata.ReadInt16(); 295 | break; 296 | case Il2CppTypeEnum.IL2CPP_TYPE_U4: 297 | val = metadata.ReadUInt32(); 298 | break; 299 | case Il2CppTypeEnum.IL2CPP_TYPE_I4: 300 | val = metadata.ReadInt32(); 301 | break; 302 | case Il2CppTypeEnum.IL2CPP_TYPE_U8: 303 | val = metadata.ReadUInt64(); 304 | break; 305 | case Il2CppTypeEnum.IL2CPP_TYPE_I8: 306 | val = metadata.ReadInt64(); 307 | break; 308 | case Il2CppTypeEnum.IL2CPP_TYPE_R4: 309 | val = metadata.ReadSingle(); 310 | break; 311 | case Il2CppTypeEnum.IL2CPP_TYPE_R8: 312 | val = metadata.ReadDouble(); 313 | break; 314 | case Il2CppTypeEnum.IL2CPP_TYPE_STRING: 315 | var len = metadata.ReadInt32(); 316 | val = Encoding.UTF8.GetString(metadata.ReadBytes(len)); 317 | break; 318 | } 319 | if (val is string str) 320 | dumpField.ValueStr = $"\"{ToEscapedString(str)}\""; 321 | else if (val is char c) 322 | { 323 | var v = (int)c; 324 | dumpField.ValueStr = $"'\\x{v:x}'"; 325 | } 326 | else if (val != null) 327 | dumpField.ValueStr = $"{val}"; 328 | } 329 | } 330 | dumpFields.Add(dumpField); 331 | } 332 | } 333 | dumpType.Fields = dumpFields.ToArray(); 334 | //dump property 335 | var dumpProperties = new List(); 336 | if (config.DumpProperty && typeDef.property_count > 0) 337 | { 338 | var propertyEnd = typeDef.propertyStart + typeDef.property_count; 339 | for (var i = typeDef.propertyStart; i < propertyEnd; ++i) 340 | { 341 | var dumpProperty = new DumpProperty(); 342 | var propertyDef = metadata.propertyDefs[i]; 343 | var propertyAttributes = GetCustomAttributes(imageDef, propertyDef.customAttributeIndex, propertyDef.token); 344 | if (propertyAttributes != null) 345 | { 346 | dumpProperty.Attributes = propertyAttributes; 347 | } 348 | if (propertyDef.get >= 0) 349 | { 350 | var methodDef = metadata.methodDefs[typeDef.methodStart + propertyDef.get]; 351 | dumpProperty.Modifier = GetModifiers(methodDef); 352 | var propertyType = il2cpp.types[methodDef.returnType]; 353 | dumpProperty.TypeStr = GetTypeName(propertyType); 354 | dumpProperty.Name = metadata.GetStringFromIndex(propertyDef.nameIndex); 355 | } 356 | else if (propertyDef.set > 0) 357 | { 358 | var methodDef = metadata.methodDefs[typeDef.methodStart + propertyDef.set]; 359 | dumpProperty.Modifier = GetModifiers(methodDef); 360 | var parameterDef = metadata.parameterDefs[methodDef.parameterStart]; 361 | var propertyType = il2cpp.types[parameterDef.typeIndex]; 362 | dumpProperty.TypeStr = GetTypeName(propertyType); 363 | dumpProperty.Name = metadata.GetStringFromIndex(propertyDef.nameIndex); 364 | } 365 | dumpProperty.Access += "{ "; 366 | if (propertyDef.get >= 0) 367 | dumpProperty.Access += "get; "; 368 | if (propertyDef.set >= 0) 369 | dumpProperty.Access += "set; "; 370 | dumpProperty.Access += "}"; 371 | dumpProperties.Add(dumpProperty); 372 | } 373 | } 374 | dumpType.Properties = dumpProperties.ToArray(); 375 | //dump method 376 | var dumpMethods = new List(); 377 | if (config.DumpMethod && typeDef.method_count > 0) 378 | { 379 | var methodEnd = typeDef.methodStart + typeDef.method_count; 380 | for (var i = typeDef.methodStart; i < methodEnd; ++i) 381 | { 382 | var dumpMethod = new DumpMethod(); 383 | var methodDef = metadata.methodDefs[i]; 384 | var methodAttributes = GetCustomAttributes(imageDef, methodDef.customAttributeIndex, methodDef.token); 385 | if (methodAttributes != null) 386 | { 387 | dumpMethod.Attributes = methodAttributes; 388 | } 389 | dumpMethod.Modifier = GetModifiers(methodDef); 390 | var methodReturnType = il2cpp.types[methodDef.returnType]; 391 | var methodName = metadata.GetStringFromIndex(methodDef.nameIndex); 392 | dumpMethod.TypeStr = GetTypeName(methodReturnType); 393 | dumpMethod.Name = methodName; 394 | for (var j = 0; j < methodDef.parameterCount; ++j) 395 | { 396 | var parameterStr = ""; 397 | var parameterDef = metadata.parameterDefs[methodDef.parameterStart + j]; 398 | var parameterName = metadata.GetStringFromIndex(parameterDef.nameIndex); 399 | var parameterType = il2cpp.types[parameterDef.typeIndex]; 400 | var parameterTypeName = GetTypeName(parameterType); 401 | if ((parameterType.attrs & PARAM_ATTRIBUTE_OPTIONAL) != 0) 402 | parameterStr += "optional "; 403 | if ((parameterType.attrs & PARAM_ATTRIBUTE_OUT) != 0) 404 | parameterStr += "out "; 405 | parameterStr += $"{parameterTypeName} {parameterName}"; 406 | dumpMethod.Parameters = new string[] { parameterStr }; 407 | } 408 | if (config.DumpMethodOffset) 409 | { 410 | var methodPointer = il2cpp.GetMethodPointer(methodDef.methodIndex, i, imageIndex, methodDef.token); 411 | if (methodPointer > 0) 412 | { 413 | dumpMethod.Address = il2cpp.MapVATR(methodPointer); 414 | } 415 | } 416 | dumpMethods.Add(dumpMethod); 417 | } 418 | } 419 | dumpType.Methods = dumpMethods.ToArray(); 420 | dumpTypes.Add(dumpType); 421 | } 422 | } 423 | catch 424 | { 425 | throw new Exception("ERROR: Some errors in dumping."); 426 | } 427 | } 428 | 429 | return dumpTypes.ToArray(); 430 | } 431 | 432 | private static string GetTypeName(Il2CppType type, bool fullName = false) 433 | { 434 | string ret; 435 | switch (type.type) 436 | { 437 | case Il2CppTypeEnum.IL2CPP_TYPE_CLASS: 438 | case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE: 439 | { 440 | var typeDef = metadata.typeDefs[type.data.klassIndex]; 441 | ret = string.Empty; 442 | if (fullName) 443 | { 444 | ret = metadata.GetStringFromIndex(typeDef.namespaceIndex); 445 | if (ret != string.Empty) 446 | { 447 | ret += "."; 448 | } 449 | } 450 | ret += GetTypeName(typeDef); 451 | break; 452 | } 453 | case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST: 454 | { 455 | var generic_class = il2cpp.MapVATR(type.data.generic_class); 456 | var typeDef = metadata.typeDefs[generic_class.typeDefinitionIndex]; 457 | ret = metadata.GetStringFromIndex(typeDef.nameIndex); 458 | var genericInst = il2cpp.MapVATR(generic_class.context.class_inst); 459 | ret += GetGenericTypeParams(genericInst); 460 | break; 461 | } 462 | case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY: 463 | { 464 | var arrayType = il2cpp.MapVATR(type.data.array); 465 | var oriType = il2cpp.GetIl2CppType(arrayType.etype); 466 | ret = $"{GetTypeName(oriType)}[{new string(',', arrayType.rank - 1)}]"; 467 | break; 468 | } 469 | case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: 470 | { 471 | var oriType = il2cpp.GetIl2CppType(type.data.type); 472 | ret = $"{GetTypeName(oriType)}[]"; 473 | break; 474 | } 475 | case Il2CppTypeEnum.IL2CPP_TYPE_PTR: 476 | { 477 | var oriType = il2cpp.GetIl2CppType(type.data.type); 478 | ret = $"{GetTypeName(oriType)}*"; 479 | break; 480 | } 481 | default: 482 | ret = TypeString[(int)type.type]; 483 | break; 484 | } 485 | 486 | return ret; 487 | } 488 | 489 | private static string GetTypeName(Il2CppTypeDefinition typeDef) 490 | { 491 | var ret = string.Empty; 492 | if (typeDef.declaringTypeIndex != -1) 493 | { 494 | ret += GetTypeName(il2cpp.types[typeDef.declaringTypeIndex]) + "."; 495 | } 496 | ret += metadata.GetStringFromIndex(typeDef.nameIndex); 497 | return ret; 498 | } 499 | 500 | private static string GetGenericTypeParams(Il2CppGenericInst genericInst) 501 | { 502 | var typeNames = new List(); 503 | var pointers = il2cpp.GetPointers(genericInst.type_argv, (long)genericInst.type_argc); 504 | for (uint i = 0; i < genericInst.type_argc; ++i) 505 | { 506 | var oriType = il2cpp.GetIl2CppType(pointers[i]); 507 | typeNames.Add(GetTypeName(oriType)); 508 | } 509 | return $"<{string.Join(", ", typeNames)}>"; 510 | } 511 | 512 | private static DumpAttribute[] GetCustomAttributes(Il2CppImageDefinition image, int customAttributeIndex, uint token, string padding = "") 513 | { 514 | if (!config.DumpAttribute || il2cpp.version < 21) 515 | return null; 516 | var index = metadata.GetCustomAttributeIndex(image, customAttributeIndex, token); 517 | if (index >= 0) 518 | { 519 | var attributeTypeRange = metadata.attributeTypeRanges[index]; 520 | var attributes = new List(); 521 | for (var i = 0; i < attributeTypeRange.count; i++) 522 | { 523 | var typeIndex = metadata.attributeTypes[attributeTypeRange.start + i]; 524 | var methodPointer = il2cpp.customAttributeGenerators[index]; 525 | var address = il2cpp.MapVATR(methodPointer); 526 | attributes.Add(new DumpAttribute { Address = address, Name = $"[{GetTypeName(il2cpp.types[typeIndex])}]" }); 527 | } 528 | return attributes.ToArray(); 529 | } 530 | else 531 | { 532 | return null; 533 | } 534 | } 535 | 536 | private static string GetModifiers(Il2CppMethodDefinition methodDef) 537 | { 538 | if (methodModifiers.TryGetValue(methodDef, out string str)) 539 | return str; 540 | var access = methodDef.flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK; 541 | switch (access) 542 | { 543 | case METHOD_ATTRIBUTE_PRIVATE: 544 | str += "private "; 545 | break; 546 | case METHOD_ATTRIBUTE_PUBLIC: 547 | str += "public "; 548 | break; 549 | case METHOD_ATTRIBUTE_FAMILY: 550 | str += "protected "; 551 | break; 552 | case METHOD_ATTRIBUTE_ASSEM: 553 | case METHOD_ATTRIBUTE_FAM_AND_ASSEM: 554 | str += "internal "; 555 | break; 556 | case METHOD_ATTRIBUTE_FAM_OR_ASSEM: 557 | str += "protected internal "; 558 | break; 559 | } 560 | if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) != 0) 561 | str += "static "; 562 | if ((methodDef.flags & METHOD_ATTRIBUTE_ABSTRACT) != 0) 563 | { 564 | str += "abstract "; 565 | if ((methodDef.flags & METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) == METHOD_ATTRIBUTE_REUSE_SLOT) 566 | str += "override "; 567 | } 568 | else if ((methodDef.flags & METHOD_ATTRIBUTE_FINAL) != 0) 569 | { 570 | if ((methodDef.flags & METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) == METHOD_ATTRIBUTE_REUSE_SLOT) 571 | str += "sealed override "; 572 | } 573 | else if ((methodDef.flags & METHOD_ATTRIBUTE_VIRTUAL) != 0) 574 | { 575 | if ((methodDef.flags & METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK) == METHOD_ATTRIBUTE_NEW_SLOT) 576 | str += "virtual "; 577 | else 578 | str += "override "; 579 | } 580 | if ((methodDef.flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) != 0) 581 | str += "extern "; 582 | methodModifiers.Add(methodDef, str); 583 | return str; 584 | } 585 | 586 | private static string ToEscapedString(string s) 587 | { 588 | var re = new StringBuilder(s.Length); 589 | foreach (var c in s) 590 | { 591 | switch (c) 592 | { 593 | case '\'': 594 | re.Append(@"\'"); 595 | break; 596 | case '"': 597 | re.Append(@"\"""); 598 | break; 599 | case '\t': 600 | re.Append(@"\t"); 601 | break; 602 | case '\n': 603 | re.Append(@"\n"); 604 | break; 605 | case '\r': 606 | re.Append(@"\r"); 607 | break; 608 | case '\f': 609 | re.Append(@"\f"); 610 | break; 611 | case '\b': 612 | re.Append(@"\b"); 613 | break; 614 | case '\\': 615 | re.Append(@"\\"); 616 | break; 617 | case '\0': 618 | re.Append(@"\0"); 619 | break; 620 | case '\u0085': 621 | re.Append(@"\u0085"); 622 | break; 623 | case '\u2028': 624 | re.Append(@"\u2028"); 625 | break; 626 | case '\u2029': 627 | re.Append(@"\u2029"); 628 | break; 629 | default: 630 | re.Append(c); 631 | break; 632 | } 633 | } 634 | return re.ToString(); 635 | } 636 | } 637 | } 638 | -------------------------------------------------------------------------------- /DumpWrapper/DumpWrapper/DumpWrapper.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {961C4433-2E3D-4927-938E-A10EBC9D69F6} 7 | Library 8 | DumpWrapper 9 | DumpWrapper 10 | v4.7 11 | 12 | 13 | true 14 | full 15 | false 16 | ..\..\Il2cppSpy\bin\Debug 17 | DEBUG; 18 | prompt 19 | 4 20 | false 21 | 22 | 23 | true 24 | ..\..\Il2cppSpy\bin\Release 25 | prompt 26 | 4 27 | false 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | {379715D4-4B7B-41F2-B78A-8B18D86320E2} 44 | Il2CppDumper 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /DumpWrapper/DumpWrapper/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("DumpWrapper")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /Il2cppSpy/application.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.append('../') 3 | sys.path.append('./ui/') 4 | import os 5 | from PySide2.QtCore import Qt 6 | from PySide2.QtGui import QIcon 7 | from PySide2.QtWidgets import QApplication, QMainWindow, QFileDialog, QProgressDialog, QDialog, QLabel, QHBoxLayout 8 | import qdarkstyle 9 | 10 | from Il2cppSpy.presentation.presenter.action_presenter import ActionPresenter 11 | from Il2cppSpy.presentation.view.explorer_view import ExplorerView 12 | from Il2cppSpy.presentation.view.tab_view import TabView 13 | from Il2cppSpy.ui.ui_mainwindow import Ui_MainWindow 14 | 15 | 16 | class MainWindow(QMainWindow): 17 | def __init__(self): 18 | super(MainWindow, self).__init__() 19 | ui = Ui_MainWindow() 20 | ui.setupUi(self) 21 | tab_view = TabView(ui) 22 | explorer_view = ExplorerView(ui, tab_view) 23 | self.action_presenter = ActionPresenter(explorer_view) 24 | ui.actionOpenFile.triggered.connect(self.action_open_file) 25 | ui.actionCompareFiles.triggered.connect(self.action_compare_files) 26 | 27 | def action_open_file(self): 28 | file_path, _ = QFileDialog.getOpenFileName(self, 'Open Apk', filter='Apk(*.apk)', options=QFileDialog.DontUseNativeDialog) 29 | if not file_path: 30 | return 31 | progress_dialog = QProgressDialog('Open Apk...', '', 0, 100, self) 32 | progress_dialog.setCancelButton(None) 33 | progress_dialog.setWindowModality(Qt.WindowModal) 34 | progress_dialog.setWindowFlags(Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint) 35 | progress_dialog.show() 36 | try: 37 | self.action_presenter.open_file(file_path, lambda value: progress_dialog.setValue(value * 100)) 38 | except: # noqa: E722 39 | progress_dialog.close() 40 | self.open_error_dialog() 41 | 42 | def action_compare_files(self): 43 | before_file_path, _ = QFileDialog.getOpenFileName(self, 'Open Before Apk', filter='Apk(*.apk)', options=QFileDialog.DontUseNativeDialog) 44 | if not before_file_path: 45 | return 46 | after_file_path, _ = QFileDialog.getOpenFileName(self, 'Open After Apk', filter='Apk(*.apk)', options=QFileDialog.DontUseNativeDialog) 47 | if not after_file_path: 48 | return 49 | progress_dialog = QProgressDialog('Compare Apks...', '', 0, 100, self) 50 | progress_dialog.setCancelButton(None) 51 | progress_dialog.setWindowModality(Qt.WindowModal) 52 | progress_dialog.setWindowFlags(Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint) 53 | progress_dialog.show() 54 | try: 55 | self.action_presenter.compare_files(before_file_path, after_file_path, lambda value: progress_dialog.setValue(value * 100)) 56 | except: # noqa: E722 57 | progress_dialog.close() 58 | self.open_error_dialog() 59 | 60 | def open_error_dialog(self): 61 | error_dialog = QDialog(self) 62 | label = QLabel() 63 | label.setText('Sorry...\nNot support this apk.') 64 | layout = QHBoxLayout() 65 | layout.addWidget(label) 66 | error_dialog.setLayout(layout) 67 | error_dialog.show() 68 | 69 | 70 | def resource_path(relative): 71 | if hasattr(sys, '_MEIPASS'): 72 | return os.path.join(sys._MEIPASS, relative) 73 | return os.path.join(relative) 74 | 75 | 76 | if __name__ == "__main__": 77 | app = QApplication(sys.argv) 78 | app.setStyleSheet(qdarkstyle.load_stylesheet_pyside2()) 79 | app.setWindowIcon(QIcon(resource_path('icon.ico'))) 80 | window = MainWindow() 81 | window.show() 82 | 83 | sys.exit(app.exec_()) 84 | -------------------------------------------------------------------------------- /Il2cppSpy/bin/Release/DumpWrapper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/Il2cppSpy/bin/Release/DumpWrapper.dll -------------------------------------------------------------------------------- /Il2cppSpy/bin/Release/Il2CppDumper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/Il2cppSpy/bin/Release/Il2CppDumper.exe -------------------------------------------------------------------------------- /Il2cppSpy/bin/Release/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/Il2cppSpy/bin/Release/Mono.Cecil.dll -------------------------------------------------------------------------------- /Il2cppSpy/bin/Release/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "DumpMethod": true, 3 | "DumpField": true, 4 | "DumpProperty": true, 5 | "DumpAttribute": true, 6 | "DumpFieldOffset": true, 7 | "DumpMethodOffset": true, 8 | "DumpTypeDefIndex": true, 9 | "DummyDll": true, 10 | "MakeFunction": true, 11 | "ForceIl2CppVersion": false, 12 | "ForceVersion": 16 13 | } -------------------------------------------------------------------------------- /Il2cppSpy/data/repository/assembly_repository.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from capstone import Cs, CS_ARCH_ARM, CS_MODE_ARM 3 | 4 | from Il2cppSpy.domain.repository.abstract_assembly_repository import AbstractAssemblyRepository 5 | from Il2cppSpy.domain.model.dump_data import DumpAssembly 6 | 7 | 8 | class AssemblyRepository(AbstractAssemblyRepository): 9 | def disassemble(self, code: bytes, address: int) -> List[DumpAssembly]: 10 | dump_assemblies = [] 11 | md = Cs(CS_ARCH_ARM, CS_MODE_ARM) 12 | for i in md.disasm(code, address): 13 | dump_assemblies.append(DumpAssembly(i.address, f'{i.mnemonic}\t{i.op_str}')) 14 | return dump_assemblies 15 | -------------------------------------------------------------------------------- /Il2cppSpy/data/repository/file_repository.py: -------------------------------------------------------------------------------- 1 | import zipfile 2 | 3 | from Il2cppSpy.domain.repository.abstract_file_repository import AbstractFileRepository 4 | 5 | 6 | class FileRepository(AbstractFileRepository): 7 | def decode(self, file_path: str, out_file_dir: str): 8 | with zipfile.ZipFile(file_path) as file_file: 9 | file_file.extractall(out_file_dir) 10 | -------------------------------------------------------------------------------- /Il2cppSpy/data/repository/il2cpp_repository.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import re 3 | from typing import List, Callable 4 | 5 | from Il2cppSpy.domain.model.dump_data import DumpType, DumpAssembly, DumpField, DumpProperty, DumpMethod 6 | from Il2cppSpy.domain.repository.abstract_il2cpp_repository import AbstractIl2cppRepository 7 | from Il2cppSpy.domain.repository.abstract_assembly_repository import AbstractAssemblyRepository 8 | from Il2cppSpy.utils.file_utils import strings 9 | 10 | import clr 11 | sys.path.append('./bin/Release') 12 | clr.AddReference('DumpWrapper') 13 | import Wrapper 14 | from Wrapper import DumpWrapper 15 | 16 | 17 | class Il2cppRepository(AbstractIl2cppRepository): 18 | def __init__(self, assembly_repository: AbstractAssemblyRepository): 19 | self.assembly_repository = assembly_repository 20 | 21 | def dump(self, out_apk_dir: str, progress: Callable[[float], None]) -> List[DumpType]: 22 | result = DumpWrapper.Dump(self.metadata_path(out_apk_dir), self.il2cpp_path(out_apk_dir), self.unity_version(out_apk_dir)) 23 | return self.to_model(result, out_apk_dir, progress) 24 | 25 | def metadata_path(self, out_apk_dir: str) -> str: 26 | return f'{out_apk_dir}/assets/bin/Data/Managed/Metadata/global-metadata.dat' 27 | 28 | def il2cpp_path(self, out_apk_dir: str) -> str: 29 | return f'{out_apk_dir}/lib/armeabi-v7a/libil2cpp.so' 30 | 31 | def unity_version(self, out_apk_dir: str) -> str: 32 | for s in strings(f'{out_apk_dir}/assets/bin/Data/Resources/unity_builtin_extra'): 33 | result = re.search(r'20[0-9]{2}\.[0-9]', s) 34 | if result: 35 | return result.group() 36 | # Before prefab in prefab 37 | return '2018.2' 38 | 39 | def to_model(self, wrapper_dump_types: List[Wrapper.DumpType], out_apk_dir: str, progress: Callable[[float], None]) -> List[DumpType]: 40 | il2cpp_path = self.il2cpp_path(out_apk_dir) 41 | with open(il2cpp_path, 'rb') as f: 42 | il2cpp_bytes = f.read() 43 | dump_types = [] 44 | pre_address = 0 45 | pre_assemblies: List[DumpAssembly] = [] 46 | for i, wrapper_dump_type in enumerate(wrapper_dump_types): 47 | dump_attributes = [] 48 | if wrapper_dump_type.Attributes: 49 | for dumpAttribute in wrapper_dump_type.Attributes: 50 | if dumpAttribute.Address and pre_address: 51 | address = pre_address 52 | code = il2cpp_bytes[address:dumpAttribute.Address] 53 | pre_assemblies.extend(self.assembly_repository.disassemble(code, address)) 54 | pre_address = 0 55 | pre_assemblies = [] 56 | dump_attributes.append(dumpAttribute.Name) 57 | dump_fields = [] 58 | if wrapper_dump_type.Fields: 59 | for dumpField in wrapper_dump_type.Fields: 60 | dump_field_attributes = [] 61 | if dumpField.Attributes: 62 | for dumpFieldAttribute in dumpField.Attributes: 63 | if dumpFieldAttribute.Address and pre_address: 64 | address = pre_address 65 | code = il2cpp_bytes[address:dumpFieldAttribute.Address] 66 | pre_assemblies.extend(self.assembly_repository.disassemble(code, address)) 67 | pre_address = 0 68 | pre_assemblies = [] 69 | dump_field_attributes.append(dumpFieldAttribute.Name) 70 | dump_fields.append(DumpField(dump_field_attributes, dumpField.Modifier, dumpField.TypeStr, dumpField.Name, dumpField.ValueStr)) 71 | dump_properties = [] 72 | if wrapper_dump_type.Properties: 73 | for dumpProperty in wrapper_dump_type.Properties: 74 | dump_property_attributes = [] 75 | if dumpProperty.Attributes: 76 | for dumpPropertyAttribute in dumpProperty.Attributes: 77 | if dumpPropertyAttribute.Address and pre_address: 78 | address = pre_address 79 | code = il2cpp_bytes[address:dumpPropertyAttribute.Address] 80 | pre_assemblies.extend(self.assembly_repository.disassemble(code, address)) 81 | pre_address = 0 82 | pre_assemblies = [] 83 | dump_property_attributes.append(dumpPropertyAttribute.Name) 84 | dump_properties.append(DumpProperty(dump_property_attributes, dumpProperty.Modifier, dumpProperty.TypeStr, dumpProperty.Name, dumpProperty.Access)) 85 | dump_methods = [] 86 | if wrapper_dump_type.Methods: 87 | for j, dumpMethod in enumerate(wrapper_dump_type.Methods): 88 | dump_method_attributes = [] 89 | if dumpMethod.Attributes: 90 | for dumpMethodAttribute in dumpMethod.Attributes: 91 | if dumpMethodAttribute.Address and pre_address: 92 | address = pre_address 93 | code = il2cpp_bytes[address:dumpMethodAttribute.Address] 94 | pre_assemblies.extend(self.assembly_repository.disassemble(code, address)) 95 | pre_address = 0 96 | pre_assemblies = [] 97 | dump_method_attributes.append(dumpMethodAttribute.Name) 98 | if dumpMethod.Address: 99 | if pre_address: 100 | address = pre_address 101 | code = il2cpp_bytes[address:dumpMethod.Address] 102 | pre_assemblies.extend(self.assembly_repository.disassemble(code, address)) 103 | pre_address = dumpMethod.Address 104 | pre_assemblies = [] 105 | dump_parameters = [] 106 | if dumpMethod.Parameters: 107 | for dump_parameter in dumpMethod.Parameters: 108 | dump_parameters.append(dump_parameter) 109 | dump_methods.append(DumpMethod(dump_method_attributes, dumpMethod.Modifier, dumpMethod.TypeStr, dumpMethod.Name, dump_parameters, pre_assemblies)) 110 | progress((i + (j / len(wrapper_dump_type.Methods))) / len(wrapper_dump_types)) 111 | dump_extends = [] 112 | if wrapper_dump_type.Extends: 113 | for dump_extend in wrapper_dump_type.Extends: 114 | dump_extends.append(dump_extend) 115 | dump_types.append(DumpType(wrapper_dump_type.Namespace, dump_attributes, wrapper_dump_type.Modifier, wrapper_dump_type.TypeStr, wrapper_dump_type.Name, dump_extends, dump_fields, dump_properties, dump_methods)) 116 | progress((i + 1) / len(wrapper_dump_types)) 117 | return dump_types 118 | -------------------------------------------------------------------------------- /Il2cppSpy/domain/model/dump_data.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class DumpAssembly: 5 | def __init__(self, address: int = 0, assembly: str = '', is_diff: bool = False): 6 | self.address = address 7 | self.assembly = assembly 8 | self.is_diff = is_diff 9 | 10 | 11 | class DumpField: 12 | def __init__(self, attributes: List[str] = [], modifier: str = '', type_str: str = '', name: str = '', value_str: str = ''): 13 | self.attributes = attributes 14 | self.modifier = modifier 15 | self.type_str = type_str 16 | self.name = name 17 | self.value_str = value_str 18 | 19 | 20 | class DumpProperty: 21 | def __init__(self, attributes: List[str] = [], modifier: str = '', type_str: str = '', name: str = '', access: str = ''): 22 | self.attributes = attributes 23 | self.modifier = modifier 24 | self.type_str = type_str 25 | self.name = name 26 | self.access = access 27 | 28 | 29 | class DumpMethod: 30 | def __init__(self, attributes: List[str] = [], modifier: str = '', type_str: str = '', name: str = '', parameters: List[str] = [], assemblies: List[DumpAssembly] = []): 31 | self.attributes = attributes 32 | self.modifier = modifier 33 | self.type_str = type_str 34 | self.name = name 35 | self.parameters = parameters 36 | self.assemblies = assemblies 37 | 38 | 39 | class DumpType: 40 | def __init__(self, namespace: str = '', attributes: List[str] = [], modifier: str = '', type_str: str = '', name: str = '', extends: List[str] = [], fields: List[DumpField] = [], properties: List[DumpProperty] = [], methods: List[DumpMethod] = []): 41 | self.namespace = namespace 42 | self.attributes = attributes 43 | self.modifier = modifier 44 | self.type_str = type_str 45 | self.name = name 46 | self.extends = extends 47 | self.fields = fields 48 | self.properties = properties 49 | self.methods = methods 50 | 51 | 52 | class DumpFile: 53 | def __init__(self, file_path: str, dump_types: List[DumpType], is_diff: bool): 54 | self.file_path = file_path 55 | self.dump_types = dump_types 56 | self.is_diff = is_diff 57 | -------------------------------------------------------------------------------- /Il2cppSpy/domain/repository/abstract_assembly_repository.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from abc import ABCMeta, abstractmethod 3 | 4 | from Il2cppSpy.domain.model.dump_data import DumpAssembly 5 | 6 | 7 | class AbstractAssemblyRepository(metaclass=ABCMeta): 8 | @abstractmethod 9 | def disassemble(self, code: bytes) -> List[DumpAssembly]: 10 | pass 11 | -------------------------------------------------------------------------------- /Il2cppSpy/domain/repository/abstract_file_repository.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class AbstractFileRepository(metaclass=ABCMeta): 5 | @abstractmethod 6 | def decode(self): 7 | pass 8 | -------------------------------------------------------------------------------- /Il2cppSpy/domain/repository/abstract_il2cpp_repository.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class AbstractIl2cppRepository(metaclass=ABCMeta): 5 | @abstractmethod 6 | def dump(self): 7 | pass 8 | -------------------------------------------------------------------------------- /Il2cppSpy/domain/use_case/compare_files_use_case.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tempfile 3 | from typing import List, Callable 4 | 5 | from Il2cppSpy.domain.model.dump_data import DumpFile, DumpType 6 | from Il2cppSpy.domain.repository.abstract_file_repository import AbstractFileRepository 7 | from Il2cppSpy.domain.repository.abstract_il2cpp_repository import AbstractIl2cppRepository 8 | 9 | 10 | class CompareFilesUseCase: 11 | def __init__(self, file_repository: AbstractFileRepository, il2cpp_repository: AbstractIl2cppRepository): 12 | self.file_repository = file_repository 13 | self.il2cpp_repository = il2cpp_repository 14 | 15 | def execute(self, before_file_path: str, after_file_path: str, progress: Callable[[float], None]) -> DumpFile: 16 | with tempfile.TemporaryDirectory() as temp_dir: 17 | # Before 18 | before_file_name = os.path.splitext(os.path.basename(before_file_path))[0] 19 | out_before_file_dir = f'{temp_dir}/{before_file_name}-before' 20 | self.file_repository.decode(before_file_path, out_before_file_dir) 21 | before_result = self.il2cpp_repository.dump(out_before_file_dir, lambda value: progress(value * 0.49)) 22 | # After 23 | after_file_name = os.path.splitext(os.path.basename(after_file_path))[0] 24 | out_after_file_dir = f'{temp_dir}/{after_file_name}-after' 25 | self.file_repository.decode(after_file_path, out_after_file_dir) 26 | after_result = self.il2cpp_repository.dump(out_after_file_dir, lambda value: progress(0.49 + value * 0.49)) 27 | # Compare 28 | compare_result = self.compare(before_result, after_result) 29 | progress(1) 30 | return DumpFile(before_file_path, compare_result, True) 31 | 32 | def compare(self, before_dump_types: List[DumpType], after_dump_types: List[DumpType]) -> List[DumpType]: 33 | dump_type_diffs = [] 34 | for before_dump_type, after_dump_type in zip(before_dump_types, after_dump_types): 35 | exists_diff = False 36 | for before_dump_method, after_dump_method in zip(before_dump_type.methods, after_dump_type.methods): 37 | for before_dump_assembly, after_dump_assembly in zip(before_dump_method.assemblies, after_dump_method.assemblies): 38 | if before_dump_assembly.assembly != after_dump_assembly.assembly: 39 | exists_diff = True 40 | after_dump_assembly.is_diff = True 41 | if exists_diff: 42 | dump_type_diffs.append(after_dump_type) 43 | return dump_type_diffs 44 | -------------------------------------------------------------------------------- /Il2cppSpy/domain/use_case/open_file_use_case.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tempfile 3 | from typing import Callable 4 | 5 | from Il2cppSpy.domain.model.dump_data import DumpFile 6 | from Il2cppSpy.domain.repository.abstract_file_repository import AbstractFileRepository 7 | from Il2cppSpy.domain.repository.abstract_il2cpp_repository import AbstractIl2cppRepository 8 | 9 | 10 | class OpenFileUseCase: 11 | def __init__(self, file_repository: AbstractFileRepository, il2cpp_repository: AbstractIl2cppRepository): 12 | self.file_repository = file_repository 13 | self.il2cpp_repository = il2cpp_repository 14 | 15 | def execute(self, file_path: str, progress: Callable[[float], None]) -> DumpFile: 16 | with tempfile.TemporaryDirectory() as temp_dir: 17 | file_name = os.path.splitext(os.path.basename(file_path))[0] 18 | out_file_dir = f'{temp_dir}/{file_name}' 19 | self.file_repository.decode(file_path, out_file_dir) 20 | result = self.il2cpp_repository.dump(out_file_dir, progress) 21 | return DumpFile(file_path, result, False) 22 | -------------------------------------------------------------------------------- /Il2cppSpy/presentation/presenter/action_presenter.py: -------------------------------------------------------------------------------- 1 | from typing import Callable 2 | 3 | from Il2cppSpy.data.repository.assembly_repository import AssemblyRepository 4 | from Il2cppSpy.data.repository.il2cpp_repository import Il2cppRepository 5 | from Il2cppSpy.data.repository.file_repository import FileRepository 6 | from Il2cppSpy.domain.use_case.open_file_use_case import OpenFileUseCase 7 | from Il2cppSpy.domain.use_case.compare_files_use_case import CompareFilesUseCase 8 | from Il2cppSpy.presentation.view.explorer_view import ExplorerView 9 | 10 | 11 | class ActionPresenter: 12 | def __init__(self, explorer_view: ExplorerView): 13 | self.explorer_view = explorer_view 14 | 15 | def open_file(self, file_path: str, progress: Callable[[float], None]): 16 | open_file = OpenFileUseCase(FileRepository(), Il2cppRepository(AssemblyRepository())) 17 | result = open_file.execute(file_path, progress) 18 | self.explorer_view.add_file(result) 19 | 20 | def compare_files(self, before_file_path: str, after_file_path: str, progress: Callable[[float], None]): 21 | compare_files = CompareFilesUseCase(FileRepository(), Il2cppRepository(AssemblyRepository())) 22 | result = compare_files.execute(before_file_path, after_file_path, progress) 23 | self.explorer_view.add_file(result) 24 | -------------------------------------------------------------------------------- /Il2cppSpy/presentation/view/explorer_view.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from PySide2.QtCore import Qt 3 | from PySide2.QtWidgets import QTreeWidgetItem 4 | 5 | from Il2cppSpy.domain.model.dump_data import DumpFile, DumpType 6 | from Il2cppSpy.ui.ui_mainwindow import Ui_MainWindow 7 | from Il2cppSpy.presentation.view.tab_view import TabView 8 | import Il2cppSpy.ui.ui_color as color 9 | 10 | 11 | class ExplorerView: 12 | def __init__(self, ui: Ui_MainWindow, tab_view: TabView): 13 | self.ui = ui 14 | self.tab_view = tab_view 15 | self.dump_types: Dict[QTreeWidgetItem, DumpType] = {} 16 | 17 | def add_file(self, dump_file: DumpFile): 18 | file_item = QTreeWidgetItem(self.ui.treeWidget) 19 | item_text = f' {dump_file.file_path}' if dump_file.is_diff else dump_file.file_path 20 | file_item.setText(0, item_text) 21 | tree_items: Dict[str, QTreeWidgetItem] = {} 22 | for dump_type in dump_file.dump_types: 23 | if dump_type.name.startswith('<'): 24 | continue 25 | names = dump_type.namespace.split('.') 26 | parent = file_item 27 | key = '' 28 | for name in names: 29 | if not name: 30 | continue 31 | key += name 32 | if key not in tree_items.keys(): 33 | tree_item = QTreeWidgetItem(parent) 34 | tree_item.setText(0, name) 35 | tree_items[key] = tree_item 36 | parent = tree_items[key] 37 | tree_item = QTreeWidgetItem(parent) 38 | tree_item.setText(0, dump_type.name) 39 | background_color = color.EXPLORER_DIFF_TEXT_COLOR if dump_file.is_diff else color.EXPLORER_TYPE_TEXT_COLOR 40 | tree_item.setTextColor(0, background_color) 41 | self.dump_types[tree_item] = dump_type 42 | file_item.sortChildren(0, Qt.AscendingOrder) 43 | self.ui.treeWidget.itemClicked.connect(self.item_clicked) 44 | 45 | def item_clicked(self, item, column): 46 | if item in self.dump_types.keys(): 47 | self.tab_view.open_type(self.dump_types[item]) 48 | -------------------------------------------------------------------------------- /Il2cppSpy/presentation/view/tab_item_view.py: -------------------------------------------------------------------------------- 1 | from PySide2.QtCore import Qt 2 | from PySide2.QtGui import QColor 3 | from PySide2.QtWidgets import QWidget, QTableWidgetItem, QUndoStack 4 | 5 | from Il2cppSpy.domain.model.dump_data import DumpType 6 | from Il2cppSpy.ui.ui_tabitemwindow import Ui_TabItemWindow 7 | import Il2cppSpy.ui.ui_color as color 8 | 9 | 10 | class TabItemView(QWidget): 11 | def __init__(self, parent: QWidget, dump_type: DumpType): 12 | super(TabItemView, self).__init__(parent) 13 | self.undo_stack = QUndoStack(self) 14 | self.current_item: QTableWidgetItem 15 | tab_ui = Ui_TabItemWindow() 16 | tab_ui.setupUi(self) 17 | self.table_widget = tab_ui.tableWidget 18 | row_count = 0 19 | for dump_attribute in dump_type.attributes: 20 | self.add_row(row_count, dump_attribute) 21 | row_count += 1 22 | name = '' 23 | if dump_type.modifier: 24 | name += f'{dump_type.modifier} ' 25 | if dump_type.type_str: 26 | name += f'{dump_type.type_str} ' 27 | if dump_type.name: 28 | name += f'{dump_type.name}' 29 | if dump_type.extends: 30 | name += f' : {", ".join(dump_type.extends)}' 31 | self.add_row(row_count, name) 32 | row_count += 1 33 | for dump_field in dump_type.fields: 34 | for dump_attribute in dump_field.attributes: 35 | self.add_row(row_count, dump_attribute) 36 | row_count += 1 37 | name = '' 38 | if dump_field.modifier: 39 | name += f'{dump_field.modifier} ' 40 | if dump_field.type_str: 41 | name += f'{dump_field.type_str} ' 42 | if dump_field.name: 43 | name += f'{dump_field.name}' 44 | if dump_field.value_str: 45 | name += f' = {dump_field.value_str}' 46 | name += ';' 47 | self.add_row(row_count, name) 48 | row_count += 1 49 | for dump_property in dump_type.properties: 50 | for dump_attribute in dump_property.attributes: 51 | self.add_row(row_count, dump_attribute) 52 | row_count += 1 53 | name = '' 54 | if dump_property.modifier: 55 | name += f'{dump_property.modifier} ' 56 | if dump_property.type_str: 57 | name += f'{dump_property.type_str} ' 58 | if dump_property.name: 59 | name += f'{dump_property.name}' 60 | if dump_property.access: 61 | name += f' {dump_property.access}' 62 | self.add_row(row_count, name) 63 | row_count += 1 64 | for dump_method in dump_type.methods: 65 | for dump_attribute in dump_method.attributes: 66 | self.add_row(row_count, dump_attribute) 67 | row_count += 1 68 | name = '' 69 | if dump_method.modifier: 70 | name += f'{dump_method.modifier} ' 71 | if dump_method.type_str: 72 | name += f'{dump_method.type_str} ' 73 | if dump_method.name: 74 | name += f'{dump_method.name}' 75 | if dump_method.parameters: 76 | name += f'({", ".join(dump_method.parameters)})' 77 | else: 78 | name += '()' 79 | self.add_row(row_count, name, color.TABLE_METHOD_CODE_TEXT_COLOR) 80 | row_count += 1 81 | for dump_assembly in dump_method.assemblies: 82 | text_color = color.TABLE_DIFF_TEXT_COLOR if dump_assembly.is_diff else color.TABLE_ASSEMBLY_TEXT_COLOR 83 | background_color = color.TABLE_DIFF_BACKGROUND_COLOR if dump_assembly.is_diff else color.TABLE_ASSEMBLY_BACKGROUND_COLOR 84 | self.add_row(row_count, dump_assembly.assembly, text_color, background_color, f'0x{dump_assembly.address:x}') 85 | row_count += 1 86 | 87 | def add_row(self, row: int, item_text: str, item_text_color: QColor = color.TABLE_CODE_TEXT_COLOR, item_background_color=color.TABLE_CODE_BACKGROUND_COLOR, header_text: str = ''): 88 | self.table_widget.setRowCount(row + 1) 89 | table_header = QTableWidgetItem(header_text) 90 | self.table_widget.setVerticalHeaderItem(row, table_header) 91 | table_item = QTableWidgetItem(item_text) 92 | table_item.setTextColor(item_text_color) 93 | table_item.setFlags(table_item.flags() ^ Qt.ItemIsEditable) 94 | table_item.setBackgroundColor(item_background_color) 95 | self.table_widget.setItem(row, 0, table_item) 96 | -------------------------------------------------------------------------------- /Il2cppSpy/presentation/view/tab_view.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from PySide2.QtWidgets import QWidget 3 | 4 | from Il2cppSpy.domain.model.dump_data import DumpType 5 | from Il2cppSpy.presentation.view.tab_item_view import TabItemView 6 | from Il2cppSpy.ui.ui_mainwindow import Ui_MainWindow 7 | 8 | 9 | class TabView: 10 | def __init__(self, ui: Ui_MainWindow): 11 | self.ui = ui 12 | self.tabs: Dict[DumpType, QWidget] = {} 13 | self.ui.tabWidget.tabCloseRequested.connect(self.close_tab) 14 | 15 | def open_type(self, dump_type: DumpType): 16 | if dump_type in self.tabs.keys(): 17 | self.ui.tabWidget.setCurrentWidget(self.tabs[dump_type]) 18 | return 19 | tab_view = TabItemView(self.ui.tabWidget, dump_type) 20 | self.ui.tabWidget.addTab(tab_view, dump_type.name) 21 | self.ui.tabWidget.setCurrentWidget(tab_view) 22 | self.tabs[dump_type] = tab_view 23 | 24 | def close_tab(self, index): 25 | self.tabs = {k: v for k, v in self.tabs.items() if v != self.ui.tabWidget.widget(index)} 26 | self.ui.tabWidget.removeTab(index) 27 | -------------------------------------------------------------------------------- /Il2cppSpy/ui/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/Il2cppSpy/ui/file.png -------------------------------------------------------------------------------- /Il2cppSpy/ui/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/Il2cppSpy/ui/folder.png -------------------------------------------------------------------------------- /Il2cppSpy/ui/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 600 11 | 12 | 13 | 14 | Il2cppSpy 15 | 16 | 17 | 18 | 19 | 0 20 | 21 | 22 | 0 23 | 24 | 25 | 0 26 | 27 | 28 | 0 29 | 30 | 31 | 0 32 | 33 | 34 | 35 | 36 | Qt::Horizontal 37 | 38 | 39 | 2 40 | 41 | 42 | 43 | false 44 | 45 | 46 | 47 | 1 48 | 49 | 50 | 51 | 52 | 53 | 54 | 1 55 | 0 56 | 57 | 58 | 59 | true 60 | 61 | 62 | true 63 | 64 | 65 | true 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 0 76 | 0 77 | 800 78 | 22 79 | 80 | 81 | 82 | 83 | File 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | toolBar 94 | 95 | 96 | 97 | 18 98 | 18 99 | 100 | 101 | 102 | TopToolBarArea 103 | 104 | 105 | false 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | :/folder.png:/folder.png 114 | 115 | 116 | Open Apk 117 | 118 | 119 | Open Apk 120 | 121 | 122 | 123 | 124 | 125 | :/file.png:/file.png 126 | 127 | 128 | Compare Apks 129 | 130 | 131 | Compare Apks 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /Il2cppSpy/ui/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | file.png 4 | folder.png 5 | 6 | 7 | -------------------------------------------------------------------------------- /Il2cppSpy/ui/resources_rc.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Resource object code 4 | # 5 | # Created: 火 9月 17 16:39:16 2019 6 | # by: The Resource Compiler for PySide2 (Qt v5.13.1) 7 | # 8 | # WARNING! All changes made in this file will be lost! 9 | 10 | from PySide2 import QtCore 11 | 12 | qt_resource_data = b"\ 13 | \x00\x005\x0c\ 14 | \x89\ 15 | PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ 16 | \x00\x02\x00\x00\x00\x02\x00\x08\x06\x00\x00\x00\xf4x\xd4\xfa\ 17 | \x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ 18 | \x00\x00\x00\x09pHYs\x00\x00\x0b\xe9\x00\x00\x0b\xe9\ 19 | \x01Z\xc0\xafP\x00\x00\x00\x19tEXtSof\ 20 | tware\x00www.inksca\ 21 | pe.org\x9b\xee<\x1a\x00\x00 \x00ID\ 22 | ATx\x9c\xed\xddy\x94dga\xdf\xfd\xdf\xad\xad\ 23 | k\xe9e\xf6U=\xa5\xd1H\xa5\x11\xd2\x18\x10\xc6\x02\ 24 | \xcc\x220X\xc8.\x90\xc0\xc6\x18\x8cq\xb09\x89\xed\ 25 | \x1c^[u\xde\x90\x13Bl\x9f\xc4y\xed\xd7\xce)\ 26 | \xc7v\xec\x98\x97\x18\x87\xd7`\xe0\xd8Q\x04\x14H\x06\ 27 | lK\x18\x12\x99E,\x8d\x16J\xcbL\xcf\xbeo\xdd\ 28 | \xb5/7\x7ft\x0f\x92F\xa3\x99\xee\xaa{\xefs\xef\ 29 | }\xbe\x9fst\xc4\xa2z\xeeo\xd4\xd5\xf5\xfc\xea.\ 30 | \xcf\xe3\xb8\xae+\x00@8T\xea\xb5\x9c\xa4\x9f\x97\xf4\ 31 | 6I\xd7I\xda,\xe9\x90\xa4'$}B\xd2\xa7\xaa\ 32 | \xa5r\xdb\x5cB\xc4\x85C\x01\x00\x80p\xa8\xd4ko\ 33 | \x95\xf4!I\x1b.\xf3\x8f\x9d\x90\xf4\x9ej\xa9\xfc\xb9\ 34 | `R!\xae\x22S\x00*s\xad\x0d\x92\xae\x91\xb4U\ 35 | \xd2\xb6\x8b\xfe\xbeYR\xca\x5c:\xd8\xa2q\xf2\xd8}\ 36 | \xeds\xa7\x7f\xe3\xa3w\xde\xdc5\x9d\x05\xf1Q\xa9\xd7\ 37 | \x1cI\xbf+\xe9\xfd+|\x89+\xe9\x03\xd5R\xf9w\ 38 | \xfdK\x85\xb8\x0bu\x01\xa8\xcc\xb5\xae\x95\xf4\x16Iw\ 39 | Jz\x99\xa4\x84\xd9D\xb0\xdd\xb9C\xfb\xfe\xb1\xdfn\ 40 | \x9d\x91\xf46J\x00\xbc\xb0<\xf9\xff\x89\xa4_\x19\xe1\ 41 | \xe5o\xa9\x96\xca\xf7x\x1c\x09\x96\x08]\x01\xa8\xcc\xb5\ 42 | n\x96\xf4V-M\xfa7\x1a\x8e\x03<\xcbr\x01x\ 43 | \x95\xa4\xcf\x88\x12\x801\x8d9\xf9K\xd29I\xc5j\ 44 | \xa9|\xce\xbbT\xb0Eh\xbeQW\xe6Z?\x5c\x99\ 45 | k\xfd\x9d\xa4oJ\xfa\xb7b\xf2G\xb8\xbdY\xd2_\ 46 | \xff\xc2=\x0feL\x07A4y0\xf9K\xd2\x8c\xa4\ 47 | w{\x93\x08\xb61^\x00*s\xad]\x95\xb9\xd6'\ 48 | %}M\xd2\xebL\xe7\x01V\x81\x12\x80\x91x4\xf9\ 49 | _\xf0\xf3\x1e\x8c\x01\x0b\x19+\x00\x95\xb9\xd6\xa6\xca\x5c\ 50 | \xeb\xbfHzT\xd2\xdb%9\xa6\xb2\x00c\xa0\x04`\ 51 | U<\x9e\xfc%\xe9z\x8f\xc6\x81e\x8c\x14\x80\xca\x5c\ 52 | \xeb6I\xdf\x97\xf4/%\xa5Md\x00M\xfe\x92\xd4\x92\xb4\xe0\xf1\x98\xb0@`\ 56 | \x05\xa02\xd7JW\xe6Z\x1f\x96\xf4\x9f%%\x83:\ 57 | .\x10 J\x00.\xc9\xc7\xc9_\x92\xea\xd5R9\x5c\ 58 | \x8fs!\x12\x02)\x00\xcb\x8b\xf8|I\xd2{\x838\ 59 | \x1e`\x10%\x00\xcf\xe2\xf3\xe4/-=\x92\x0a\xac\x9a\ 60 | \xef\x05\xa02\xd7\xda(\xe9AI\xaf\xf6\xfbX@H\ 61 | P\x02 )\x90\xc9\xbf\xaf\xa5\xa5\x83\x81U\xf3\xb5\x00\ 62 | T\xe6Z\x19IwK\xda\xe5\xe7q\x80\x10\xa2\x04X\ 63 | .\x80\xc9_\x92~\xb3Z*\x1f\xf2q|\xc4\x98\xdf\ 64 | g\x00\xfeL\xd2+}>\x06\x10V\x94\x00K\x054\ 65 | \xf9\xffOI\xbf\xe3\xe3\xf8\x889\xdf\x0a@e\xaeU\ 66 | \x91\xf4\x1e\xbf\xc6\x07\x22\x82\x12`\x99\x80&\xff\xfb$\ 67 | \xbd\x83\x9b\xff0\x0e_\x0a@e\xaeu\xbb\xa4\xdf\xf7\ 68 | cl \x82(\x01\x96\x08p\xf2\xbf\xb3Z*w|\ 69 | <\x06,\xe0y\x01\xa8\xcc\xb5\xb6K\xfa\xa4\x1fc\x03\ 70 | \x11F\x09\x889&\x7fD\x8d\x1f\x93\xf4oIbU\ 71 | *\xe0\xb9(\x011\x15\xd0\xe4\x7f\xaf\x98\xfc\xe1!O\ 72 | \x0b@e\xaeu\x83\xb8\xee\x0f\x5c\x0e% f\x02\x9c\ 73 | \xfc\xdf\xc2\xe4\x0f/y}\x06\xe0w\xc4*\x7f\xc0\x95\ 74 | P\x02b\x82\xc9\x1fQ\xe6Y\x01\xa8\xcc\xb5^!\xe9\ 75 | \x0e\xaf\xc6\x03b\x8e\x12\x10qL\xfe\x88:/\xcf\x00\ 76 | \xfc\x9e\x87c\x016\xa0\x04DT@\x93\xff\xe7\xc5\xe4\ 77 | \x0f\x1fyR\x00*s\xadWJ\xfaQ/\xc6\x02,\ 78 | C\x09\x88\x98\x00'\xff\xb72\xf9\xc3O^\x9d\x01x\ 79 | \x8bG\xe3\x006\xa2\x04D\x04\x93?\xe2\xc4\xab\x02p\ 80 | \xa7G\xe3\x00\xb6\xa2\x04\x84\x5c@\x93\xff\xe7\xc4\xe4\x8f\ 81 | \x80\x8c]\x00*s\xad\x9b$]\xe3A\x16\xc0v\x94\ 82 | \x80\x90b\xf2G\x1cyq\x06\x80o\xff\x80w(\x01\ 83 | !\x13\xf0\xe4\xdf\xf5\xf1\x18\xc0\xb3P\x00\x80\xf0\xa1\x04\ 84 | \x84\x04\x93?\xe2l\xac\x02P\x99km\x95\xf4\x12\x8f\ 85 | \xb2\x00x\x1a%\xc0\xb0\x80&\xff\x9a\x98\xfca\xc8\xb8\ 86 | g\x00\xae\xf3$\x05\x80K\xa1\x04\x18\x12\xe0\xe4\xffS\ 87 | L\xfe0e\xdc\x02\xb0\xcd\x93\x14\x00\x9e\x0f% `\ 88 | L\xfe\xb0\xc5\xb8\x05`\xbb')\x00\x5c\x0e% \ 89 | L\xfe\xb0\x09g\x00\x80h\xa0\x04\xf8,\xa0\xc9\xff\xb3\ 90 | b\xf2GHp\x06\x00\x88\x0eJ\x80O\x02\x9c\xfc\x7f\ 91 | \x9a\xc9\x1fa\xc1\x19\x00 Z(\x01\x1ec\xf2\x87\xad\ 92 | \x1c\xd7uG~qe\xae\xf5\xb8\xa4k\xbd\x8b\x03\x84\ 93 | \xdb\xb9C\xfb\xfe\xb1\xdfn\xbd\xcat\x0eI\x9f\x91\xf4\ 94 | \xb6\x8f\xdey3\x13\xca\x18\x02\x9a\xfc\xcfH\xfa-I\ 95 | \xfc\xac\xc6\xd7\x90tX\xd2!I\x87\xaa\xa5\xf2\x82\xe1\ 96 | <\x916n\x01\xd8'\xa9\xe8Y\x1a \xe4BT\x00\ 97 | $J\xc0X\x02\x9a\xfc\xe1\xaf\x05-\x95\x81\x0b\xa5\xe0\ 98 | \xa0\xa4\xfb%\xdd\xcf\xd9\x96+\xa3\x00\x00\xab\x10\xb2\x02\ 99 | Q\x02F\xc2\xe4\x1f{\xe7%\xdd+\xe9\x1eI\xf7\ 100 | VK\xe5s\x86\xf3\x84\x92W\xbb\x01\x020\x83{\x02\ 101 | F\xf3\xaf\xc4\xe4\x1fg\xd3\x92\xde.\xe9\x13\x92NT\ 102 | \xea\xb5/T\xea\xb5_\xad\xd4kW\x19\xce\x15*\x14\ 103 | \x00 \xfa(\x01\xabP\xa9\xd7n\x90\xf4\xefM\xe7@\ 104 | `\xd2\x92\xde\xa0\xa53>\xfb+\xf5\xda\xc7*\xf5\xda\ 105 | \xd5f#\x85\x03\x05\x00\x88\x07J\xc0\x0aT\xea\xb5\x84\ 106 | \xa4\xbf\x904a:\x0b\x8cp$\xfd\x9c\xa4\xefW\xea\ 107 | \xb5j\xa5^[o:\x90I\x14\x00 >(\x01W\ 108 | \xb6G\xd2-\xa6C\xc0\xb8\x8c\xa4\xbb$=Y\xa9\xd7\ 109 | \xfeM\xa5^\xcb\x99\x0ed\x02\x05\x00\x88\x17J\xc0\xe5\ 110 | \xbd\xd4t\x00\x84\xca\x8c\xa4\xffG\xd2\xe3\x95z\xed\x97\ 111 | *\xf5Z\xd2t\xa0 Q\x00\x80\xf8\xa1\x04Z\xa9\ 119 | \xd7b\xf9\xd8(\x05\x00\xb0\x03%@R\xb5T>+\ 120 | \xe9_\x9b\xce\x81Hy\xb7\xa4\xcfU\xea\xb5\x94\xe9 \ 121 | ^\xa3\x00\x00\xf6\xa0\x04,\xf9SI\x0f\x98\x0e\x81H\ 122 | \xf91I\x7fd:\x84\xd7(\x00\x80]\xac/\x01\xd5\ 123 | R\xd9\x95\xf4\x0bZ\xda9\x0eX\xa9_\xa9\xd4k\xbf\ 124 | l:\x84\x97(\x00\x80}(\x01\xa5\xf2\xbc\xa4\xd7\x8a\ 125 | \x12\x80\xd5\xf9\xe3J\xbdv\xab\xe9\x10^a;``\ 126 | \x15\xce\x1d\xda\xf7\xe5~\xbb\xf5j\xd39w:.\ 134 | g\x00.\xa0\x04\x04S\x02\xdeY-\x95\xff\xda\xa7\xf1\ 135 | \xadW\xa9\xd7&%\xbdQ\xd2\x1d\x92\xee\x944\xe9\xf3\ 136 | !\xffg\xb5T~\xab\xcf\xc7\xf0\x15\x05\x00X\x85\xf6\ 137 | \xb93\x0f6N\x1e}\x99\xe9\x1c>\xa0\x04P\x02b\ 138 | \xa3R\xafm\x94\xf4\xef$\xfd\xb2\xa4\xb4\x8f\x87\xba\xad\ 139 | Z*\x7f\xc1\xc7\xf1}\xc5M\x80\xc0*\xa4\xb2\xb9\x0d\ 140 | \xa63\xf8\x84\x1b\x03K\xe5'%\xdd*\xffn\x0cL\ 141 | I\xfa\xabJ\xbd\xf66\x9f\xc6\xc7\xb2j\xa9|\xa2Z\ 142 | *\xff_\x92n\x90\xf4)I\xa3\x7f\xd3\xbd\xbc\xff\xb7\ 143 | R\xafEv\x1e\x8dlp\xc0\x84\xd4D\xf6Z9\xce\ 144 | \xbc\xe9\x1c>\xa1\x04P\x02b\xa5Z*?Y-\x95\ 145 | \x7fV\xd2\xab%\x1d\xf5\xe1\x10/\x92\xf4s>\x8c\x1b\ 146 | \x08\x0a\x00\xb0J\xe9\x5c~\x9f\xe9\x0c>\xa2\x04<]\ 147 | \x02\x0e\xf8t\x88\x0b%\xe0g|\x1a\x1f\x17\xa9\x96\xca\ 148 | _\xd1\xd2V\xd0~l\x06\xf5\xdbQ]*\x98\x02\x00\ 149 | \xacR~\xed\xc6\xcd\xa63\xf8\x8c\x12\xb0T\x02^+\ 150 | \x7fK\xc0\xc7)\x01\xc1\xa9\x96\xca\x07%\xbdJ\xd2'\ 151 | =\x1ez\x87\xa4\xf7y.R-\x95\x17\xb5\xf4\ 169 | \xde>\xe1\xd1\x90\xeb\xb4t\x8fAdXW\x00\xde4\ 170 | \xdd\xd2M\xd9\x9e\xe9\x18V\xcb'\x5c\xdd9\xdd\xd4\x8e\ 171 | t\xc4K\x80\xe3\xa4\xd7\xcc\xee*\xcaq\xf6\x99\x8e\x12\ 172 | \x00J@p%\xe0g}\x1a\x1f\x17Y\xde\x14\xea\x97\ 173 | <\x1c\xf2\x0e\x0f\xc7\xf2\x9dU\x05\xe0\x85\xd9\xaevf\ 174 | \x22>\xe9\xc4\xc8\xed\xd3me\x1c\xbf\xd6\xe7\x08\x86\x93\ 175 | L\xae]\xbbcW\xceI$\x1e5\x9d%\x00\x94\x80\ 176 | `J\xc0\xc7(\x01\xc1\xa9\x96\xca\x9f\x95\xf4e\x8f\x86\ 177 | \xa3\x00\x84\xd1d\xc2\xd5\xad\x93\x1d\xd31\xf0\x0c\xd3\x89\ 178 | \xa1^]\x88\xfe\xcf$\x91Jo^{u\xe9\xead\ 179 | :\xf3\xa0\xe9,\x01\xa0\x04P\x02\xe2\xe8\xfd\x1e\x8d\xb3\ 180 | \xb3R\xaf\xed\xf1h,\xdfYS\x00f\xd3\xfd\xc8\x7f\ 181 | \xdb\x8c\xa3kcp/\x80$9\x8e\x93[\xb3c\xd7\ 182 | -\xf9\xf5\x9b\xbe*\xc7\xf1kb\x08\x0bJ\x00% \ 183 | V\xaa\xa5\xf2?I\xf2j\xb7\xc6\xc8\x9c\x05\xb0\xa6\x00\ 184 | lNE\xe6\xc6L\xabL%\x86*$bS\xcc\x9c\ 185 | \xdc\x9a\xf5?\xba~\xe7\xf5[\xb23\xeb\xbe\xec8\xce\ 186 | \x13\xa6\x03\xf9\x88\x12\xf0t\x09\xd8\xef\xd3!.\x94\x80\ 187 | w\xf84>\x9e\xed\x83\x1e\x8dC\x01\x08\x9b\xcdi\xee\ 188 | \xf8\x0f\xab-q+g\x8e\x93.l\xd8\xfc\xeau\xd7\ 189 | \xec\xbev\xcd\xec5\xf3\xd9\xe95\x0f$R\xe9\x7fr\ 190 | \x12\x89\xc7\xb4t\xc7q\x5c\x1a\x0f% \x98\x12\xf0\x97\ 191 | \x94\x00\xffUK\xe5\xefKz\xc8\x83\xa1^R\xa9\xd7\ 192 | \xb6{0\x8e\xefR\xa6\x03\x04\xc5\x89\xcdgn\xfc8\ 193 | \xd1_\x12\xe0y%3\x13\xc5\xc2\xc6\xad\xc5\xc23\xff\ 194 | G\xd7\xed\xbbK\xcf}\xc7\xc1m\x8e\xf4rI\x0f\x98\ 195 | \x0ebJ\xb5T\xde[\xa9\xd7n\xd5\xd2:\x01;|\ 196 | 8\xc4\x85\x12\xa0j\xa9\xfc\x09\x1f\xc6\xc7\xd3>-\xe9\ 197 | \xe61\xc7p\x96\xc784~\x1c\x7fYs\x06\xe0X\ 198 | ?i:\x02\x9e\xc7\xd1\x9ee?\x1b\xc7I9\x8e3\ 199 | \x11\x97\xbf\xe4\xc4\xb9\xc2\xadL\xb5T\xde\xab`\xce\x04\ 200 | \xbc\xd3\xa7\xf1\xb1\xe4\xd3\x1e\x8d\xb3\xcd\xa3q|eO\ 201 | \x01\xb0m\x92\x89\x88\xc6\xd0\xd1b\x0cV\x05\x04\x02*\ 202 | \x01\xff?%\xc0?\xd5R\xf9;\x92\xf6y0\x14\x05\ 203 | L\x0e\xf4\x92\xea\xc5d\x1d\xfa8y\xa2\x9b6\x1d\ 204 | \x01\xf0\x0c% \x16\xbe\xe0\xc1\x18\x14\x800Y\x18&\ 205 | \xf4\xe5F$\xb7l\x8e\xad\xc5\xa1\xa3\x07\x16\xf9\x99 \ 206 | ^\x02,\x01,\x1b\xec\x0f/~n\x14\x80\xb0y\xa8\ 207 | \x95\xd1\xfe\x9e5\xf7=\x86\xde}\x0b9u8+\x83\ 208 | \x18\x0a\xa8\x04\xfc\xf7J\xbd\xf6b\x9f\xc6\xb7\xd9a\x0f\ 209 | \xc6\xa0\x00\x84\xd1g\xce\xe7\xf4X\x87\xd3\xce&\xb5]\ 210 | G\x9f=\x9f\xd3\xde.e\x0c\xf1\x15@\x09\xc8J\xfa\ 211 | \x9bJ\xbd\xc6/\x92\xb7(\x00q\xd5\x1a.M>\x9f\ 212 | 9\x9fS\x83\x9b\xcf\x02\xf7d7\xa5\x8f\x9c\x9e\xa4\x84\ 213 | \xc1\x0a\xcf(\x01\xf3>\x1d\xe2\x1aIo\xf1il[\ 214 | yQ\x006F\xa1\x98\x85>\xa0_\xbe\xdfI\xab\xde\ 215 | Ik]r\xa8-\xe9\x81\xb6\xa4\x06,\x15\xec\x03W\ 216 | \xd2\xd9ABG\xfbI\x1d\xed%\xd5\xe6\x94?,s\ 217 | \xd1:\x01E\x1f\x0e\xf1\x8b\x92\xfe\xda\x87qmu\xd4\ 218 | \x831\x1cI\x9b\xe4M\x99\xf0\x8d\xb5\x05@Z\x9a\x9c\ 219 | N\x0d\x12:5H\xe8a\xf1\x8d\x14\x80?\xaa\xa5\xf2\ 220 | >\x1fK\xc0\x8b<\x1e\xcfv^\xed\x17\x1f\xfa\x152\ 221 | \xad\xbb\x04\x00\x00&TK\xe5}\xf2\xe7r\xc0\x96J\ 222 | \xbd6\xe9\xf1\x98\xb0\x00\x05\x00\x00\x02\xe2S\x09\xe8K\ 223 | jy8\x1e,A\x01\x00\x80\x00\xf9P\x02\x0eVK\ 224 | \xe5\xb8\xec-\x81\x00Q\x00\x00 `\x1e\x97\x80/z\ 225 | 0\x06,D\x01\x00\x00\x03<,\x01\x7f2v\x18X\ 226 | \x89\x02\x00\x00\x86xP\x02>\xba\xbc\x81\x0d\xb0j\x14\ 227 | \x00\x000\xe8\x19%`\xef*_\xfa=I\xbf\xeau\ 228 | \x1e\xd8\x83\x02\x00\x00\x86-\x97\x80\x97J\xfa\xbb\x15\xbe\ 229 | \xa4&\xe95\xd5R\xb9\xe9[(\xc4\x1e\x05\x00\x00B\ 230 | \xa0Z*\x9f\x92t\x9b\xa4\xf7Jz\xbe\xd3\xfa\x0fJ\ 231 | z\x97\xa47WK\xe5\xd3AeC\xa2\x00\x00\x00\xf0l\xe3\x16\x80q_\ 278 | \x1f\x08\x0a\x00\x00\x00\xcf\xf6)I\x83\x11_\xebJ\xfa\ 279 | \x84\x87Y|C\x01\x00\x00\xe0\x19\xaa\xa5\xf27%\xfd\ 280 | \xde\x88/\xff\xb3j\xa9\xfc\x0f^\xe6\xf1\x0b\x05\x00\x00\ 281 | \x80\xe7\xfa-I\xdf[\xe5k\xf6Jz\xbf\xf7Q\xfc\ 282 | A\x01\x00\x00\xe0\x22\xd5R\xb9+\xe95Z\xf9\xe9\xfc\ 283 | OKzE\xb5T^\xf4/\x95\xb7\xd8\x0e\x18\x00\x80\ 284 | K\xa8\x96\xca\xa7%\xbd\xb3R\xaf\xfd\x8d\xa4\xdf\x96\xb4\ 285 | [\x92s\xd1?\xf6\xb8\xa4\x7f_-\x95?\x16t\xbe\ 286 | qQ\x00\x00\x00\xb8\x8cj\xa9|\xb7\xa4\xbb+\xf5\xda\ 287 | \xb4\xa4\x97H\xbaAK\x13\xff7\xaa\xa5\xf2\xb8k\x06\ 288 | \x18C\x01\x00\x00`\x05\xaa\xa5\xf2yI\xff\xb0\xfcW\ 289 | \xe4q\x0f\x00\x00\x00\x16\xa2\x00\x00\x00`!\x0a\x00\x00\ 290 | \x00\x16\xa2\x00\x00\x00`!\x0a\x00\x00\x00\x16\xa2\x00\x00\ 291 | \x00`!\x0a\x00\x00\x00\x16b\x1d\x00\x00\x97\x95\x92\xab\ 292 | \xad\xa9\xbe&\x9d\xa1\x0a\x89\xa1\x0a\xce\xf2_\xcb\xffy\ 293 | *1\xf8\xec\xfc\xfc\xc8;\xa7\x01+v\xf6\xcc\xf9?\ 294 | |\xe1\x8bn\xfcM\xd39\xe2\x82\x02\x00\xe09r\xce\ 295 | P;S]\xedJw\xb5#\xd9S\xcaq/\xf7\x8f\ 296 | O\x06\x95\x0bv\x1b\x0e\x87\xbf\xf4\xad\x87\xe6\xa6_|\ 297 | \xf3\x9e\xbbLg\x89\x03\x0a\x00\x00IR\xc1\x19\xea\xfa\ 298 | tG\xbb\xd2]mM\xf6\x9e\xb3\xe09\x10\x12\xbf\xfe\ 299 | \xad\x87\xe6D\x09\x18\x1f\x05\x00\xb0\x5c\xc6q\xf5\x92L\ 300 | K7gZW\xfa\xa6\x0f\x84\x05%\xc0\x03\xdc\x04\x08\ 301 | X*!\xe9\x85\x99\x96\xfe\xd9\xe4\x19\xfd\xc8D\x93\xc9\ 302 | \x1fQ\xf3\xeb\xdfzh\xee\x0fL\x87\x882\x0a\x00`\ 303 | \xa1\xeb\xd2\x1d\xfd\xfc\xe4\x19\xdd\x9am(\xe7\x0cM\xc7\ 304 | \x01FE\x09\x18\x03\x05\x00\xb0HR\xae\xde\x98[\xd0\ 305 | O\xe4\x16\xb4&\xc1\x8d\xfb\x88\x05J\xc0\x88(\x00\x80\ 306 | %&\x9d\xa1\xdeV8\xa7\xeb\xd3\x1d\xd3Q\x00\xafQ\ 307 | \x02F\xc0M\x80\x92\xf2\x09W[R\x03e\x12\x5c\x03\ 308 | \xc5\xe5\xf5\x5cG'z\x09\x9d\x1fF\xab;oI\xf6\ 309 | U\xce\x9fW\x81\xd3\xfd\x88/n\x0c\x5c%k\x0b\xc0\ 310 | Tb\xa8WOvtUz\xa0\xe9\x04\x1f\x8aX\x9d\ 311 | \xe6\xd0\xd1\x91^R\xff\xd8\xcc\xeaD?\xdce`w\ 312 | \xba\xa3\xd7\xe7\x16\x95\x14\x05\x17\xb1G\x09X\x85p\x7f\ 313 | r\xf9\xe4\xa6lW\xefY\xbb\xa8\x17L\xf4\x98\xfc1\ 314 | \x92|\xc2\xd5\xae\x89\xbe\xde\xbd\xb6\xa1\x97\xe5;J\x84\ 315 | \xf4\xa1\xf9\x9b2m\xdd\x96[`\xf2\x87M\xb8\x1c\xb0\ 316 | B\xd6\x15\x80\xd7\x14:\xba}\xaa\xad\x09\xeb\xfe\xe4\xf0\ 317 | CB\xae^U\xe8\xe8\xce\xa9\xa6\xe9(\xcf\xb1=\xd9\ 318 | \xd3k\xb3\x8b\xa6c\x00&P\x02V\xc0\xaai\xf0\xaa\ 319 | t_/\xcds\x03\x14\xbc\xb7k\xa2\xaf=\xd9\xae\xe9\ 320 | \x18?0\x9d\x18\xe8'\xf3\x0bv\xfd\x82\x03\xcfF\x09\ 321 | \xb8\x02k>\x1f\xd2\x8e\xab\xdb\xa7\xda,o\x0a\xdf\xbc\ 322 | n\xb2\x13\x8aKJi\xc7\xd5\x9b\xf2\x0b<\xdf\x0fP\ 323 | \x02.\xcb\x9a\x02\xb0#3\xd0\x9a$\x1f\x88\xf0O\xc6\ 324 | q\xb5;\xdb3\x1dC\xb7\xe5\x16\xb4!\xd17\x1d\x03\ 325 | \x08\x0bJ\xc0\xf3\xb0\xa6\x00lN\xb1\xe8\x09\xfc\xb7%\ 326 | e\xb6d\xbe0\xd3\xd2\xaeTx.E\x00!A\x09\ 327 | \xb8\x04k\x0a\xc0\x96$\x05\x00\xfe\xdb\x9a6\xf7>\x9b\ 328 | p\x5c\xdd2\xd12v| \xe4(\x01\x17\xb1\xa6\x00\ 329 | \xe4X\xe4\x07\x01\xc8;\xae\xb1\xfbL^\x92ir\xdd\ 330 | \x1f\xb8k\xe4$\ 339 | \xfc5i\x1e\xfb\x03\xc6`m\x09\xb0j6\xec\xba\x8e\ 340 | >}>\xa7\xb3\x94\x00x\xa8\xe5:\xaa\x9d\xcf\x19\xd9\ 341 | \x22xK\xb2\xaf\x0b\ 373 | \xac\x04P\x00\x00\x00\x91\x91\xcf\xe7n\x91t\xc4t\x0e\ 374 | \x9f\x05R\x02R~\x1f \xcc&\x1cW\x9bS\x03m\ 375 | I\x0f\xb495\xd4\x84\x13\x975&\xe0\x97\xbe\x1c\x1d\ 376 | \xef%u\xb4\x9f\xd4\x91~R\xad\xa1c:Rd\xf5\ 377 | \xba]-6\x9aj4\x9aj\xb7\xda\x1a\x0e\xe3z\x7f\ 378 | \x979\x89\xa4\xa3\x5c.\xa7B>\xaf\xc2d^\xe9t\ 379 | \xdat\xa4\xb19\x8e\x93\xcd\xe5\xb3O\xb6\x9a\xed\xad\xa6\ 380 | \xb3\xf8\xec\xd7\xbf\xf5\xd0\x9c^|\xf3\x9e\xbb\xfc:\x80\ 381 | \x95\x05\xc0\x91\xf4\xa2\x5cW\xaf)t\x94v\xf8\xd0\xc1\ 382 | \xea\x5c\x97\xe9K\x92\x86\xae\xf4\xf5\xd6\x84\xbe\xda\xc8h\ 383 | \x8a\xc0J\x0d\x06\x03\xed\x9f?\xa8S\xa7N\x9b\x8e\ 384 | b\x85\xb3g\xce\xfd\xe0?o\xdc\xb4AW]\xb5]\ 385 | \xc9d\xb4O\xfe\xe6r\xd9W\xb4[\x9d\xef\xba\xae\xfb\ 386 | C\xa6\xb3\xf8\xcc\xd7\x12\x10\xedw\xc1\x08\xa6\x12C\xfd\ 387 | \xcc\x9a\xa6^?\xd9f\xf2\xc7X\x12\x8etK\xbe\xa3\ 388 | w\xafmhS\x92\xb3G+\xb1p~Q\x0f\x7f\xef\ 389 | 1&\x7fCN\x1c?\xa9G\x1eyL\x8b\x8b\x0d\xd3\ 390 | Q\xc6\x95\x98Y3\xbd]\xd2A\xd3A\x02\xe0\xdb\xe5\ 391 | \x00\xab\x0a@\xc2\x91\xee\x9ciiG\xbao:\x0ab\ 392 | dCj\xa8\x9f\x9eih\x82ByY\x9dNWO\ 393 | <\xf1\xa4\xba\xdd\xae\xe9(V\xeb\xb4;z\xe2\xf1\xa7\ 394 | \xd4\xeb\xf5LG\x19K\x22\xe1\xac\x9f\x9e\x99jI\x8a\ 395 | \xd3\xf2\xc0\xcf\xc7\x97\x12`U\x01\xb8%\xd7\xd1\x96\xd4\ 396 | \xc0t\x0c\xc4P!\xe9\xea\xf5Sm\xd31B\xcbu\ 397 | ]\xed\xdb;\xaf\xc1\x803%a\xd0\xef\xf7\xb5o\xdf\ 398 | ~\xd31\xc6\x96J%\xaf\x9b\x9e\x99:\x22\xce\x04\x8c\ 399 | \xc4\x9a\x02\xb0&9\xd4\xcb\xf3q\x5cE\x12a\xf1\x82\ 400 | \x89\x9e\x8a\x19\xce.]\xca\xc9\x93\xa7\xb4\xb0`\xc3\x17\ 401 | \xb5\xe88w\xf6\xbcN\x9f>k:\xc6\xd8R\xa9\xe4\ 402 | uk\xd6\xce\xe4\x1c\xc7\xf9\xae\xe9,\x01\xf0\xb4\x04X\ 403 | S\x00\xaeJ\xf7\x95\xe4>-\xf8\xec\xea4g\x98.\ 404 | e\xe1|\xdc\xf6p\x89\x87\xb8\xfc\x5c\x12\x09g\xfd\xda\ 405 | u37\xe5\xf2\xd9\xaf\x88G\x04W\xcc\x9a\x02\xb09\ 406 | \xc5\xa9G\xf8o\x0b\x05\xe0\x92\x16\x1bM\xd3\x11p\x09\ 407 | \x8dx\xfd\x5c\x12\xb9\x5c\xf6\x95k\xd7\xcd\xac\x9d\xc8f\ 408 | \x1e`\xc5\xc0+\xb3\xe61\xc0\xcd|0#\x00[R\ 409 | K\x0f\x04r;\xe0\xd3\xfa\xfd\xbe\xba\x1dn\xfc\x0b\xa3\ 410 | V\xab\xa5\xe1\xd0U\x22\x11\x9f\xd3\xa3\x8e\xe3d\x0b\x85\ 411 | \xfck\x0a\x05i8\x1c\x1en\xb7:O\xf4\xfb}g\ 412 | 8t'\x5c\xd7\x9dr]wR\xf1\xf8\xf2\xfb\xb6\xef\ 413 | |\xfb\xe1\xf3/|\xd1\x8d\xbf9\xea\x00\xd6\x14\x80.\ 414 | '\x00\x10\x80\x9e\xcb\xe4\x7f\xb1D\x22!\xc7q\xe4\xba\ 415 | \xfc\x9b\x09\x9bD\xc2\x91\x13\x9f\xb9\xff9\x12\x89\xc4\xb6\ 416 | |!\xb7\xcdt\x0e\x1f\xfd\x9a\xa4\x91\x0b@\x1cZ\xd0\ 417 | \x8a\x1c\xef[\xd3u`\xd0\xd1~\xd2t\x84\xd0I$\ 418 | \x12\xcaf'L\xc7\xc0%\xe4\xf399qn\x00\xb8\ 419 | ,k\x0a\xc0\xb1\xbe5\x7fT\x18t\xacG\x01\xb8\x94\ 420 | |!o:\x02.!\x97\xe7\xe7b3kf\xc5\xfd\ 421 | \xbd\x94Z.M\x17\xfe\x19\xb8R\xbd\x1b\xfd\xb5\xd6\xfd\ 422 | \xb0n\xddZ\xd3\x11p\x09\xfc\x5c\xecfM\x01h\x0d\ 423 | \x1d}i!k:\x06b\xec\xc1\xe6\x84Np\xa6\xe9\ 424 | \x92ff\xa6\xb5a\xc3z\xd31\xf0\x0c\x9b7o\xd2\ 425 | \xe4d\xc1t\x0c\x18d\xd5\xa7\xd5c\x9d\xb4\x1e\xeb\xf0\ 426 | \x0d\x0d\xde;\xd6O\xea\xc1\x16\xd7\xb9/gv\xc7v\ 427 | \xa53\x19\xd31 )\x9b\xcdj\xfbUq\xdfL\x0f\ 428 | WbU\x01\x90\xa4\xcf\x9f\xcf\xeak\xcd\x09\xb1\xf3(\ 429 | \xbc\xf2H'\xadO\x9d\xcd\xf3\x9e\xba\x82d2\xa9\x17\ 430 | \xdcp\x9d\xa6g\xa6LG\xb1\xda\x9a53\xda\xbd\xfb\ 431 | :%\x12\xd6}\xfc\xe3\x22\xd6\xdd\x1a?\x90\xa3\x07\x1a\ 432 | \x13z\xbc\x9b\xd2\x8fM\xb6\xb59\xc5F\xae\x18\xcd\x99\ 433 | AB\xf77\xb2z\xa2c\xdd\xaf\xd1\xc8\xd2\x99\x8cJ\ 434 | \xa5ku\xe2\xc4I\x1d9|T\xddn\xb47\xa4\x89\ 435 | \x92L&\xadm\xdb\xb7i\xc3\x86u\xa6\xa3 $\xac\ 436 | \xfd\xe4:\xdcK\xea/\xcf\x14\x94q\x5cmN\x0d\xb4\ 437 | 95T&\xc1W8\x5c^\xdf\x95\x8e\xf7\x92:\xda\ 438 | O\xaa\xcdM\xa5#\xdb\xb8q\x836n\xdc\xa0^\xb7\ 439 | \xa7F\xa3\xa9V\xbb\xcd:\x01>H8\x8er\xb9\x9c\ 440 | \x0a\x93y\xa5R\xd6~\xdc\xe3yX\xff\x8e\xe8\xba\x8e\ 441 | \x0e\xf4R:\xc0\x17\x11 p\xe9LZk23Z\ 442 | \xa3\x19\xd3Q\x00\xebp\x11\x08\x00\x00\x0bQ\x00\x00\x00\ 443 | \xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\ 444 | \x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\ 445 | \x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\ 446 | \x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\ 447 | \x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\ 448 | \x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\ 449 | \x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\ 450 | \x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0b\ 451 | Q\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\ 452 | \x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\ 453 | \x0bQ\x00\x00\x00\xb0P\xcat\x80\xb0H;\xae2\x8e\ 454 | \xe9\x14\x08\xbb\xbe\x1cu\x86\xa6S\xc4O\xbf\xdf\x97\xeb\ 455 | \x9aN\x01\x1b$\x12\x8e\x92\xc9\xa4\xe9\x18\xa1`m\x01\ 456 | H8\xd2\x8d\x13]\xcd\xa6\x07\xda\x92\x1ej]r \ 457 | \xe6\x7f\xac\xc4\xb9ABG\xfaI\x1d\xe9%\xf5\x9dv\ 458 | Z=\x97w\xcej\xf5\xfb}\x9d8~R\x8dFS\ 459 | \x8dFS\xbd^\xcft$Xd\x22\x9b\xd5d!\xaf\ 460 | \xc9\xc9\x826l\x5c/\xc7\xb1\xf3w\xd8\xca\x02\xb0>\ 461 | 9\xd0\xedSmmM\x0fLGA\x04\xcd$\x87\x9a\ 462 | I\x0e\xb5{\xa2\xa7\x17\xe7\xba\xbaw!\xab\x83=+\ 463 | \x7f\x95Fr\xe6\xccY\xcd\xef;\xa0~\xbfo:\x0a\ 464 | ,\xd5i\xb7\xd5i\xb7u\xea\xd4i\x1d?~R;\ 465 | \xaf\xd9\xa1|>o:V\xe0\xac\xbb\x07\xe0\xfa\x89\x9e\ 466 | ~a]\x93\xc9\x1f\x9eX\x93\x1c\xeag\xd74uK\ 467 | \xbec:J$\xcc\xef;\xa0'\x9f\xd8\xcb\xe4\x8f\xd0\ 468 | h\xb5Zz\xf4\x91\xbaN\x9c8i:J\xe0\xac*\ 469 | \x00\xd3\x89\xa1n\x9bj+).6\xc2;\x8e\xa4W\ 470 | \x15:\xda\x9e\xa2T^\xce\xe9\xd3g\xac\xfc\x90E\xf8\ 471 | \xb9\xae\xab\x03\xfb\x0f\xaa\xdd\xb6\xab\xc8[S\x00\x1cI\ 472 | \xb7O\xb55\xe10\xf9\xc3{\x8e\xa4\x9f\x98n)\xcd\ 473 | \xfb\xeb\x92z\xbd\xbe\xf6\xcf\x1f4\x1d\x03x^\xc3\xa1\ 474 | \xab\xbdO\xed\x93k\xd1\xdd\xa8\xd6\x14\x80\xab\xd2}\xed\ 475 | \xc8p\xda\x11\xfeY\x93\x1c\xea\xc6\x09\xdec\x97r\xfc\ 476 | \xd81N\xfb#\xf4\x1a\x8d\xa6\xce\x9d;o:F`\ 477 | \xac)\x00[R<\xbb\x05\xffqo\xc9\xa5-.\xb6\ 478 | LG\x00Vdq\xb1a:B`\xac)\x00\x9b\xb9\ 479 | >\x8b\x00lN\xf1-\xf7R\x9aM{>T\x11m\ 480 | \xcdF\xd3t\x84\xc0XS\x00\xd6r\x06\x00\x01X\x9f\ 481 | rYO\xe2\x22\xbdnO\x83\x01\xbf\x7f\x88\x86\x96E\ 482 | 7\x02ZS\x00\xce\xf4\xad\xf9\xa3\xc2\xa0S}\x87g\ 483 | L.\x92\xce\xa4\x95L\xf2\xfb\x87h\xc8e'LG\ 484 | \x08\x8c5\xbf\x95\xc7\xfa,\xfd\x08\xff\x1d\xeb\xb3 \xd0\ 485 | \xa5\xe4\xf3\x05\xd3\x11\x80\x15\xc9\x17\xecY\x10\xc8\x9a\x02\ 486 | p\x943\x00\x08\xc0\x91\x1eE\xf3R&'s\xa6#\ 487 | \x00+29iOY\xb5fV<\xd8Ki?\xcb\ 488 | \xb5\xc2Gg\x07\x09=\xdc\xe1=v)\x9b6oR\ 489 | *E9B\xb8\x15\x0ay\xcd\xccL\x9b\x8e\x11\x18k\ 490 | \x0a\x80+\xe9\xbe\x85\xac\xbal\xdc\x02\x1f\xb8\x92\xee]\ 491 | \xc8\xb21\xd0\xf3H\xa7\xd3\x9a\xddq\x95\xe9\x18\xc0\xf3\ 492 | r\x1cGW\xef,Z\xb51\x905\x05@Z\xda\xc5\ 493 | \xed\x8b\x0bY\x0d\xb8K\x0b\x1e\xfb\xdf\x8d\x096\x04\xba\ 494 | \x82\xf5\xeb\xd7i\xfd\x86u\xa6c\x00\xcf\xe18\x8ef\ 495 | w\x5c\xa5\x5c.k:J\xa0\xac\xfb\xc4z\xa4\x93\xd6\ 496 | \x89AR?1\xdd\xd4\xa6$\x8f&a<\xe7\x87\x09\ 497 | \xdd\xb7\x90\xd5|\xd7\xba_\xa5\x91\xec\xdcY\xd4\xf4\xf4\ 498 | \x94\x0e\xec?\xa8~\x9f\xb59`^6;\xa1\x9d\xd7\ 499 | \x14U(\xd8s\xed\xff\x02+?\xb5N\xf4\x13\xfa\xd8\ 500 | \x99I\xbd0\xdb\xd5\xf6\xf4@[S\x03\xcdP\x06\xb0\ 501 | B\x8bCG\xc7zI\x1d\xea'\xf5\xadV\x86\xcbJ\ 502 | \xab\xb4~\xfd:MOM\xe9\xf8\x89\x93j4\x1aj\ 503 | 6Z,\x13\x8c@e2\x19\x15\x0ayMN\x15\xb4\ 504 | q\xe3F%\x12v\xfe\x0e[Y\x00$i\xe0J\x0f\ 505 | \xb52zhy\x85\xd2\x09\xc7U6\xc1\xb5\x01\x5c^\ 506 | \xcfu\xd4\x1c\xda\xf9a\xe1\xa5t&\xad\xed\xdb\xb7\xfe\ 507 | \xe0\xbf\xf7\xba=\xab6a\x819\x89dB\xa9\x94\xb5\ 508 | S\xdf\xb3\xf0oaY\xc7u\xd4\x19\xf0\xc1\x0e\x98\x90\ 509 | \xce\xa4MG\x00\xacc\xd5M\x80\x00\x00`\x09\x05\x00\ 510 | \x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\ 511 | \x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\ 512 | \x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\ 513 | \x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\ 514 | \x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0b\ 515 | Q\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\ 516 | \x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\ 517 | \x0bQ\x00\x00\x00\xb0\xd0\xb8\x05\xc0\xf5$\x05\x00\x00\x08\ 518 | \xd4\xb8\x05\xe0\xbc')\x00\x00@\xa0\xc6-\x00\x87<\ 519 | I\x01\x00\x00\x025n\x018\xecI\x0a\x00\x00\x10(\ 520 | \xce\x00\x00\x00`!\x0a\x00\x00\x00\x16\xe2\x12\x00\x00\x00\ 521 | \x16\xe2\x0c\x00\x00\x00\x16\x1a\xb7\x00|O\xd29/\x82\ 522 | \x00\x00\x80\xe0\xa4\xc6yquO\xaeW\x99k}^\ 523 | \xd2;<\xca\x03\xc0\x22\xfd~_\xcdfK\xadfK\ 524 | \xae\xcb\xbab\xf0_\x22\x99P>\x9fW>\x9fS\x22\ 525 | a\xf7b\xb8c\x15\x80e\x9f\x16\x05\x00\xc0*\x9c:\ 526 | yZ\x87\x8f\x1cU\xa7\xdd1\x1d\x05\x96r\x1cG\xf9\ 527 | |^\xb3;\xb6kr\xb2`:\x8e\x11^\x14\x80{\ 528 | %u%e<\x18\x0b@\x8c\xf5z}\xcd\xef\x9b\xd7\ 529 | \xd9\xb3,\x22\x0a\xb3\x5c\xd7U\xa3\xd1\xd0\xf7\x1f{\x5c\ 530 | \x9b7o\xd4\xb6\xed\xdb\x94H8\xa6c\x05j\xec\xf3\ 531 | \x1f\xd5=\xb9\xf3\x92\xfe\xc1\x83,\x00bl0\x18\xe8\ 532 | \xb1G\xbf\xcf\xe4\x8fPq]WG\x8f\x1e\xd7SO\ 533 | >e:J\xe0\xbc\xba\x00r\x8fG\xe3\x00\x88\xa9\x83\ 534 | \x07\x0f\x97N:6\x00\x00\x14}IDAT\xa9\xd3\ 535 | \xe9\x9a\x8e\x01\x5c\xd2\xd9\xb3\xe7u\xf2\xe4)\xd31\x02\ 536 | \xe5U\x01\xb8[R\xd3\xa3\xb1\x00\xc4\xcc\xf9\xf3\x0b:\ 537 | q\xdc\xae\x0fWD\xcf\x81\xfd\x07\xd5\xed\xf6L\xc7\x08\ 538 | \x8c'\x05\xa0\xba'w\x5cR\xd5\x8b\xb1\x00\xc4\xcf\xe9\ 539 | SgLG\x00\xaeh0\x18\xea\xdc9{\x9el\xf7\ 540 | \xf2\x19\x88\xdf\x97t\xd2\xc3\xf1\x00\xc4D\xb3\xc9\x09B\ 541 | DC\xb3\xd12\x1d!0\x9e\x15\x80\xe5\x9b\x01\x7f\xdb\ 542 | \xab\xf1\x00\xc4\xc3p8T\xab\xd56\x1d\x03X\x91F\ 543 | \xc3\x9e\xb2\xea\xf5*\x08\xffU\xd2^\x8f\xc7\x04\x10a\ 544 | \xc3\xe1\x90E~\x10\x19\xc3\xe1\xc0t\x84\xc0xZ\x00\ 545 | \xaa{r]I\x1f\xf4rL\x00\xd1\x96J\xa5\x94\x99\ 546 | `\x99\x10DC>\x9f7\x1d!0~\xac\x83\xf8\x09\ 547 | I\x9f\xf3a\x5c\x00\x115Y\xb0\xe7C\x15\xd1V\xb0\ 548 | \xe8\xbd\xeay\x01\xa8\xee\xc9\xb9\x92\xde)\xe9\x11\xaf\xc7\ 549 | \x06\x10MS\xd3S\xa6#\x00W\xe48\x8e\xa6g\xec\ 550 | y\xaf\xfa\xb2\x13\xc2\xf2\x0d\x81o\x92\xc4\x83\xbf\x00\xb4\ 551 | a\xc3zk\xd7[Gtl\xda\xb4Q\xb9\x5c\xcet\ 552 | \x8c\xc0\xf8\xb6\x15RuO\xee)I?-\xc9\x9eU\ 553 | \x15\x00\x5c\x92\xe38\xbazg\xd1\xfa\xdd\xd7\x10^\x13\ 554 | \xd9\xac\xb6_\xb5\xd5t\x8c@\xf9\xfa\xdbX\xdd\x93\xbb\ 555 | _\xd2\xfb\xfc<\x06\x80h\xc8f'\xb4\xeb\xda\x9dJ\ 556 | \xa7\xbd\xd8\x83\x0c\xf0N>\x9f\xd3u\xd7\xee\xb4\xae\xa0\ 557 | \xfa\xfe\xa7\xad\xee\xc9}H\xd2\x07$\xf1\x1c\x10`\xb9\ 558 | \x99\x99i\xddx\xd3\x0dZ\xbbn\xad\xe9(\x80\x1c\xc7\ 559 | \xd1\xb6m[t\xc3\x0b\xaeW6\x975\x1d'pN\ 560 | P\xcf\xe7V\xe6Zo\x91\xf4\x97\x92\xb8\x10\x08\x8ci\ 561 | mb\xa0wOF{y\xddv\xbb\xa3f\xa3\xa1F\ 562 | \xa3\xa5V\xbb%w\xc8w\x04\xf8/\x99L(_(\ 563 | (\x9f\xcfkr2\xafT*\xd2g\xa4\xce\x15\x8b\xb3\ 564 | kF}q`\x05@\x92*s\xad\x17J\xfa\x8c\xa4\ 565 | \x1d\x81\x1d\x14\x88\xa18\x14\x00\x00c\x1b\xab\x00\x04z\ 566 | \xc1\xa3\xba'\xf7\x1dI/\x95\xf4\xd5 \x8f\x0b\x00\x00\ 567 | \x9e-\xf0;\x1e\x96w\x0e|\x9d\xa4?\x90\xc4\xe6\xe0\ 568 | \x00\x00\x18`\xe4\x96\xc7\xea\x9e\x5c\xb7\xba'W\x91t\ 569 | \x83\x96V\x0e\xe4\xe2\x1f\x00\x00\x012\xfa\xccCuO\ 570 | \xee\xa9\xea\x9e\xdc;%\xfd\xb0\xa4/\x9a\xcc\x02\x00\x80\ 571 | MB\xf1\xd0cuO\xee\xa1\xea\x9e\xdc\x8fK\xfaq\ 572 | -\x15\x81\xbe\xe1H\x00\x00\xc4Z(\x0a\xc0\x05\xd5=\ 573 | \xb9/.\x17\x81\x8d\x92~^\xd2\xff\x90\xd40\x9b\x0a\ 574 | \x00\x80\xf8\x09\xf41\xc0QT\xe6ZYIo\xd0\xd2\ 575 | \xde\x02\xd7J\xda*i\x9b\xa4i\x93\xb9\x00\x93x\x0c\ 576 | \x10\x80\xa2\xb4\x0e\x80\x97*s\xad\xbc\x96\x8a\xc0VI\ 577 | \x9b%Ez5\x07`5\xaeOw\xb6\xbe1\xb7P\ 578 | 5\x9d\x03\x80Qv\x16\x00\xc0f\xf3\xf3\x07vKz\ 579 | \xd4t\x0e\x00FEg! \x00\x00\x10\x0e\x14\x00\x00\ 580 | \x00,D\x01\x00\x00\xc0B\x14\x00\x00\x00,D\x01\x00\ 581 | \x00\xc0B\x14\x00\x00\x00,D\x01\x00\x00\xc0B\x14\x00\ 582 | \x00\x00,D\x01\x00\x00\xc0B\x14\x00\x00\x00,D\x01\ 583 | \x00\x00\xc0B\x14\x00\x00\x00,D\x01\x00\x00\xc0B\x14\ 584 | \x00\x00\x00,D\x01\x00\x00\xc0B\x14\x00\x00\x00,D\ 585 | \x01\x00\x00\xc0B\x14\x00\x00\x00,D\x01\x00\x00\xc0B\ 586 | \x14\x00\x00\x00,D\x01\x00\x00\xc0B\x14\x00\x00\x00,\ 587 | D\x01\x00\x00\xc0B\x14\x00\x00\x00,\x942\x1d`T\ 588 | \x95z\xedG$\xdd\x22\xe9\x87%\xdd \xe9qI\xdf\ 589 | \x90\xf4uI_\xad\x96\xca\xae\xc1x\x00\xae`qq\ 590 | Q\x8d\xc5\xa6\x1a\x8d\xa6Z\xad\xb6\x5cwh:\x12,\ 591 | \x90L&\x95\xcf\xe7U(\xe4U\x98,(\x97\xcb\x9a\ 592 | \x8ed\x8c\xe3\xba\xd1\x9a'+\xf5\xdafI\x1f\x92t\ 593 | \xc7e\xfe\xb1\xfb%\xbd\xa7Z*\xef\x0b\x22\x13\x10\xb4\ 594 | \xf9\xf9\x03\xbb%=j:\xc7(:\x9d\xae\xf6\xed\x9d\ 595 | \xd7\xc2\xc2\xa2\xe9(\x806n\xda\xa0\xd9\xd9\xedJ$\ 596 | \x22yB\xfc\x5c\xb18\xbbf\xd4\x17G\xeaO\x5c\xa9\ 597 | \xd7~R\xd2\xf7t\xf9\xc9_\x92n\x95\xf4\xddJ\xbd\ 598 | \xf6.\xdfC\x01X\xb1S\xa7N\xeb\x91\x87\x1fe\xf2\ 599 | Gh\x9c8~R\x0f\x7f\xefQ5\x1a\x0d\xd3Q\x02\ 600 | \x17\x99\x02P\xa9\xd7vJ\xfa\xa4\xa4\x0d+|\xc9\x94\ 601 | \xa4\x8fT\xea\xb5\x9b\xfdK\x05`\xa5\x9a\xcd\xa6\xf6\xed\ 602 | \xdd\xaf\xc1\x80S\xfd\x08\x97N\xa7\xab'\x9f\xd8\xab\xc1\ 603 | ``:J\xa0\x22Q\x00*\xf5\x9a#\xe9/$M\ 604 | \xae\xf2\xa5iI\x1f\xad\xd4k\x13\xde\xa7\x02\xb0R\xae\ 605 | \xebj\xefS\xf3\x8a\xda%G\xd8\xa3\xdb\xedi\xff\xfc\ 606 | A\xd31\x02\x15\x89\x02 \xe9\x1d\x92^3\xe2ko\ 607 | \x92\xf4/=\xcc\x02`\x95\x8e\x1f;\xa1V\xabm:\ 608 | \x06pY\xa7N\x9d\xd6\xe2\xa2=\x97\x02\xa2R\x00F\ 609 | \x9d\xfc\xbdz=\x801p\xcd\x1fQa\xd3{5*\ 610 | \x05\xe0\xa5\x86_\x0f`\x0c\x8dF\xd3t\x04`E\x9a\ 611 | \x16\xbdWC_\x00*\xf5ZFK\xa7\xf1\xc7\xb1\xb5\ 612 | R\xafm\xf5\x22\x0f\x80\xd5\xe9\xf5\xfa\xea\xf5z\xa6c\ 613 | \x00+\xd2lR\x00\xc2$\xaf\xa5\x9b\xf9\xc65\xe3\xc1\ 614 | \x18\x00V)\x95J\xcaq\x1c\xd31\x80\x15I\xa5\xbc\ 615 | \x98n\xa2!\x0a\x05\x00@\x849\x8e\xa3|>g:\ 616 | \x06\xb0\x22\x85B\xdet\x84\xc0P\x00\x00\xf8.o\xd1\ 617 | \x87*\xa2\x8d\x02\x00\x00\x1e\xda\xb0a=\x97\x01\x10z\ 618 | \xe9tZ3k\xec\xb9ZL\x01\x00\xe0\xbbB!\xaf\ 619 | -[6\x99\x8e\x01\x5cV\xf1\xeaY\xa5RI\xd31\ 620 | \x02C\x01\x00\x10\x88m\xdb\xb7*\xc7\xbd\x00\x08\xa9\xf5\ 621 | \x1b\xd6i\x8dE\xdf\xfe%\x0a\x00\x80\x808\x8e\xa3\xdd\ 622 | \xbbK\xda\xb0q\xbd\xe9(\xc0\x0f$\x12\x09\xcd\xcen\ 623 | \xd7\xce\x9dE\xd3Q\x02\x972\x1d\x00\x80=\x92\xc9\x84\ 624 | \xae\xbez\x87\xd6\xae]\xa3#\x87\x8f\xaa\xd9li8\ 625 | ds \x04/\x95Jir\xb2\xa0\xabf\xb7+\x9b\ 626 | \xb5s\xbb\x18\x0a\x00\x80\xc0\xcd\xccLkffZ\xae\ 627 | \xeb\xaa\xddj\xab\xd5jk\xc8FA\x08@2\x99P\ 628 | >\x9f\xd7\xc4D\xc6t\x14\xe3(\x00\x00\x8cq\x1cG\ 629 | \xb9|\x8e{\x03\x00\x03\xb8\x07\x00\x00\x00\x0bQ\x00\x00\ 630 | \x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\ 631 | \x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\ 632 | \x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\ 633 | \x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\ 634 | \x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\ 635 | \x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0b\ 636 | Q\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\ 637 | \x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\ 638 | \x0bQ\x00\x00\x00\xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\ 639 | \xb0\x10\x05\x00\x00\x00\x0bQ\x00\x00\x00\xb0P\xcat\x00\ 640 | \xc4K\xa5^\x9b\x95t\x9d\xa4\xab$\x9d\x94\xf4D\xb5\ 641 | T\xae\x9bM\x05\x00\xb8\x18\x05\x00\x9e\xa8\xd4k?%\ 642 | \xe9}\x92^s\x89\xff\xef1I\x7f*\xe9\xff\xab\x96\ 643 | \xca\x9d\xa0\xb3\x01\x00\x9e\x8b\x02\x80\xb1T\xea\xb5)I\ 644 | \x1f\x96\xf4\xf6\xcb\xfcc\xbb%\xfd\x91\xa4wU\xea\xb5\ 645 | \xb7TK\xe5\xc3\x81\x84C$\x0c\x06C\xb5\xdbmI\ 646 | \xae\xe9(\x08\xb9d2\xa5lv\xc2h\x06\xc7q\x94\ 647 | H$4\x1c\x0e\xe5\xba\xd1~\xcfR\x000\xb2J\xbd\ 648 | \x96\x96\xf4\x05I/[\xe1K~D\xd27*\xf5\xda\ 649 | \xeb\xaa\xa5\xf2c\xfe%C\xd8\xb5Z-\x1d=r\x5c\ 650 | \x8dfS\x9dv'\xf2\x1f\xa4\x08N2\x99P>\x9f\ 651 | \xd7\xd4\xf4\x94\xb6n\xdd,\xc7q|?f\x22\x99P\ 652 | 6\x9bU*\x95T2\x99\xfc\xc1\xff>\x18\x0c4\xe8\ 653 | \x0f\xd4nw4\x18\x0c|\xcf\xe15n\x02\xc48\xfe\ 654 | \xa3V>\xf9_\xb0U\xd2?T\xea\xb5\xdd>\xe4A\ 655 | \xc8\xb9\xae\xab#\x87\x8f\xea\x91\x87\xbf\xafS\xa7N\xab\ 656 | \xddj3\xf9cU\x06\x83\xa1\x16\x16\x16u\xf8\xd0\x11\ 657 | =\xf2\xf0cj4\x9a\xbe\x1eo\x22;\xa1\xe9\xe9)\ 658 | MLd\x9e5\xf9KR2\x99Tf\x22\xa3\xe9\x99\ 659 | )esY_s\xf8\x81\x02\x80\x91T\xea\xb5\xed\x92\ 660 | \xee\x1a\xf1\xe5[D\x09\xb0\x8e\xeb\xbaz\xbc\xfe\xa4\x0e\ 661 | \x1d:\xc2\xa4\x0fO\xb4Zm=\xf6h]g\xcf\x9c\ 662 | \xf5e\xfc\xc2dA\xf9|nEg\x19r\xb9\xac&\ 663 | \xa7&}\xc9\xe1\x17\x0a\x00F\xf5/4\xde%$J\ 664 | \x80e\x8e\x1f?\xa1\xf3\xe7\x17L\xc7@\xcc\xb8\xae\xab\ 665 | \xf9\xf9\x03\xea\xf7\xfb\x9e\x8e\x9b\x99\xc8(\x93I\xaf\xea\ 666 | 5\xe9\xb4\xf9{\x14V\x83\x02\x80Q\xbd\xc1\x831.\ 667 | \x94\x80\x1b<\x18\x0b!\xd6i\xb7u\xe8\xe0\x11\xd31\ 668 | \x10S\xbd^_\xf3\xfb\x0ex6^\x22\x91P>\x9f\ 669 | \x1b\xe9\xb5\xd9\x5cV\xc9d4\xa6\xd6h\xa4D\x18]\ 670 | \xed\xd18[$\xfd=% \xde\x8e\x9f8\xa9\xe1p\ 671 | h:\x06b\xec\xcc\x99\xb3\xeav\xba\x9e\x8c\x95\x99\xc8\ 672 | \x8c|s\xa1\xe38\x9a\x98\x88\xc6Y\x00\x0a\x00F5\ 673 | \xed\xe1X\x9c\x09\x88\xb9\xc6\xa2\xbf7j\x01\x92\xb4\xe8\ 674 | \xd1\x0d\x81\xa9\x8bn\xf6[\xaddj\xbc\xd7\x07\x85\x02\ 675 | \x80Q\xed\xf5x\xbc\xcd\xa2\x04\xc4\x92\xeb\xbaj6[\ 676 | \xa6c\xc0\x02\xcd\xa67\x05`\xdc\x09\xfc\xe2\xa7\x05\xc2\ 677 | *\x0a\x05\xc0\x9bs:\xd2\xea\xee\xe6\xc0\x95\xcc\xf90\ 678 | &% \x86\xfa\xbd>\xa7\xff\x11\x88ng\xfc\x85F\ 679 | /,\xf4cz\x8c \x84>a\xb5TnJ\xf2\xe2\ 680 | \xd6\xe1-\x1e\x8c\x81\xa7}\xc4\xa7q)\x011\x93\xce\ 681 | \xa4\x95J\xb1\xe6\x18\xfc\x97\xcb\x8dv\xe3\x9e\xadB_\ 682 | \x00\x96yq\xfb\xf06\x0f\xc6\xc0\xd3\xbe$\xe9;>\ 683 | \x8dM\x09\x88\x99|>o:\x02,P(\xf0>[\ 684 | \x8d\xa8\x14\x00/\xd6\x8e\xa7\x00x\xa8Z*\xbb\x92\xde\ 685 | &\xc9\x9f\x158(\x01\xb129\xc9\x073\xfc\xe58\ 686 | \x8e\xf2\x14\x80U\xa1\x00`d\xd5R\xf9q-\x95\x00\ 687 | \xbfv\xf8\xbbP\x02^\xe0\xd3\xf8\x08\xc8\xe6-\x9b\x95\ 688 | \xcedL\xc7@\x8cm\xdd\xb6\x85KM\xabdS\x01\ 689 | \xd8\xe1\xc1\x18\xb8H\xb5T\xfe\x92\xa4;\xe5o\x09\xf8\ 690 | {J@\xb4%\x93\x09\xed\xdc\xc9\xaf \xfc\x91\xcb\xe5\ 691 | \xb4u\xebf\xd31\x22\xc7\xa6\x02pk\xa5^\xe3+\ 692 | \x88\x0f\xaa\xa5\xf2}\xa2\x04\xe0\x0a\xa6\xa7\xa7\xb4m\xdb\ 693 | \x96@vo\x83=2\x99\x8c\xae\xd9u5\xef\xab\x11\ 694 | \xd8T\x00\xa6%\xbd\xd6\x83qp\x09\x94\x00\xac\xc4\xb6\ 695 | \xed[U\xba\xfeZML\xd0\xc51\xbe\x0d\x1b\xd7\xeb\ 696 | \xc6\x9bnP.\x82;\xf1\x85AT.\x98xQ\x00\ 697 | $\xe9\x0eI\x7f\xeb\xd1X\xb8H\xb5T\xbe\xafR\xaf\ 698 | \xdd)\xe9\x1eI~\xac\x85y\xe1\x9e\x80\xd7VK\xe5\ 699 | G|\x18\x1f\x01\x98\x9a\x9a\xd4\x0bn\xbcAgN\x9f\ 700 | Q\xa3\xd9T\xb3\xd1R\xbb\xddf\xad\x00\x5cQ:\x9d\ 701 | R>\x9fW\xbe\x90\xd7\xd4\xd4\xa4\xa6\x22\xb6\xfb^\xd8\ 702 | 8Q\xd8\x96\xb3R\xaf\xcdH:\xa1\xf1\x17\xf39$\ 703 | iv\xf9\x0ev\xf8\xa4R\xaf\xbdQ\xfe\x95\x00I:\ 704 | .\xc9\xea\x120?\x7f`\xb7\xa4GM\xe7\x00\xe2\xc6\ 705 | q\x1c\xadY;3\xf68\xe7\xce\x9e\x0f\xa2\xd4\x9e+\ 706 | \x16g\xd7\x8c\xfa\xe2H\x5c\x02\xa8\x96\xca\xe7$\xdd\xef\ 707 | \xc1P\xdb%\xbd\xca\x83qp\x19\x01\x5c\x0e\xd8$\x9e\ 708 | \x0e\x00\x80\xb1D\xa2\x00,\xbb\xc7\xa3q\xfe\xa3G\xe3\ 709 | \xe02(\x01\x00\x10nQ*\x00\x9f\x96\xe4\xc5\xa9\xfb\ 710 | WV\xea\xb57{0\x0e\xae \xc0\x12p\xa3O\xe3\ 711 | \x03@lE\xa6\x00TK\xe5C\x92\xbe\xe1\xd1p\xbf\ 712 | [\xa9\xd7\xa2\xb1]S\xc4\x05T\x02\xfe\x9e\x12\x00\x00\ 713 | \xab\x13\x99\x02\xb0\xcc\xab\xcb\x007H\xfaE\x8f\xc6\xc2\ 714 | \x15P\x02\x00 |l-\x00\x92T\xad\xd4k?\xe4\ 715 | \xe1x\xb8\x0cJ\x00\x00\x84K\xa4\x0a\xc0\xf2c_\x8f\ 716 | {4\xdc\xa4\xa4\xcfT\xea\xb5\x8d\x1e\x8d\x87+\xa0\x04\ 717 | \x00@xD\xaa\x00,\xfb\x90\x87c\x15%\xdd\xcd\x12\ 718 | \xc1\xc1\xa1\x04\x00@8D\xb1\x00\xfc\x17I\xf3\x1e\x8e\ 719 | \xf7JI\x1f\xe6\xa6\xc0\xe0P\x02\x00\x84U2\xe9\xcd\ 720 | T\x10\x85E\xf6\x22W\x00\xaa\xa5rG\xd2\x07=\x1e\ 721 | \xf6\xdd\x92j\xcb+\x0e\x22\x00<\x22\x08 \x8cR\xa9\ 722 | \xf1\x0b\x80\xeb\xba\x14\x00\x1f}\x5c\xd2\xb7=\x1e\xf3\x8d\ 723 | \x92\x1e\xac\xd4k\xd7z<.\x9eG\x00%`\xa3\x96\ 724 | J\xc0M>\x8d\x0f f\x92\xa9\xf1\xb7\xc8\x89\xca\xbe\ 725 | \x16\x91,\x00\xcbk\xf9\xbf\xdf\x87\xa1wK\xfa\xa7J\ 726 | \xbd\xf6\xe3>\x8c\x8dK\x08\xa8\x04\xfc=%\x00\xc0\x95\ 727 | $\x93I\xa5\xd3^\x14\x80\xf0\x7f\xfb\x97\x22Z\x00$\ 728 | \xa9Z*\x7fQ\xd2\x17|\x18z\x9d\xa4\xbf\xad\xd4k\ 729 | \x9f\xae\xd4k7\xf80>.B\x09\x00\x10\x06\x85B\ 730 | ^\x8e\xe3\x8c=\x8e\xcb\x19\x80@\xfcky\xb3<\xf0\ 731 | \xa5\xbcY\xd2\x5c\xa5^\xfbp\xa5^\xdb\xe6\xd31\xb0\ 732 | \x8c\x12\x00\xc0\xa4\x5c>\xa7\xa4\x07\xd7\xff%\xa9\xd7\xef\ 733 | {2\x8e\xdf\x22\xb1\x1d\xf0\xe5T\xea\xb5?\x95\xf4+\ 734 | >\x1f\xa6%\xe93Z\xda\x8f\xe0\xf3\xcb\xbb\x13\xc2\x07\ 735 | \x01l%|B\xd2\xeb\xaa\xa5\xf2\xf7|\x1a?\x10l\ 736 | \x07\x0cx#\x91H(_\xc8{r\xea\xff\x82\xb3g\ 737 | \xce\x05u\x13\xe0X\xdb\x01\xc7\xa1\x00d$\xfd\x9d\x96\ 738 | \x1e\xe7\x0bBO\xd2\x03Z*\x04\x8fJ:,\xe9p\ 739 | \xb5T>\x1b\xd0\xf1c\x8f\x12pe\x14\x00`t\x8e\ 740 | \xe3(\x99J*\x95J)\x9b\x9d\xf0\xe4\xb4\xff\x05\xfd\ 741 | ~_\x0b\xe7\x17=\x1b\xef\x0a\xec.\x00\x92\xb4\xbc\x9a\ 742 | \xdf\xd7\xb5\xb4\xb0\x8f)--\x95\x81\xc0~\xf21W\ 743 | \x944\xf2\x1b{\x05\x22]\x02(\x00\xb0\x81\xe38J\ 744 | \xa5\x92J\xa6RJ%\x93J$\xc7\xbfj\xed8\x8e\ 745 | \x12\x09\xff\xae~\xb7\x9a-\xb5\xdb~]\xc9|\x0e\x0a\ 746 | \x80$U\xea\xb5\x17J\xfa\xaa\xa4\x82\xe9,\x88\x8c\xc8\ 747 | \x96\x00\x0a\x00\xe2.\x9dN)_\xc8\xfb:Y\xfb\xe1\ 748 | \xdc\xd9\xf3A>\x068V\x01\x88\xd6\xbf\xd9\xcb\xa8\x96\ 749 | \xca\xdf\xd1\xd2\x82>\xf1h4\x08\xc2\x85\x1b\x03w\x9b\ 750 | \x0e\x02\xe0i\xf9B^\x93S\x93\x91\x9b\xfc\xbb\x9dn\ 751 | d\xd6\x00\x90bT\x00$\xa9Z*\xdf-\xe9\xb7L\ 752 | \xe7@\xa4l\x94\xf4\xf1J\xbd\xe6\xdd\x1d@\x00F\x96\ 753 | \xcde51\x11\xbd\xedY\x5c\xd7U\xab\xd56\x1dc\ 754 | UbU\x00\x96\xfd\x07I\x9f4\x1d\x02\x91r\xb3\x96\ 755 | \x1e)\x05`P2\x95T.\x975\x1dc$\x9d\x88\ 756 | }\xfb\x97bX\x00\x96W\x09|\x97\xa4?0\x9d\x05\ 757 | \x91\xf2\x1b\x95zm\xbb\xe9\x10\x80\xcd\xf2\xf9\x9c\xe9\x08\ 758 | #q]W\xed\x88}\xfb\x97bX\x00$\xa9Z*\ 759 | \x0f\xaa\xa5rE\xd2/I\xea\x9a\xce\x83H\xc8H\xfa\ 760 | Q\xd3!\x00[-\xdd\xf1\x1f\xcd+q\xcdF3\x12\ 761 | \x9b\xff\x5c,\x96\x05\xe0\x82j\xa9\xfc\x11I?\xa6\xa5\ 762 | \xbb\xbd\x81+y\xa9\xe9\x00\x80\xad\xbc\xda\x867h\xed\ 763 | V[\xddn\xcft\x8c\x91\xc4\xba\x00HR\xb5T\xfe\ 764 | \x8a\x96>\xd8\xbfk:\x0bB\xef%\xa6\x03\xacB\xf4\ 765 | \xben\x00\x97\xe1\xd52\xbcA\xeav{\xa6o\xfc\x1b\ 766 | \xebs \xf6\x05@\x92\xaa\xa5\xf2\xbc\x96N\xef~\xda\ 767 | t\x16\x84Z\x94\xce\x14\x9d6\x1d\x00\xf0\x92\x1b\x91\x1d\ 768 | \xf4.\x18\xf4\x07j6\x9a\xa6c\x8c\xf59`E\x01\ 769 | \x90\xa4j\xa9\xbc(\xe9-\x92~N\xd2^\xc3q\x10\ 770 | N_7\x1d`\x15NjiYj \x16\x06\x83h\ 771 | l\xa0#I\xbd^O\x0b\x0b\x8ba\xb8\xee\x7fd\x9c\ 772 | \x17[S\x00\xa4\xa5'\x04\xaa\xa5\xf2_I\xda-\xe9\ 773 | .I\xa7\x0cGB\xb8D\xa6\x00\x14\x8b\xb3\xae\xa4c\ 774 | \xa6s\x00^\x19\x0c\x86a\x98P\xaf\xa8\xdd\xeehq\ 775 | \xa1\x11\x96\xac\x14\x80\xd5\xaa\x96\xca\xddj\xa9\xfc\x9f%\ 776 | \xed\x92\xf4;ZZ\xc7\x1fv{X\xd2\xff6\x1db\ 777 | \x95\x0e\x9b\x0e\x00x\xa9\xdb\x09\xf7C[\x8dFS\xad\ 778 | f\xa8\xa6\x8b\xb1>\x03\xac,\x00\x17TK\xe5s\xd5\ 779 | R\xf9\x03\x92\xae\x93\xf4\xe7\x92\x06\x86#\xc1\x8c\x81\xa4\ 780 | \xf7TK\xe5p\x7f\xfa<\xd7X\xed\x1f\x08\x9bV\xab\ 781 | \xad\xe1 |\x8b\xe9\xf4\xba=\x9d?w>\x8c\x05\x85\ 782 | 3\x00\xe3\xaa\x96\xca\x87\xaa\xa5\xf2{%]%\xe9\x9f\ 783 | K\xfa\xbc\xa4\xc0\xb6s\x82q\xbfW-\x95#s\xfa\ 784 | \xff\x198\x03\x80Xq]W\x0d\xf37\xd6\xfd\xc0\x85\ 785 | \xad}\x17\x17\x1b\x1a\x84\xb0\x98h\xcc\xcf\x80h\xae\xba\ 786 | \xe0\x93j\xa9|T\xd2\x87%}\xb8R\xafMJ\xba\ 787 | M\xd2\x9d\x92~R\xd2Z\x93\xd9\xe0\x9b\x8fK\xfaw\ 788 | \xa6C\x8c\xe8\x90\xe9\x00\x80\xd7\x96&\xdd\x05\xe5\x0by\ 789 | #k\x03\xb8\xae\xab^\xaf\xa7n\xa7\xa7^/\xf4\xf7\ 790 | \xd9\x8e\xf5\x19\x10\x9b\xed\x80\xfd\xb4\xbcQ\xcc\xab$\xbd\ 791 | N\xd2\xac\xa4\xed\x92\xb6-\xff}\xc6`4\x8c\xe7\xe3\ 792 | \x92~\xa1Z*G\xf2\xd2\xcf\xfc\xfc\x81Whi\x0b\ 793 | l v\x1c\xc7Q6\x97U&\x93\xf6}W\xc0\xe1\ 794 | `\xb84\xe9\xf7z\xea\xf7\x22\xf34B[\xd2\x86b\ 795 | q\xb61\xea\x00\x14\x801U\xea\xb5\x82\x9e]\x08\xa6\ 796 | \xcc&\x8a\x85\xa4\xa4\x0fJ\xda\xe2\xe31\x22=\xf9K\ 797 | \xd2\xfc\xfc\x81\x84\x96N\x01n6\x9d\x05\xf0\xd3\xd22\ 798 | \xc1\xc9\xe5\x22\xe0\x8c5\x96+W\xee\xd0\xd5p8\xd4\ 799 | p\x18\x8d'\x0f\x9eG\xadX\x9c}\xd38\x03P\x00\ 800 | \x10*\x95z-)\xe9\xa3ZZ\xaf\xc1/\x91\x9f\xfc\ 801 | /\x98\x9f?\xf0aI\xef5\x9d\x03@\xe0\xde[,\ 802 | \xce\xfe\xf98\x03p\x13 B\x83\xc9\x7f$\xacn\x09\ 803 | \xd8g(\xe9\xb3\xe3\x0eB\x01@(0\xf9\x8f\xecK\ 804 | \x92F\xbe\x06\x08 \x92\x1e,\x16g\x8f\x8f;\x08\x05\ 805 | \x00\xc61\xf9\x8f\xaeX\x9cmK\xfa\x82\xe9\x1c\x00\x02\ 806 | \xe5\xc9\x99?\x0a\x00\x8cb\xf2\xf7\xc4X\xd7\x01\x01D\ 807 | J[\xd2_y1\x10\x05\x00\xc60\xf9{\xa3X\x9c\ 808 | \xfd\x9c\xa4\x07L\xe7\x00\x10\x88?,\x16g\x0fz1\ 809 | \x10\x05\x00F0\xf9{\xee\xfd\x1asop\x00\xa1w\ 810 | Z\xd2\xefz5\x18\x05\x00\x81c\xf2\xf7^\xb18\xfb\ 811 | 5I\x7fm:\x07\x00_\xfdv\xb18{\xd6\xab\xc1\ 812 | (\x00\x08\x14\x93\xbf\xaf> )\xf4k\x97\x02\x18\xc9\ 813 | >I\x7f\xe2\xe5\x80\x14\x00\x04\x86\xc9\xdf_\xc5\xe2\xec\ 814 | \x93\x92\xfe\xcct\x0e\x00\xbe\xf8\xb7\xc5\xe2\xac\xa7\xdb\x11\ 815 | R\x00\x10\x08&\xff\xc0|P\xd2\xa3\xa6C\x00\xf0\xd4\ 816 | \xff\x90\xf4\x09\xaf\x07e)`\xf8\x8e\xc9?X\xf3\xf3\ 817 | \x07\xae\x95\xf45\xb1\x83%\x10\x07\xdf\x96\xf4\xcaq6\ 818 | \xfdy>\x9c\x01\x80\xaf\x98\xfc\x83W,\xce>!\xe9\ 819 | g$\xf1\xef\x03\x88\xb6\xe3\x92\xee\xf0c\xf2\x97(\x00\ 820 | \xf0\x11\x93\xbf9\xc5\xe2\xec\x97$\xdde:\x07\x80\x91\ 821 | u%\xfdT\xb18\xbb\xdf\xaf\x03P\x00\xe0\x0b&\x7f\ 822 | \xf3\x8a\xc5\xd9?\x96\xf4\xdfL\xe7\x000\x92_-\x16\ 823 | g\xbf\xe2\xe7\x01(\x00\xf0\x1c\x93\x7f\xa8\xfc\xaa\xa4\x8f\ 824 | \x98\x0e\x01`\xc5\x06\x92~m\xdc\xad~W\x82\x9b\x00\ 825 | \xe1)&\xffp\x9a\x9f?p\x97\xa4\xdf\x97\x944\x9d\ 826 | \x05\xc0\xf3:+\xe9g\x8b\xc5\xd9\xbf\x0d\xe2`\x14\x00\ 827 | x\x86\xc9?\xdc\xe6\xe7\x0f\xdc\xae\xa5G\x89fLg\ 828 | \x01\xf0\x1c\x8fKzS\xb18\xfb\xfd\xa0\x0e\xc8%\x00\ 829 | x\x82\xc9?\xfc\x8a\xc5\xd9{%\xbd\x5c\xd2\x13\xa6\xb3\ 830 | \x00x\x96/I\xba%\xc8\xc9_\xa2\x00\xc0\x03L\xfe\ 831 | \xd1Q,\xce>*\xe9\x16-\xdd\x17\xc0\xbfK\xc0\xac\ 832 | \x05I\xbf!\xe9\xf6bq\xf6L\xd0\x07\xe7\x12\x00\xc6\ 833 | \xc2\xe4\x1f]\xf3\xf3\x07^ \xe9w$\xbd\xd9t\x16\ 834 | \xc02=I\x1f\x92\xf4\x1f\x8a\xc5\xd9\xe3\xa6Bp\x06\ 835 | \x00\xe3\xfa\x131\xf9GR\xb18\xfbH\xb18{\x87\ 836 | \xa4WI\xfa_\xa6\xf3\x00\x16p%}R\xd2\x0d\xc5\ 837 | \xe2\xec\xfbLN\xfe\x12g\x000\x86J\xbd\xf6\xcb\x92\ 838 | \xfe\xab\x8f\x87`\xf2\x0f\xd0\xfc\xfc\x81;$\xbdW\xd2\ 839 | \xeb%e\x0d\xc7\x01\xe2\xe4\xb4\xa4\xcfI\xfa\xc3bq\ 840 | \xf6\x9b\xa6\xc3\x5c@\x01\xc0H*\xf5\xda\x1aI\x87$\ 841 | \xe5}:\x04\x93\xbf!\xf3\xf3\x07\x0a\x92n\x93t\x87\ 842 | \xa4\x9f\x94\xb4\xdel\x22 \x92\xf6J\xfa\x8c\xa4{$\ 843 | }\xa5X\x9c\xed\x1b\xce\xf3\x1c)\xd3\x01\x10Y\xbf(\ 844 | &\xffXZ^w\xfcnIw\xcf\xcf\x1fHJz\ 845 | \xa5\xa4\x1f\x934+i\xbb\xa4m\xcb\x7f_c,$\ 846 | \x10\x0e\xae\xa4\x13Z\xfa2tx\xf9\xefOI\xba\xb7\ 847 | X\x9c\xfd\xae\xc9`+A\x01\xc0\xa8\xde\xe4\xd3\xb8L\ 848 | \xfe!R,\xce\x0e$=\xb0\xfc\xd7\xb3\xcc\xcf\x1f\xc8\ 849 | i\xa9\x08\xac\x97\xe4\x04\x1c\x0d0i \xe9\x98\xa4#\ 850 | \xc5\xe2l\xcft\x98QQ\x000\xaak}\x18\x93\xc9\ 851 | ?B\x8a\xc5\xd9\x96\x96\xd6\x14`]\x01 \x82x\x0a\ 852 | \x00\xa3\xf2\xfa\xba0\x93?\x00\x04\x88\x02\x80Q\x1d\xf4\ 853 | p,&\x7f\x00\x08\x18\x05\x00\xa3z\xcc\xa3q\x98\xfc\ 854 | \x01\xc0\x00\x0a\x00F\xf5\x97\x1e\x8c\xc1\xe4\x0f\x00\x86P\ 855 | \x000\xaa{$\x1d\x18\xe3\xf5L\xfe\x00`\x10\x05\x00\ 856 | #\xa9\x96\xca=I\xef\xd2h\x1b\xca0\xf9\x03\x80a\ 857 | \x14\x00\x8c\xacZ*\x7fY\xd2\xfb\xb4\xba\x12\xf0gb\ 858 | \xf2\x07\x00\xe3X\x0a\x18c\xab\xd4k\xaf\x95\xf41-\ 859 | \xad\x10\xf7|\xceK\xba\xabZ*\x7f$\x98T\x00\x80\ 860 | \xcb\xa1\x00\xc0\x13\x95z-#\xe9\xadZ\xba,P\x92\ 861 | t\x95\xa4\x93ZZ$\xe6\x1eI\x7fQ-\x95\x17\xcc\ 862 | %\x04\x00<\xd3\xff\x01F\x8c2\xf9\xc7\xa1\xe9\xb4\x00\ 863 | \x00\x00\x00IEND\xaeB`\x82\ 864 | \x00\x00\x1d1\ 865 | \x89\ 866 | PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ 867 | \x00\x02\x00\x00\x00\x02\x00\x08\x06\x00\x00\x00\xf4x\xd4\xfa\ 868 | \x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ 869 | \x00\x00\x00\x09pHYs\x00\x00z/\x00\x00z/\ 870 | \x01\x1f\xfd\xfb\xc9\x00\x00\x00\x19tEXtSof\ 871 | tware\x00www.inksca\ 872 | pe.org\x9b\xee<\x1a\x00\x00\x1c\xaeID\ 873 | ATx\xda\xed\xdd\xf9\x97\xdde}\xc0q\x01\x17\x14\ 874 | \xadZ+\x09\x9b\x22\x8aH\x01\x05q\x05\x17D\x84\x04\ 875 | \xd7Z\x97\xdaj]\xearj\xabV\xeb^\x8f+j\ 876 | -*\xc2\xa1\xa0\xa2\xe0\x02\x14\x84\x86\xb0\x05\x92\x99\xec\ 877 | \xfb\xac\x99\xccd2\x93\xc9\xbe'3s\xef,\x01\x02\ 878 | Yn\x9f\x1b\xc39\xd6\x15d\x9e;\x9f\x99\xef\xeb\x87\ 879 | \x17\x7f\xc0\x93\x0f\xf7\xf3\x9e{\xef\xf7\xb9\x8f\xaaT*\ 880 | \x8f\xe2w\xed*\xaf~_R\x01\xfe\xb8\x9d\x1b\xe6\xef\ 881 | Z\xdfq\xf3\x07\xbcn\xc0\xd8\xe2\x10\x04\x00<\x22\xdb\ 882 | \xd7\xce\xaa\xb4\xcf\xbbx\xbf\x08\x00\x01 \x00\xa0`\x01\ 883 | \xd06\xfb[\x22\x00\x04\x80\x00\x80\x22\x06\x80\x08\x00\x01\ 884 | \x00\xa0\xa0\x01 \x02@\x00\x08\x00(h\x00\x88\x00\ 885 | \x10\x00\x02\x00\x0a\x1a\x00\x22\x00\x04\x80\x00\x80\x82\x06\x80\ 886 | \x08\x00\x01 \x00\xa0\xa0\x01 \x02@\x00\x08\x00(h\ 887 | \x00\x88\x00\x10\x00\x02\x00\x0a\x1a\x00\x22\x00\x04\x80\x00\x80\ 888 | \x82\x06\x80\x08\x00\x01 \x00\xa0\xa0\x01 \x02@\x00\x08\ 889 | \x00(h\x00\x88\x00\x10\x00\x02\x00\x0a\x1a\x00\x22\x00\x04\ 890 | \x80\x00\x80\x82\x06\x80\x08\x00\x01 \x00\xa0\xa0\x01 \x02\ 891 | @\x00\x08\x00(h\x00\x88\x00\x10\x00\x02\x00\x0a\x1a\x00\ 892 | \x22\x00\x04\x80\x00\x80\x82\x06\x80\x08\x00\x01 \x00\xa0\xa0\ 893 | \x01 \x02@\x00\x08\x00(h\x00\x88\x00\x10\x00\x02\x00\ 894 | \x0a\x1a\x00\x22\x00\x04\x80\x00\x80\x82\x06\x80\x08\x00\x01 \ 895 | \x00\xa0\xa0\x01 \x02@\x00\x08\x00(h\x00\x88\x00\x10\ 896 | \x00\x02\x00\x0a\x1a\x00\x22\x00\x04\x80\x00\x80\x82\x06\x80\x08\ 897 | \x00\x01 \x00\xa0\xa0\x01 \x02@\x00\x08\x00(h\x00\ 898 | \x88\x00\x10\x00\x02\x00\x0a\x1a\x00\x22\x00\x04\x80\x00\x80\x82\ 899 | \x06\x80\x08\x00\x01 \x00\xa0\xa0\x01 \x02@\x00\x08\x00\ 900 | (h\x00\x88\x00\x10\x00\x02\x00\x0a\x1a\x00\x22\x00\x04\x80\ 901 | \x00\x80\x82\x06\x80\x08\x00\x01 \x00\xa0\xa0\x01 \x02@\ 902 | \x00\x08\x00(h\x00\x88\x00\x10\x00\x02\x00\x0a\x1a\x00\x22\ 903 | \x00\x04\x80\x00\x80\x82\x06\x80\x08\x00\x01 \x00\xa0\xa0\x01\ 904 | \x02@\x00\x08\x00(h\x00\x88\x00\x10\x00\x02\x00\x0a\ 905 | \x1a\x00\x22\x00\x04\x80\x00\x80\x82\x06\x80\x08\x00\x01 \x00\ 906 | \xa0\xa0\x01 \x02@\x00\x08\x00(h\x00\x88\x00\x10\x00\ 907 | \x02\x00\x0a\x1a\x00\x22\x00\x04\x80\x00\x80\x82\x06\x80\x08@\ 908 | \x008\x04\x01\x00\x05\x0d\x00\x11\x80\x00@\x00@A\x03\ 909 | @\x04 \x00\x10\x00P\xd0\x00\x10\x01\x08\x00\x04\x00\x14\ 910 | 4\x00D\x00\x02\x00\x01\x00\x05\x0d\x00\x11\x80\x00@\x00\ 911 | @A\x03@\x04 \x00\x04\x80\x00\x80\x82\x06\x80\x08@\ 912 | \x00\x08\x00/\xf0P\xd0\x00\x10\x01\x08\x00\x01\x00\x144\ 913 | \x00D\x00\x02@\x00\x00\x05\x0d\x00\x11\x80\x00\x10\x00@\ 914 | A\x03@\x04 \x00\x04\x00P\xd0\x00\x10\x01\x08\x00\x01\ 915 | \x00\x144\x00D\x00\x02@\x00\x8cK\xc3\xa5U\x95\xbe\ 916 | m\xed\xc9r2\x1a\xea\xef\x16\x00\x22\x00\x04\x80\x00\x18\ 917 | ]\xd5\x85\xbf\xa6kNe\xc5\xb2i\x95\x96\xa5\xb7$\ 918 | S\xa8\x81\x8e\xd6;+\xabW\xce\xae\xec\xdc\xb2L\x00\ 919 | \x88\x00\x10\x00\x02\xa0\x96\x7f\xed\xf7T6\xac^Xi\ 920 | m\xb0\xf4G\xdb\xda\xee\xb9\x95\xa1\xfeU\x02@\x04\x80\ 921 | \x00\x10\x00\xf9\xdf\xea\xefl\xbb\xcb\xf2\x0d\xa4\xbd\xe5\x8e\ 922 | \xca@o\x97\x00\x10\x01 \x00\x04@>\xd5\xbf8-\ 923 | \xddxV\xad\xa8\x17\x00\x22\x00\x04\x80\x00\xc8\xa3\xfa\x99\ 924 | \xb3e\x1b\xd7\xb6\x8dM\x02@\x04\x80\x00\x10\x00#o\ 925 | \xe5\xf2\xbb-\xda\xe0\x1f\x05\x08\x00\x11\x00\x02@\x00\x8c\ 926 | \xf8\x17\xffZ\x1b\xa6Z\xb4\xc1\x0d\xf6u\x09\x00\x11\x00\ 927 | \x02@\x00\x8c\x9c\xfe\xed\x1d\x16\xec\x18\xb0cs\x8b\x00\ 928 | \x10\x01 \x00\x04\xc0\xc8\xa9~\xbel\xc1\xc6\xb7q\xcd\ 929 | \x22\x01 \x02@\x00\x08\x80\x91\xd3\xbb\xb5\xcd\x82\xf5E\ 930 | @\x01 \x02@\x00\x14-\x00\xaa\x97\xcd\xb8\xed/\xbe\ 931 | \xf2\xceN\x01 \x02@\x00\x08\x80\x91\xd5\xd1:\xcd\x92\ 932 | \x0d\xac\xad\xe9VO\x01\x88\x00\x10\x00\x02`\xe4m^\ 933 | \xb7\xd4\xa2\x0dl}\xcf\x02\x01 \x02@\x00\x08\x80<\ 934 | \xba\xdagX\xb6\x01U\x7f\x90\xa9\xfa\xa8\xa6\x00\x10\x01\ 935 | \x00\x04@\x16\xd5\xcf\x98\x975\xdej\xe9\x06R\xfd\ 936 | Q\xa6\xea/3\xba\x0aX\x04\x80\x00\x10\x00\xd9#`\ 937 | \xe5\xf2\xe9\x96o\x90\xbf\xfc\xfb\xb7\xb7\x8f\xd9Y\x12\x00\ 938 | \x22\x00\x01 \x00\xc6\xa0Mk\x97\x1c\xb8~\xd6\x22\x1e\ 939 | \x9dk\x7f\xab?\xc9<\x16\xdf\xf6\x17\x00\x22\x00\x01 \ 940 | \x00\xc6\xcd#\x82\xdd\x07~(\xa8\xfa%\xc1j\x14\x90\ 941 | \xc7\xe6uK\xd29\xb7V\x06\xfb\xba\xc7\xcd\xec\x08\x00\ 942 | \x11\x80\x00\x10\x00P@\x02@\x04 \x00\x04\x00\x08\x00\ 943 | D\x00\x02@\x00\x80\x00@\x04 \x00\x04\x00\x08\x00D\ 944 | \x00\x02@\x00\x80\x00@\x04 \x00\x04\x00\x08\x00D\x00\ 945 | \x02@\x00\x80\x00\x10\x01\x22\x00\x01 \x00@\x00\x88\x00\ 946 | \x10\x00\x02\x00\x04\x80\x08\x00\x01 \x00@\x00\x88\x00\x10\ 947 | \x00\x02\x00\x04\x80\x08\x00\x01 \x00@\x00\x88\x00\x10\x00\ 948 | \x02\x00\x04\x80\x08\x00\x01 \x00@\x00\x88\x00\x04\x00\x02\ 949 | \x00\x04\x80\x08@\x00\x08\x00/\xee \x00D\x00\x02@\ 950 | \x00\x00\x02@\x04P\xb8\x00\xe8\x9dq\xe4S\x93\xf7$\ 951 | W'\xd3\x93\xf6dk\xb2}<\xea_t\xee\x0c/\ 952 | \xee \x00D\x00\x85\x0d\x80\xb4\x0c\xcf>\xb8\xf0\xf7$\ 953 | \x95\xa2\xe8_p\xd6\x02/\xee \x00D\x00\x85\x0b\x80\ 954 | \xb4\x04OH\xa6\x16i\xe9\x0b\x00\x10\x00\x22\x80B\x07\ 955 | @Z\x80\xe7%\xa5\xa2.\x7f\x01\x00\x02@\x04P\xb8\ 956 | \x00H\xcb\xef\xc3\xc9\xde\x22/\x7f\x01\x00\x02@\x04P\ 957 | \xa8\x00H\x8boR\xb2\xaf\xe8\xcb_\x00\x80\x00\x10\x01\ 958 | \x14&\x00\xd2\xd2{n2`\xf9\x0b\x00\x10\x00\x22\x80\ 959 | b\x05\xc0L\x8b_\x00\x80\x00\x10\x01\x14(\x00\xd2\xc2\ 960 | \xbb\xd0\xd2\x17\x00 \x00D\x00\xc5\x0b\x80\x16K_\x00\ 961 | \x80\x00\x10\x01\x14(\x00\x0e>\xefo\xe9\x0b\x00\x10\x00\ 962 | \x22\x80\x82\x05\xc0\xbfY\xf8\x02\x00\x04\x80\x08\xa0x\x01\ 963 | p\x9b\x85\xff\xfb\x02\xe0\xec\xf9^\xdcA\x00\x88\x00\xc6\ 964 | s\x00\xf8\xfc\xdf;\x00 \x00D\x00\x05\x0c\x80\xed\x16\ 965 | \xbe\x00\x00\x01 \x02(^\x00\xb8\xf9O\x00\x80\x00\x10\ 966 | \x01\x96b\x01\x03\xc0\xc2\x17\x00 \x00D\x80\x08\x10\x00\ 967 | \x08\x00\x10\x00\x22\x00\x01 \x00\x00\x01 \x02\x10\x00\x02\ 968 | \x00\x10\x00\x22\x00\x01 \x00@\x00X\x9c\x22\x00\x01 \ 969 | \x00@\x00 \x02\x10\x00\x02\x00\x04\x00\x22\x00\x01 \x00\ 970 | @\x00 \x02\x10\x00\x02\x00\x04\x00\x22\x00\x01 \x00@\ 971 | \x00 \x02\x10\x00\x02\xa0\xa6\x86K\xab*}\xdb\x96W\ 972 | \xb6\xacoH\x96\x92MC\xa5wk[e\xa8\x7f\x95\ 973 | \x00@\x04 \x00\x04\xc0\xe8\xa9.\xa5\x15\xcb\xa6UZ\ 974 | \x96\xde\x92L\xa1\x86:Z\xef\xacl\x5c\xb38\xfd;\ 975 | \xf4\x08\x00D\x00\x02@\x00\xd4\xc6@\xef\xcaJW{\ 976 | \x9dE\x1c@g\xdb\xdd\x95\xd2\x8e\x0e\x01\x80\x08@\x00\ 977 | \x08\x80\xfc\xcb\xbf\xad\xe9V\xcb7\x90\xd6\x86[*\xfd\ 978 | \xdb\xdb\x05\x00\x22\x00\x01 \x00\xf2\xe9\xee\xf0\x97\x7fD\ 979 | \xd5\x8fb\x86K=\x02\x00\x11\x80\x00\x10\x009>\xf3\ 980 | o\xb0l\x03\xdb\xb0z\xa1\x00@\x04 \x00\x04\xc0\xc8\ 981 | \xfb\xf5\x17\xfe,\xda\xa8\xda\x9an\x13\x00\x88\x00\x04\x80\ 982 | \x00\x18\xf9G\xfd|\xdb?\xbe\xf2\xceN\x01\x80\x08@\ 983 | \x00\x08\x80\x91S}\xce\xdf\x82\x8do\xdb\xc6&\x01\x80\ 984 | \x08@\x00\x08\x80\x91S],\x16l|\x1b\xd7,\x1a\ 985 | SsU\xde\xbe\xac\xb2\xb5g:\x1c\xb0m\xed\xcc{\ 986 | \xd2\x5c<\xc1\x82\x15\x00\x02 \x90\xfe\xed\x1d\x16\xec\x18\ 987 | \xb0cs\x8b+\x86\x19\xeb\x9eb\xc1\x0a\x00\x01\x10\xea\ 988 | ;\x00=\x07\x9e7\xb7dc\x1b\xe8\xed\xb2@\x10\x00\ 989 | \x08\x00\x010\xb2\xaa\xb7\xceY\xb2q\xb5\xb7\xdcay\ 990 | \x00\x10\x00\x02`\xe4\xed\xdc\xd2j\xd1\x06\xb6uC\ 991 | \xa3\xe5\x81\x00@\x00\x08\x80<\xd6t\xcd\xb5l\x03\xaa\ 992 | \xde\xd0hq \x00\x10\x00\x02 \x9b\xeaO\xd1\xba\x10\ 993 | (\x96\xe5\xcd\xb7\x1f\xf8\x8d\x06\x8b\x03\x01\x80\x00\x10\x00\ 994 | \xd9\xbf\x10\xb8n\xd5<\xcb7\x80\xd5+g\xa7(\xeb\ 995 | \xb64\x10\x00\x08\x00\x01P;\xbd[\xdb*=\x9d3\ 996 | \x0f|\xf9\xcc2\xae\xed_\xfc\xabV\xd4W\xb6o\xf2\ 997 | \xc8\x1f\x02\x00\x01 \x00F\xd9`_\xf7\x81 \xd8\xb9\ 998 | e\x19\x99T\xcfw\xb0\xcfc~\x08\x00\x04\x80\x00\x00\ 999 | \x10\x00\x08\x00\x01\x00 \x00\x10\x00\x02\x00@\x00 \x00\ 1000 | \x04\x00\x80\x00@\x00\x08\x00\x00\x01\x80\x00\x10\x00\x00\x02\ 1001 | \x00\x01 \x00\x00\x04\x00\x02@\x00\x00\x08\x00\x04\x80\x00\ 1002 | \x00\x10\x00\x02\x00\x01\x00 \x00\x04\x00\x02\x00@\x00\x08\ 1003 | \x00\x01\x00\x80\x00\x10\x00\x02\x00\x00\x01 \x00\x04\x00\x00\ 1004 | \x02@\x00\x08\x00\x00\x04\x80\x00\x10\x00\x00\x02\x00\x01 \ 1005 | \x00\x00\xc6\xbdr\xeb\x87NL\xaf\xa3\x13\x83\x99\x90<\ 1006 | \xc6\xe2\x17\x00\x02\x00 \x93\xde\x19\x13\x06\x83\xbe\xb6\xef\ 1007 | Ov&\xad\xc9e\xc9yE\x8e\x02\x01 \x00\x00\x8a\ 1008 | \x12\x00\xbfO)\xf9\x5cr\xb8\x00@\x00\x00\x14'\x00\ 1009 | \x1e\xb4)y\x8b\x00@\x00\x00\x14+\x00\x1e\xfc\x88\xe0\ 1010 | +\xc9!\x02@\x00\xf8\x9f\x19\xa08\x01\xf0\xa0_\x14\ 1011 | !\x02\x04\x80\x00\x00\x10\x00\xbf\xeb\xab\x02@\x00\x00P\ 1012 | \xbc\x00\xa8~\x1c\xf07\x02@\x00\x00P\xac\x00\xa8\xda\ 1013 | \x90\x12\xe8\xe9\x9cu\xe0\x91$/\xd20\xb2\ 1047 | \x7f\xedw\xb6\xdd]Y\xdb=\xb7\xb2uC\xe3\xb8\xfd\ 1048 | \xcc_\x00\x08\x00\x010N~-\x10\x18\x19E|\x0d\ 1049 | \x11\x00\x02@\x00\x00\x08\x00\x01 \x00\x04\x00\x80\x00\x10\ 1050 | \x00\x02@\x00\x00\x08\x00\x01 \x00\x04\x00\x80\x00\x10\x00\ 1051 | \x02@\x00\x00\x08\x00\x01 \x00\x04\x00\x80\x00\x10\x00\x02\ 1052 | @\x00\x00\x08\x00\x01 \x00\x04\x00\x80\x00\x10\x00\x02@\ 1053 | \x00\x00\x08\x00\x01 \x00\x04\x00\x80\x00\x10\x00\x02@\x00\ 1054 | \x00\x08\x00\x01 \x00\x04\x00\x80\x00\x10\x00\x08\x00\x00\x01\ 1055 | \x00\x04\x80\x00\x00\x10\x00\x02@\x00\x00 \x00\x04\x80\ 1056 | \x00\x00@\x00\x08\x00\x01\x00\x80\x00\x10\x00\x02\x00@\x00\ 1057 | \x08\x00\x01 \x00\x00\x04\x80\x00\x10\x00\x02\x00@\x00\x08\ 1058 | \x00\x01 \x00\x00\x04\x80\x00\x10\x00\x02\x00@\x00\x08\x00\ 1059 | \x01 \x00\x00\x04\x80\x00\x10\x00\x02\x00@\x00\x08\x00\x01\ 1060 | \x00\x00\x04\x80\x00\x10\x00\x02\x00@\x00\x08\x00\x01 \ 1061 | \x00\x00\x04\x80\x00\x10\x00\x02\x00@\x00\x08\x00\x01 \x00\ 1062 | \x00\x04\x80\x00@\x00\x00\x08\x00\x01\x80\x00\x00\x10\x00\x02\ 1063 | @\x00\x00 \x00\x04\x80\x00\x00@\x00\x08\x00\x01\x00\x80\ 1064 | \x00\x10\x00\x02\xe0\x91\xd8\xb7\xab\xd4\xb5n\xb8\xb7a\xc9\ 1065 | \xd0\x96[f\x0f\xae\xfd\xc1\x82\xc15\x17/\x02\x18K\ 1066 | \xfa\x17\xbdta\xff\xc23\x17\x8d'\xe5\x96\xc97\x96\ 1067 | [.\xbc!\xa8\xeb\x93\xef&\xff\x92\x5c\x98\x1c!\x00\ 1068 | \xc6L\x00\xac\xda6\xb4\xee\x8ay\xe5\xd67\xdf\x97\xfe\ 1069 | \xe1*\x00\xf0\x08\x0c&W&\xa7\x09\x80\xb0\x01\xd03\ 1070 | 0\xb4\xe9\xba9i\xf1\xdfk`\x01\x18a{\x93/\ 1071 | $\x87\x08\x80H\x01\xd0\xbfbe\xb9\xed\x1d\xfd\x06\x14\ 1072 | \x80\xcc\xeeL\x1e/\x00\x22\x04@\xa9k\x8d\xe5\x0f@\ 1073 | \x0d\xdd\xf8\xdb\xef\x04\x08\x80Z\x07@\xa9{\xd3\xc0\xf2\ 1074 | \x7f\xd8f\x18\x01\xa8\xb1\xaf\x09\x80\xd1\x0b\x80\xfb\x07\xda\ 1075 | ?\xb0\xce\x10\x020J\xdf\x09x\x9e\x00\x18\x85\x00\x18\ 1076 | \xde1w\xbe\x01\x04`\x14M\x15\x00\xb5\x0f\x80\xfd\x03\ 1077 | \x1d\x1f\xe91|\x00\x8c\xb2\x17\x09\x80\x1a\x06\xc0po\ 1078 | S\x83\xa1\x03 \x80K\x04@\x0d\x03`\xb0\xeb\xf3\xad\ 1079 | \x86\x0e\x80\x006W\x9f\x08\x10\x00\xb5\x08\x80R\xf7\xa6\ 1080 | r\xcb\xeb\xf7\x1b:\x00\x828C\x00\xd4 \x00\x86\xb6\ 1081 | L\x99m\xd8\x00\x08\xe4\xed\x02\xa0\x06\x010\xd0\xf1O\ 1082 | \x1e\xfd\x03 \x92\xcf\x0a\x80\xdc\x01\xd0\xdf\xd1a\xd0\x00\ 1083 | \x08\xe6\x0a\x01\x909\x00\x86\xd6_5\xd7\xa0\x01\x10\xcc\ 1084 | 4\x01\x907\x00\x1ep\xe7?\x00\x01\xad\x14\x00\x19\x03\ 1085 | `\xb8\xb7a\x89!\x03 \xa0a\x01\x901\x00\x06W\ 1086 | \x7f{\xb1!\x03 \xa0\xe9\x02 [\x00\xf4\x94\xcb\xad\ 1087 | o\xdam\xc8\x00\x08\xe8\xdd\x02 S\x00\x0co\x9f9\ 1088 | \xcf\x80\x01\x10\xf1\xed\xff\xe4\x08\x01\x90)\x00\x06V\xfe\ 1089 | \xfbrC\x06@@?\xf7[\x00\xb9\x02\xa0\xd4\xbd\xd1\ 1090 | \x80\x01\x10\xd4y\x02 S\x00\x0cm\xbey\xb6\x01\x03\ 1091 | \xa0\xea\x0f\x01\x1d*\x002\x05\xc0@\xfb\xfb7\x18\ 1092 | 2\x00\x02\xfaNu\xf9\x0b\x80\x1c\x01\xd0\xdf\xden\xc0\ 1093 | \x00\x08\xeaT\x01\x90)\x00\x86\xd6\xff\xc8\xd5\xbf\x00D\ 1094 | \xd4\xf2\xe0\xf2\x17\x00#\x1f\x00\xf7\x97\x97\xbd\xbdl\xc8\ 1095 | \x00\x08\xe8\x93\x02 S\x00\x0c\xf7.u\xf5/\x00\x11\ 1096 | \xedM&\x08\x80L\x010\xd8s\x91\x00\x00 \xa2i\ 1097 | \xbf\xb9\xfc\x05\xc0\x88\x06@O\xa9\xdc\xfa\xa6\x07\x0c\x19\ 1098 | \x00\x01\xbdK\x00d\x0a\x80\xe1\xedu\xae\xfe\x05 \xa2\ 1099 | \xa1\xe4\xf1\x02 S\x00\x0c\xac\xfc\xa4\xc7\xff\x00\x88\xe8\ 1100 | \xea\xdf^\xfe\x02`\xa4\x02\xa0\xd4\xb5\xce\x80\x01\x10\xd4\ 1101 | k\x04@\xa6\x00\x18\xda\xfc\xab9\x06\x0c\x80\x80\xaa7\ 1102 | \xd3\x1e\x22\x00\xf2\x04\xc0\xfe\x81\xf6\xf7\xfa\xf1\x1f\x00\x22\ 1103 | \xfa\xd6\xef[\xfe\x02`$\x02\xa0\x7fy\x9b\x01\x03 \ 1104 | \xa8\x93\x05@\xa6\x00\x18Zw\xa5o\xff\x03\x10Q\xe3\ 1105 | \x1fZ\xfe\x02\xe0\x91\x07\xc0\xee\xf2\xb2\xb7\x0d\x1a2\x00\ 1106 | \x02\xfa\xb8\x00\xc8\x14\x00\xc3;\x17/6`\x00\x04\xb4\ 1107 | 'y\xba\x00\xc8\x14\x00\x83=\xdfh0d\x00\x04t\ 1108 | \xfb\x1f[\xfe\x02\xe0\x11\x05@O\x7f\xb9\xf5\x8d{\x0c\ 1109 | \x19\x00\x01\xbdC\x00d\x0a\x80\xe1m\xd3\xe7\x1a0\x00\ 1110 | \x02\x1aH\x0e\x17\x00\x99\x02`\xa0\xf3\x13+\x0c\x19\x00\ 1111 | \x01]\xf5\xa7\x96\xbf\x00\xf8s\x03\xa0\xd4\xb5\xd6\x80\x01\ 1112 | \x10\xd4+\x05@\xa6\x00\x18\xdat\x83\xab\x7f\x01\x88h\ 1113 | ]\xf9\x0f\x5c\xfd+\x00\x1ey\x00\xec\x1fX\xfe\x8f[\ 1114 | \x0c\x19\x00\x01}\xe3\xa1,\x7f\x01\xf0\xe7\x04@_\xdb\ 1115 | 2\x03\x06@P\xcf\x15\x00\x99\x02`h\xdd\xe5\xf3\x0d\ 1116 | \x18\x00\x01-y\xa8\xcb_\x00<\xfc\x00\xb8\xaf\xbc\xec\ 1117 | o\x87\x0c\x19\x00\x01}T\x00d\x0a\x80\xe1\x9d\x8b\x16\ 1118 | \x190\x00\x02z y\x9a\x00\xc8\x14\x00\x83\xab\xbe\xda\ 1119 | h\xc8\x00\x08h\xea\xc3Y\xfe\x02\xe0a\x05@Oo\ 1120 | \xb9\xf5\x0d\xae\xfe\x05 \xa2\xb7\x0a\x80L\x010\xbc\xed\ 1121 | nW\xff\x02\x10Q)y\xac\x00\xc8\x14\x00\x03\x9d\x1f\ 1122 | [i\xc8\x00\x08\xe8\x87\x0fw\xf9\x0b\x80\x87\x1a\x00\xa5\ 1123 | \x95k\x0c\x18\x00A\x9d%\x002\x05\xc0\xd0\xa6\xeb]\ 1124 | \xfd\x0b@D\xab\xff\x9c\xe5/\x00\x1eZ\x00\xec\x1fX\ 1125 | \xfe\xee\xad\x86\x0c\x80\x80\xbe\x22\x00r\x05@\xdf\xb2V\ 1126 | \x03\x06@P\xcf\x16\x00\x99\x02`p\xede\x0b\x0c\x18\ 1127 | \x00\x01-\xfcs\x97\xbf\x00\xf8\xd3\x01poy\xd9[\ 1128 | w\x192\x00\x02\xfa\x88\x00\xc8\x14\x00\xc3;\x17\xba\xfa\ 1129 | \x17\x80\x88v'O\x15\x00\x99\x02`p\xd5\x97\x9b\x0c\ 1130 | \x19\x00\x01\xdd\xfcH\x96\xbf\x00\xf8#\xfa\xe6\x9d9\xaf\ 1131 | \xdc\xf2\x86\xbd\x86\x0c\x80\x80\xde,\x00\xb2\x05\xc0)\xb7\ 1132 | \x190\x00\x02\xeaK\x1e#\x00\xf2\xd8Sn:\xaf\xc3\ 1133 | \x90\x01\x10\xd0\xe5\x8ft\xf9\x0b\x80?\xa4\xee\xa8y\x06\ 1134 | \x0c\x80\xa0^*\x00\xb2}\x01\xf0\x8c\xdb\x0d\x18\x00\x01\ 1135 | u\x8f\xc4\xf2\x17\x00\xbf\xdf@\xb9y\x92\xab\x7f\x01\x88\ 1136 | \xe8K\x02 \xd7\x97\xfff>c\x9a\x01\x03 \xa0\xfd\ 1137 | \xc9\xf1\x02 \x93\xd2\xe2\x97O7d\x00\x044w\xa4\ 1138 | \x96\xbf\x00\xf8]\xeb\xd3\x01\xbb\xfa\x17\x80\x88>(\x00\ 1139 | r\xbd\xfd?\xfb9S\x0d\x18\x00\x01\xdd\x97\x9a~\x98\x00\xc8\xe3\x9er\xf3\ 1154 | \x05]\x86\x0c\x80\x80\xbe\x9f{\xf9\x177\x00\xea\x8f\x99\ 1155 | f\xc0\x00\x08\xeat\x01\x90\xeb\xed\xffE/\xbe\xc5\x80\ 1156 | \x01\x10P{-\x96\x7fQ\x03`K:\xe0\x1d\x86\x0c\ 1157 | \x80\x80>+\x00r=\xfb?\xebx\xcf\xfe\x03\x10\xd1\ 1158 | \xbe\xe4\x18\x01\x90\xeb\xea\xdf\xa5\xafr\xf5/\x00\x11\xd5\ 1159 | \xd5j\xf9\x170\x00&\xb4\xa5\x03\xbe\xcf\x90\x01\x10\xd0\ 1160 | {\x04@\xae\xb7\xff\xe7\x9et\x83\x01\x03 \xa0]\xc9\ 1161 | \x11\x02 \x8f=\xe5\xa6\xf3\x16\x1b2\x00\x02\xfae-\ 1162 | \x97\x7f\xb1\x02\xa0n\xe2\xac\xb2\xab\x7f\x01\x88\xe9u\x02\ 1163 | \xd7\xb3\xff\x0b^\xe0\xed\x7f\x00\x22\xaa>\x9e~\xa8\ 1164 | \x00\xc8c\xa0\xdc<\xa9\xdb\x90\x01\x10\xd0\xc5\xb5^\xfe\ 1165 | \xc5\x09\x80\xfac\xa7\x1a0\x00\x82:M\x00\xe4z\xf6\ 1166 | \x7f\xf1\xcb\xa6\x180\x00\x02Z6\x1a\xcb\xbf(\x01\xb0\ 1167 | .\x1dp\xaf!\x03 \xa0O\x09\x80\x5c\xcf\xfe\xcf>\ 1168 | \xc1\x97\xff\x00\x88ho2Q\x00\xe4z\xfb\xbf\xe1\x1c\ 1169 | W\xff\x02\x10\xd1\xdd\xa3\xb5\xfc\x0b\x10\x00\x13\x1a\xd2\x01\ 1170 | \xef6d\x00\x04\xf4\xf7\x02 \xdb\xd5\xbf'_k\xc0\ 1171 | \x00\x08h(y\x82\x00\xc8cw\xb9\xe9\xfc%\x86\x0c\ 1172 | \x80\x80\xae\x19\xcd\xe5?\xbe\x03\xa0\xee\xa8\xbb\x0c\x18\x00\ 1173 | A\x9d+\x00r]\xfd\xbb\xf0\x8c\xeb\x0c\x18\x00\x01m\ 1174 | *\x8f\xc2\xd5\xbfE\x09\x80\xder\xcb\xe4\xd5\x86\x0c\x80\ 1175 | \x80\xbe=\xda\xcb\x7f\xdc\x06@\xdf\xcc\xe3~e\xc0\x00\ 1176 | \x08\xea\xaf\x05@\xaeg\xff\x97\x9cu\x93\x01\x03 \xa0\ 1177 | \xe6\x08\xcb\x7f\xbc\x06\xc0\xcat\xc0\xfd\x86\x0c\x80\x80>\ 1178 | !\x00\xb2]\xfd\xfb\x1c\xcf\xfe\x03\x10\xd1\x9e\xe4H\x01\ 1179 | \x90\xc7\xbeR\xe3\xb9\x1e\xff\x03 \xa2;\xa2,\xffq\ 1180 | \x18\x00\x13\xe6\xa5\x03\xbe\xdf\x90\x01\x10\xd0;\x05@\xae\ 1181 | g\xff\xe7\x9d\xf2s\x03\x06@@\x83\xc9\xe1\x02 \x8f\ 1182 | {\xca\xcd\x174\x182\x00\x02\xfaI\xa4\xe5?\xbe\x02\ 1183 | \xa0\xee\xe8\xa9\x06\x0c\x80\xa0^-\x00\xb2]\xfd\xfb\x22\ 1184 | \xdf\xfe\x07 \xa2\xf5\xc9!\x02 \x8f-\xe9p\xd7\x1a\ 1185 | 2\x00\x02\xba(\xda\xf2\x1f7\x01\xd07\xf3\x99\xd7\x1b\ 1186 | 0\x00\x82:I\x00\xe4\xba\xfaw\xe9+]\xfd\x0b@\ 1187 | DK#.\xff\xf1\x12\x00\xad\xe9\x80\xcb\x86\x0c\x80\x80\ 1188 | \xfeU\x00\xe4z\xfb\x7f\xce\x89\xd7\x180\x00\x02z \ 1189 | \xf9+\x01\x90\xc7\x9er\xd3yw\x1b2\x00\x02\xba5\ 1190 | \xea\xf2\x1f\xfb\x01P7q\xc6\xc1\xc22h\x00D\xf3\ 1191 | 6\x01\x90\xeb\xd9\xff\xf9\xa7]m\xc0\x00\x08\xa8\xfa\xdd\ 1192 | \xb4\xc7\x09\x80<\x06\xca\xcd\x93\x1a\x0d\x19\x00\x01\xfd(\ 1193 | \xf2\xf2\x1f\xdb\x01P\x7f\xcc\xaf\x0c\x18\x00A\xbdB\x00\ 1194 | \xe4z\xfb\x7f\xd1K\xfc\xf2\x1f\x00\x11\xad\x89\xbe\xfc\xc7\ 1195 | r\x00T\xaf\xfd]o\xc8\x00\x08\xe8k\x02 \xd7\xb3\ 1196 | \xff\xb3\x8e\xff\x99\x01\x03 \xa8\xe7\x08\x80\x5cW\xff6\ 1197 | \xbc\xda\xe7\xff\x00D\xb4h,,\xff\xb1\x1a\x00\x8b\xd3\ 1198 | \x01\x0f\x1a2\x00\x02\xfag\x01\x90\xeb\xed\xff\xb9'\xfd\ 1199 | \xc4\x80\x01\x10\xd0\xfd\xc9_\x0a\x80C\x00\xe4\xb1\xa7\xd4\ 1218 | \xf8ZW\xff\x02\x10\xd1\x9c\xf1\xb0\xfc\x83\x06\xc0\x84\xbb\ 1219 | \xd2\x01\xef2d\x00\x04\xf4\x01\x01\x90\xeb\xd9\xffy\xa7\ 1220 | ^n\xc0\x00\x08\xe8\xde\xe4/\x04@\x1e\x03\xe5\xe6I\ 1221 | \xf5\x86\x0c\x80\x80\xfeg\xbc,\xffx\x01Pw\xd4u\ 1222 | \xe9\x80\xf7\x192\x00\x02\xbaP\x00\xe4z\xfb\x7f\xd1\x8b\ 1223 | \xaf0`\x00\x04\xb4=y\xb4\x00\xc8cm:\xdc\xe5\ 1224 | \x86\x0c\x80\x80.\x19O\xcb?T\x00\xf4\xcd|\x86\x1f\ 1225 | \xfe\x01 \xaa\x17\x0a\x80\x5cW\xff.}\xd5O\x0d\x18\ 1226 | \x00\x01u\x8c\xb7\xe5\x1f)\x00\x16\xa5\x03\xdef\xc8\x00\ 1227 | \x08\xe8s\x02 \xd7\xdb\xffsN\xbc\xcc\x80\x01\x10P\ 1228 | \xf5\xc9\xb4c\x05@\x1e\xbb\xcbM\xaf\xbb\xc9\x90\x01\x10\ 1229 | P\xfdx\x5c\xfeA\x02`\xc2\xd4t\xc0\xf7\x182\x00\ 1230 | \x02z\xaf\x00\xc8\xf5\xec\xff\xfc\xe7_j\xc0\x00\x08\xa8\ 1231 | \xfa\xc7\xe9\x13\x05@\x1e\xbd\xe5\xe6\xc9\xb3\x0c\x19\x00\x01\ 1232 | ];^\x97\xff\xe8\x07@\xfd\xd1W\x97]\xfd\x0b@\ 1233 | L\x17\x08\x80\x5c\xcf\xfe/~\x99_\xfe\x03 \xa2\xad\ 1234 | \xc9a\x02 \x8f\xcet\xb8+\x0c\x19\x00\x01}w<\ 1235 | /\xffQ\x0d\x80\xbeY\xcf\xf4\xec?\x00Q\xbd@\x00\ 1236 | \xe4\xb1\xaf\xd4p\x8e\xab\x7f\x01\x88\xa8m\xbc/\xff\xd1\ 1237 | \x0c\x80\xea7\xffw\x182\x00\x02\xfa\xb4\x00\xc8\xf5\xf6\ 1238 | \xff\xdc\x93\xbeg\xc0\x00\x08hor\x94\x00\xc8cW\ 1239 | \xb9\xf9\xfc\x9b\x0d\x19\x00\x01M/\xc2\xf2\x1f\x9d\x00\xa8\ 1240 | \x9bxC:\xe0{\x0d\x19\x00\x01\xbd[\x00\xe4\xba\xfa\ 1241 | w\xc1\xe9\xdf5`\x00\x044\x9c\x1c!\x00\xf2\xd8\x5c\ 1242 | n\x99<\xc7\x90\x01\x10\xd0\xcf\x8b\xb2\xfck\x1f\x00\xf5\ 1243 | \xc7\x5c\x99\x0ex\xbf!\x03 \xa0\xd7\x0a\x80\x5cW\xff\ 1244 | .9\xcb\xe5?\x00D\xb499T\x00\xe4\xd1\x92\x0e\ 1245 | \xb7\xcb\x90\x01\x10\xd0w\x8a\xb4\xfck\x1a\x00}\xb3\x9e\ 1246 | \xf5}\x03\x06@P\xa7\x08\x80<\xf6\x94\x1a_\xfb\x13\ 1247 | \x03\x06@@-E[\xfe\xb5\x0c\x80;\xd3\x01\xf7\x1a\ 1248 | 2\x00\x02\xfa\xa4\x00\xc8v\xf5\xef\xc9\xdf1`\x00\x04\ 1249 | T\xbd\xfaw\x82\x00\xc8c\xa0\xdcj\xe1g\x0a\x80\xfe\xf9\xcf\xff\ 1270 | \xba\x01\x03 \xa0\xea\xc5tO\xb3\xf0\xf3\x04\xc0\xe6r\ 1271 | \xcb\xe4[\x0d\x19\x00\x01\xddb\xd9\xe7\x0a\x80\xba\xa3.\ 1272 | K\x07\xfc\x80!\x03 \xa0\xb7Z\xf6\x99\x02\xa0\xb4\xf8\ 1273 | \xe5\x17\x190\x00\x02\xaa~7\xed\xb1\x96}\x9e\x00h\ 1274 | N\x87\xbb\xd4\x90\x01\x10\xd0\x95\x16}\xa6\x00\xe8\x9b\xf9\ 1275 | \x0c\x7f\xfd\x03\x10\xd5Y\x16}\x9e\x00\xd8Sj<\xd7\ 1276 | \xd5\xbf\x00D\xb4\xda\x92\xcf\x17\x00w\xa4\x03^g\xc8\ 1277 | \x00\x08\xe8+\x96|\xa6\x00\xe8\x9bs\xd2W\x0c\x18\x00\ 1278 | A\x9d`\xc9\xe7\x09\x80\x81r\xf3\x05W\x1b0\x00\x02\ 1279 | Z`\xc1g\x0b\x80\x09\xd5{\xff\x07\x0c\x19\x00\x01}\ 1280 | \xc4\x82\xcf\x14\x00\xfd\x0b\xce\xf8\xb2\x01\x03 \xa0\xdd\xc9\ 1281 | S-\xf8<\x01\xb0&\x1d\xee\xed\x86\x0c\x80\x80n\xb6\ 1282 | \xdcs\x05@\xdd\xd1\x17\xa7\x03\xdec\xc8\x00\x08\xe8\xcd\ 1283 | \x96{\xa6\x00(-}\x85_\xfe\x03 \xa2\xbe\xe41\ 1284 | \x96{\x9e\x00X\x98\x0e\xb7\xd1\x90\x01\x10\xd0\xe5\x16{\ 1285 | \xa6\x00\xe8\x9bu\xbcg\xff\x01\x88\xea%\x16{\x9e\x00\ 1286 | \xd8]n:\xcf\xd5\xbf\x00D\xd4m\xa9\xe7\x0b\x80\x9b\ 1287 | \xd2\x01o4d\x00\x04\xf4%K=S\x00\xf4\xcd=\ 1288 | \xf9\x8b\x06\x0c\x80\x80\xf6'\xc7[\xeay\x02`g\xb9\ 1289 | y\xd2\xcf\x0c\x19\x00\x01\xcd\xb5\xd0s\x05@\xdd\x84+\ 1290 | \xd2\x01\x0f\x192\x00\x02\xfa\xa0\x85\x9e)\x00\xfa\x17\xbd\ 1291 | \xe8?\x0c\x18\x00\x01\xdd\x97<\xd9B\xcf\x13\x00\x9d\xe9\ 1292 | p\xa7\x192\x00\x02\xba\xd12\xcf\x15\x00\xf5\xc7\x5c\x94\ 1293 | \x0ex\xaf!\x03 \xa0\xd7[\xe6y\x02`_\xa9\xe1\ 1294 | \xd5_3`\x00\x04\xb4#y\xb4e\x9e'\x00\xea\xd3\ 1295 | \xe1\xb6\x182\x00\x02\xba\xd4\x22\xcf\x14\x00}\xb3O\xf0\ 1296 | \xec?\x00Q\x9di\x91\xe7\x09\x80]\xe5\xa6\xf3/1\ 1297 | `\x00\x04\xd4i\x89\xe7\x0b\x80k\xd3\x01o6d\x00\ 1298 | \x04\xf4yK\x0b\xf1\xe0\xedJ\x06\x0d\x80h\xde\ 1312 | ca\xe7\x0b\x80\xf7\x1a0\x00\x02\xda\x95\x1caa\xe7\ 1313 | \x0b\x80zC\x06@@\xbf\xb0\xac3\x05@:\xdcc\ 1314 | \x0f~\xc1\xc2\xa0\x01\x10\xcd\xeb,\xeb|\x01\xe0\xdb\xff\ 1315 | \x00D\xb4%9\xd4\xb2\xce\x17\x00\xbf4d\x00\x04\xf4\ 1316 | _\x16u\xde\x00h4d\x00\x04t\x9aE\x9d7\x00\ 1317 | \x06\x0d\x19\x00\xc1\xb4Z\xd2\x02\x00\x80\xe2\xf9\x94%\x9d\ 1318 | ?\x00V\x194\x00\x02\xd9\x9bL\xb4\xa4\xf3\x07\xc0|\ 1319 | \xc3\x06@ wY\xd0\xb5\x09\x80\xef\x1b6\x00\x02y\ 1320 | \x97\x05]\x9b\x008\xcb\xb0\x01\x10D\xf5g\xe9\x1fk\ 1321 | A\xd7&\x00\x0e9x\xd9\x82\xc1\x03`\xb4}\xc1r\ 1322 | \xae\xedo\x01|\xcc\xd0\x010\xca\xaa?\xfc\xf3T\xcb\ 1323 | \xb9\xb6\x01pX\xd2b\xf8\x00\x18E\x97Y\xcc5\x0e\ 1324 | \x80\x83\x11\xf0\x92d\xb7\x01\x04`\x14,M\x9ed1\ 1325 | \x8fB\x00\x1c\x8c\x807%{\x0c\x22\x005\xd4\xe6\xad\ 1326 | \xffQ\x0e\x80\x83\x11\xf0\xce\xe4\x01\x03\x09@\x0dt%\ 1327 | GZ\xc8\x01\x02\xe0`\x04\x9cV\xf6#A\x00\xe4S\ 1328 | }\xb7\xf9J\xcb?X\x00\xfc\xc6\x17\x03?^vU\ 1329 | 0\x00#g\x7frcr\xa2%\x1c4\x00~+\x06\ 1330 | \xceN\xfe;\xa9O\xba\x93{\x0d1\x00\x0f\xc1\xb6\x83\ 1331 | \xbb\xe3\xd2\xe4\xc3\xc9\xa9\x96o\x0c\xff\x076P\x5cw\ 1332 | \x09pTO\x00\x00\x00\x00IEND\xaeB`\x82\ 1333 | \ 1334 | " 1335 | 1336 | qt_resource_name = b"\ 1337 | \x00\x08\ 1338 | \x00(Z\xe7\ 1339 | \x00f\ 1340 | \x00i\x00l\x00e\x00.\x00p\x00n\x00g\ 1341 | \x00\x0a\ 1342 | \x0a\xc8\xfb\x07\ 1343 | \x00f\ 1344 | \x00o\x00l\x00d\x00e\x00r\x00.\x00p\x00n\x00g\ 1345 | " 1346 | 1347 | qt_resource_struct = b"\ 1348 | \x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\ 1349 | \x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ 1350 | \x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x005\x10\ 1351 | " 1352 | 1353 | def qInitResources(): 1354 | QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) 1355 | 1356 | def qCleanupResources(): 1357 | QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) 1358 | 1359 | qInitResources() 1360 | -------------------------------------------------------------------------------- /Il2cppSpy/ui/tabitemwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TabItemWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 34 | 35 | 1 36 | 37 | 38 | false 39 | 40 | 41 | true 42 | 43 | 44 | 24 45 | 46 | 47 | false 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Il2cppSpy/ui/ui_color.py: -------------------------------------------------------------------------------- 1 | from PySide2.QtGui import QColor 2 | 3 | EXPLORER_DIFF_TEXT_COLOR = QColor(246, 175, 144) 4 | EXPLORER_TYPE_TEXT_COLOR = QColor(78, 201, 176) 5 | 6 | TABLE_ASSEMBLY_BACKGROUND_COLOR = QColor(25, 35, 45) 7 | TABLE_DIFF_BACKGROUND_COLOR = QColor(83, 42, 12) 8 | TABLE_CODE_BACKGROUND_COLOR = QColor(40, 55, 65) 9 | TABLE_ASSEMBLY_TEXT_COLOR = QColor(113, 181, 231) 10 | TABLE_DIFF_TEXT_COLOR = QColor(255, 255, 255) 11 | TABLE_CODE_TEXT_COLOR = QColor(150, 150, 150) 12 | TABLE_METHOD_CODE_TEXT_COLOR = QColor(255, 255, 255) 13 | -------------------------------------------------------------------------------- /Il2cppSpy/ui/ui_mainwindow.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'mainwindow.ui', 4 | # licensing of 'mainwindow.ui' applies. 5 | # 6 | # Created: Tue Sep 17 16:34:23 2019 7 | # by: pyside2-uic running on PySide2 5.13.1 8 | # 9 | # WARNING! All changes made in this file will be lost! 10 | 11 | from PySide2 import QtCore, QtGui, QtWidgets 12 | 13 | class Ui_MainWindow(object): 14 | def setupUi(self, MainWindow): 15 | MainWindow.setObjectName("MainWindow") 16 | MainWindow.resize(800, 600) 17 | self.centralwidget = QtWidgets.QWidget(MainWindow) 18 | self.centralwidget.setObjectName("centralwidget") 19 | self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) 20 | self.verticalLayout.setSpacing(0) 21 | self.verticalLayout.setContentsMargins(0, 0, 0, 0) 22 | self.verticalLayout.setObjectName("verticalLayout") 23 | self.splitter = QtWidgets.QSplitter(self.centralwidget) 24 | self.splitter.setOrientation(QtCore.Qt.Horizontal) 25 | self.splitter.setHandleWidth(2) 26 | self.splitter.setObjectName("splitter") 27 | self.treeWidget = QtWidgets.QTreeWidget(self.splitter) 28 | self.treeWidget.setObjectName("treeWidget") 29 | self.treeWidget.headerItem().setText(0, "1") 30 | self.treeWidget.header().setVisible(False) 31 | self.tabWidget = QtWidgets.QTabWidget(self.splitter) 32 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) 33 | sizePolicy.setHorizontalStretch(1) 34 | sizePolicy.setVerticalStretch(0) 35 | sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) 36 | self.tabWidget.setSizePolicy(sizePolicy) 37 | self.tabWidget.setDocumentMode(True) 38 | self.tabWidget.setTabsClosable(True) 39 | self.tabWidget.setMovable(True) 40 | self.tabWidget.setObjectName("tabWidget") 41 | self.verticalLayout.addWidget(self.splitter) 42 | MainWindow.setCentralWidget(self.centralwidget) 43 | self.menubar = QtWidgets.QMenuBar() 44 | self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22)) 45 | self.menubar.setObjectName("menubar") 46 | self.menuFile = QtWidgets.QMenu(self.menubar) 47 | self.menuFile.setObjectName("menuFile") 48 | MainWindow.setMenuBar(self.menubar) 49 | self.statusbar = QtWidgets.QStatusBar(MainWindow) 50 | self.statusbar.setObjectName("statusbar") 51 | MainWindow.setStatusBar(self.statusbar) 52 | self.toolBar = QtWidgets.QToolBar(MainWindow) 53 | self.toolBar.setIconSize(QtCore.QSize(18, 18)) 54 | self.toolBar.setObjectName("toolBar") 55 | MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) 56 | self.actionOpenFile = QtWidgets.QAction(MainWindow) 57 | icon = QtGui.QIcon() 58 | icon.addPixmap(QtGui.QPixmap(":/folder.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 59 | self.actionOpenFile.setIcon(icon) 60 | self.actionOpenFile.setObjectName("actionOpenFile") 61 | self.actionCompareFiles = QtWidgets.QAction(MainWindow) 62 | icon1 = QtGui.QIcon() 63 | icon1.addPixmap(QtGui.QPixmap(":/file.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) 64 | self.actionCompareFiles.setIcon(icon1) 65 | self.actionCompareFiles.setObjectName("actionCompareFiles") 66 | self.menuFile.addAction(self.actionOpenFile) 67 | self.menuFile.addAction(self.actionCompareFiles) 68 | self.menubar.addAction(self.menuFile.menuAction()) 69 | self.toolBar.addAction(self.actionOpenFile) 70 | self.toolBar.addAction(self.actionCompareFiles) 71 | 72 | self.retranslateUi(MainWindow) 73 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 74 | 75 | def retranslateUi(self, MainWindow): 76 | MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "Il2cppSpy", None, -1)) 77 | self.menuFile.setTitle(QtWidgets.QApplication.translate("MainWindow", "File", None, -1)) 78 | self.toolBar.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "toolBar", None, -1)) 79 | self.actionOpenFile.setText(QtWidgets.QApplication.translate("MainWindow", "Open Apk", None, -1)) 80 | self.actionOpenFile.setToolTip(QtWidgets.QApplication.translate("MainWindow", "Open Apk", None, -1)) 81 | self.actionCompareFiles.setText(QtWidgets.QApplication.translate("MainWindow", "Compare Apks", None, -1)) 82 | self.actionCompareFiles.setToolTip(QtWidgets.QApplication.translate("MainWindow", "Compare Apks", None, -1)) 83 | 84 | import resources_rc 85 | -------------------------------------------------------------------------------- /Il2cppSpy/ui/ui_tabitemwindow.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'tabitemwindow.ui', 4 | # licensing of 'tabitemwindow.ui' applies. 5 | # 6 | # Created: Tue Sep 17 17:05:33 2019 7 | # by: pyside2-uic running on PySide2 5.13.1 8 | # 9 | # WARNING! All changes made in this file will be lost! 10 | 11 | from PySide2 import QtCore, QtGui, QtWidgets 12 | 13 | class Ui_TabItemWindow(object): 14 | def setupUi(self, TabItemWindow): 15 | TabItemWindow.setObjectName("TabItemWindow") 16 | TabItemWindow.resize(400, 300) 17 | self.verticalLayout = QtWidgets.QVBoxLayout(TabItemWindow) 18 | self.verticalLayout.setSpacing(0) 19 | self.verticalLayout.setContentsMargins(0, 0, 0, 0) 20 | self.verticalLayout.setObjectName("verticalLayout") 21 | self.tableWidget = QtWidgets.QTableWidget(TabItemWindow) 22 | self.tableWidget.setColumnCount(1) 23 | self.tableWidget.setObjectName("tableWidget") 24 | self.tableWidget.setColumnCount(1) 25 | self.tableWidget.setRowCount(0) 26 | self.tableWidget.horizontalHeader().setVisible(False) 27 | self.tableWidget.horizontalHeader().setStretchLastSection(True) 28 | self.tableWidget.verticalHeader().setDefaultSectionSize(24) 29 | self.tableWidget.verticalHeader().setHighlightSections(False) 30 | self.verticalLayout.addWidget(self.tableWidget) 31 | 32 | self.retranslateUi(TabItemWindow) 33 | QtCore.QMetaObject.connectSlotsByName(TabItemWindow) 34 | 35 | def retranslateUi(self, TabItemWindow): 36 | TabItemWindow.setWindowTitle(QtWidgets.QApplication.translate("TabItemWindow", "Form", None, -1)) 37 | 38 | -------------------------------------------------------------------------------- /Il2cppSpy/utils/file_utils.py: -------------------------------------------------------------------------------- 1 | import string 2 | 3 | 4 | def strings(filename, min=4): 5 | with open(filename, errors='ignore') as f: 6 | result = '' 7 | for c in f.read(): 8 | if c in string.printable: 9 | result += c 10 | continue 11 | if len(result) >= min: 12 | yield result 13 | result = '' 14 | if len(result) >= min: 15 | yield result 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 yukiarrr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | autopep8 = "*" 8 | flake8 = "*" 9 | mypy = "*" 10 | pyinstaller = "*" 11 | v = {editable = true,version = "*"} 12 | 13 | [packages] 14 | pyside2 = "*" 15 | pycparser = "*" 16 | pythonnet = "*" 17 | capstone = "*" 18 | qdarkstyle = "*" 19 | 20 | [requires] 21 | python_version = "3.7" 22 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "53bf5bd59783f5c9a8647ae1ca283fcb7024ead68f2fd4b6501f98bb14dd02dc" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.7" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "capstone": { 20 | "hashes": [ 21 | "sha256:5857accc0de1e769b0ec0a0ca985715bfa96e5a66a2ebb3aaed43a8e3655377f", 22 | "sha256:5d97df74a8ffdd02706bc67155b7d41dd3ca8ff2caa034f8e54b99044b96037e", 23 | "sha256:a85763eccae63c3b7a1123a17afcda03303771b18db38a44453055ff360edd94", 24 | "sha256:dae578f97b24212fb97a5c833342e56c69e7fb71502187a0b51a4326381e4204", 25 | "sha256:ee7f55aa4326b1e345b1fb28d1b0798974503e914b006cc9806431e8c3e95549" 26 | ], 27 | "index": "pypi", 28 | "version": "==4.0.1" 29 | }, 30 | "helpdev": { 31 | "hashes": [ 32 | "sha256:6cb2c604d97101a47b81d6d234b48e0f452efe4490b4cc67c33708420c2deaa0", 33 | "sha256:9e61d24458b7506809670222ca656b139e67d46c530cd227a899780152d7b44e" 34 | ], 35 | "version": "==0.6.10" 36 | }, 37 | "importlib-metadata": { 38 | "hashes": [ 39 | "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f", 40 | "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e" 41 | ], 42 | "version": "==1.6.0" 43 | }, 44 | "psutil": { 45 | "hashes": [ 46 | "sha256:1413f4158eb50e110777c4f15d7c759521703bd6beb58926f1d562da40180058", 47 | "sha256:298af2f14b635c3c7118fd9183843f4e73e681bb6f01e12284d4d70d48a60953", 48 | "sha256:60b86f327c198561f101a92be1995f9ae0399736b6eced8f24af41ec64fb88d4", 49 | "sha256:685ec16ca14d079455892f25bd124df26ff9137664af445563c1bd36629b5e0e", 50 | "sha256:73f35ab66c6c7a9ce82ba44b1e9b1050be2a80cd4dcc3352cc108656b115c74f", 51 | "sha256:75e22717d4dbc7ca529ec5063000b2b294fc9a367f9c9ede1f65846c7955fd38", 52 | "sha256:a02f4ac50d4a23253b68233b07e7cdb567bd025b982d5cf0ee78296990c22d9e", 53 | "sha256:d008ddc00c6906ec80040d26dc2d3e3962109e40ad07fd8a12d0284ce5e0e4f8", 54 | "sha256:d84029b190c8a66a946e28b4d3934d2ca1528ec94764b180f7d6ea57b0e75e26", 55 | "sha256:e2d0c5b07c6fe5a87fa27b7855017edb0d52ee73b71e6ee368fae268605cc3f5", 56 | "sha256:f344ca230dd8e8d5eee16827596f1c22ec0876127c28e800d7ae20ed44c4b310" 57 | ], 58 | "version": "==5.7.0" 59 | }, 60 | "pycparser": { 61 | "hashes": [ 62 | "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0", 63 | "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705" 64 | ], 65 | "index": "pypi", 66 | "version": "==2.20" 67 | }, 68 | "pyside2": { 69 | "hashes": [ 70 | "sha256:307e58c1f327c9215d276fc7d312b3c537c72446af06230b4f130c2cc6980735", 71 | "sha256:692fc35171ef3b58226f5ba7bc75a00b641709f94e39b98ce22f3705d478372b", 72 | "sha256:80efed294ad4f7a5fa2c7d2707ce25d5afb60269825dce21034937056edb1754", 73 | "sha256:a7c5c94f925186f7cee5755477662cac40f59a27c2f9d6163c5ab4f89b1fa56a", 74 | "sha256:d2ada2f2236a7f1393a4e6657c4421cd99411cb99739d80dd1522e861ac1308a", 75 | "sha256:dc43c593800ba67d8081eb26deef83c893dd7b52680bfd5193e76e3efaf4f186" 76 | ], 77 | "index": "pypi", 78 | "version": "==5.14.2" 79 | }, 80 | "pythonnet": { 81 | "hashes": [ 82 | "sha256:0bc4dfe352ab97ee6f00f13ff5b70ce5ba67576913a523cc4ec6e3fdaadf83fd", 83 | "sha256:1e380e7735b047258da469e36e122d1e0a13f79b4b4902b852a0dc626c0ceb0a", 84 | "sha256:38fdb7f5f2e1889175b7d88c64adc902e537d7d646cdc88ee7c0389bb1fdfd34", 85 | "sha256:6483dba7db4053da0cb4fdfa3580fed34623ac9100c3d0ce90e7688dc5d3ac47", 86 | "sha256:7be226daafc2d40b30cb80a16e298460bd68f3484d8c7fce1ff82f4f35cda321", 87 | "sha256:878e27a1a34ebf6b7a160abd1269d75a4fbebf5323e02679ed8226c0ad5fbf10", 88 | "sha256:a3a38e67fdfcda94df51c805343150016097f284771156f76839a9c3a24c90a9", 89 | "sha256:e1b3f5d87996302557d876c582590438f71ffe6b7076e79865c6afd57adf476c", 90 | "sha256:f16af543895fbaadfc593b9c436bf1a2c0e32329f80401aefc316a52e8f9bd18" 91 | ], 92 | "index": "pypi", 93 | "version": "==2.4.0" 94 | }, 95 | "qdarkstyle": { 96 | "hashes": [ 97 | "sha256:7cead57817a8a1f38b48d76ef38986b6cc397d0315c0dd0431fcd06749556947", 98 | "sha256:d53b0120bddd9e3efba9801731e22ef86ed798bb5fc6a802f5f7bb32dedf0321" 99 | ], 100 | "index": "pypi", 101 | "version": "==2.8.1" 102 | }, 103 | "qtpy": { 104 | "hashes": [ 105 | "sha256:2db72c44b55d0fe1407be8fba35c838ad0d6d3bb81f23007886dc1fc0f459c8d", 106 | "sha256:fa0b8363b363e89b2a6f49eddc162a04c0699ae95e109a6be3bb145a913190ea" 107 | ], 108 | "version": "==1.9.0" 109 | }, 110 | "shiboken2": { 111 | "hashes": [ 112 | "sha256:1ab673cab00ac787f055f5859c6ad1e03e294c3a12247545f3b516860363b076", 113 | "sha256:32fa77f9464b1fa055f2d8c1511e624dbd39a8ad13053acc08c330d5631a7788", 114 | "sha256:4a1be8396c748b850d2b0bddc9ef3d277873d14503c83efbc34be7148c3c92fc", 115 | "sha256:6eda654156bdcabf14dd366f7da5ab2ffcf4d3099eb437f9a22742fd3f828f6a", 116 | "sha256:77b9bac57f7524c21a0711466dea43d4b45543f7d4ec1fc54acff9349d8296e3", 117 | "sha256:e887fccaa60dbf2b6f9ce46c32fb0d36434796ef3468d742e0bdad9cfc5b0c02" 118 | ], 119 | "version": "==5.14.2" 120 | }, 121 | "zipp": { 122 | "hashes": [ 123 | "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b", 124 | "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96" 125 | ], 126 | "version": "==3.1.0" 127 | } 128 | }, 129 | "develop": { 130 | "altgraph": { 131 | "hashes": [ 132 | "sha256:1f05a47122542f97028caf78775a095fbe6a2699b5089de8477eb583167d69aa", 133 | "sha256:c623e5f3408ca61d4016f23a681b9adb100802ca3e3da5e718915a9e4052cebe" 134 | ], 135 | "version": "==0.17" 136 | }, 137 | "autopep8": { 138 | "hashes": [ 139 | "sha256:cc6be1dfd46f2c7fa00e84a357f1a269683985b09eaffb47654ed551194399eb" 140 | ], 141 | "index": "pypi", 142 | "version": "==1.5.1" 143 | }, 144 | "entrypoints": { 145 | "hashes": [ 146 | "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", 147 | "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" 148 | ], 149 | "version": "==0.3" 150 | }, 151 | "flake8": { 152 | "hashes": [ 153 | "sha256:45681a117ecc81e870cbf1262835ae4af5e7a8b08e40b944a8a6e6b895914cfb", 154 | "sha256:49356e766643ad15072a789a20915d3c91dc89fd313ccd71802303fd67e4deca" 155 | ], 156 | "index": "pypi", 157 | "version": "==3.7.9" 158 | }, 159 | "macholib": { 160 | "hashes": [ 161 | "sha256:0c436bc847e7b1d9bda0560351bf76d7caf930fb585a828d13608839ef42c432", 162 | "sha256:c500f02867515e6c60a27875b408920d18332ddf96b4035ef03beddd782d4281" 163 | ], 164 | "version": "==1.14" 165 | }, 166 | "mccabe": { 167 | "hashes": [ 168 | "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", 169 | "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" 170 | ], 171 | "version": "==0.6.1" 172 | }, 173 | "mypy": { 174 | "hashes": [ 175 | "sha256:15b948e1302682e3682f11f50208b726a246ab4e6c1b39f9264a8796bb416aa2", 176 | "sha256:219a3116ecd015f8dca7b5d2c366c973509dfb9a8fc97ef044a36e3da66144a1", 177 | "sha256:3b1fc683fb204c6b4403a1ef23f0b1fac8e4477091585e0c8c54cbdf7d7bb164", 178 | "sha256:3beff56b453b6ef94ecb2996bea101a08f1f8a9771d3cbf4988a61e4d9973761", 179 | "sha256:7687f6455ec3ed7649d1ae574136835a4272b65b3ddcf01ab8704ac65616c5ce", 180 | "sha256:7ec45a70d40ede1ec7ad7f95b3c94c9cf4c186a32f6bacb1795b60abd2f9ef27", 181 | "sha256:86c857510a9b7c3104cf4cde1568f4921762c8f9842e987bc03ed4f160925754", 182 | "sha256:8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae", 183 | "sha256:8dfb69fbf9f3aeed18afffb15e319ca7f8da9642336348ddd6cab2713ddcf8f9", 184 | "sha256:a34b577cdf6313bf24755f7a0e3f3c326d5c1f4fe7422d1d06498eb25ad0c600", 185 | "sha256:a8ffcd53cb5dfc131850851cc09f1c44689c2812d0beb954d8138d4f5fc17f65", 186 | "sha256:b90928f2d9eb2f33162405f32dde9f6dcead63a0971ca8a1b50eb4ca3e35ceb8", 187 | "sha256:c56ffe22faa2e51054c5f7a3bc70a370939c2ed4de308c690e7949230c995913", 188 | "sha256:f91c7ae919bbc3f96cd5e5b2e786b2b108343d1d7972ea130f7de27fdd547cf3" 189 | ], 190 | "index": "pypi", 191 | "version": "==0.770" 192 | }, 193 | "mypy-extensions": { 194 | "hashes": [ 195 | "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", 196 | "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" 197 | ], 198 | "version": "==0.4.3" 199 | }, 200 | "pycodestyle": { 201 | "hashes": [ 202 | "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", 203 | "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" 204 | ], 205 | "version": "==2.5.0" 206 | }, 207 | "pyflakes": { 208 | "hashes": [ 209 | "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", 210 | "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" 211 | ], 212 | "version": "==2.1.1" 213 | }, 214 | "pyinstaller": { 215 | "hashes": [ 216 | "sha256:3730fa80d088f8bb7084d32480eb87cbb4ddb64123363763cf8f2a1378c1c4b7" 217 | ], 218 | "index": "pypi", 219 | "version": "==3.6" 220 | }, 221 | "typed-ast": { 222 | "hashes": [ 223 | "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", 224 | "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", 225 | "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", 226 | "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", 227 | "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", 228 | "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", 229 | "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", 230 | "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", 231 | "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", 232 | "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", 233 | "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", 234 | "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", 235 | "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", 236 | "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", 237 | "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", 238 | "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", 239 | "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", 240 | "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", 241 | "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", 242 | "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", 243 | "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" 244 | ], 245 | "version": "==1.4.1" 246 | }, 247 | "typing-extensions": { 248 | "hashes": [ 249 | "sha256:6e95524d8a547a91e08f404ae485bbb71962de46967e1b71a0cb89af24e761c5", 250 | "sha256:79ee589a3caca649a9bfd2a8de4709837400dfa00b6cc81962a1e6a1815969ae", 251 | "sha256:f8d2bd89d25bc39dabe7d23df520442fa1d8969b82544370e03d88b5a591c392" 252 | ], 253 | "version": "==3.7.4.2" 254 | }, 255 | "v": { 256 | "hashes": [ 257 | "sha256:2d5a8f79a36aaebe62ef2c7068e3ec7f86656078202edabfdbf74715dc822d36", 258 | "sha256:cd6b6b20b4a611f209c88bcdfb7211321f85662efb2bdd53a7b40314d0a84618" 259 | ], 260 | "index": "pypi", 261 | "version": "==0.0.0" 262 | } 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![logo](https://github.com/yukiarrr/Il2cppSpy/raw/master/docs/images/logo.png) 2 | 3 | # What's this? 4 | 5 | IL2CPP Disassembler. 6 | 7 | ## Open Apk 8 | 9 | Select apk, and it is automatically expanded and disassembled. 10 | 11 | Like the code editor, you can see the result of the disassembly. 12 | 13 | ![open](https://github.com/yukiarrr/Il2cppSpy/raw/master/docs/images/open.gif) 14 | 15 | ## Compare Apks 16 | 17 | Select two apks, and the difference between them is displayed. 18 | 19 | If there is a difference, the background color is changed. 20 | 21 | ![diff](https://github.com/yukiarrr/Il2cppSpy/raw/master/docs/images/diff.png) 22 | 23 | # Getting Started 24 | 25 | ## Windows 26 | 27 | 1. Download [here](https://github.com/yukiarrr/Il2cppSpy/releases) 28 | 2. Open exe 29 | 30 | ## Mac 31 | 32 | 1. Install [Mono](https://www.mono-project.com/docs/getting-started/install/) 33 | 2. Download [here](https://github.com/yukiarrr/Il2cppSpy/releases) 34 | 3. Open app 35 | 36 | # Resources credits 37 | 38 |
Icons made by Smashicons from www.flaticon.com
39 | 40 |
Icons made by srip from www.flaticon.com
41 | -------------------------------------------------------------------------------- /docs/images/diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/docs/images/diff.png -------------------------------------------------------------------------------- /docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/docs/images/logo.png -------------------------------------------------------------------------------- /docs/images/open.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/docs/images/open.gif -------------------------------------------------------------------------------- /scripts/Il2cppSpy.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | import sys 5 | sys.path.append('../') 6 | sys.path.append('../Il2cppSpy/ui/') 7 | 8 | 9 | # https://github.com/pyinstaller/pyinstaller/issues/4064 10 | import distutils 11 | if distutils.distutils_path.endswith('__init__.py'): 12 | distutils.distutils_path = os.path.dirname(distutils.distutils_path) 13 | 14 | 15 | block_cipher = None 16 | 17 | 18 | import os 19 | import platform 20 | import capstone 21 | 22 | 23 | site_package_path = '/'.join(capstone.__file__.split(os.sep)[:-2]) 24 | icon_path = './icons/icon.icns' if platform.system() == 'Darwin' else './icons/icon.ico' 25 | 26 | a = Analysis(['../Il2cppSpy/application.py'], 27 | pathex=['../Il2cppSpy/scripts'], 28 | binaries=[], 29 | datas=[('./icons/icon.ico', '.'), ('../Il2cppSpy/bin/Release/DumpWrapper.dll', '.'), ('../Il2cppSpy/bin/Release/Il2cppDumper.exe', '.'), ('../Il2cppSpy/bin/Release/Mono.Cecil.dll', '.'), (capstone._cs._name, './capstone/lib'), (f'{site_package_path}/Python.Runtime.dll', '.')], 30 | hiddenimports=[], 31 | hookspath=[], 32 | runtime_hooks=[], 33 | excludes=[], 34 | win_no_prefer_redirects=False, 35 | win_private_assemblies=False, 36 | cipher=block_cipher, 37 | noarchive=False) 38 | pyz = PYZ(a.pure, a.zipped_data, 39 | cipher=block_cipher) 40 | exe = EXE(pyz, 41 | a.scripts, 42 | a.binaries, 43 | a.zipfiles, 44 | a.datas, 45 | [], 46 | name='Il2cppSpy', 47 | debug=False, 48 | bootloader_ignore_signals=False, 49 | strip=False, 50 | upx=True, 51 | upx_exclude=[], 52 | runtime_tmpdir=None, 53 | console=False , icon=icon_path) 54 | app = BUNDLE(exe, 55 | name='Il2cppSpy.app', 56 | icon=icon_path, 57 | bundle_identifier=None, 58 | info_plist={ 59 | 'NSHighResolutionCapable': 'True' 60 | }) 61 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd `dirname $0` 4 | 5 | pyinstaller Il2cppSpy.spec 6 | -------------------------------------------------------------------------------- /scripts/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/scripts/icons/icon.icns -------------------------------------------------------------------------------- /scripts/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yukiarrr/Il2cppSpy/25ac60e1981899886aaaef45d582d6fb8f3c8ab1/scripts/icons/icon.ico -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E402,E501 3 | --------------------------------------------------------------------------------