hexwalk-1.9.1/0000755000175100017510000000000015005423177012523 5ustar carmixcarmixhexwalk-1.9.1/README.md0000664000175100017510000000567515005342073014014 0ustar carmixcarmix![hexwalk](hexwalk/images/hexwalk64.png) # HexWalk - Hex Editor/Viewer/Analyzer HexWalk is an Hex editor, viewer, analyzer. Based on opensource projects like qhexedit2,binwalk and QT. It is cross platform and has plenty of features: * Advanced Find (can find patterns in binary files based on HEX,UTF8,UTF16 and regex) * Binwalk integration * Entropy Analysis * Byte Map * Hash Calculator * Bin/Dec/Hex Converter * Hex file editing * Diff file analysis * Byte Patterns to parse headers ## Screenshots * Main page ![hexwalk gui](screenshots/hexwalk_gui1.png) * Byte Map ![hexwalk gui](screenshots/hexwalk_gui17.png) * Advanced Search ![hexwalk gui](screenshots/hexwalk_gui5.png) * Entropy Calculator ![hexwalk gui](screenshots/hexwalk_gui2.png) * Binary Analyzer ![hexwalk gui](screenshots/hexwalk_gui3.png) * Hash Calculator ![hexwalk gui](screenshots/hexwalk_gui4.png) * Diff Analysis ![hexwalk gui](screenshots/hexwalk_gui13.png) * Binary Patterns for header parsing ![hexwalk gui](screenshots/hexwalk_gui15.png) ## Usage HexWalk release executables are self-contained, you can use as-is. Binwalk functionalities need Binwalk to be installed on the OS. For Linux OS simply install binwalk with your package manager (eg. sudo apt install binwalk). On Mac install with "brew install binwalk" or from sources following the instructions on Binwalk repository. For more details about the usage go to the Wiki: https://github.com/gcarmix/hexwalk/wiki ## Windows HexWalk on Windows is released in different flavours: - as an installer - as a portable zip file The fastest way to install it is through winget: ``` winget install hexwalk ``` ## MacOS On MacOS you can easily download the .dmg file available in the release page and drag the app in the Applications folder as usual ## Ubuntu The project is also available on launchpad https://launchpad.net/hexwalk to install on Ubuntu you can simply do: ``` sudo add-apt-repository ppa:carmix/ppa sudo apt update sudo apt install hexwalk ``` ## Linux For other Linux distributions there's the AppImage file available in the release page. Just download, give execution permissions and you are ready to go. ## Build If you want to build from source just open hexedit.pro in QT Creator and build it. It is possible also to build from command line (linux_build.sh script provided). ## License Copyright (C) 2024 Carmix (Carmine Gianni) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. A copy of the license is in the COPYING file in the root of the project. ## Acknowledgments Thanks to these projects: * Binwalk - https://github.com/ReFirmLabs/binwalk * QHexEdit2 - https://github.com/Simsys/qhexedit2 * QT5 hexwalk-1.9.1/hexwalk.desktop0000644000175100017510000000036615005342073015561 0ustar carmixcarmix [Desktop Entry] Version=1.0 Type=Application Terminal=false Name=HexWalk Exec=/usr/bin/hexwalk Comment=Hex Analyzer Icon=/usr/share/pixmaps/hexwalk.ico StartupNotify=false Encoding=UTF-8 Categories=HexEditor;Development;Qt; hexwalk-1.9.1/COPYING0000644000175100017510000010451515005342073013557 0ustar carmixcarmix GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . hexwalk-1.9.1/hexwalk.ico0000644000175100017510000004107615005342073014665 0ustar carmixcarmix@@ (B(@ RRROOO````````````````````````````````````````````````````````````RRRBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBQQQ``````[[[666WWWYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYWWW666ZZZ``````"FFFLLL```````````````````````````````````````````````````MMMFFF```#```VVV777___```````````````````````````````````````````````````___888VVV```___=???SSS``````````b``b``b``b``b``b``b``b``b``b``b``b``b``````````TTT>>>___B```QQQ===``````````b`:4.%.%.%.%.%.%.%.%.%.%.%;6`a``````````???PPP```]]]c888YYY``````````b`0'2+`a``````````ZZZ777]]]k``````KKKFFF`````````````b`0'2+`a`````````````HHHJJJ``````ZZZ666]]]`````````````b`94.$.$.$&,".$.$;6`a`````````````]]]666YYY``````%EEEMMM```````````````````b``b``b``b`GC [wZ`b``b``b```````````````````OOOCCC```.```VVV888___``````````````````````````````GD [v[```````````````````````````___:::TTT```___B>>>TTT`````````````````````````````````GD [v[``````````````````````````````VVV<<<^^^Q```PPP???````````````````````````````````````GD [v[`````````````````````````````````BBBNNN``` UUUBBB```]]]g888YYY````````````````````````````````````GD [v[`````````````````````````````````[[[666[[[x```]]]`````````````````````````````````````````````````````````KKKGGG```````````````````````````````````````GD [v[````````````````````````````````````JJJHHH``````VVVKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKYYY===WWW```````````````````````````````````````GD [v[````````````````````````````````````^^^333^^^e```]]]e888LLLOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOKKK:::RRR@@@```````````````````````````````````````GD [v[````````````````````````````````````TTT>>>___<```KKKGGG```````````````````````````````````````````````````DDDOOO===UUU````````````````````````````````````GD [v[`````````````````````````````````___888VVV``````YYY666]]]```````````````````````````````````````````````````\\\666UUU999___`````````````````````````````````GD [v[`````````````````````````````````LLLFFF```#```(DDDNNN`````````````````````````````````````````````````````````LLLHHHFFFNNN`````````````````````````````````GD [v[``````````````````````````````\\\666ZZZ``````UUU999___``````````````````_f_SRHED@IFUS_d_``````````````````^^^888VVV666]]]``````````````````Y}Y?;?:?:1) [v[``````````````````````````````CCCMMM``` ___H===UUU``````````````````VT0'3+XW``````````````````SSS???LLLGGG``````````````````UT [v[```````````````````````````WWW:::^^^VUUU```PPP@@@``````````````````US#&WV``````````````````???SSS888YYY```````````````UT [v[````````````````````````___;;;SSS``````]]]l777ZZZ```````````````]n]+! 0(_h^```````````````YYY888SSS???```````````````^l]OM@<( [v[````````````````````````PPPBBB___1```JJJHHH``````````````````IF&TR^i^RQ$MK``````````````````GGGMMM>>>TTT`````````````````````^j^NL-#  ![u[`````````````````````]]]666XXX``````YYY666]]]```````````````_c_.%IG`````````FC4-`a````````````````]]]666UUU888___````````````````````````_d_^j^^j^^i^`a``````````````````````HHHJJJ``````,CCCPPP``````````````````XX  Z{Y`````````XW [u[``````````````````OOOEEEGGGMMM`````````````````````````````````````````````````````````ZZZ888\\\k``````TTT999___``````````````````NL)_c_`````````_g^#RQ``````````````````___999TTT666]]]``````````````````````````````````````````````````````???PPP```___O<<>>___C```NNNBBB````````````````````````A=93`````````````a`3+FC````````````````````````AAAPPP999UUU[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[888VVV```___;;;;XXX````````````````````````?:;5`````````````a`5.D@````````````````````````[[[777VVV===================================================LLL```"```IIIIII````````````````````````?;:5`````````````a`5-DA````````````````````````XXX:::___R```(```(```(```(```(```(```(```(```(```(```(```(```(```(```(```(```(`````````\\\p777[[[`````````````````````C?71`````````````a`1)HE`````````````````````___<<9C?`a````````````````UUU===___I```]]]k777ZZZ```````````````^l]94>9_g^```````````````___999UUU``````OOO???``````````````````_e_NL5." #70PN`c_``````````````````MMMEEE```'___D>>>TTT``````````````````````a`_g^]p\_f_`a``````````````````````\\\666ZZZ``````UUU888___``````````````````````````````````````````````````````EEELLL``````+DDDNNN```````````````````````````````````````````````````XXX999^^^]---```ZZZ666\\\`````````````````````````````````````````````___<<&;.#yi <~Fߔ@Z>N4u|^wywwgoip:rNLbKGD pHYs.#.#x?vtIME )*wStEXtCommentCreated with GIMPW IDATx^ٗe}߭G4ИbDI EHˎ%K;S&ZIdYc/ٲ,JdS% )c@CuP"vչ9󢵴~u$tύUT@3߿]T|O?'x6v>Mf˄`h"W P=A&i5p#648p޾}J"BF h&:w}tLh`kZ7 hʱZ8aV =˚19z3?&P k &coMPW~Ù0Q^BLn|%>#e ߿-P'ѩ=|\H]s/~9`P'~NS'0(RF~kDzoP~äNS =!:kZԵ|o~͘C5 "׈4ԑI$!k5aMV \B> pR*TI)>&=WJ]PB)>$IY_hB`7ܤ@>0d@/ &Conn,~9ˁ[Eoԉ"6M!PY;A#u~ <0z#5Dc @Y8X !uH%TI= k:Kf)5PGLN _"2 脀xjHc`@8X DE|M膀_{*B>57zÞ:IݬS08 H!ுMXM{`nD@&|9p Z ]r5@ K HQ?c1 cab,./R,cih9C˭^h-btn$FՑ2#FbX _.?̀ڿ駟n0D&hiij9v5.7]+q~z6NK?c솘4SXD}0ZԾ}0+~IR6=3w[f䶳qlb #sqaM#DC,Ml lɃZ04FO`zx;f3wv3E?FŹ#vx4bji4n?#v561FOי)>`ԡ}ʆaz_v\xl&N}&~ Hsa{>=nz~K몬a: Wgލs׊x嵝配1tR2'yDiǹ\Coo:UTxh+ۏ+ۏ\z{ovԄGuOf[ڰ7>u4>TTP<]1qp]Q9+Q&]Jݜq3} '|k9~p`xmqǷĺE?FEL*B^i+'v+8zG͛c̣;}Qf/1:|1xƑEDR~(^ƮoּKS||ͱy1{퇊JY-_/MRԾbj XZ]og:Kߏh,O.SCʜS8բr<{x{>."V#W(uӦ3㹽Jұ G8'"S|O(ksq ʳqlBQ)kZxxiT-gC)iFMP;瞏kCKE]ɋ1g5J+4 KF|Jsx.fM! .Z[غ?ī/*bF?8bQ)kP%3+=qh㙢Rzdnh)ڗ5)>`&XGw~yikhՎ{!>SEt)uP: o*R7My>_<]g|83nnͯ^v.΋}C|ɗ5%e1LQ)5g^s(UR)>vko;SJV; 1RHV[z8rZg~ŘyD؀oz_~[QsgǮ+7 ו)>`Ȁo.ķ|xg|#*I:HHT +IS7]>nn\k5n?wW'}oͯ7֑qH`@@>~|?1STHc_>bj'M:գ䡻J'-*!QjLdWYV[STHӱl/*-V;WT8⧿DL0UTZ-G =QTB~Mwyq-c1Ҟ[K=TT8>;S|fit7] ʮKҎ?9twQY,Ee$JkN, ?ēbא3GmQ7{{?Pz'y} 9p | eNYh;޸+7zyS{ЊZ-*m3cW#!˒:]|l&d}1tc;5{,* }Π`VP)uƎߟW({ȝ1dQY-cfkQYcXpضT%)S'[]NjcX-EeZnKZ8D~ZԞO|˙'|k1{9;RTV+/NC'sSRȝ06ԸO냢غ8o[J㝩qtEfjT/kzo+qpS>.cr_[D~ٯƼFx{XfrPۀQtwwz-m,*iGo**iԥ2(Oaz'5®ӱ躢Fxh1~9p P_ +IN(6sG>"bωϹnym>y]w|1˻"uMS|z]ZǶ.jpd_jQ %*+WԩPD6,ŻyAgji4/*ԉɢƸrQ 5%V͐ [**E%qaoԾڷF>͐t|[)2XL/5ɭJ1S|k7oSgylRĮEUKp/ڿ(_iNٜ'yl{yT,gWJR?%-O,L׽ǻ;5u.7].> ,} 8rֹhGצbx/f7MMMIgnz_O9MMl,*|M%i i|<ҩcE%xi-Ծ@9ziͳE%`2;M5¥5_TFTgM4|WIJ>c ,Dh;Nd
EﷲB)>@5zB􍅵߾K|౓y|kkE%4P|k|w޸.gʲn&\\w[Н}mqW :׍]/3SޅS|rU"GNCL^9T/#}* eN++ّƸ4[ʨ)nWi/Kꔈ\y?"b~BQ =?Oeiͣf'r @zg&M}4-l-\]7>k|?CNRv@gJ .y+t!UB{NiR7.#"/^[ʸ?|x4,U떇5**|>-uH:`u6ԍ,~u# /0|-"?H #ti~< B>oVNV;&z,7yzuXӎo|&#R^&&H k<̍+7Jv2#t_p>lG9`ڭC!WژS?sy$gJ7|^&p XW;kcOZ꣞r^/>u?Gnhy"!Yn Mooz? OC~dX`hg[ޢ^FJKJ==i_o@Y>Byۮ,o*uȓ:Dt|t4n+?Jo$ ~Q lcdf߾}чtO?t^(59L|U|w}Q/}tVCdn=[v7`_ԅz-<9dٝC3Jw{\=ӚC ܴ <zZk'-iovw^%7:߿mN>4PnϬgnۡnBMCN-M OmW2{PkE8p]*Z?i;$7Z,hWW_nW;*^1!z5&,gӍnrZ~|}eM5[Ӊ Z*h̞?H^%RCR:[xp^ٝUU]\^:YAi\GXv; B^Q~\of_ovHnhh>FnFnKE%Hꀧpz]Aq3,Cz3ѢfZ}) )~TEW4Sk17i!d7L9K ⩃NUu]hup[OI;)`Ywi4 `KGR)]H]s) cy*5>RuaФԵGCeXQIc,rf-:kUVv3ůal>GtFJDN!k'GW54Y;9y?3I/R#Tk%u-{]|Sdoi,?n_Wjnj>l/do1Gt6-RU< 5&5|62OZNKc<497^TBC >5|S|^'GD,n,d΄_K}}gc5&NF/& X[(*i>@nUJw6O3X?Q_wEM!f̩&yy| pck)uR)~~F.r>"\yZQIc Lmv7MU5@O[G3 z|RuAU:R,*5E%173詖b{G/'(@=M{oWr Yw!\T|D~t'unWY7= IDAT|X0_vum:3~nޝkmU#ɱhE>jd:+2'fylRqjTUn̚kJ~R7њoŮEe19Iv+uNjJȜL_2Q8oҹ>>%uiOnMȯV5:e<O4ƕML;olj٢F\ށ}Evk|nm|>/mgݩ]ю<%f7GkQ;M:5:= IR7n|5p$;s[y,i|knuS k1uv= ͵x>H'E%t-*~]uk׀枺ynûy<qzGw5 ;F}ꦢLv|nc14RTG6剼vvo>!mycQ %Hl;̫./S{_MjODHӚosۋa'ś/4|z4hRrj%u :So7}1.񕕜yMƺEeQ&#?8p[Znb;|yYڸ7w˩mE%Qj/Wu]`pݩM&_xusE%ӊxg׉F{iK}_? 7AG \jXy䀹vYWu] ܖv5@&CgfxkqՃx==Wdl:qsW!/vw.uB~gj𩷩&cF02#|tQIc8HOqZlv5ƻj[g/{5b>$vo.'u_M携Pl|^ڶ޹Z;ą8?z>+.7=p[~u඾_- 'JjGD>6#!I @/*Ȁᵙum1nG[?/z]ms}'7߽͸2c A)*iwWޏjds!k?\ME$ũ¶ƚo-Ƿ|=~T,+7/l_#v,<?HQyWc%u.iDžO_W{:ӭA%퍃_Eٱ^MGnm'}ryr\|Rt=|XDQP-qj8xϻq|b&n8` Y=޲ROD@xsɢ쾺!vNNcX XiR,M.]bv帰}&t*f VoA\[z\Uץf9n F~3EeHjX YL{{{˃ߟoBC14FnnB} gʡvR3xVg/Oƃ'=csFCqRTFR7NU]>|vƓ/ 4Zj_*௦ imI0w1o)CjVu]m/w$~& 73J-gMe;m:KSq~߅x?ܳqadGqR\e#[r[b等x{c䜃neHO\;'|:^7?oㇷ! M-5rn8Ɠ/;/lkQ[=ܭ3Γq|k-\n,%d~fG{_}1dQUu]-n]Kw^7_g}T&3eAx{ '{܊qwR˦5h>s.$)g.fUv.N+)$o^&X}Χ(*%#n_STFE:N8tz]"v.=Wcv8bg :Ƈ?ػT6}1{w9oV}0&rNZUZj?)Ք!!ّ̟=yVu*)Ħt:\}p-*Ҥ RM5p?:j-߹7vӌ hkUu%O ہ xw[l,*&Zъ/=Hlz %l7ů#?>;MR_z[HW:[U]RUj?l !鯱c{4ϭ/*⃱ۊHORa?߁Zwt<>n(*~湇cvQ#nܥԾ$WCѸmvsQ)=2nx&UH# to_oc'G3R*~y$7{ɀC#s#xmETdT|NSU>_ ]/*dw^)=;\ީ 0(b=;~/ cEՔwoOboNR74Aj?g֙߁A͖n/hg{1tURjHGMvp9so[TJ;/_qRo"8Ikκ;4j-b%˛)0<OxuGNj)AjHCr9p+)~L<zkHws;g?yKRoLB4t6VKӻ+&g<OS^JSU].R\j#b9|Hdкx_/y|%K#W?T)/nNj__AYS|c7ľh|{-W|9u떇3_?{;g8e Iy)]IS[Ϸ'x1Gai,~+߹5FOz}NMuX] p6Vl}fs/O'o`jo1 ߻9FOdӁI.~HLj;{o?+צ~qC{/OvR@}&5uoW駟nHv-#;c+qsqhqj|Gki|y89+v_(Pj߮V v#=41{88lt:Zym*[^3B}U+.kl|0qǔ;Mh߾}I`j)bɘzu2xlz).?o[gsqqZU*1nŭ[⦳bɩpxڷ6HJS|C<×cӳcSlx1g.W\+8;5[ڣ=Ӌʆpi*&g&bu1qr]?<C8t'm8l!=ҎōKa1cqb)GcyXnG 8C˭h-bhq(ctv$FfcH ]sSUo꺔#:VRV/?)>+i-bH=Ҝ-ŋ7PGujH8p tPuloxCEedju @YP<.tAԾڗMjL , &u] p+wNY@5r~R?$6P_~QuPj߬__S|>!__#nRq}q3?P&, %0RGSt/C.uݦz+O_nqh~|R7Mi?t&* %2ŇRf@}z/́[`%uH_SwU|.6MfÁ[@R}j_ Mc^L]Kj_@*7E uSN꤮N{U}7I)>%Yn ~@9Roj/Ё&&z]~]? =`H7k:oP_U|R7n6.u],}>uY+G>fPULHݴ @wR[zTU;}9u?Y LYRq>WnsH荺g|NWu]ʑڧ{1)><)7z`)+ 53uz]}ສOzjʘ 5T@`euuԾ/%٦6s/TuVﳲܦwRg ?k ~n!> C <Jmܩv/\f&u麬[j?O/5aTS6t~8p H]zg_%P})_3|/u}0xRB ! 5d I]"FrUF\IS?)0a 5l?u:.͖SO2)K:ҔSfʵjoxCEe.*ʕO=a_ceWVV P}f 5ggz@ &$@u/"F(:H+6ޔk@79W"Xm_IzJu)M*AB~]kkG,C"tmPW~<ӭwFtZYGt[uw7P_Mzd++؛IU}(WY A֦`7:fH$gFH1@E]R:y> XiR:esٺGPO|oL#|L`'upt#>@LN>T"u%$0}>uYP< Y7:IJڤS7G% 6]:)`G ]rK?kljh*~}SOMa@DzO'RßňQT OjNZ~]ַu%"|[:ZT OJФR 5o}]TWjO$GY#e5e%u0SڏJ-`IשA|2>@LCjNB枺y@ʚ_~yOR@T=*׋f@uR,8XQ>@[_G=Sց&N(ߦ5)n:O/>@OНAJꠦJ>@Mn׏cht.uR%WSv/P~M#|1~گ{EM#uS:G}MJv|2>@a0R$uG-@Ծ>Q]>@mVjL"4@ꦒiн:M#|Z&AH~Ƚ? 5Si k>B%nSnLʕSm] nj꾉4Eꠣik?Jh(S|ΤZ7>@5aZ0ҏ|p;}/֑2 Mjkڏ2 | 9A6Eh\>@6L>Rg i@5 -Ծ>K AS>@c5E"%d(5nd-IDATuRd )@W|LNR_uڿRcӌPoO?tk:7hOubfC͙iNsEeT }DDDM˷cfx 7~"6?RV%GxD {=u^|L4}D@b>@0rڧR` m P6u:+)5@qz!dUj_% !h*3>@rNtb>@2&}Jj9nK?-7>a>@0* ڏUjIg M>j@+u*Ϥ dЦX|-Pwڏ #>2*8~I'jPj[@ ԩX RHj$>)}Mx?]@ߤ{ az_L`UB>P~ڏ@D~ͥ}@ԩYT<}" 2f 4|>Ɓ[j4>Iā>7P*+HSu@RAjC>7d:ԕ:dSԩ>`m|Vd#ʐYUut~m|&ER}j_ 25M꜀NRy@s~@ćӳ//*J`z?IV &uGtTe{#k3^1@i| u] $3UtOTӸiP_jt PO3kⵙ@Dyk`LX=Xbz_uH'fnZ#T.uOzu7|Ja8p w|ބ6>2:ez_ Reg|Jg*'#SӼi!P`mTy)+S=8p | *&;&r T7|FȇK]w@l#WP_|zRV|zƁ[=U?Ԑ:e+kGlPOzS|hz %f9f蛲ܦ:nO|>-2|X P[S)$n? ? ԋ@-8p &^|z3zMԆ)>4}4I]6@ PpO4)>}PKo/CvS-ח >Tց[|} 7%P[P?'HB>Tf5zs 4 f9|jo`!Cy<1Vz7uޑ) 2RTMq=Й`!7_R4%7_#Co@c P h EditTagDialog 0 0 400 200 400 200 400 200 Edit Tag true true 110 50 141 25 10 50 91 20 Name: 10 10 91 20 Color: 10 90 91 20 Offset: 110 90 141 25 10 130 91 20 Length: 110 130 141 25 10 170 91 20 Type: 110 170 141 25 String BigEndian LittleEndian HEX 290 10 93 29 Apply 110 10 141 29 hexwalk-1.9.1/src/hexwalk/bytemapdialog.h0000664000175100017510000000265315005675407017764 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BYTEMAPDIALOG_H #define BYTEMAPDIALOG_H #include #include "../qhexedit/qhexedit.h" #include namespace Ui { class ByteMapDialog; } class ByteMapDialog : public QDialog { Q_OBJECT public: explicit ByteMapDialog(QHexEdit * hexedit,QWidget *parent = nullptr); ~ByteMapDialog(); void showByteMapDialog(); private slots: void updatePos(); void gotoAddress(); void refresh(); void on_spinCols_valueChanged(int arg1); void on_closeBtn_clicked(); void on_colorBox_stateChanged(int arg1); private: int imageWidth; int imageHeight; Ui::ByteMapDialog *ui; QHexEdit * _hexedit; QGraphicsScene *scene; }; #endif // BYTEMAPDIALOG_H hexwalk-1.9.1/src/hexwalk/tagsdialog.ui0000644000175100017510000000362014561356105017435 0ustar carmixcarmix TagsDialog 0 0 863 345 HexWalk - Byte Pattern Load Add Del Save Qt::Horizontal 40 20 Reset Close hexwalk-1.9.1/src/hexwalk/translations/0000755000175100017510000000000015005675407017503 5ustar carmixcarmixhexwalk-1.9.1/src/hexwalk/translations/hexwalk_cs.ts0000664000175100017510000004066715005675407022222 0ustar carmixcarmix MainWindow About HexEdit O HexEdit The HexEdit example is a short Demo of the QHexEdit Widget. Příklad HexEdit je krátká ukázka doplňku QHexEdit. Save As Uložit jako Save To Readable File Uložit do čitelného souboru HexEdit HexEdit About QHexEdit The QHexEdit example is a short Demo of the QHexEdit Widget. QHexEdit Cannot write file %1: %2. Nelze zapsat soubor %1: %2. File saved Soubor uložen Overwrite Přepsat Insert Vložit &Open... &Otevřít... Open an existing file Otevřít stávající soubor &Save &Uložit Save the document to disk Uložit dokument na disk Save &As... Uložit &jako... Save the document under a new name Uložit dokument pod novým názvem Save &Readable... Uložit Č&itelné... Save document in readable form Uložit dokument v čitelné podobě E&xit &Ukončit Exit the application Ukončit program &Undo &Zpět &Redo &Znovu &Save Selection Readable... &Uložit výběr čitelný... Save selection in readable form Uložit výběr v čitelné podobě &About &O programu Show the application's About box Ukázat informace o programu About &Qt O &Qt Show the Qt library's About box Ukázat informace oknihovně Qt Find next occurrence of the searched pattern &Options &Volby Show the Dialog to select applications options Ukázat dialog pro výběr voleb programu Edit Cannot write file %1. &Find/Replace Drop File: Show the Dialog for finding and replacing Find &next &File &Soubor &Edit Ú&pravy &Help &Nápověda Address: Adresa: Size: Velikost: Mode: Režim: Ready Připraven File Soubor SDI SDI Cannot read file %1: %2. Nelze číst soubor %1: %2. File loaded Soubor nahrán OptionsDialog Dialog Dialog QHexEdit - Options Flags Příznaky ReadOnly PouzeProČtení Highlighting Zvýraznění Overwrite Mode Režim přepisu Address Area Oblast s adresou Ascii Area Oblast ASCII Colors and Fonts Barvy a písma Highlighting Color Barva pro zvýraznění Address Area Color Barva pro oblast s adresou Selection Color Barva výběru Widget Font Písmo doplňku 01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef Address Area Width Šířka oblasti s adresou Hex Area Bytes per Line SearchDialog Dialog Dialog QHexEdit - Find/Replace Find Hex UTF-8 Replace Options &Backwards &Prompt on replace &Find F3 &Replace Replace &All &Close QHexEdit %1 occurrences replaced. Replace occurrence? UndoStack Inserting %1 bytes Delete %1 chars Overwrite %1 chars hexwalk-1.9.1/src/hexwalk/translations/hexwalk_de.ts0000664000175100017510000004177315005675407022204 0ustar carmixcarmix MainWindow About HexEdit Über HexEdit The HexEdit example is a short Demo of the QHexEdit Widget. Das HexEdit Beispiel ist eine einfache Demo Anwendung für das QHexEdit Widget. Save As Speichern unter Save To Readable File Als lesbare Datei speichern HexEdit HexEdit About QHexEdit Über QHexEdit The QHexEdit example is a short Demo of the QHexEdit Widget. Das QHexEdit Beispiel ist eine einfache Demo Anwendung für das QHexEdit Widget. QHexEdit QHexEdit Cannot write file %1: %2. Kann Detei %1 nicht schreiben: %2. File saved Datei gespeichert Overwrite Überschreiben Insert Einfügen &Open... Öf&fnen... Open an existing file Existierende Datei öffnen &Save &Speichern Save the document to disk Dokument auf Platte speichern Save &As... Speichern &unter... Save the document under a new name Dokument unter neuem Namen speichern Save &Readable... Als &lesbare Datei speichern... Save document in readable form Das Dokument in lesbarer From speichern E&xit &Beenden Exit the application Applikation beenden &Undo &Wiederherstellen &Redo &Rückgängig &Save Selection Readable... &Auswahl in lesbarer Form speichern... Save selection in readable form Speichere die Auswahl in lesbarer Form &About Ü&ber Show the application's About box Zeige Informationen zur Anwendungj About &Qt Über &Qt Show the Qt library's About box Zeige Informationen über Qt Find next occurrence of the searched pattern Zeige die nächste Fundstelle mit dem gleichen Suchmuster &Options &Optionen Show the Dialog to select applications options Zeige den Dialog, um Optionen der Anwendunge einzustellen Edit Bearbeiten Cannot write file %1. Kann Datei %1 nicht schreiben. &Find/Replace &Suchen/Ersetzen Drop File: Datei erhalten: Show the Dialog for finding and replacing Zeige den Suchen/Ersetzen Dialog Find &next &Weitersuchen Find next occurance of the sarched pattern Zeige die nächste Fundstelle mit dem gleichen Suchmuster &File &Datei &Edit &Beearbeiten &Help &Hilfe Address: Adresse: Size: Größe: Mode: Mode: Ready Fertig File Datei SDI SDI Cannot read file %1: %2. Kann Datei %1 nicht lesen: %2. File loaded Datei geladen OptionsDialog Dialog Optionen QHexEdit - Options QHexEdit - Optionen Flags Eigenschaften ReadOnly Nur lesen Highlighting Hervorheben Overwrite Mode Überschreibe Modus Address Area Adressfeld Ascii Area Ascii-Feld Colors and Fonts Farben und Schriftarten Highlighting Color Farbe Hervorhebung Address Area Color Farbe Adressfeld Selection Color Farbe Markierung Widget Font Font-Auswahl 01 23 45 67 89 ab cd ef Address Area Width Hex Area Hexadezimalfeld Bytes per Line Bytes pro Zeile SearchDialog Dialog Optionen QHexEdit - Find/Replace QHexEdit - Suchen/Ersetzen Find Suchen Hex Hex UTF-8 UTF-8 Replace Ersetzen Options Optionen &Backwards &Rückwärts &Prompt on replace Vor dem Ersetzen &nachfragen &Find &Suchen F3 &Replace &Ersetzen Replace &All &Alle ersetzen &Close &Schließen QHexEdit QHexEdit %1 occurrences replaced. %1 Vorkommnisse ersetzt. Replace occurrence? Vorkommnis ersetzen? Replace occurrance? Vorkommnis ersetzen? UndoStack Inserting %1 bytes %1 Bytes eingefügt Delete %1 chars %1 Zeiche(n) gelöscht Overwrite %1 chars %1 Zeichen überschrieben hexwalk-1.9.1/src/hexwalk/translations/hexwalk_ru.ts0000664000175100017510000004132115005675407022227 0ustar carmixcarmix MainWindow About QHexEdit Про QHexEdit The QHexEdit example is a short Demo of the QHexEdit Widget. QHexEdit пример это короткая демонстрация работы QHexEdit компоненты. Save As Сохранить как Save To Readable File i hope it is text file with hex dump Сохранить как читаемый файл QHexEdit QHexEdit Cannot write file %1: %2. Не могу записать файл %1: %2. File saved Файл сохранен Overwrite Замена Insert Вставка &Open... &Открыть... Open an existing file Открыть существующий файл &Save &Сохранить Save the document to disk Сохранить документ на диск Save &As... Сохранить &как... Save the document under a new name Сохранить документ под новым именем Save &Readable... Сохранить как &читаемый... Save document in readable form Сохранить документ в читабельной форме E&xit В&ыход Exit the application Выход из приложения &Undo &Отмена &Redo &Повторение &Save Selection Readable... &Сохранить выделеное читабельно... Save selection in readable form Сохранить выделеное в читабельной форме &About &О программе Show the application's About box Показать сообщение рассказывающее о программе About &Qt Про &QT Show the Qt library's About box Показать сообщение о библиотеке QT &Find/Replace &Поиск/Замена Show the Dialog for finding and replacing Показать диалоговое окно для поиска и замены Find &next Найти &следующий Find next occurrence of the searched pattern Найти следующие вхождение поискового шаблона &Options &Настройки Show the Dialog to select applications options Показать диалоговое окно для установок приложения &File &Файл &Edit &Редактирование &Help &Помощь Address: Адрес: Size: Размер: Mode: Режим: Ready Готово File Файл Edit Редактирование Cannot read file %1: %2. Не могу прочитать файл %1: %2. File loaded Файл загружен Cannot write file %1. Не могу записать файл %1. OptionsDialog QHexEdit - Options QHexEdit - Настройки Flags Флаги ReadOnly Только чтение Highlighting Подсвечивание Overwrite Mode Режим замены Address Area Адресная область Ascii Area Область ASCII Colors and Fonts Цвета и Шрифты Highlighting Color Цвет подсвечивания Address Area Color Цвет адресной области Selection Color Цвет для выбраной области Widget Font Шрифт для компоненты 01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef Address Area Width Ширина адресной области Hex Area Шестнадцатиричная область Bytes per Line Байт в строке SearchDialog QHexEdit - Find/Replace QHExEdit - Поиск/Замена Find Найти Hex Hex UTF-8 UTF-8 Replace Замена Options Настройки &Backwards &Обратный поиск &Prompt on replace &Предупреждать перед заменой &Find &Найти F3 F3 &Replace За&менить Replace &All Заменить &всё &Close &Закрыть QHexEdit QHexEdit %1 occurrences replaced. %1 найденых фрагментов заменено. Replace occurrence? заменить найденое? UndoStack Inserting %1 bytes Вставить %1 байт Delete %1 chars Удалить %1 символов Overwrite %1 chars Заменить %1 символов hexwalk-1.9.1/src/hexwalk/translations/hexwalk_de.qm0000644000175100017510000001622714561356105022162 0ustar carmixcarmixbu`?W z4{p6^~ > i2`S%s\ "'):Ol{{RaE @6lxx}\[$^V!Y~%%8'$ t /  H yb 1 9Pq z n em QS }d \ S  ^~( `lM 5 hs l< B s *.0qZTT)e Rg!$i &ber&About MainWindow&Beearbeiten&Edit MainWindow &Datei&File MainWindow &Suchen/Ersetzen &Find/Replace MainWindow &Hilfe&Help MainWindowf&fnen...&Open... MainWindow&Optionen&Options MainWindow&Rckgngig&Redo MainWindow&Speichern&Save MainWindowL&Auswahl in lesbarer Form speichern...&Save Selection Readable... MainWindow"&Wiederherstellen&Undo MainWindowber &Qt About &Qt MainWindowber QHexEditAbout QHexEdit MainWindowAdresse:Address: MainWindow<Kann Datei %1 nicht lesen: %2.Cannot read file %1: %2. MainWindow<Kann Datei %1 nicht schreiben.Cannot write file %1. MainWindowDKann Detei %1 nicht schreiben: %2.Cannot write file %1: %2. MainWindowDatei erhalten: Drop File:  MainWindow&BeendenE&xit MainWindowBearbeitenEdit MainWindow&Applikation beendenExit the application MainWindow DateiFile MainWindowDatei geladen File loaded MainWindow"Datei gespeichert File saved MainWindow&Weitersuchen Find &next MainWindowpZeige die nchste Fundstelle mit dem gleichen Suchmuster,Find next occurrence of the searched pattern MainWindowEinfgenInsert MainWindow Mode:Mode: MainWindow2Existierende Datei ffnenOpen an existing file MainWindowberschreiben Overwrite MainWindowQHexEditQHexEdit MainWindow FertigReady MainWindowSDISDI MainWindow&Speichern &unter... Save &As... MainWindow>Als &lesbare Datei speichern...Save &Readable... MainWindowSpeichern unterSave As MainWindow6Als lesbare Datei speichernSave To Readable File MainWindowNDas Dokument in lesbarer From speichernSave document in readable form MainWindowLSpeichere die Auswahl in lesbarer FormSave selection in readable form MainWindow:Dokument auf Platte speichernSave the document to disk MainWindowHDokument unter neuem Namen speichern"Save the document under a new name MainWindow@Zeige den Suchen/Ersetzen Dialog)Show the Dialog for finding and replacing MainWindowrZeige den Dialog, um Optionen der Anwendunge einzustellen.Show the Dialog to select applications options MainWindow6Zeige Informationen ber QtShow the Qt library's About box MainWindowDZeige Informationen zur Anwendungj Show the application's About box MainWindow Gre:Size: MainWindowDas QHexEdit Beispiel ist eine einfache Demo Anwendung fr das QHexEdit Widget.F `?W z4E{p6F~i`S%{s\"',)2:)l%{{baE rlxx}\$^'VeY 3~%%'$ t 2 /  : yb ] 9P/ z nm e Q } \ ST  ^~ `lM e hs l< sx *.0qTTe Rg!i& ?@>3@0<<5&About MainWindow& 540:B8@>20=85&Edit MainWindow &$09;&File MainWindow&>8A:/0<5=0 &Find/Replace MainWindow&><>IL&Help MainWindow&B:@KBL...&Open... MainWindow&0AB@>9:8&Options MainWindow&>2B>@5=85&Redo MainWindow&!>E@0=8BL&Save MainWindowD&!>E@0=8BL 2K45;5=>5 G8B015;L=>...&Save Selection Readable... MainWindow&B<5=0&Undo MainWindow@> &QT About &Qt MainWindow@> QHexEditAbout QHexEdit MainWindow 4@5A:Address: MainWindow<5 <>3C ?@>G8B0BL D09; %1: %2.Cannot read file %1: %2. MainWindow25 <>3C 70?8A0BL D09; %1.Cannot write file %1. MainWindow:5 <>3C 70?8A0BL D09; %1: %2.Cannot write file %1: %2. MainWindow &KE>4E&xit MainWindow 540:B8@>20=85Edit MainWindow&KE>4 87 ?@8;>65=8OExit the application MainWindow$09;File MainWindow$09; 703@C65= File loaded MainWindow$09; A>E@0=5= File saved MainWindow 09B8 &A;54CNI89 Find &next MainWindowX09B8 A;54CNI85 2E>645=85 ?>8A:>2>3> H01;>=0,Find next occurrence of the searched pattern MainWindowAB02:0Insert MainWindow  568<:Mode: MainWindow2B:@KBL ACI5AB2CNI89 D09;Open an existing file MainWindow 0<5=0 Overwrite MainWindowQHexEditQHexEdit MainWindow >B>2>Ready MainWindow"!>E@0=8BL &:0:... Save &As... MainWindow4!>E@0=8BL :0: &G8B05<K9...Save &Readable... MainWindow!>E@0=8BL :0:Save As MainWindow6!>E@0=8BL :0: G8B05<K9 D09;Save To Readable File MainWindowL!>E@0=8BL 4>:C<5=B 2 G8B015;L=>9 D>@<5Save document in readable form MainWindowN!>E@0=8BL 2K45;5=>5 2 G8B015;L=>9 D>@<5Save selection in readable form MainWindow4!>E@0=8BL 4>:C<5=B =0 48A:Save the document to disk MainWindowF!>E@0=8BL 4>:C<5=B ?>4 =>2K< 8<5=5<"Save the document under a new name MainWindowX>:070BL 480;>3>2>5 >:=> 4;O ?>8A:0 8 70<5=K)Show the Dialog for finding and replacing MainWindowb>:070BL 480;>3>2>5 >:=> 4;O CAB0=>2>: ?@8;>65=8O.Show the Dialog to select applications options MainWindowD>:070BL A>>1I5=85 > 181;8>B5:5 QTShow the Qt library's About box MainWindowZ>:070BL A>>1I5=85 @0AA:07K20NI55 > ?@>3@0<<5 Show the application's About box MainWindow 07<5@:Size: MainWindowQHexEdit ?@8<5@ MB> :>@>B:0O 45<>=AB@0F8O @01>BK QHexEdit :><?>=5=BK.1;0ABL Address Area OptionsDialog*&25B 04@5A=>9 >1;0AB8Address Area Color OptionsDialog.(8@8=0 04@5A=>9 >1;0AB8Address Area Width OptionsDialog1;0ABL ASCII Ascii Area OptionsDialog09B 2 AB@>:5Bytes per Line OptionsDialog&25B0 8 (@8DBKColors and Fonts OptionsDialog $;038Flags OptionsDialog2(5AB=04F0B8@8G=0O >1;0ABLHex Area OptionsDialog$&25B ?>4A25G820=8OHighlighting Color OptionsDialog>4A25G820=85 Higlighting OptionsDialog 568< 70<5=KOverwrite Mode OptionsDialog(QHexEdit - 0AB@>9:8QHexEdit - Options OptionsDialog">;L:> GB5=85ReadOnly OptionsDialog2&25B 4;O 2K1@0=>9 >1;0AB8Selection Color OptionsDialog((@8DB 4;O :><?>=5=BK Widget Font OptionsDialog@%1 =0945=KE D@03<5=B>2 70<5=5=>.%1 occurrences replaced. SearchDialog&1@0B=K9 ?>8A: &Backwards SearchDialog&0:@KBL&Close SearchDialog &09B8&Find SearchDialog8&@54C?@5640BL ?5@54 70<5=>9&Prompt on replace SearchDialog0&<5=8BL&Replace SearchDialogF3F3 SearchDialog 09B8Find SearchDialogHexHex SearchDialog0AB@>9:8Options SearchDialogQHexEditQHexEdit SearchDialog.QHExEdit - >8A:/0<5=0QHexEdit - Find/Replace SearchDialog 0<5=0Replace SearchDialog0<5=8BL &2AQ Replace &All SearchDialog$70<5=8BL =0945=>5?Replace occurrence? SearchDialog UTF-8UTF-8 SearchDialog&#40;8BL %1 A8<2>;>2Delete %1 chars UndoStack AB028BL %1 109BInserting %1 bytes UndoStack(0<5=8BL %1 A8<2>;>2Overwrite %1 chars UndoStack ) , hexwalk-1.9.1/src/hexwalk/translations/hexwalk_cs.qm0000644000175100017510000001024114561356105022165 0ustar carmixcarmix @z4 1~\`S%s\Yl{aE l?xx1}\u^V Y $H t q yb  9P z n e} `lM hs l< / s  *.0q ReSRg ! ji&O programu&About MainWindow&pravy&Edit MainWindow&Soubor&File MainWindow&Npovda&Help MainWindow&OtevYt...&Open... MainWindow &Volby&Options MainWindow &Znovu&Redo MainWindow&Ulo~it&Save MainWindow0&Ulo~it vbr  iteln...&Save Selection Readable... MainWindow &Zpt&Undo MainWindow O &Qt About &Qt MainWindowAdresa:Address: MainWindow2Nelze  st soubor %1: %2.Cannot read file %1: %2. MainWindow6Nelze zapsat soubor %1: %2.Cannot write file %1: %2. MainWindow&Ukon itE&xit MainWindowUkon it programExit the application MainWindow SouborFile MainWindowSoubor nahrn File loaded MainWindowSoubor ulo~en File saved MainWindow Vlo~itInsert MainWindow Re~im:Mode: MainWindow0OtevYt stvajc souborOpen an existing file MainWindowPYepsat Overwrite MainWindowPYipravenReady MainWindowSDISDI MainWindowUlo~it &jako... Save &As... MainWindow$Ulo~it  &iteln...Save &Readable... MainWindowUlo~it jakoSave As MainWindow6Ulo~it do  itelnho souboruSave To Readable File MainWindow@Ulo~it dokument v  iteln podobSave document in readable form MainWindow:Ulo~it vbr v  iteln podobSave selection in readable form MainWindow.Ulo~it dokument na diskSave the document to disk MainWindow@Ulo~it dokument pod novm nzvem"Save the document under a new name MainWindowLUkzat dialog pro vbr voleb programu.Show the Dialog to select applications options MainWindow:Ukzat informace oknihovn QtShow the Qt library's About box MainWindow6Ukzat informace o programu Show the application's About box MainWindowVelikost:Size: MainWindow.01 23 45 67 89 ab cd ef01 23 45 67 89 ab cd ef OptionsDialog Oblast s adresou Address Area OptionsDialog4Barva pro oblast s adresouAddress Area Color OptionsDialog.`Yka oblasti s adresouAddress Area Width OptionsDialogOblast ASCII Ascii Area OptionsDialogBarvy a psmaColors and Fonts OptionsDialogPYznakyFlags OptionsDialog(Barva pro zvraznnHighlighting Color OptionsDialogZvraznn Higlighting OptionsDialogRe~im pYepisuOverwrite Mode OptionsDialogPouzePro tenReadOnly OptionsDialogBarva vbruSelection Color OptionsDialogPsmo doplHku Widget Font OptionsDialoghexwalk-1.9.1/src/hexwalk/disasmwidget.h0000664000175100017510000000227715005675407017631 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DISASMWIDGET_H #define DISASMWIDGET_H #include #include "../qhexedit/qhexedit.h" namespace Ui { class DisasmWidget; } class DisasmWidget : public QDockWidget { Q_OBJECT public: explicit DisasmWidget(QHexEdit * hexedit,QWidget *parent = nullptr); ~DisasmWidget(); void capst(void); void refresh(void); private slots: void on_btnDisasm_clicked(); private: Ui::DisasmWidget *ui; QHexEdit * _hexedit; }; #endif // DISASMWIDGET_H hexwalk-1.9.1/src/hexwalk/optionsdialog.cpp0000664000175100017510000001612515005675407020350 0ustar carmixcarmix /* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "optionsdialog.h" #include "ui_optionsdialog.h" OptionsDialog::OptionsDialog(QSettings * appSettings,QWidget *parent) : QDialog(parent), ui(new Ui::OptionsDialog) { ui->setupUi(this); this->appSettings = appSettings; } OptionsDialog::~OptionsDialog() { delete ui; } void OptionsDialog::show() { readSettings(); QWidget::show(); } void OptionsDialog::accept() { writeSettings(); emit accepted(); QDialog::hide(); } void OptionsDialog::readSettings() { ui->cbAddressArea->setChecked(appSettings->value("AddressArea").toBool()); ui->cbAsciiArea->setChecked(appSettings->value("AsciiArea").toBool()); ui->cbHighlighting->setChecked(appSettings->value("Highlighting").toBool()); ui->cbOverwriteMode->setChecked(appSettings->value("OverwriteMode").toBool()); ui->cbReadOnly->setChecked(appSettings->value("ReadOnly").toBool()); setColor(ui->lbHighlightingColor, appSettings->value("HighlightingColor").value()); setColor(ui->lbAddressAreaColor, appSettings->value("AddressAreaColor").value()); setColor(ui->lbSelectionColor, appSettings->value("SelectionColor").value()); setColor(ui->lbAddressFontColor, appSettings->value("AddressFontColor").value()); setColor(ui->lbAsciiAreaColor, appSettings->value("AsciiAreaColor").value()); setColor(ui->lbAsciiFontColor, appSettings->value("AsciiFontColor").value()); setColor(ui->lbHexFontColor, appSettings->value("HexFontColor").value()); #ifdef Q_OS_WIN32 ui->leWidgetFont->setFont(appSettings->value("WidgetFont", QFont("Courier", 10)).value()); #else ui->leWidgetFont->setFont(appSettings->value("WidgetFont", QFont("Monospace", 10)).value()); #endif ui->sbAddressAreaWidth->setValue(appSettings->value("AddressAreaWidth").toInt()); ui->sbBytesPerLine->setValue(appSettings->value("BytesPerLine").toInt()); } void OptionsDialog::writeSettings() { appSettings->setValue("AddressArea", ui->cbAddressArea->isChecked()); appSettings->setValue("AsciiArea", ui->cbAsciiArea->isChecked()); appSettings->setValue("Highlighting", ui->cbHighlighting->isChecked()); appSettings->setValue("OverwriteMode", ui->cbOverwriteMode->isChecked()); appSettings->setValue("ReadOnly", ui->cbReadOnly->isChecked()); appSettings->setValue("HighlightingColor", ui->lbHighlightingColor->palette().color(QPalette::Background)); appSettings->setValue("AddressAreaColor", ui->lbAddressAreaColor->palette().color(QPalette::Background)); appSettings->setValue("SelectionColor", ui->lbSelectionColor->palette().color(QPalette::Background)); appSettings->setValue("AddressFontColor", ui->lbAddressFontColor->palette().color(QPalette::Background)); appSettings->setValue("AsciiAreaColor", ui->lbAsciiAreaColor->palette().color(QPalette::Background)); appSettings->setValue("AsciiFontColor", ui->lbAsciiFontColor->palette().color(QPalette::Background)); appSettings->setValue("HexFontColor", ui->lbHexFontColor->palette().color(QPalette::Background)); appSettings->setValue("WidgetFont",ui->leWidgetFont->font()); appSettings->setValue("AddressAreaWidth", ui->sbAddressAreaWidth->value()); appSettings->setValue("BytesPerLine", ui->sbBytesPerLine->value()); } void OptionsDialog::setColor(QWidget *widget, QColor color) { QPalette palette = widget->palette(); palette.setColor(QPalette::Background, color); widget->setPalette(palette); widget->setAutoFillBackground(true); } void OptionsDialog::on_pbHighlightingColor_clicked() { QColor color = QColorDialog::getColor(ui->lbHighlightingColor->palette().color(QPalette::Background), this); if (color.isValid()) setColor(ui->lbHighlightingColor, color); } void OptionsDialog::on_pbAddressAreaColor_clicked() { QColor color = QColorDialog::getColor(ui->lbAddressAreaColor->palette().color(QPalette::Background), this); if (color.isValid()) setColor(ui->lbAddressAreaColor, color); } void OptionsDialog::on_pbAddressFontColor_clicked() { QColor color = QColorDialog::getColor(ui->lbAddressFontColor->palette().color(QPalette::Background), this); if (color.isValid()) setColor(ui->lbAddressFontColor, color); } void OptionsDialog::on_pbAsciiAreaColor_clicked() { QColor color = QColorDialog::getColor(ui->lbAsciiAreaColor->palette().color(QPalette::Background), this); if (color.isValid()) setColor(ui->lbAsciiAreaColor, color); } void OptionsDialog::on_pbAsciiFontColor_clicked() { QColor color = QColorDialog::getColor(ui->lbAsciiFontColor->palette().color(QPalette::Background), this); if (color.isValid()) setColor(ui->lbAsciiFontColor, color); } void OptionsDialog::on_pbHexFontColor_clicked() { QColor color = QColorDialog::getColor(ui->lbHexFontColor->palette().color(QPalette::Background), this); if (color.isValid()) setColor(ui->lbHexFontColor, color); } void OptionsDialog::on_pbSelectionColor_clicked() { QColor color = QColorDialog::getColor(ui->lbSelectionColor->palette().color(QPalette::Background), this); if (color.isValid()) setColor(ui->lbSelectionColor, color); } void OptionsDialog::on_pbWidgetFont_clicked() { bool ok; QFont font = QFontDialog::getFont(&ok, ui->leWidgetFont->font(), this); if (ok) ui->leWidgetFont->setFont(font); } void OptionsDialog::on_buttonBox_clicked(QAbstractButton *button) { if(button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) { ui->cbAddressArea->setChecked(true); ui->cbAsciiArea->setChecked(true); ui->cbHighlighting->setChecked(true); ui->cbOverwriteMode->setChecked(true); ui->cbReadOnly->setChecked(false); setColor(ui->lbHighlightingColor, QColor("#540c00")); setColor(ui->lbAddressAreaColor, QColor("#545454")); setColor(ui->lbSelectionColor, QColor("#0998c7")); setColor(ui->lbAddressFontColor, QColor("#f0f0f0")); setColor(ui->lbAsciiAreaColor, QColor("#424242")); setColor(ui->lbAsciiFontColor, QColor("#00ff5e")); setColor(ui->lbHexFontColor, QColor("#00ff5e")); #ifdef Q_OS_WIN32 ui->leWidgetFont->setFont(QFont("Courier",12)); #else ui->leWidgetFont->setFont(QFont("Monospace",12)); #endif ui->sbAddressAreaWidth->setValue(6); ui->sbBytesPerLine->setValue(16); } } hexwalk-1.9.1/src/hexwalk/hashdialog.h0000664000175100017510000000230015005675407017233 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef HASHDIALOG_H #define HASHDIALOG_H #include namespace Ui { class HashDialog; } class HashDialog : public QDialog { Q_OBJECT public: explicit HashDialog(QWidget *parent = nullptr); ~HashDialog(); void calculate(QString curFile); protected: void keyPressEvent(QKeyEvent *event); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); private: Ui::HashDialog *ui; bool haltCalc; }; #endif // HASHDIALOG_H hexwalk-1.9.1/src/hexwalk/bytemapdialog.ui0000664000175100017510000001035614570654654020160 0ustar carmixcarmix ByteMapDialog 0 0 833 584 Byte Map 1 QLayout::SetMaximumSize 100 30 Value: false Qt::Horizontal 30 20 Cols: 50 0 QAbstractSpinBox::UpDownArrows true true 80 940 1 QAbstractSpinBox::DefaultStepType 256 100 30 Addr: false false Color map Qt::Horizontal 40 20 Close false ByteMap QWidget
bytemap.h
1
hexwalk-1.9.1/src/hexwalk/converterwidget.cpp0000664000175100017510000001201715005675407020704 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "converterwidget.h" #include "ui_converterwidget.h" ConverterWidget::ConverterWidget(QWidget *parent) : QDockWidget(parent), ui(new Ui::ConverterWidget) { ui->setupUi(this); hide(); } ConverterWidget::~ConverterWidget() { delete ui; } void ConverterWidget::on_decTextEdit_textChanged(const QString &arg1) { if(decValue != ui->decTextEdit->text()) { updateDec(); } } void ConverterWidget::on_hexTextEdit_textChanged(const QString &arg1) { if(hexValue != ui->hexTextEdit->text()) { updateHex(); } } void ConverterWidget::update(QString hexString) { ui->hexTextEdit->setText(hexString); } void ConverterWidget::on_binTextEdit_textChanged(const QString &arg1) { if(binValue != ui->binTextEdit->text()) { QString check = ui->binTextEdit->text(); int i; bool good = true; if(check.length()){ for(i=0;ibinTextEdit->text().length() < 64 && good == true) { binValue = ui->binTextEdit->text(); decValue = QString("%1").arg(binValue.toLongLong(NULL,2),1,10); hexValue = QString("%1").arg(binValue.toLongLong(NULL,2),1,16); blockSignals(true); ui->decTextEdit->setText(decValue); ui->hexTextEdit->setText(hexValue); blockSignals(false); } else { blockSignals(true); ui->binTextEdit->setText(binValue); blockSignals(false); } } } } void ConverterWidget::updateHex() { QString check = ui->hexTextEdit->text(); int i; bool good = true; if(check.length()){ for(i=0;i0x39 && check.at(i) < 0x41) || (check.at(i)>0x46 && check.at(i) < 0x61) ||(check.at(i)> 0x66)) { good = false; break; } } if(ui->hexTextEdit->text().length() <= 16 && good == true) { hexValue = ui->hexTextEdit->text(); QByteArray baValue = QByteArray::fromHex(hexValue.toUtf8()); binValue = QString("%1").arg(hexValue.toLongLong(NULL,16),1,2); if(!isBE) { std::reverse(baValue.begin(),baValue.end()); } decValue= (QString("%1").arg((signed long long)baValue.toHex().toULongLong(NULL,16))); //decValue = QString("%1").arg(hexValue.toLongLong(NULL,16),1,10); blockSignals(true); ui->decTextEdit->setText(decValue); ui->binTextEdit->setText(binValue); qint64 num = (signed long long)baValue.toHex().toULongLong(NULL,16); float *numf; numf = (float *)# ui->floatTextEdit->setText(QString::number(*numf)); blockSignals(false); } else { blockSignals(true); ui->hexTextEdit->setText(hexValue); blockSignals(false); } } } void ConverterWidget::updateDec() { QString check = ui->decTextEdit->text().replace(" ",""); int i; bool good = true; if(check.length()) { for(i=0;i0x39) { good = false; break; } } if(ui->decTextEdit->text().length() <= 16 && good == true) { decValue = ui->decTextEdit->text(); hexValue = QString("%1").arg(decValue.toLongLong(),1,16); binValue = QString("%1").arg(decValue.toLongLong(),1,2); blockSignals(true); ui->hexTextEdit->setText(hexValue); ui->binTextEdit->setText(binValue); blockSignals(false); } else { blockSignals(true); ui->decTextEdit->setText(decValue); blockSignals(false); } } } void ConverterWidget::on_checkBox_be_stateChanged(int arg1) { isBE = ui->checkBox_be->isChecked(); updateHex(); } hexwalk-1.9.1/src/hexwalk/worditemdelegate.cpp0000664000175100017510000000405315005675407021017 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "worditemdelegate.h" #include WordItemDelegate::WordItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {} QString WordItemDelegate::anchorAt(QString html, const QPoint &point) const { QTextDocument doc; doc.setHtml(html); auto textLayout = doc.documentLayout(); Q_ASSERT(textLayout != 0); return textLayout->anchorAt(point); } void WordItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { auto options = option; initStyleOption(&options, index); painter->save(); QTextDocument doc; doc.setHtml(options.text); options.text = ""; options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &option, painter); painter->translate(options.rect.left(), options.rect.top()); QRect clip(0, 0, options.rect.width(), options.rect.height()); doc.drawContents(painter, clip); painter->restore(); } QSize WordItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItemV4 options = option; initStyleOption(&options, index); QTextDocument doc; doc.setHtml(options.text); doc.setTextWidth(options.rect.width()); return QSize(doc.idealWidth(), doc.size().height()); } hexwalk-1.9.1/src/hexwalk/hashdialog.cpp0000664000175100017510000000556515005675407017606 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "hashdialog.h" #include "qevent.h" #include "ui_hashdialog.h" #include #include #include HashDialog::HashDialog(QWidget *parent) : QDialog(parent), ui(new Ui::HashDialog) { ui->setupUi(this); } HashDialog::~HashDialog() { delete ui; } void HashDialog::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Escape) { haltCalc = true; this->hide(); } else { QDialog::keyPressEvent(event); } } void HashDialog::calculate(QString filepath) { QFile in(filepath); haltCalc = false; ui->md5Lbl->setText(""); ui->sha1Lbl->setText(""); ui->sha256Lbl->setText(""); if (in.open(QIODevice::ReadOnly)) { qint64 fileSize = in.size(); ui->progressBar->setMinimum(0); ui->progressBar->setMaximum(100); ui->progressBar->setValue(0); ui->progressBar->show(); QCryptographicHash hashmd5(QCryptographicHash::Md5); QCryptographicHash hashsha1(QCryptographicHash::Sha1); QCryptographicHash hashsha256(QCryptographicHash::Sha256); hashmd5.reset(); hashsha1.reset(); hashsha256.reset(); char buf[4096]; qint64 bytesRead; qint64 totalBytes = 0; while ((bytesRead = in.read(buf, 4096)) > 0) { if(haltCalc == true) { break; } totalBytes+=bytesRead; ui->progressBar->setValue(100.0*totalBytes/fileSize); hashmd5.addData(buf, bytesRead); hashsha1.addData(buf, bytesRead); hashsha256.addData(buf, bytesRead); QCoreApplication::processEvents(); } ui->progressBar->hide(); if(haltCalc == false) { ui->md5Lbl->setText(hashmd5.result().toHex()); ui->sha1Lbl->setText(hashsha1.result().toHex()); ui->sha256Lbl->setText(hashsha256.result().toHex()); } else { haltCalc = false; } in.close(); } } void HashDialog::on_pushButton_clicked() { haltCalc = true; } void HashDialog::on_pushButton_2_clicked() { haltCalc = true; this->hide(); } hexwalk-1.9.1/src/hexwalk/entropydialog.cpp0000664000175100017510000001244315005675407020354 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "entropydialog.h" #include "ui_entropydialog.h" #include #include #include EntropyDialog::EntropyDialog(QHexEdit * hexedit,QWidget *parent) : QDialog(parent), ui(new Ui::EntropyDialog) { _hexed = hexedit; ui->setupUi(this); connect(parent,SIGNAL(fileLoaded()),this,SLOT(refresh())); } double EntropyDialog::blockEntropy(QByteArray * data) { int seen[256]={0}; double p_x; double entropy = 0; for(int i=0;ilength();i++){ seen[uchar(data->at(i))]++; } for(int i=0;i<256;i++){ p_x = double(seen[i])/data->length(); if(seen[i] > 0) { entropy -= p_x*log2(p_x); } } return entropy/8; } void EntropyDialog::refresh() { if(this->isVisible()) { calculate(); } } void EntropyDialog::calculate() { qint64 cursor = 0; qint64 dataSize = 1024; qint64 blockSize = 1024; if(_hexed->getSize() > 32*1024*1024) { blockSize = 4096; } if(_hexed->getSize() > 128*1024*1024) { blockSize = 16384; } series = new QLineSeries(); progrDialog = new QProgressDialog("Entropy calculation in progress...","Cancel",0,100,this); progrDialog->setValue(0); progrDialog->show(); while(cursor < _hexed->getSize()) { dataSize = blockSize; if(dataSize > (_hexed->getSize()-cursor)) { dataSize = (_hexed->getSize()-cursor); } QByteArray data = _hexed->dataAt(cursor,dataSize); series->append(cursor,blockEntropy(&data)); cursor+=dataSize; progrDialog->setValue(int(100.0*(double(cursor)/double(_hexed->getSize())))); QCoreApplication::processEvents(); if(progrDialog->wasCanceled()) break; } progrDialog->cancel(); series->setColor(Qt::green); QChart *chart = new QChart(); chart->legend()->hide(); chart->addSeries(series); chart->createDefaultAxes(); chart->axes(Qt::Vertical).back()->setRange(0.0,1.0); chart->axes(Qt::Vertical).back()->setLabelsBrush(QBrush(QColor("lightgray"))); chart->axes(Qt::Horizontal).back()->setLabelsBrush(QBrush(QColor("lightgray"))); chart->setTitle("Entropy chart"); chart->setBackgroundBrush(QBrush(QColor("black"))); chart->setTitleBrush(QBrush(QColor("lightgray"))); //entropyView = new EntropyChart(chart,this); //entropyView->setRenderHint(QPainter::Antialiasing); ui->entropyChart->setChart(chart); ui->entropyChart->setRubberBand(QChartView::HorizontalRubberBand); ui->entropyChart->setDragMode(QGraphicsView::ScrollHandDrag); //QLayoutItem *item; /*while((item=ui->verticalLayout->takeAt(0)) != NULL) { delete item; } ui->verticalLayout->addWidget(entropyView);*/ connect(ui->entropyChart,SIGNAL(mousePressed(qint64)),this,SLOT(mousePressed(qint64))); connect(ui->entropyChart,SIGNAL(mouseMoved(qint64)),this,SLOT(mouseMoved(qint64))); connect(ui->entropyChart,SIGNAL(rubberBandEvent()),this,SLOT(limitZoomOut())); } void EntropyDialog::mousePressed(qint64 value) { _hexed->setCursorPosition(2*value); _hexed->ensureVisible(); } void EntropyDialog::mouseMoved(qint64 address) { if(address > 0 && address < _hexed->getSize()){ ui->AddressEdt->setText(QString::asprintf("%lld",address)); ui->ValueEdt->setText(QString::asprintf("%3.2f",findClosestPoint(series,address).y())); } } void EntropyDialog::limitZoomOut() { // Limit zoom out to 1.0x QValueAxis *axisX = dynamic_cast(ui->entropyChart->chart()->axisX()); if (axisX) { if(axisX->min()< 0.0) { ui->entropyChart->chart()->axes(Qt::Horizontal).back()->setRange(0.0,axisX->max()); } if(axisX->max()>_hexed->getSize()) { ui->entropyChart->chart()->axes(Qt::Horizontal).back()->setRange(axisX->min(),_hexed->getSize()); } } } QPointF EntropyDialog::findClosestPoint(QLineSeries* lineSeries, qreal x) { QPointF closestPoint; qreal minDistance = std::numeric_limits::max(); // Itera sui punti della serie e trova il punto più vicino for (const QPointF& point : lineSeries->points()) { qreal distance = qAbs(point.x() - x); if (distance < minDistance) { minDistance = distance; closestPoint = point; } } return closestPoint; } EntropyDialog::~EntropyDialog() { delete ui; } void EntropyDialog::on_buttonBox_clicked(QAbstractButton *button) { } void EntropyDialog::on_entropyChart_mousePressed(qint64 ) { } hexwalk-1.9.1/src/hexwalk/bytemap.h0000664000175100017510000000320615005675407016577 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BYTEMAP_H #define BYTEMAP_H #include #include #include #include "../qhexedit/qhexedit.h" class ByteMap: public QAbstractScrollArea { Q_OBJECT public: ByteMap(QWidget *parent=0); void loadBytes(QHexEdit * hexedit); qint64 cursorPosition(QPoint pos); void setCursorPosition(qint64 actpos); qint64 getCurrentPosition(); void setBytesPerLine(int value); bool colored = false; protected: void paintEvent(QPaintEvent *event); void mouseMoveEvent(QMouseEvent * event); void mousePressEvent(QMouseEvent * event); void showEvent(QShowEvent *event); signals: void mouseEvent(); void mousePress(); private: int _rowsShown; QColor _jetColor(int value); int _pxHeight; int _pxWidth; int _bytesPerLine; QHexEdit * _hexedit; qint64 _currentPos; QPoint mPoint; private slots: void adjust(); }; #endif // BYTEMAP_H hexwalk-1.9.1/src/hexwalk/stringsdialog.cpp0000664000175100017510000002254515005675407020351 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "stringsdialog.h" #include "ui_stringsdialog.h" #include StringsDialog::StringsDialog(QHexEdit *hexEdit,QWidget *parent) : QDialog(parent), ui(new Ui::StringsDialog) { ui->setupUi(this); _hexEdit = hexEdit; ui->tableWidget->setColumnCount(2); ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("Address")); ui->tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("String")); ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); ui->tableWidget->horizontalHeader()->resizeSection(1,400); } StringsDialog::~StringsDialog() { delete ui; } void StringsDialog::searchStrings() { QStringList stringList; qint64 cursor = 0; if(!ui->cbBegin->isChecked()) { cursor = _hexEdit->cursorPosition()/2; } int occurrencies = 0; qint64 dataSize = 1024; std::string rawString = ""; bool toAdd = false; bool validChar = false; QElapsedTimer timer; timer.start(); //qInfo()<<"Starting search...\n"; progrDialog = new QProgressDialog("Search in progress...","Cancel",0,100,this); progrDialog->setValue(0); progrDialog->show(); /*while(ui->tableWidget->rowCount() > 0) { ui->tableWidget->removeRow(0); }*/ ui->tableWidget->clearContents(); ui->tableWidget->setRowCount(0); while(cursor < _hexEdit->getSize()) { dataSize = 16384; if(dataSize > (_hexEdit->getSize()-cursor)) { dataSize = (_hexEdit->getSize()-cursor); } QByteArray data = _hexEdit->dataAt(cursor,dataSize); if(ui->cbFindFormat->currentIndex() == 1) { for(int i=0;i 126) { toAdd = false; } else if(test_c ==' ' && ui->cbSpaces->isChecked()) { toAdd = true; } else if(test_c>='a' && test_c <='z' && ui->cbLower->isChecked()) { toAdd = true; } else if(test_c >='A' && test_c <='Z' && ui->cbUpper->isChecked()) { toAdd = true; } else if(test_c >='0' && test_c <='9' && ui->cbNumbers->isChecked()) { toAdd = true; } else if(ui->cbSymbols->isChecked()) { toAdd = true; } if(toAdd == true && (int)rawString.length() < ui->spinBoxMaxLen->value()) { rawString.push_back(test_c); } else { if((int)rawString.length() >= ui->spinBoxMinLen->value()) { ui->tableWidget->insertRow(ui->tableWidget->rowCount()); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,0,new QTableWidgetItem(QString("%1").arg(cursor+i-rawString.length(),1,16).toUpper())); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,1,new QTableWidgetItem(QString::fromStdString(rawString))); //stringList.append(QString::fromStdString(rawString)); occurrencies++; } rawString.clear(); } } } } else { for(int i=0;i 126) { toAdd = false; } else if(test_c ==' ' && ui->cbSpaces->isChecked()) { toAdd = true; } else if(test_c>='a' && test_c <='z' && ui->cbLower->isChecked()) { toAdd = true; } else if(test_c >='A' && test_c <='Z' && ui->cbUpper->isChecked()) { toAdd = true; } else if(test_c >='0' && test_c <='9' && ui->cbNumbers->isChecked()) { toAdd = true; } else if(ui->cbSymbols->isChecked()) { toAdd = true; } if(toAdd == true && (int)rawString.length() < ui->spinBoxMaxLen->value()) { rawString.push_back(test_c); } else { if((int)rawString.length() >= ui->spinBoxMinLen->value()) { ui->tableWidget->insertRow(ui->tableWidget->rowCount()); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,0,new QTableWidgetItem(QString("%1").arg(cursor+i-rawString.length(),1,16).toUpper())); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,1,new QTableWidgetItem(QString::fromStdString(rawString))); //stringList.append(QString::fromStdString(rawString)); occurrencies++; } rawString.clear(); } } } cursor+=dataSize; progrDialog->setValue(int(100.0*(double(cursor)/double(_hexEdit->getSize())))); QCoreApplication::processEvents(); /*if(occurrencies > 100000) { QMessageBox::warning(this, tr("HexWalk"),tr("Too much occurrencies found, stopping search.")); break; }*/ if(progrDialog->wasCanceled()) break; } progrDialog->cancel(); if((int)rawString.length() >= ui->spinBoxMinLen->value()) { ui->tableWidget->insertRow(ui->tableWidget->rowCount()); if(ui->cbFindFormat == 0) ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,0,new QTableWidgetItem(QString("%1").arg(_hexEdit->getSize()-rawString.length(),1,16).toUpper())); else ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,0,new QTableWidgetItem(QString("%1").arg(_hexEdit->getSize()-2*rawString.length(),1,16).toUpper())); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,1,new QTableWidgetItem(QString::fromStdString(rawString))); //stringList.append(QString::fromStdString(rawString)); occurrencies++; } QString message = QString("%1 occurrencies found").arg(occurrencies); QMessageBox::information(this, tr("HexWalk"),message); //qDebug() << timer.elapsed(); //qInfo()<<"done.\n"; } void StringsDialog::on_pbSearch_clicked() { searchStrings(); } void StringsDialog::on_tableWidget_clicked(const QModelIndex &index) { _hexEdit->indexOf("",ui->tableWidget->item(index.row(),0)->text().toInt(NULL,16),false,false); _hexEdit->setSelection(ui->tableWidget->item(index.row(),0)->text().toInt(NULL,16)*2+ui->tableWidget->item(index.row(),1)->text().length()*2); _hexEdit->setCursorPosition(ui->tableWidget->item(index.row(),0)->text().toInt(NULL,16)*2); _hexEdit->ensureVisible(); } void StringsDialog::on_btnNext_clicked() { findStringInColumn(ui->edtFind->text()); } bool StringsDialog::findStringInColumn(const QString& target) { int rowCount = ui->tableWidget->rowCount(); int currentRow = ui->tableWidget->currentRow() +1; for (int row = currentRow; row < rowCount; ++row) { QTableWidgetItem* item = ui->tableWidget->item(row, 1); if (item && item->text().contains(target)) { //item->setSelected(true); ui->tableWidget->setCurrentItem(ui->tableWidget->item(row, 1)); // Scroll to make the item visible ui->tableWidget->scrollToItem(ui->tableWidget->item(row, 1), QAbstractItemView::PositionAtTop); //qDebug() << "Found at row:" << row << "column:" << 1; return true; } } //qDebug() << "String not found in column:" << 1; return false; } hexwalk-1.9.1/src/hexwalk/entropychart.h0000664000175100017510000000244515005675407017664 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ENTROPYCHART_H #define ENTROPYCHART_H #include #include #include QT_CHARTS_USE_NAMESPACE class EntropyChart : public QChartView { Q_OBJECT public: explicit EntropyChart(QWidget *parent = nullptr); signals: void mousePressed(qint64 value); void mouseMoved(qint64 address); void rubberBandEvent(); protected: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void resizeEvent(QResizeEvent *event); void mouseReleaseEvent(QMouseEvent *event); }; #endif // ENTROPYCHART_H hexwalk-1.9.1/src/hexwalk/diffdialog.ui0000664000175100017510000000352015005675407017413 0ustar carmixcarmix DiffDialog 0 0 1320 725 HexWalk - Diff Analysis 9 50 640 650 660 50 640 650 110 10 93 29 Next Diff 10 10 93 29 Prev Diff 210 10 93 29 Exit QHexEdit QWidget
../qhexedit/qhexedit.h
1
hexwalk-1.9.1/src/hexwalk/hexwalkmain.h0000664000175100017510000001147115005675407017451 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef HEXWALKMAIN_H #define HEXWALKMAIN_H #include #include "../qhexedit/qhexedit.h" #include "searchdialog.h" #include "advancedsearchdialog.h" #include "entropydialog.h" #include "binanalysisdialog.h" #include "hashdialog.h" #include "diffdialog.h" #include "tagsdialog.h" #include "edittagdialog.h" #include "stringsdialog.h" #include "bytemapdialog.h" #include "disasmwidget.h" #include "converterwidget.h" #include "optionsdialog.h" QT_BEGIN_NAMESPACE class QAction; class QMenu; class QUndoStack; class QLabel; class QDragEnterEvent; class QDropEvent; QT_END_NAMESPACE namespace Ui { class HexWalkMain; } class HexWalkMain : public QMainWindow { Q_OBJECT public: explicit HexWalkMain(QWidget *parent = nullptr); ~HexWalkMain(); void loadFile(const QString &fileName); signals: void fileLoaded(); protected: void closeEvent(QCloseEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); private slots: void about(); void dataChanged(); void open(); void close(); void openRecent(); void findNext(); bool save(); bool saveAs(); void saveSelectionToReadableFile(); void saveToReadableFile(); void setAddress(qint64 address); void setOverwriteMode(bool mode); void setSize(qint64 size); void showSearchDialog(); void showAdvancedSearchDialog(); void showEntropyDialog(); void showBinaryDialog(); void showDiffDialog(); void showOptionsDialog(); void showConverterWidget(); void showHashDialog(); void showTagsDialog(); void showStringsDialog(); void showByteMap(); void showDisasm(); void toggleOverwriteMode(); void gotoAddress(); void setWidth(); void updateOptions(); void on_signedcb_clicked(); private: void init(); void adjustForCurrentFile(const QString& filePath); void updateRecentActionList(); void setFileActionsEnabled(bool enabled); void updateInfo(); QList recentFileActionList; QString curFile; QFile file; QFile hexfile; QString diffFile; bool isUntitled; QMenu *fileMenu; QMenu *editMenu; QMenu *helpMenu; QMenu *analysisMenu; QMenu *toolsMenu; QMenu *recentFilesMenu; QString currentFilePath; QToolBar *infoToolBar; QToolBar *fileToolBar; QToolBar *editToolBar; QToolBar *analysisToolBar; QString binToStr(QByteArray bin); QAction *openAct; QAction *saveAct; QAction *saveAsAct; QAction *saveReadable; QAction *closeAct; QAction *exitAct; QAction *binaryAct; QAction *optionsAct; QAction *overwriteAct; QAction *hashAct; QAction *diffAct; QAction *tagsAct; QAction *stringsAct; QAction *byteMapAct; QAction *disasmAct; QAction *undoAct; QAction *redoAct; QAction *copyAct; QAction *pasteAct; QAction *cutAct; QAction *saveSelectionReadable; QAction *aboutAct; QAction *aboutQtAct; QAction *findAct; QAction *findNextAct; QAction *advancedFindAct; QAction *entropyAct; QAction *converterAct; void createActions(); void createMenus(); void createStatusBar(); void createToolBars(); void setCurrentFile(const QString &fileName); void readSettings(); void writeSettings(); bool saveFile(const QString &fileName); QString strippedName(const QString &fullFileName); Ui::HexWalkMain *ui; QHexEdit *hexEdit; EntropyDialog *entropyDialog; ByteMapDialog *byteMapDialog; HashDialog * hashDialog; SearchDialog *searchDialog; binanalysisdialog * analysisDialog; AdvancedSearchDialog *advancedSearchDialog; OptionsDialog *optionsDialog; TagsDialog *tagsDialog; DiffDialog *diffDialog; StringsDialog *stringsDialog; DisasmWidget * disasmWidget; ConverterWidget * converterWidget; QLabel *lbAddress, *lbAddressName; QLabel *lbOverwriteMode, *lbOverwriteModeName; QLabel *lbSize, *lbSizeName; QLabel * gotoLbl; QLineEdit * gotoText; QLabel * widthLbl; QLineEdit * widthText; QSettings * appSettings; }; #endif // HEXWALKMAIN_H hexwalk-1.9.1/src/hexwalk/binanalysisdialog.cpp0000664000175100017510000002020615005675407021164 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "binanalysisdialog.h" #include "ui_binanalysisdialog.h" #include #include #include #include #include #include #include #include #include #include BinTableModel::BinTableModel(QObject *parent) : QAbstractTableModel(parent) { } void BinTableModel::populateData(const QList &resultlist) { tm_cursor.clear(); tm_content.clear(); for(int i=0;isetupUi(this); _hexEdit = hexEdit; progrDialog = new QProgressDialog(this); progrDialog->setLabelText("Please wait..."); progrDialog->setModal(true); progrDialog->setRange(0,0); progrDialog->setMinimumDuration(500); progrDialog->cancel(); connect(progrDialog,SIGNAL(canceled()),this,SLOT(kill_process())); binwalkProcess = new QProcess(); #ifdef Q_OS_WIN if(!QFile::exists("binw.py")) { QFile file( "binw.py" ); if ( file.open(QIODevice::ReadWrite) ) { QTextStream stream( &file ); stream << "import sys" << Qt::endl; stream << "import os" << Qt::endl; stream << "sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'binwalk', 'src'))" << Qt::endl; stream << "import binwalk" << Qt::endl; stream << "if len(sys.argv) == 2:" << Qt::endl; stream << " binwalk.scan('--signature', sys.argv[1])" << Qt::endl; stream << "elif len(sys.argv) == 3 and sys.argv[1] == '-e':" << Qt::endl; stream << " binwalk.scan('--signature','--extract', sys.argv[2])" << Qt::endl; } file.close(); } #else QString path = qgetenv("PATH"); path = path + ":/usr/local/bin:/opt/homebrew/bin:/opt/local/bin"; qputenv("PATH",path.toUtf8()); #endif connect(binwalkProcess,SIGNAL(finished(int)),this,SLOT(renderAnalysis(int))); } binanalysisdialog::~binanalysisdialog() { delete ui; } void binanalysisdialog::kill_process() { binwalkProcess->kill(); } void binanalysisdialog::renderAnalysis(int status_code) { if(processType == 0) { BinwalkResult_S binwalkResult; if(status_code != 0) { progrDialog->hide(); QMessageBox::warning(this, tr("HexWalk"), tr("Could not start binwalk.\r\nError: \r\n%1").arg(QString(binwalkProcess->readAllStandardError()))); //qInfo() <readAllStandardError()); return; } resultslist.clear(); QString p_stdout = binwalkProcess->readAll(); progrDialog->hide(); QStringList lines = p_stdout.split("\n"); if(lines.length() < 3) { return; } lines.removeFirst(); lines.removeFirst(); lines.removeFirst(); QString line; foreach(line,lines) { if(line.length()>0){ binwalkResult.cursor = line.section(' ',1,1,QString::SectionSkipEmpty).toLongLong(NULL,16); binwalkResult.datastr = line.section(' ',2,-1,QString::SectionSkipEmpty); resultslist.append(binwalkResult); } } if(model) { delete model; model = NULL; } model = new BinTableModel(this); model->populateData(resultslist); ui->binwalkTableView->setModel(model); ui->binwalkTableView->setColumnWidth(1,750); ui->binwalkTableView->resizeRowsToContents(); ui->binwalkTableView->setSelectionBehavior(QAbstractItemView::SelectRows); } else { progrDialog->hide(); if(status_code == 0) { QMessageBox::warning(this, tr("HexWalk"), "Extraction complete."); } else { progrDialog->hide(); QMessageBox::warning(this, tr("HexWalk"), tr("Could not start binwalk.\r\nError: \r\n%1").arg(QString(binwalkProcess->readAllStandardError()))); //qInfo() <readAllStandardError()); return; } } } void binanalysisdialog::analyze(QString filename) { //QCoreApplication::processEvents(); processType = 0; curFile = filename; if(model) { delete model; model = NULL; } progrDialog->show(); QStringList params; #ifdef Q_OS_WIN params << "binw.py" << filename; binwalkProcess->start("py",params); #else params << filename; binwalkProcess->start("binwalk",params); #endif binwalkProcess->waitForStarted(2000); if(binwalkProcess->state() != QProcess::Running) { binwalkProcess->close(); #ifdef Q_OS_WIN QMessageBox::warning(this, tr("HexWalk"),tr("Could not start binwalk.\r\nError: \r\n%1").arg("Python executable not found")); #else QMessageBox::warning(this, tr("HexWalk"),tr("Could not start binwalk.\r\nError: \r\n%1").arg("Binwalk executable not found")); #endif progrDialog->hide(); } } void binanalysisdialog::on_binwalkTableView_clicked(const QModelIndex &index) { _hexEdit->indexOf("",resultslist.at(index.row()).cursor,false,false); _hexEdit->setCursorPosition(resultslist.at(index.row()).cursor*2); _hexEdit->update(); } void binanalysisdialog::on_closeBtn_clicked() { this->close(); } void binanalysisdialog::on_extractAllBtn_clicked() { processType = 1; progrDialog->show(); QStringList params; #ifdef Q_OS_WIN params << "binw.py"<<"-e" << curFile; binwalkProcess->start("py",params); if(binwalkProcess->state() != QProcess::Running) { binwalkProcess->close(); QMessageBox::warning(this, tr("HexWalk"), tr("Could not start binwalk.\r\nError: \r\n%1").arg("Python executable not found")); progrDialog->hide(); } #else QDir d = QFileInfo(curFile).absoluteDir(); QString curDir=d.absolutePath(); curDir=curDir+"/extracted"; params << "-e" << curFile << "-C"<start("binwalk",params); #endif } hexwalk-1.9.1/src/hexwalk/searchdialog.cpp0000664000175100017510000000676415005675407020132 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "searchdialog.h" #include "ui_searchdialog.h" #include SearchDialog::SearchDialog(QHexEdit *hexEdit, QWidget *parent) : QDialog(parent), ui(new Ui::SearchDialog) { ui->setupUi(this); _hexEdit = hexEdit; } SearchDialog::~SearchDialog() { delete ui; } qint64 SearchDialog::findNext() { qint64 from = _hexEdit->cursorPosition() / 2; _findBa = getContent(ui->cbFindFormat->currentIndex(), ui->cbFind->currentText()); qint64 idx = -1; if (_findBa.length() > 0) { if (ui->cbBackwards->isChecked()) idx = _hexEdit->lastIndexOf(_findBa, from); else idx = _hexEdit->indexOf(_findBa, from,false,false); } return idx; } void SearchDialog::on_pbFind_clicked() { findNext(); } void SearchDialog::on_pbReplace_clicked() { int idx = findNext(); if (idx >= 0) { QByteArray replaceBa = getContent(ui->cbReplaceFormat->currentIndex(), ui->cbReplace->currentText()); replaceOccurrence(idx, replaceBa); } } void SearchDialog::on_pbReplaceAll_clicked() { int replaceCounter = 0; int idx = 0; int goOn = QMessageBox::Yes; while ((idx >= 0) && (goOn == QMessageBox::Yes)) { idx = findNext(); if (idx >= 0) { QByteArray replaceBa = getContent(ui->cbReplaceFormat->currentIndex(), ui->cbReplace->currentText()); int result = replaceOccurrence(idx, replaceBa); if (result == QMessageBox::Yes) replaceCounter += 1; if (result == QMessageBox::Cancel) goOn = result; } } if (replaceCounter > 0) QMessageBox::information(this, tr("QHexEdit"), QString(tr("%1 occurrences replaced.")).arg(replaceCounter)); } QByteArray SearchDialog::getContent(int comboIndex, const QString &input) { QByteArray findBa; switch (comboIndex) { case 0: // hex findBa = QByteArray::fromHex(input.toLatin1()); break; case 1: // text findBa = input.toUtf8(); break; } return findBa; } qint64 SearchDialog::replaceOccurrence(qint64 idx, const QByteArray &replaceBa) { int result = QMessageBox::Yes; if (replaceBa.length() >= 0) { if (ui->cbPrompt->isChecked()) { result = QMessageBox::question(this, tr("QHexEdit"), tr("Replace occurrence?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); if (result == QMessageBox::Yes) { _hexEdit->replace(idx, replaceBa.length(), replaceBa); _hexEdit->update(); } } else { _hexEdit->replace(idx, _findBa.length(), replaceBa); } } return result; } hexwalk-1.9.1/src/hexwalk/stringsdialog.h0000664000175100017510000000257115005675407020013 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef STRINGSDIALOG_H #define STRINGSDIALOG_H #include #include #include "../qhexedit/qhexedit.h" namespace Ui { class StringsDialog; } class StringsDialog : public QDialog { Q_OBJECT public: explicit StringsDialog(QHexEdit *hexEdit,QWidget *parent = nullptr); ~StringsDialog(); private slots: void on_pbSearch_clicked(); void on_tableWidget_clicked(const QModelIndex &index); void on_btnNext_clicked(); private: Ui::StringsDialog *ui; QHexEdit * _hexEdit; void searchStrings(); QProgressDialog *progrDialog; bool findStringInColumn(const QString& target); }; #endif // STRINGSDIALOG_H hexwalk-1.9.1/src/hexwalk/edittagdialog.h0000664000175100017510000000254215005675407017741 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EDITTAGDIALOG_H #define EDITTAGDIALOG_H #include #include "../qhexedit/qhexedit.h" #include "../qhexedit/bytepattern.h" namespace Ui { class EditTagDialog; } class EditTagDialog : public QDialog { Q_OBJECT public: explicit EditTagDialog(BytePattern * bytePtr,QWidget *parent = nullptr); void colorGen(); void loadTag(int row); ~EditTagDialog(); BytePattern * bytePattern; private slots: void on_colorButton_clicked(); void on_applyButton_clicked(); signals: void tagReady(); private: Ui::EditTagDialog *ui; QHexEdit * hexEdit; int editedTagIdx; }; #endif // EDITTAGDIALOG_H hexwalk-1.9.1/src/hexwalk/advancedsearchdialog.cpp0000664000175100017510000002303315005675407021604 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "advancedsearchdialog.h" #include "ui_advancedsearchdialog.h" #include #include #include "resultType.h" #include "worditemdelegate.h" #include #include AdvancedSearchDialog::AdvancedSearchDialog(QHexEdit *hexEdit, QWidget *parent) : QDialog(parent), ui(new Ui::AdvancedSearchDialog) { ui->setupUi(this); _hexEdit = hexEdit; //model = new TableModel(this); } AdvancedSearchDialog::~AdvancedSearchDialog() { delete ui; } qint64 AdvancedSearchDialog::findNext() { qint64 from = _hexEdit->cursorPosition() / 2; _findBa = getContent(ui->cbFindFormat->currentIndex(), ui->cbFind->currentText()); qint64 idx = -1; if (_findBa.length() > 0) { if (ui->cbBackwards->isChecked()) idx = _hexEdit->lastIndexOf(_findBa, from); else idx = _hexEdit->indexOf(_findBa, from,ui->cbRegex->isChecked(),ui->cbCase->isChecked()); } return idx; } void AdvancedSearchDialog::on_pbFind_clicked() { if(ui->cbBegin->isChecked() == true) { _hexEdit->setCursorPosition(0); ui->cbBegin->setChecked(false); } findNext(); } QByteArray AdvancedSearchDialog::getContent(int comboIndex, const QString &input) { QByteArray findBa; switch (comboIndex) { case 2: // hex findBa = QByteArray::fromHex(input.toLatin1()); break; case 0: // text findBa = input.toUtf8(); break; case 1: findBa = QByteArray::fromRawData((char*)(input.utf16()),input.length()*2); } return findBa; } QString AdvancedSearchDialog::binToStr(QByteArray bin) { QString outString; for(int i=0;i127) { outString += QString("."); } else if(bin.at(i) == '<') { outString += QString("<"); } else if(bin.at(i) == '>') { outString += QString(">"); } else if(bin.at(i) == '&') { outString += QString("&"); } else { outString += QString(bin.at(i)); } } return outString; } void AdvancedSearchDialog::findAll() { progrDialog = new QProgressDialog("Task in progress...","Cancel",0,100,this); progrDialog->setValue(0); progrDialog->setModal(true); progrDialog->show(); resultslist.clear(); int ret = 1; Result_S result; int count=0; while(ret > 0) { ret = findNext(); if(progrDialog->wasCanceled() == true) { break; } progrDialog->setValue(int(100.0*double(_hexEdit->cursorPosition()/2)/double(_hexEdit->getSize()))); QCoreApplication::processEvents(); if(ret > -1) { QByteArray preData; QByteArray postData; result.cursor=ret; QByteArray inData = _hexEdit->selectedDataBa(); if(_hexEdit->cursorPosition()/2 > 8) { preData = _hexEdit->dataAt(ret-8,8); } else { preData = _hexEdit->dataAt(ret-(_hexEdit->cursorPosition()/2),_hexEdit->cursorPosition()/2); } qint64 remainingBytes = _hexEdit->getSize() - _hexEdit->cursorPosition()/2; if(remainingBytes > 8) { postData = _hexEdit->dataAt(ret+inData.length(),8); } else { postData = _hexEdit->dataAt(ret+inData.length(),remainingBytes); } if(resultslist.length() > 0) { if(resultslist.last().cursor == result.cursor) { break; } } result.datastr = binToStr(preData) + QString("")+ binToStr(inData) + QString("")+ binToStr(postData); result.hexdatastr = preData.toHex()+ QString("") + inData.toHex() + QString("")+ postData.toHex(); resultslist.append(result); count++; } if(count > 65535) { QMessageBox::warning(this, tr("HexWalk"),tr("Too much occurrencies found, stopping search.")); break; } } QString message = QString("%1 occurrencies found").arg(count); QMessageBox::information(this, tr("HexWalk"),message); setData(); ui->resultsTableView->resizeColumnsToContents(); ui->resultsTableView->verticalHeader()->show(); ui->resultsTableView->setSelectionBehavior(QAbstractItemView::SelectRows); QCoreApplication::processEvents(); } void AdvancedSearchDialog::on_pbFindAll_clicked() { if(ui->cbBegin->isChecked() == true) { _hexEdit->setCursorPosition(0); } findAll(); } TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) { } void TableModel::populateData(const QList &resultlist) { tm_cursor.clear(); tm_content.clear(); tm_contenthex.clear(); for(int i=0;icancel(); try{ if(model) { delete model; } model = new TableModel(this); model->populateData(resultslist); ui->resultsTableView->clearSpans(); ui->resultsTableView->setModel(model); auto wordItemDelegate = new WordItemDelegate(this); ui->resultsTableView->setItemDelegate(wordItemDelegate); } catch(QException &) { qInfo() <<"Exception!!\n"; } } void AdvancedSearchDialog::on_resultsTableView_clicked(const QModelIndex &index) { //_hexEdit->indexOf("",resultslist.at(index.row()).cursor,ui->cbRegex->isChecked(),ui->cbCase->isChecked(),ui->cbFindFormat->currentIndex()==1); _hexEdit->setCursorPosition(resultslist.at(index.row()).cursor); _hexEdit->indexOf(_findBa, resultslist.at(index.row()).cursor - 1,ui->cbRegex->isChecked(),ui->cbCase->isChecked()); _hexEdit->update(); } void TableModel::clearData() { tm_cursor.clear(); tm_content.clear(); tm_contenthex.clear(); } void AdvancedSearchDialog::on_pbCancel_clicked() { resultslist.clear(); } void AdvancedSearchDialog::on_cbCase_clicked() { if(ui->cbCase->isChecked()) { ui->cbRegex->setChecked(true); ui->cbBackwards->setChecked(false); } } void AdvancedSearchDialog::on_cbFindFormat_currentIndexChanged(int index) { if(!ui->cbFindFormat->currentText().compare("UTF-8")) { ui->cbRegex->setEnabled(true); ui->cbCase->setEnabled(true); } else { ui->cbRegex->setChecked(false); ui->cbCase->setChecked(false); ui->cbRegex->setEnabled(false); ui->cbCase->setEnabled(false); } } void AdvancedSearchDialog::on_cbBackwards_clicked() { if(ui->cbBackwards->isChecked()) { ui->cbRegex->setChecked(false); ui->cbCase->setChecked(false); ui->cbBegin->setChecked(false); } } void AdvancedSearchDialog::on_cbBegin_clicked() { if(ui->cbBegin->isChecked()) { ui->cbBackwards->setChecked(false); } } void AdvancedSearchDialog::on_cbRegex_clicked() { if(ui->cbRegex->isChecked()) { ui->cbBackwards->setChecked(false); } else { ui->cbCase->setChecked(false); } } hexwalk-1.9.1/src/hexwalk/entropydialog.ui0000664000175100017510000000566114570654654020222 0ustar carmixcarmix EntropyDialog 0 0 752 564 HexWalk - Entropy Analysis Value: false Address: false Qt::Horizontal 40 20 Qt::Horizontal QDialogButtonBox::Close EntropyChart QGraphicsView
entropychart.h
buttonBox accepted() EntropyDialog accept() 248 254 157 274 buttonBox rejected() EntropyDialog reject() 316 260 286 274
hexwalk-1.9.1/src/hexwalk/advancedsearchdialog.ui0000644000175100017510000001237314561356105021437 0ustar carmixcarmix AdvancedSearchDialog 0 0 775 550 HexWalk - Advanced Find Find UTF-8 UTF-16 Hex 0 0 true Options &Backwards Start from beginning true Regex Case Insensitive Results false true true &Find F3 true Find All &Close Qt::Vertical 20 40 cbFind cbFindFormat cbBackwards pbFind pbCancel pbCancel clicked() AdvancedSearchDialog hide() 360 134 364 162 hexwalk-1.9.1/src/hexwalk/optionsdialog.h0000664000175100017510000000323615005675407020014 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef OPTIONSDIALOG_H #define OPTIONSDIALOG_H #include #include #include namespace Ui { class OptionsDialog; } class OptionsDialog : public QDialog { Q_OBJECT public: explicit OptionsDialog(QSettings * appSettings,QWidget *parent = 0); ~OptionsDialog(); Ui::OptionsDialog *ui; void show(); public slots: virtual void accept(); private slots: void on_pbHighlightingColor_clicked(); void on_pbAddressAreaColor_clicked(); void on_pbAddressFontColor_clicked(); void on_pbAsciiAreaColor_clicked(); void on_pbAsciiFontColor_clicked(); void on_pbHexFontColor_clicked(); void on_pbSelectionColor_clicked(); void on_pbWidgetFont_clicked(); void on_buttonBox_clicked(QAbstractButton *button); private: void readSettings(); void writeSettings(); void setColor(QWidget *widget, QColor color); QSettings * appSettings; }; #endif // OPTIONSDIALOG_H hexwalk-1.9.1/src/hexwalk/searchdialog.h0000664000175100017510000000262415005675407017566 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SEARCHDIALOG_H #define SEARCHDIALOG_H #include #include #include "../qhexedit/qhexedit.h" namespace Ui { class SearchDialog; } class SearchDialog : public QDialog { Q_OBJECT public: explicit SearchDialog(QHexEdit *hexEdit, QWidget *parent = 0); ~SearchDialog(); qint64 findNext(); Ui::SearchDialog *ui; private slots: void on_pbFind_clicked(); void on_pbReplace_clicked(); void on_pbReplaceAll_clicked(); private: QByteArray getContent(int comboIndex, const QString &input); qint64 replaceOccurrence(qint64 idx, const QByteArray &replaceBa); QHexEdit *_hexEdit; QByteArray _findBa; }; #endif // SEARCHDIALOG_H hexwalk-1.9.1/src/hexwalk/converterwidget.h0000664000175100017510000000277615005675407020364 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CONVERTERWIDGET_H #define CONVERTERWIDGET_H #include namespace Ui { class ConverterWidget; } class ConverterWidget : public QDockWidget { Q_OBJECT public: explicit ConverterWidget(QWidget *parent = nullptr); void update(QString hexString); ~ConverterWidget(); private slots: void on_decTextEdit_textChanged(const QString &arg1); void on_hexTextEdit_textChanged(const QString &arg1); void on_binTextEdit_textChanged(const QString &arg1); void on_checkBox_be_stateChanged(int arg1); //void update(QByteArray ba); private: Ui::ConverterWidget *ui; bool isBE=false; bool isSigned=false; void updateDec(); void updateHex(); QString binValue; QString decValue; QString hexValue; }; #endif // CONVERTERWIDGET_H hexwalk-1.9.1/src/hexwalk/searchdialog.ui0000644000175100017510000001220214561356105017740 0ustar carmixcarmix SearchDialog 0 0 436 275 HexWalk - Find/Replace Find Hex UTF-8 0 0 true Replace Hex UTF-8 0 0 true Options &Backwards &Prompt on replace &Find F3 true &Replace Replace &All &Close Qt::Vertical 20 40 cbFind cbReplace cbFindFormat cbReplaceFormat cbBackwards cbPrompt pbFind pbReplace pbReplaceAll pbCancel pbCancel clicked() SearchDialog hide() 360 134 364 162 hexwalk-1.9.1/src/hexwalk/hexwalk.pro0000664000175100017510000000423615005711412017141 0ustar carmixcarmixQT += charts CONFIG += static RC_ICONS = images/hexwalk.ico #Only for Windows: win32:QMAKE_LFLAGS += -no-pie -lstdc++ -Bstatic -static-libgcc -static-libstdc++ -static #Only for Mac: macx:ICON = images/hexwalk.icns ############### VERSION = "1.9.1" QMAKE_TARGET_COPYRIGHT = "gcarmix" QMAKE_TARGET_PRODUCT = "HexWalk" HEADERS = \ ../qhexedit/bytepattern.h \ ../qhexedit/colortag.h \ ../qhexedit/tagparser.hpp \ advancedsearchdialog.h \ binanalysisdialog.h \ bytemap.h \ bytemapdialog.h \ converterwidget.h \ diffdialog.h \ disasmwidget.h \ edittagdialog.h \ entropychart.h \ entropydialog.h \ hashdialog.h \ hexwalkmain.h \ optionsdialog.h \ ../qhexedit/qhexedit.h \ ../qhexedit/chunks.h \ ../qhexedit/commands.h \ resultType.h \ searchdialog.h \ stringsdialog.h \ tagsdialog.h \ worditemdelegate.h SOURCES = \ ../qhexedit/bytepattern.cpp \ ../qhexedit/colortag.cpp \ ../qhexedit/tagparser.cpp \ advancedsearchdialog.cpp \ binanalysisdialog.cpp \ bytemap.cpp \ bytemapdialog.cpp \ converterwidget.cpp \ diffdialog.cpp \ disasmwidget.cpp \ edittagdialog.cpp \ entropychart.cpp \ entropydialog.cpp \ hashdialog.cpp \ hexwalkmain.cpp \ main.cpp \ optionsdialog.cpp \ ../qhexedit/qhexedit.cpp \ ../qhexedit/chunks.cpp \ ../qhexedit/commands.cpp \ searchdialog.cpp \ stringsdialog.cpp \ tagsdialog.cpp \ worditemdelegate.cpp RESOURCES = \ hexwalk.qrc FORMS += \ advancedsearchdialog.ui \ binanalysisdialog.ui \ bytemapdialog.ui \ converterwidget.ui \ diffdialog.ui \ disasmwidget.ui \ edittagdialog.ui \ entropydialog.ui \ hashdialog.ui \ hexwalkmain.ui \ optionsdialog.ui \ searchdialog.ui \ stringsdialog.ui \ tagsdialog.ui DEFINES += QHEXEDIT_EXPORTS \ APP_VERSION=\\\"$$VERSION\\\" DESTDIR = ../bin MOC_DIR = ../build/moc RCC_DIR = ../build/rcc UI_DIR = ../build/ui unix:OBJECTS_DIR = ../build/o/unix win32:OBJECTS_DIR = ../build/o/win32 macx:OBJECTS_DIR = ../build/o/mac win32:LIBS += -lcapstone unix:LIBS += -lcapstone macx:LIBS += -lcapstone hexwalk-1.9.1/src/hexwalk/converterwidget.ui0000664000175100017510000000660015003442601020522 0ustar carmixcarmix ConverterWidget 0 0 280 250 0 0 280 250 true QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea CONVERTER 100 10 171 25 100 40 171 25 10 10 90 25 Hex: 10 40 90 25 Bin: 100 70 171 25 10 70 90 25 Dec: 100 100 171 25 true 10 100 90 25 Float: 10 160 121 24 Big Endian hexwalk-1.9.1/src/hexwalk/worditemdelegate.h0000664000175100017510000000233615005675407020466 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WORDITEMDELEGATE_H #define WORDITEMDELEGATE_H #include class WordItemDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit WordItemDelegate(QObject *parent = 0); QString anchorAt(QString html, const QPoint &point) const; protected: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; }; #endif // WORDITEMDELEGATE_H hexwalk-1.9.1/src/hexwalk/fonts/0000755000175100017510000000000015002001047016067 5ustar carmixcarmixhexwalk-1.9.1/src/hexwalk/fonts/Roboto.ttf0000664000175100017510000051050415002001047020061 0ustar carmixcarmix GDEFQabGPOSHvJ ]GSUB\Q24|OS/2(`cmapTcvt +Tfpgmw`gasp, glyf& lhdmxUz`z headjz6hhea x$hmtxr D8locaw$ maxp> 8 name:apostmdX prepfIT$jdl IJ 0#_<.R 0s *xdNZ`V4<` ! :33fP [ GOOG@f :  ++++:0%+H;.!+XH8(+RC4%+^M<++6,"+q]F2+w\:#+~gP9+ TE6&+ v`K6+ dN:#+ ٲc<+  +<2'+@4)+PA.!+ + E}iD?s_ss/tOtottttu?u_uussst_tttt?uou/ so s,K PXY _^-, EiD`-,*!-, F%FRX#Y Id F had%F hadRX#eY/ SXi TX!@Yi TX!@eYY:-, F%FRX#Y F jad%F jadRX#Y/-,K &PXQXD@DY!! EPXD!YY-, EiD` E}iD`-,*-,K &SX@Y &SX#!#Y &SX#!#Y &SX#!#Y &SX#!@#Y &SX%EPX#!#!%E#!#!Y!YD- ,KSXED!!Y- ,(E- ,)E- ,' SX@cTX(pY#SX TX(pYYY- ,@ ZX)D)DY-(Y%>E^yy  "$%*+3466;<ADGHKMQQTX]^bbddhhjlnnpp  ((++--03_cz|  y$%&'  ^   x     &R 6 @   & \T Thttp://www.apache.org/licenses/LICENSE-2.0Licensed under the Apache License, Version 2.0Christian RobertsonGoogle.comGoogleRoboto is a trademark of Google.Roboto-RegularVersion 2.137; 2017RegularRobotoCopyright 2011 Google Inc. All Rights Reserved.                   p ~%'08@S_g~7Y #%/EOboy?M    " ' 0 3 : < D t  !!!!"!&!.!^"""""""+"H"`"e% &(19AT`h7Y #&0FPcpz>M    % 0 2 9 < D t  !!!!"!&!.!["""""""+"H"`"d%/eD# (%^S~|}rsolkiaYP!ߔyMߪެߞߝߖߓ߇kTQ &@@@Lnnn\d BPt{z|  }~   ,-./012345678wxLM}~yzVWXYZ{|[\]^_opvaaaaa:@?rUJQ~[pJ 5 0 r  a |  ( v  T  u3Xoq$?9dco 9M-a1.? P p !!B!t!!!!""{"###$`% %%&U&','''(A((),)*L*}*+L+,,l,,-Z----..?.u../+/H/e/n///0 0N0Z001,1Y112 2~23A34.4a45B556k667c788l899J9::x:;D;<<= =~=>>i>?1??@8@@A(AmAABMBBC}DDkDETE{EFFFFGRGGH?HnHI&I\IIJ JxJK&KL L|LMwMN]NOOdOP.PQNQQRTRS9ST5TURUVpVW/WuWXJYYZAZ[[a[[[\\\]]]x]]^Y^^_(_~____``[`aasaaab@bbcd9dEdQddddeNeefPfgggghhhhhhi$iiijjjjijkUkl6llmkmn`no@oop8ppppppppppppppppppqqqq2qVqzqqqqrrGrrrrs sstt+t?tuuv?vKw+wx xyyyzQ{{j||^|||}}*}}}~~M~",erˁ4ÃÅv2^}y>ĊK{ċLuԍs!dVgƐ&@?r^J͘f)i gכUv؝9,=3uJ!;ңEUܥYϦ5z%=ĩN Jd(pbv­٭IhѯP=dձoҲ 3DUh{ͳسHĵ%xٶTfʸCK3hֻ''/Z1H_x׽5Le|ؾ6Of}ٿ !8Ng}3Lcz3—/F]tÊáø-DZqĈğĶ ŦŽ.E\hƖƨƿ2=H_kwǎǥDZǽMYe|ȓȟȫ1Hazɑɨɴ2HT`lxʏʥʱʽ/F\sˊˣ˼L̳'>Ul͚̓Ͱ /Wj΁Θή%F]sۊۡ۸/7?Kbj܁ܘܤܰ 5NZfr~݊ݖݞݦݮ+DLTkނޛޣ޼6Le~ߗ߰߸ #:Pi&2>Ul0Ke~-Hco{ 8Qi !-D[t:Tk #/;Ri ,8DPg~ (+k.x!x2Kd},E^jv(4@LXz5AMYeq} %-5=EMf~ #+BJRZbjrz Z&2>JVbnzdw~nieeg&rN5%L~s~~]~^~5~~~M~p~d)Hd.K/j85w?lsz-j5Nv mP10=9VH( X@y9Zm}0\_=]<}`hj[}_ _ i!+)X@q`i[i3ZXeI[fnJZFaB>{CtzzfU5P9oDzDYvN~G[_sO")"hDa]~e[7bjy*2{^Z~o^'8  qsqg>2xEMZRqd.`Pc%mzn%e)Me`,Q]W_zyBHJ*d{1> 2CP/M,Szd'Yla[. XR,(dYgx6XMdd/hMg'+V+(F   #PLqg[ .qg[$~+2uGdtgqf, Vca ~D>1qm9*),4\gojo/? Z/,O>]hi:;.9@)WYdV6+1IRyDu?ve# Fd/, o)) \04%4%@? `0$Oh<$iFWZ~RDflfY;6`z[Uv+~_"*t H]Ozh:g&TdcjYjE?:b ed>/+Ln\<n<<<<_3[5\BzPU`Br0NNc#G+ T&1g|t&( CJY\`T+c C30 g`g>?g``ur&|`A'Ot(Y$. ?GN'"(j=QN{KvP Gy 7#`_ &a&j=j^?G`30B"(>6[V:OI:dL$=|`Pn^iiP6[V:OI~~~~X>ke.Jg`;s#wv7~_pPx ;}2\[[Z[=]}`yWg9 `05%]]188888885w----vvvvv0000ZmZmZmZmZmZmZm0\=]=]=]=]j[[[[[iiii8Zm8Zm8Zm5w0\5w0\5w0\5w0\?_=]=]=]=]=]sz}`sz}`sz}`sz}`h-----j5NNWNNjjjjv[v[v[ScP _P _P _P _P _1 1 1 0i0i0i0i0i0i=+VXVXVXzNv[&(|``````|t|t|t|t+ |`|`|`|`cccc+T```JJJ C C C C&(&(&(|t|t|t|t|t|t1+ + #G#G#G8)7-=2f8V-v 19-dPc]s[!)][]zsP--j5$M8sv 5w19Zm=][}0\)=][ _R=+=+=+eg08Zm=]Z_ Y[ IvPX5w0\.-C -8Zm8ZmzN=]]7b7bC PXv[qg[qg[dMdMMMzYg6_8Zm8Zm8Zm8Z8Zm8Zm8Zm8Zm8Zm8Zm8Zm8Zm=]=]=]=]==]=]=]--v[v[v[Gv[v[v[~e[~e[~e[~e[~e[0i0i_1(zYgs[/?hs[8'.9)Pcl?~]~^~5~dsz}`j8Z9_=)- v3U0i+}?_?_hNjv }P _1 0!!=+VX2"c$gP#GT`\&(+ T&+  C+T"P`\|`&(T&?G|`+ "g`9 ` C111+ 8Zm=] bDFLT*cyrl*grek*latnAZE CRT FRA MOL \NAV .ROM \TRK       c2sc*ccmp"dligdnomfrac ligaligaligalnumloclloclloclnumronumpnumsmcpss01ss02ss03ss04ss05ss06ss07tnum         F jrH$> &zX6V >zst?@ABCD4  !"#$%%.pfJOSSU^ ee.[]^XUWVY\ZJKLMNOSefp.pfLNMKOeSJU^ .Z^XUWV[Y]\OJKLMNSeff pp   nooIKj EGFHIghijklm '(+35FGHKSTU./ ,-/O6oK*  XXJJW@ PJP MJMJ{    OX 26Z@&hVvlZ( h^<"vlbXN$|r$ mkiog$ ljhnf$ _][aY$ ^\Z`X$ G.,-+ &$ usq ,& ec   ,& MK$  I,& ;97 ,& ! %$ trp 4.("db   4.("LJ$  ,& FH ,& :86 ,&  %)+-/46;=>EIKMOTV[$]^*,-./015a_bc` MNIrZB*IrZB*N"$'Mq3210(ds0ut/rwR   ; v123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abdefghijklmnopqrstuvwyxz{|}~    EFGHIJKLMNOPQRSTUVWXYZ[\]^0468:<BDFJMZ|~   !#&(*,.~ q3210(sutvrwR   ; /0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwyxz{|}~    %&'()*+,-./0123456789:;<=>eg/3579;ACEIKLXYz{}   "$%')+- }  2LDFLTcyrlgreklatncpspkern[v!b  &% x -&~| v8{q?;QyVD3DK>,r'jzb m %),4 8>EGIILLQTVV"ZZ#\^$'()-./02347>?@ABD  F  GH.0K35N77Q99R;;SCDTTTVVVWXXX\^Y\cefgilm00p33qEErGHsz{u}}wx  "*/8CGMOTTeimoxx  "#$%&(25;BDEFJPQS_a  eghFoHHJW__bbddpuww{|#       " !   !$     #         $    #"      " " " !   !       t !!%%&&''(()).. // 0033448899 ::;;<<== >>EEFFGGIILLQRSSTTVVZZ \\]] ^^"  %      ..//"00334455 77 99 CCDDXX\\]]^^!!!# $ 00 33EEGHz{}}             "" ## $$ %%&&''(())**/0 11#28CG MOTT eefi$mo xx#     "  %"           % % %   !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEJJKKLLMMNNOOPPQQRRSSTTUUVVWW__bb dd pp qq rr ss tt uu ww{{"|| "        # #9999x9r99 8885.5 5 445 5 8433F2x2Z2<11d1J1000//.//.^0.P------j08,,*989+,**)H((-(%/#"!!!!f0tNN5 L1v5 5 ,5 5 5 N5 N*TJ - 0 T  0 r H 9.^2Z-0,*J1-4445 1-5 5 8J1-9999R888882x9999999888885 5 5 5 5 888881d00000000000/.^.^.^.^.^--9090908888880808080805 /5 5 5 5 5 444445 /5 /5 //8.^8.^8.^.P.P.P2x2x2x2<1d-1d1J1J1J985 5 81d99 81J5 5 45 5 842x1d15 1d/.^-.^8,*5 5 44,99 ,*85 5 8482x100.^0--0J-2<2<2<1d-9995 /90802Z-81d-5 1-5 909080001-8.^.^0,-,-,-90909090909090909090909080808080808080805 5 8.^8.^8.^8.^8.^8.^8.^.^1d-1d-1d-2x,*J/N,*41d5 /9085 8.^.P9 0885 /4445 /5 /840.P2x2Z-2Z-2<1J8 %*,- /6 88:?EFIJLL OO!QT"VV&XX'Z](__,-./0589;=@HITdehjm  p  qr""u.0v35y77|99};;~CDTTVVXX\^0033EEGHz{}}  "%''))/8CGMOTTeimoxx!"(89:;<>@GJPRVXYZ^deghrt  xz{FHHJW__puww{|1LxLx (L O P SW[     KMOQSUW_     "Z\]4DQ^p#qsu  :PJcemLMG H I K U :   " :B HJQ` a k mp                               7 9 ; = ? A C E Y [ ] a z    :HJQmpz EGHIJ KSUZ ]   "BQ`ac e kp        13  # 23456789CDEFGL MNOPQRSZ[\]mnostuvx               !#%')+-/13579;=?ACEKMOQSUWY[]_aq s u       vGHIKSU"B`ak19CDEFGPQRSZ[\]mno 79;=?ACEKMOQSUWY[]_a   :HJmz# Z] :m#qsu9QRT\  +46:<>DSUW\^m |8=9E"$prtw$8<39CEPQ]fopw18<=39CEPQ]flop"$prtwj%8:<=  39:CEGHIJLPQ]bdflmop"$     "$&(*,.024prtwyz.08@JM_il58:<=39CEP]bdflo"$prtw%'+358:= !9AEGHIJMPQXbdfjlnopEFHI"$-   "$&(*,.024JLNPRTVXZ\^`prtwyz?8:<=\349:CDEGI]^bdlm"$prtwy(8Z]  9:ELcm#qsuw :ILbdlm 8:<=QRTZ\]  +3469:<>CDEGISUW\]^bcdlm"#$ pqrstuwy|"Z\]^4D^#&(*qsu \^4D^&(*\^4D^&(* GHIJ KSUZ ]  "B`ak        13  # 23456789CDEFGL MNOPQRSZ[\]mnostuvx               79;=?ACEKMOQSUWY[]_aq s u        :mAGHIKU"B`ak79;=?ACEY[]a< JYZ] #cegikmoqsu| GHIKUYZ]"B`ak#79;=?ACEY[]acegikmoqsuGHIKQRSTUYZ]"+6<>BSUW\`ak#  79;=?ACEKMOQSUWY[]_acegikmoqsu|(%  "$&(*,.0248%<= 3C]"$ "$&(*,.024prt@'+35!AjEFHI-  JLNPRTVXZ\^`?'+35 !AjEFHI-  JLNPRTVXZ\^`/Vm[m|}+KaFRIh < .0<8:j@IJ L?MX_c1e_i lm0n  Z]#qsu.9bdJ S KMOQSUW_JX2[   :cm@GHIKU"B`ak79;=?ACEY[]aM  AGHIKUa"B`ak79;=?ACEY[]a:m  :cem.9bd[1 AJVXam| 1:JLMXb d mn1 A Va1 AVa13V[m|(M~gejs^t}y}  .08}:@J|LMlX_kcei{lmn18:=9E"$prtw38:;=9E3 "$2345678MNOprtwX_[T1[  :JXcemn1IJLbdl%V.8EGHIKSUVYZ]VV V"9BE`ak3VVVVVVVVVV#2345678MNOVVVVVV V V!"V#$V%&V'(V)*V+,V-.V/0V12V34V579;=?ACEKMOQSUWY[]_acegikmoqsuwVJ[l AaM l#X[:IQJ{LMXbudlOm :;= "$prt[ 89Ew $H %&'()*+,-./0123456789:;<=>eg/3579;ACEIKLXYz{}   "$%')+- } d( q 9 а а  а  EX/>YEX/>Y9999 9 9 01!!!!5!(<6 }wx^^^{ 0EX/>YEX / >Y +X!Y901#3462"&[ 7l88l7-==Z;;# / 9/а01#3#3ooxwEX / >YEX/>YEX/>YEX/>Y 9|/ +X!Yаа а / +X!Y а аааа01!##5!!5!3!33#3##!!PP ERRRREPEfb``f#bn0+iEX / >YEX"/">Y" 9  а а  +X!Y +X!Y"а"&а") +X!Y014&'&&546753#4&#"#5&&53326Xÿrw~1Q˷ӹw\~3Aѡ͍{nfycwjƋ~i &48|EX/>YEX#/#>Y а / +X!Y +X!Y#а/#* +X!Y1 +X!Y5#95/7#97/014632#"&5326554&"46  &5326554&#"'iXJGWVV;XJHVWIGYiiGNebUINffRуGOecUJOdcTBrBe'3EX / >YEX/>YEX/>Y" 9* 9"*9*"9 9 9 99 +X!Y!9 1 +X!Y01467&&54632653#'#"$2776654&#"euaBĨYokDD{aJgדz!"vvD2dLR`iuvGXRO}sBEKp{v`S0W>CYog!/9/01#3*k //0147&'y& Uu&yOTFzp4U~`qJT&*7k //01'654'77u'Xb'wEgIqv/ iPqIdaU EX/>Y/  /01%73%'J.. ).|}ZpXn[^ [N4  /а  +X!Y01!!#!5!3jj 4̯4 / +X!Yа/01'6753i^cHe% / +X!Y01!5! v EX/>Y +X!Y017462"&9r;;r9a0@@0.>>/EX/>Y01#3`}-s  ;EX / >YEX/>Y  +X!Y +X!Y01#"532'4&#"3267 m53A8 :EX/>YEX/>Y9/ +X!Y901!#5%3ٺщ]3OEX/>YEX/>Y +X!Yв9  +X!Y в901!!56654&#"#4$32!3FpUszۅ0UrձY^&{EX / >YEX/>Y 9/]q/]_r  +X!Y  а& +X!Y&9а +X!Y013665#"#4632 $5332654&'#x{jxf~2rq_,&޶s5P JEX / >YEX/>Y 9/ +X!Yа в 9 9013##!53!ʺiRm9(-dEX/>YEX / >Y +X!Y 9/ +X!Y9 а  +X!Y01!!632#"&'332654&#"J,kvyE1֫s?ֽ}5(!QEX/>YEX / >Y +X!Y 9/ +X!Y  +X!Y01#632#"55%"32654&O"sǾWS_y}AGprVDܸM%3EX/>YEX/>Y +X!Y901#!5!%YHp!+dEX/>YEX / >Y' 9'/'] +X!Y'9'9  +X!Y" +X!Y01#"&5467&&546324&"326"264&sbrrap헛mޅ4m01wv10lztoތd$[EX / >YEX/>Y 9/ 9 +X!Y +X!Y  +X!Y01#"&&546632#5366%26754&#">:`~fö$']$yzET|ሒ|6WyrTJ仙mD&sEX / >Y01)UD's EX/>Y01HzJEX/>Yа/015r2{z'/а/ +X!Y +X!Y01!5!!5!BB.KEX/>Yа/0155kVKv!SEX/>YEX / >Y +X!Y99  +X!Y в9016677654&#"#6632462"&e2MTnif|㶽ӢmI7l88l7wT_miwl[˱lQ-==Z;;j;5Bl2/EX/>Yв29/99 +X!Yа2 +X!Y*а*/# +X!Y@ +X!Y01#"'#"&766323267!"3267#"$$3232677&#" ص56JyiQP4qȴ 'Z<%>i |dQXYEX/>YEX/>Y9/ +X!Y 901!#3#!,-M|PXEX/>YEX/>Y9/ +X!Y9 +X!Y +X!Y013!2#!265!%!2654&#!tdv="~f+!z~lxmwGEX / >YEX/>Y а  +X!Y +X!Y01# 54$32#&&#"3267ɑ Ʋr64宜葴 ;EX/>YEX/>Y  +X!Y  +X!Y013!232554'$]ʦUF QEX/>YEX/>Y 9 / +X!Y +X!Y +X!Y01!!!!!!c-w,/ BEX/>YEX/>Y 9 / +X!Y +X!Y01!#!!!:c}zlEX / >YEX/>Y а  +X!Y +X!Y 9/]]?O] +X!Y01%#"$'5!2#!"3267!5!J36l5ji4Ij!w09G gEX/>YEX / >YEX/>YEX/>Y а / ] q q/ ] r +X!Y01!#!#3!3"_rwEX/>YEX/>Y01!#3w5/EX/>YEX/>Y а  +X!Y013#"&533267 w} tEX/>YEX/>YEX/>YEX / >Y9@JZjz]9]9@6FVfv ]01#33#j0})EX/>YEX/>Y +X!Y01%!!3jRYEX/>YEX/>YEX/>YEX/>YEX / >Y99 901 3###"#\P7de L 9EX/>YEX/>YEX/>YEX/>Y9901!##33#߿bgv ;EX / >YEX/>Y  +X!Y +X!Y01#"$'54$32'#"327   лӹ9iBk O 9  EX/>YEX/>Y 9 / +X!Y +X!Y01#!2#%!2654&'!iY:坑m "O#$9EX/>YEX/>Y9 +X!Y  +X!Y01%#"$'54$32'#" 7yHP  ;tVy9iBkc9EX/>YEX/>YEX / >Y9/ +X!Y 9 +X!Y01!#!2#!2654&'! Vn'Mֈ2 |Pr&d'(9EX/>YEX/>Y а +X!Y&9& +X!Yа" +X!Y01&&54$32#4&#"#"$&533264&VܖkcãGϘty}oY{f{os|u1/EX/>YEX/>Y +X!Y01!#!5!,-f=9EX/>YEX / >YEX/>Y +X!Y01"'332653"&89EX/>YEX/>YEX/>Y901%3#3P=YEX/>YEX/>YEX/>YEX / >YEX/>Y 9 9  9017373#'#3) (ɯP%oo9 kEX/>YEX / >YEX/>YEX/>Y9@ ]9@ ]9 9013##3]43.."81EX/>YEX/>YEX/>Y9013#3e| oVz FEX/>YEX/>Y +X!Y9 +X!Y 901%!!5!5!9A $// +X!Y +X!Y01#3!! yx(8/EX/>Y013#(` '// +X!Y +X!Y01!!53# zH@'9EX/>Yв9/01#3#+*)iEX/>Y +X!Y01!5!l9#/]/а/]01#3ڟ&mN(|)*9 EX/>YEX/>YEX/>Y9 9 / +X!Y 9 +X!Y # +X!Y01!&'#"&54$3354&#"#46632%2675# ( tqcsv& W#t RUasdGQXXZHWb f9/EX / >YEX/>YEX/>Y9 9  +X!Y +X!Y01#"'#36 '4&#"326 p pṒPUӑ}ËΪ,\NK9EX/>YEX/>Y +X!Yаа +X!Y01%2673#"546632#&&#">cvntٔixZ]d'ڮi#_f9/EX/>YEX / >YEX/>Y 9  9  +X!Y +X!Y014323#'#"5327&#"_쿾o oƼQS&/4t4О]Nl9EX/>YEX/>Y9/]  +X!Y +X!Y9 +X!Y01"5546632!3267"!5&&M{݁#b3qp!"MPBXʣ<e9EX/ >YEX/>YEX/>YEX/>Y +X!Y  +X!Yа013#5354632&#"3#竫@? /5Zbo ibrU`VN$"%&9" EX/>YEX/>YEX / >YEX/>Y9 9  +X!Y9 +X!Y" +X!Y0143273#"&'732655#"7327&#"`o u;`wo뺖RU&+xdWo]2џJ 9/EX/>YEX/>YEX/>Y9  +X!Y0163 #&&#"#3E{WioZ&}5up`Nh ? 9EX/>YEX/>Y а / +X!Y01!#3462"&U7l88l7:->>Z<<KY K9EX / >YEX/>Y +X!Y а/ +X!Y01!"'532654632"&K=4 4>A75688l6:ICS,?>Z<<  uEX/ >YEX/>YEX/>YEX / >Y9@:JZjz ]9@6FVfv ]01#373#tcQ[y_wd<UEX/ >YEX/>Y01!#3UxNx9EX/>YEX/>YEX/>YEX / >YEX/>YEX/>Y 9 9 +X!Y01632663 #4&#"#4#"#:wR6vdj}g C:xN`+ts{h2:NT 9EX/>YEX/>YEX/>YEX/>Y9  +X!Y0163 #&&#"#;|WioZ&:}5up`N:[4NE 9 EX/>YEX / >Y +X!Y +X!Y0146632#"532654&#"[}ߏyﺧ' 2 Dz`Np9 EX / >YEX / >YEX/>YEX/>Y 9 9  +X!Y +X!Y01#"'#3632'4&#"326q q㹜TS}xԕ_`Nm9EX/>YEX/>YEX/>YEX / >Y 9  9 +X!Y +X!Y0143273##"5327&#"_op鹝WX&)m&x1ԒN G9EX / >YEX/>YEX/>Y  +X!Y 901&#"#3632*1A[6:}_N&d '(9EX / >YEX/>Y 9  а  +X!Y +X!Y!а$ +X!Y014&$&&54632#4&#"#"&&53326qO᯸庁berjS蹂qriKSVyW\`]mU V@a9EX/>YEX/>YEX / >Yа/ +X!Y  +X!Yа013#327#"&5#536A 8IE|~@aAA :T 9EX/>YEX / >YEX/>YEX/>Y 9  +X!Y01%#"&'33273#(lѭFkE!:89EX/>YEX/>YEX/>Y901%3#3 |x?:+: ` 9EX/>YEX/>YEX / >YEX/>YEX/>Y 9 9 901%3##33JйŖƸ;4:*): SEX/>YEX / >YEX/>YEX/>Y 9 99 9013##3mmk#K:J9EX/>YEX/>YEX/>Y9  +X!Y 013#''526773Me#E2^i")~+ Len.X: FEX/>YEX/>Y +X!Y9 +X!Y 901%!!5!5!:yU4@=29 // 9/] +X!Y901&&554#5255667x&ѧ2з3sCYZBD/EX/>Y01#3Dr=29 // 9/] +X!Y9016547&55'73"&ԵA TRCs2ʼ2"D9EX/>Yаа/ +X!Y +X!Y 01#".#"4632265ﻉHJ*NTL@L_ 5$k^@ t_fM 3 9/EX / >Y +X!Y9013#"&462 7l88l7L->>Z<<i &!T"#9EX/>YEX / >Yб +X!Y ааа +X!Y01%2673#5&554753#&&#"JdƐʱiyY~"#!Ԗi#[h!"#9EX/>YEX/>Y9/_rq] +X!Y +X!Yаа ааа +X!Y01!!536675'#534632#4&#"!>M(2 Ⱦ޿oi ?nܚ[ `ݝԱk|}i[*A+,9'EX/>Yа/ +X!Y' +X!Y01%#"''7&547'7632726654&&#"Oϟhpğnf`sqqpqspΣxyğ{{z{{zyx$q9EX/>YEX / >Y 9 9/а/ +X!Y  +X!Y аааа013!!!!#!5!5!5!34D>0}|B|}M/EX/>Y+013#3Zy4D#EF9#5/EX#/#>Y#9? +X!Y?9а +X!Y0#907 +X!Y709#'а#* +X!Y01#"&'&5732654&'.547&&54$32#4&#"%&'6654&yEHpFѶ]BG 8q:ZKPK6,NTU1d89qu`Yi>0ooX1d}sbEPAPHaeEFPBReEXme/ +X!Y аа/01462"&%462"&e7l88l77l88l7[-==Z<<+->>Z<<[*9':;9'а'6EX./.>YEX6/6>Y6.9/] .69 /  ] 9 +X!Y +X!Y 96  +X!Y.' +X!Y01#"&554632#4&#"3265% $54$#"4$ #"$__[^ll^\]@sKJUӶnӤcU{qxTeۦ%"ܪZX%o&'9EX/>Y&9/в9 9 / +X!Y 9 +X!Y   +X!Y01&'#"&5463354#"'4632%2675#j Lwl|EO+XpSY"&V|gox463 gaQ{(?3^fd&Dw /а/ +X!Y01#!5!{?wZ4=6>?96 а6а6#EX/>YEX / >Y +X!Y +X!Y 9 /" 9"/""]5 "95/5]55] +X!Y(59 /а//"= +X!Y014$ #"$732$54$#"#!2#&4'&''36654&##ZKJs졠zsHXNdZXǬۦ"!Q}{A2=V&$`B6I=.9/ +X!Y01!5!.`| 1EX/>Y а /  +X!Y +X!Y014632#"&2654&#"jhhi6JJ67KKhijG9:KOlJa H /EX / >Y а  +X!Yа  +X!Y9 ]01!!#!5!3!5!lACVb BV9EX/>YEX/>Y +X!Yв9 +X!Y в901!5654&#"#46 !,m@& '(9EX/>YEX/>Y9/o]?q/]_r +X!Y 9& +X!Y&99  +X!Y0132654&#"#4632#"&5332654'# TJH?F9K|FBOCFIXf=0-:3)b{yh7[)j}~k-<<3q{#/]а/]/013#<`:Q 9EX/>YEX/>YEX/>YEX / >Y +X!Y  9013273#'#"'#Sgt> ]Q: sI+C@ + 9EX/>YEX/>Y901!#"$54$3!T  PkyI  9/ +XY01462"&9r;;r90@@0/??tMB9EX/>YEX/>Y#]9 +XY 01!#'2654&'7 OW@b 4aqk4/,* zA9EX/>YEX/>Y9/ +X!Y901#5%3cY9uz' B9EX/>Y 9 / +X!Y +X!Y014632 &5326554&#"z̾aTS_aSQ`cJ¥drseNcrnafx& jU'' EX/>Y01P''EX / >Y01o'' 21EX!/!>Y01DxM"Y #$9 /EX!/!>Y!99  +X!Y в9! +X!Y0132653#"&547765"&5462L)` tmd}֠mB7l88l7jvc%msq[ɳqN=->>-,<<W{EX/>YEX/>YEX/>Y9/ +X!Y +X!Y 9 /  +X!Y +X!Y901!!!#!!!!!!WpMNa)xYc 8/ 9 / 9 9 9в 9  017YJwIIwJwIPO{O{{Qv )h*+9а&EX/>YEX/>Y9#9#а +X!Y$а& +X!Y01#"'#7&54$3273&#"4'327 a ֔g,b4f8[yRhSB}co @] Y 9 EX/>YEX / >Y 9/ 9/  +X!Y +X!Y01!2#!#!2654&'`wi~Cޗx{j*k!+,9EX/ >YEX/>YEX/>Y 99 +X!Y 9#9( +X!Y01!#4632#"&'732654.54654&#"DϺŀKV˶Q&+15kqJWhXW볟}E3_L, ,^R4`QYT^kN|N*5=ʲ>?9.а9EX/>YEX/>YEX/>YEX/>Y9 9 / ] +X!Y 99:9:/::]! +X!Y% +X!Y(9+а / +X!Y601 '#"&5463354&#"'46326632!3277%2675#"!54&A⍧nhis2?i(y/@ H2ujPsV^Uk{nQSSOWsLyJ6nSM]4~-,+V,-9(EX/ >YEX/>Y9/9" +X!Y( +X!Y01#"&&546632&''7&'77'&&#"32654u؆ypρy0I9ﯽIh!\}g]rÍc[16d8=IG- S9а/ +X!Y +XY +XY +XY +XY01!5!462"&462"&-9r;;r99r;;r9X:0@@0/>>0@@0.??[z4&e'(9а#EX/>YEX/>Y# +X!Y!#9!а +X!Y9 014663273#"'#7&&#"4'3265[{n^I|f|hVJ|d͹aW>HfW7B'*͚#˕7o ڵoP۹`'f9 /EX / >YEX/>YEX/>Y 9 9  +X!Y +X!Y01#"'#3632'4&#"326'qq㹜TS}ʄԕ_"/EX / >YEX/>YEX/>Y]/]9/ +X!Yв 9 9а +X!Y   +X!Y01##'#"55432!5!533327&#" oƼ쿾olQS/t4/ОmEX/>YEX/>Y9/9/а +X!Yаа +X!Y а а013##!##533!3!5!#b#_""U:EX/>YEX/>Y01!#3U:?: iEX/>YEX/>YEX/>YEX / >Yа/]]/]] +X!Y 901##333#k[<3:6" ]EX / >YEX/>Y 9/а +X!Yа +X!Yа а а 01%!!573iKT}Tϝ*}*"  KEX / >YEX/>Y 9/а +X!Yааа а017#573le={=7{7K[9EX/>YEX/>YEX/>YEX/>Y  +X!Y 9901#"'73255#3=6%=3GjhKNc 9EX/>YEX/>YEX / >YEX/>Y9  +X!Y +X!Y01632#"'73254&#"#7 t˳=6#Bo}Q: :h #$%9EX / >YEX/>YEX/>YEX/>Y +X!Y9/ +X!Y +X!Y +X!Y  +X!Y01!!#"&'4632!!!!!27&#" r|F-wqfml5,aN ,4569&а0EX/>YEX / >YEX/>YEX/>Y 91 91/ +X!Y +X!Y 9 9$а* +X!Y-01466326632!327#"&'#"532654&#"%"!54&ayێ=Ap2xJ?>dž-c'udfstl~pdcq0 ζ֣} 3 9EX/ >YEX/>Y  +X!Y0136632&#";T(3 `]^ !9EX/>YEX/>Y9/  +X!Y +X!Y +X!Y01 5!5#"'763 '27!ݥ=/.dꧩYEu: XT"Kt 9EX/ >YEX/>YEX/>YEX/>Y +X!Y  +X!Yаа +X!Y01##"'73265#5356632&#"3`˨=2CAG;T&< h\x ze7%U&'9"EX / >YEX/>Y 9а  +X!Y" +X!Y01#"$'54$326653#"32 `]aϽӹ>dA=k[#U$%9EX/>YEX/>Y9 а +X!Y! +X!Y01466326653#"5326554&#"[{ψG@I|񹧍'd33 ۹M 9EX/>YEX/>YEX / >Y 9а  +X!Y016653"'33265saI ~&a9EX/>YEX / >YEX/>YEX/>Y9в9 +X!Y01#'#"&'33273>5lѭFDDkE#HlKe: )EX/>YEX/>Y  +X!Y01#"'73265e;4CAH:m h\bOh9EX/>YEX/>Y 9 / +X!Y9 +X!Y  +X!Y012'"&55!&&#"'6267!|z{IbO$tl}5}4/а/]9//в901#'#53p  /а/]9а/0173#53qU  .p /01 ' 9/]  +X!Yа/ 01 &533265إLIFOyxFONGh 9/ +X!Y01462"&7l88l7W->>Z<<y'P *9 /а/?] а01#"&4623264&#"'|[\{{{C10DC12BWuvzzV/DBbEF2O829/EX / >Y +X!Y@ /?]01!327#"&5467~:qN04 FZYg{-[VHy,hVY8{>@/а/] а / +X!Y +X!Y01#".#"'46323265>{\) ?1k:D-^,;/а/]/а/а//013#3#]mږ/~k 4/@  0@] а /@ 0 @ P ` ] ]а014632#"&72654&#"~dJGb`ILbW4F00#%2Fa`GF]^E#00#$24H//а/]01#3H&o/а/]/013#0N^t./]а/@ /?]в9 901'664HtKF[KNMٙN'jgU=P G'7//а/а//]а//01#3#3  8v/ +X!Y01462"&87l88l7->>Z<<?/а/]9/013#tp?q 8 /а/а//  +X!Yа а/013#462"&%462"&e7l88l777l88l7%-==Z<<+->>Z<<kyIx/010,EX/>YEX/>Y +X!Y01!#!0Bs0EX/>YEX/>Y +X!Y9013!%!CLgP(g#z$%9а EX/>YEX/>Y9/]]/]q +X!Y +X!Y  +X!Y01!5!#"$'54$32#"327: лѻª9iB k21EX/>YEX/>YEX/>Y901#3#fwPx! REX/>YEX/>Y +X!Yа//] +X!Y  +X!Y017!!!!!!xWWSl?9EX/>YEX/>YEX/>Y +X!Y01!#!#!2OED >EX/>YEX/>Y +X!Yа  +X!Y01!!55!!C$ϝJGMt#n $%9 а  EX/>YEX / >Y 9/в 9/ а! +X!Yа +X!Y 01#5&546767534&'66B}t²/IW" ʵZ!]9EX/>YEX/>YEX/>YEX / >Y 9/а  +X!Y 016653#&'33 ת j*q$^%&9EX/>YEX/>YEX#/#>Y +X!Y аа +X!Y!а"01%6754& !53&5546323!ኚjxxjqf3o$䴂fdwN!"#9EX/>YEX/>YEX/>YEX / >Y +X!Y 99  +X!Y +X!Y01327#"'#"55327327&#"N0J&kk̒RU:"=úM*l+,9/EX/>YEX / >Y( 9(/% +X!Y%(9 9 +X!Y  +X!Y012#"'#4664&#"32654&'#5326]bX{͵xzgkl,^mUx~ۮ[.-Â_5lk{fk4?vw.`:8 9EX/>YEX/>YEX/>Y9013#3 &'`'*a+,9"EX/ >YEX/>Y +X!Y9/( +X!Y а" +X!Y014632&#"#"5547'&&32654&'"˯|Vevۑck>}7;H>l'' #'cƈcM%r&'9EX/>YEX / >Y +X!Y а "а"//"]"]# +X!Y#"9"9 +X!Y0132653#"&547&&54632#4&#"33#vqXbʺkp0MbnQB$zIFe[JmM !9/EX/>Y +X!Yв 99 +X!Y901'6654$'&&547!5fCRQGlCb/36g[xUZaHXNE6T5U-DN-@CaNT 9EX/>YEX/>YEX/>YEX/>Y9  +X!Y01632#4&#"#8 xȾl\":Q|WN:z  9аEX / >YEX/>Y 9/_]]qq/q]/]q  +X!Y +X!Y +X!Y01#"532!54&#"! 67!%%ےL4=N,7'K: )EX/>YEX / >Y +X!Y01327#"|7@0'FI:?@ & %;R9/EX / >YEX/>Y  +X!Y 9а +X!Y01237#"&&'#'&&#'6bx!-#&$*MN>`5-/*P_3' %VPQ8. ew-Y./9/EX+/+>Y +X!Y.+9/  +X!Y.+9 +X!Y% 901&#"!3#'7654.5467&&54$32raMǐ| OhHk91LwAvp$gUۘpA%1i@=T@<>'.3Bio.*`'):^ 9EX/>YEX / >YEX/>Y +X!Y  +X!Y ааа01#327#"!##5!q6A0'FIoHr@A &_`NY9EX/>YEX / >YEX/>Y 9 +X!Y +X!Y012#"'#46632654&#"P rq̈́SuNB|ȓةeN"K#$9/EX/>YEX/>Yа +X!Y  +X!Y012#4&#"'7654&'&55466=篆o@bPcJb/1FVwNմn۳ c&`P?>U6YEX/>Y +X!Y +X!Y01!#"554667!32654&#"{z݌vٌ@/ ׷ˬQ:K 9EX/>YEX / >Y +X!Y  +X!Y а01!327#"&'!5!i+1*Lj}ui4:=9EX/>YEX/>YEX/>Y +X!Y013265&3#"&'IɁvq:y!W"L:"^#$9/EX/>YEX/>YEX/>Yа +X!Y а  +X!Y01$5474632#665&&#"le qB3Wi}3fޤR_(C:Y9 /EX/>YEX/>YEX/>YEX / >Y +X!Y а01665&3#&3zv:N96z:#[$%9EX/>YEX/>YEX/>YEX/>Y +X!Y 9в901326533265&3#"'#"7ĊrjlqqkjrÇϼU)wχ:㭦-Τuy1yy(q)*9&EX/>YEX/>Y9/ +X!Y 9 +X!Yа#а& +X!Y01#"&5732655&5463267&#"yYEX/>YEX / >Y 9  +X!Y016632&#"#&#"'632$+kWH4$ 'F$׿'C' $4GXk*cXOw<OT]J:&r'(9EX/>YEX/>YEX / >Y +X!Y9аааа  +X!Y 9$01##"'#"47#5!&'!32673326@SS@tJK`XiqqjV`0ȩ㧢*d9EX/>YEX / >Y +X!Y 9/   +X!Y +X!Yа01!632#'265&&#"#!5!aj90N㖑.Z{ !9EX / >YEX/>Y а  +X!Y 9/q]q]/]_rr +X!Y +X!Y01# 54$32#&&#"!!3267ɏ :Ʋr65嬞葴1;!w "#9 EX/>YEX/>YEX/>Y9/  +X!Y +X!Y +X!Yа01!!!#57>7!2654&'iY?(]d4 w_܉k-M9EX/>YEX/>YEX/>YEX / >Y9/ 9/ +X!Y +X!Y  +X!Y01!3!!!#3!2654&'rj2_9w⽿dzt>_9EX/>YEX/>YEX/>Y +X!Y9/  +X!Yа01!632#&&#"#!5!hhP(-Θ*> I /EX/>YEX/>YEX/>YEX / >Y +X!Y013!3!#!@2Pg ^9EX / >YEX / >Y  +X!Y 9/  +X!Y  +X!Y01!!!!!2654&'!BjB_Lݘ{2]9 /EX / >YEX/>Yа +X!Y аааа  +X!Y01#!#367!3!!!ǿw^o g kejeouT5EX / >YEX / >YEX/>YEX/>YEX/>YEX/>Yа//]] +X!Yв9 в901####33333#d<<hhxxQPj(u)*9EX / >YEX/>Y  +X!Y в% 9%/%]%q$ +X!Y$%9а +X!Y014&#"#46632#"&&533265%#5366|oô)thtge0Vgsx~ ]EX/>YEX/>YEX/>YEX/>Y9@ ] 9@ ]013##3?3Pb/O9EX/>YEX/>YEX / >Y +X!Y   +X!Y01#!#57>7Y?(]d4 P܉kMK9EX/>YEX/>YEX/>Y9  +X!Y9013#"'72?3O4Zy[O[i3&cMCta3 e4Y6S!*] +,9  а " // 9/в 9 / а +X!Y $ +X!Yа"013##5#"$$3353"33332654&#x#ּڿĘ N g < /EX/>YEX/>YEX / >Y +X!Y013!33#!_G9EX/>YEX / >YEX/>Y9/ +X!Y01##"&'3327inP[26 IEX/>YEX/>YEX/>YEX / >Y +X!Yа01!3!3!qPjU /EX/>YEX/>YEX/>YEX / >Y +X!Yаа а а01!3!33#!q _ a9 EX/>YEX / >Y 9/  +X!Y  +X!Y  +X!Y01!!2!!!2654&'[Zf[_ݘ{0 o9аEX / >YEX/>YEX/>YEX/>Y 9/  +X!Y  +X!Y01!!3!2654&'#3rj_W^ݘ{@ O 9 EX / >YEX/>Y 9/  +X!Y  +X!Y01!!3!2654&'cj_^ݘ{ !9EX/>YEX/>Yа +X!Y9/q]/qqq]/]_rr +X!Y  +X!Y01327!5!4#"#632#"$'T=Ϻ δɑ̥%!&'9!EX/>YEX / >YEX/>YEX / >Y 9/_]]O_qq/q]/]q +X!Y +X!Y" +X!Y01#"$'##336$32'#"327ڐ  лӹ*d7kYd c9 EX / >YEX/>YEX/>Y 9/ +X!Y 9  +X!Y01!!#$4$3!!!"R7loP>a((d)*9EX/ >YEX/>Y9/999 +X!Y# +X!Y012#"55766536"32654&gvݐbq|#ZU,H?}'ę):9аEX/>YEX/>Y9/]q]q/?]or +X!Y9 +X!Y +X!Y013!2#!2654#%3 '#ZXbw2ts:Ky ]VN0G:,EX/>YEX/>Y +X!Y01!#!G _:.:]9 /EX/>YEX / >Y +X!Yаа  ааа +X!Y01776!3#!#!!!@l / O]+>:EX / >YEX / >YEX/>YEX/>YEX/>YEX/>Yа/]]/]q +X!Yв9 в901####33333#낹~**0 @@XM&'(9EX / >YEX/>Y  +X!Y% 9%//%?%]%%]%%qo%%r% 9" +X!Y"%9 9 +X!Y014&#"#4632#"&5332654&##536teb챾XQijmsɽLYfEIz$@OqbN[O: EEX/>YEX/>YEX/>YEX/>Y9 9013##3H ::?: xEX/>YEX/>YEX/>YEX / >Yа/]]qq]/]or +X!Y 901##333#݇ylT3:6,:O9EX/>YEX/>YEX/>Y +X!Y  +X!Y01#!#57667J5ZN :k R: YEX/>YEX / >YEX/>YEX/>YEX / >Y 9 9 901%3###3pE$:: EX/>YEX / >YEX/>YEX/>Y а /o ] ]? q q r q ] q ]/ ]o  r +X!Y01!#!#3!32:+:9EX/>YEX/>YEX/>Y +X!Y01!#!#!e_:(:2EX/>YEX/>Y +X!Yа01!#!5!\d`i%0129 а+/EX/>YEX / >YEX/>YEX/>YEX/>Y  +X!Y# +X!Y)а.01323632#"'##"5%4&#"326%327&#"dҷU@F^ѷaEBUL{?/-C|mz:/*=z 6+# U: </EX/>YEX/>YEX / >Y +X!Y013!33#!:]](Ag;G9EX/>YEX/>YEX/>Y 9 / +X!Y01!##"&'33273zz C : IEX/>YEX/>YEX/>YEX / >Y +X!Yа01!3!3!V:]]:m:L /EX/>YEX/>YEX/>YEX / >Y +X!Yа 01!3!33#!K:]]](A:: a9 EX/>YEX / >Y 9/  +X!Y  +X!Y  +X!Y01!!#!!!2654&'ܺ6hrod:ik]Zs: o9 аEX / >YEX / >YEX/>YEX / >Y 9/ +X!Y +X!Y01!#!3#3!2654&'Vܺ6)hrod::ik]Zs: O9 EX / >YEX/>Y 9/  +X!Y  +X!Y01!#!3!2654&'Vܺ6hrod:ik]ZsdN !9EX/>YEX/>Y +X!Y9//?]]qor99 +X!Y +X!Y01"#46632#"&533267!5!&&cvjw׊fw j~V]ef0N !9 EX/>YEX/>YEX/>YEX / >Y9/]q]q/?]_or +X!Y  +X!Y +X!Y01!632#"'!#3 654&#"V  |o:):״Ʊ/: c9 EX/>YEX/>YEX/>Y9/ +X!Y9 +X!Y01#!#&&5467!!"Ǻho޺lY&gz:[&jOageK" #$9/EX/>YEX/>YEX / >Y]/]]9/!б +X!Y9  +X!Y +X!Y01!63 #"'72654&#"##5353!c{W=6#HipZ&}ܪ h\ xr`NgN !9EX/>YEX/>Y +X!Y99/r]qq]q/?]orr9 +X!Y +X!Y01%2673#"546632#&&#"!!Hcxnuؔh l xZ^c(ڮi':} !9 EX/>YEX/>YEX/>Y9/  +X!Y +X!Y +X!Y +X!Y01!!!#57667!2654&'ӷ)A6UM eurc:dZ iVQ`:~9EX/>YEX/>YEX / >YEX/>Y 9/а  +X!Y +X!Y  +X!Y01!3!#!!#3!2654&'V"ٽ6eurcc :iVQ`{ 9/EX/>YEX/>YEX/>Y]/]]9/ +X!Y9  +X!Yа01!63 #&&#"##5353!y{WioZ&4}5up`N: F/EX/>YEX/>YEX/>YEX / >Y +X!Y01!3!#!V:]d:u a!"9EX/>YEX/>YEX/>YEX/>YEX / >Y9 +X!Y01#"&'#"&'3326533265um14qrbr|ijzWYYW&{|#}}":a 9EX/>YEX / >YEX/>YEX/>YEX/>Y9 +X!Y01#"'#"&'3326533267ʮY_Χ[Sboe\Ye:'Ɣð#fuxg'gxuft9EX/ >YEX/>Y9/ +X!Y9/ а а +X!Y +X!Y01!!!#533!!2654&'Է*Aiqod::EEwda}&'(9EX/>YEX&/&>YEX/>YEX#/#>Y9/а а  +X!Y +X!Y +X!Yа!0136$32#&&#"!!32673# 5##3xƲ@&謞蓲r6WN$Dz%&9EX/>YEX$/$>YEX!/!>YEX/>Y9/]?Oqqrq]q/?]orв9  +X!Y +X!Y +X!Y9013632#&&#"!!32673#"'##3SѶh K cxngڮixZ^c0:( WEX/>YEX/>YEX/>YEX / >Y 9 / +X!Yв901####3#! JJPZI%: WEX/>YEX/>YEX/>YEX / >Y 9 / +X!Yв901####3#!'u|w/)):;YY}EX/>YEX/>YEX/>YEX/>YEX / >YEX/>Y9/а +X!Y ав901!3#####!#3!5ŖŞEYWPJJHI:EX/>YEX/>YEX/>YEX/>YEX / >YEX/>Y9/б +X!Y ааав901!3#######3!'vzu|wyѺ/y))(:;YY?!x"#9EX/>YEX/>YEX / >YEX/>Y 9/  +X!Yааа  +X!Y0132#&&'##'#"#6633!3!A| *x*x#v{|~zK:u !9EX/>YEX/>YEX/>YEX / >Y9/аб +X!Yа +X!Y0135667!#5&&###'#"3!s5 >u! ЭO ~\Fr"&&'(9&EX/>YEX / >YEX/>YEX"/">YEX/>YEX/>Y 9 / +X!Y #а ааа & +X!Y01!67!#3!!32#&&'##'#"3!ObYyx|xil|zx%u{|*;:!%&'9%EX/>YEX / >YEX/>YEX/>YEX/>YEX/>Y 9 / +X!Yа  аа "а $ +X!Y01!567!#3!!#5&&###'#3!Fs5 Koh<:"! ЭO \FPF)2*349*/./EX/>YEX/>Y +X!Y(9(/% +X!Y %(9 +X!Y.].+а+/++]*.+92014&#!5!2##&&54673665%#53 73#53ڝ+s4Jz4?r*nزg-)miB}5czy  LFv0)2.349././EX/>YEX/>Y +X!Y(9(//(]((]((qo((r% +X!Y %(9 +X!Y.+а+/++]*.+92014&'!5!2##&&5467367654%#53 73#53p'f[2K|6rC?虈ٗr CSIw$BmiB}7az0.H  g !9аEX / >YEX/>Y  +X!Y 9//]]/q]_]O_qq +X!Y +X!Y01#"$'54$32"!&27! ζª9iB  p[4N9аEX/>YEX / >Y 9/]q]q/?]q +X!Y  +X!Y +X!Y0146632#"5! 6"!&&[{ | }^':3DyG9EX/>YEX/>YEX / >Y 9 +X!Y017663"#3C!#3g.@@|v?xYEX/>YEX/>Y9  +X!Y017632&#"#3MG# <׍YEX/>Yа б +X!Yа$ +X!Y!01#5&5753'4'#55365#q#`$vvx% #ad]fd" [4%Z&'9EX/>YEX/>Yа а# +X!Yа +X!Y014753#5&56654&'#553[ԹݶFcvtebrqc'*"po kl'yͫ ba!Х"foQ,@I JK9 2а IEX/>YEX / >Yа в 9 +X!Y  +X!Y  9%а,а8а8//б- +X!Y/4а4/< +X!Y8DаIаI/012#"&'#"&'463"3265332654&##".#"#546326753ۻٻp44pؽcqrbrscpodh+P4qn(Hj@B[;UXXUJ񞝉Č|Tz:"P p$nlRPYEX / >Yа в 9 +X!Y  +X!Y 9$а+а7а7/-а-/, +X!Y-3а3/; +X!Y7CаC/HаH/012#"'#"&'463"32655332654&##".#"#546326753B_/bR]\SbopaQ]]Q,O~0ro)JmAA[;DڕKJл2ۘ|{xggu}!| R o$nlPN?hf2u u ()*9'EX/>YEX/>YEX / >YEX / >Yв 9  +X!Yа'а'/(а(/" +X!Y(%а%/01#"&'#"&'3326533265%5!!#5um14qrbr|ijzB,WYYW&{|#}}"kk}}&'(9#EX / >YEX/>YEX/>YEX/>Yа/ 9 +X!Yа %а%/&а&/  +X!Y&#а#/01#"'#"&'33265332675!!#5ʮY_Χ[Sboe\Ye,:'Ɣð#fuxg'gxuf kkuK9/EX / >YEX/>Y а  +X!Y +X!Y01#&554$32#&&#"3 ŝ|lV dNK9/EX / >YEX/>Y а  +X!Y +X!Y01#&5546632#4&#"3w׋emp&#eڵt>/EX/>Y01%#%7%73%X!DݶD%F#%H{{m}Khzg'/ +X!Y01'7!' #}lqd0/а/ +X!Yа/ +X!Y012#54#"#52>vor*-ovY +X!YEаEL +X!YаSаSZ +X!Y%а`+а`g +X!Y2а8? +X!Y01462#4&#"4632#4&#"4632#4&"4632#4&#"462#4&#"462#4&#"4632#4&"4632#4&#"stp30.3t]_uq5.,3Hu]_tp5\3t]_tp5.-3Ostp30.3Mttp30.3u]_tp5\35u]_uq5.-3ThhT.750ThgU1450 UghT147.ThhT147.ThhT.77.ThhT.750 UghT147.UggU1450,ck "'9!// //&/EX/>YEX/>YEX/>Y01#'37%%57%'%'7/ z`F: z`F Mu Z@DE&+A`B<aR |bG; |bGDEFEG+&'1BEX/>Y 01&'EX/>Y 01qw9EX / >YEX/>YEX/>Y +X!Y 9/ а а +X!Y +X!Y01!!!#5353!!2654&'Է*AiqodEwda}V9EX/>YEX/>Y9/ +X!Y 9 +X!Y01#!2'#654&'!!27'7ig~mv%XbEnn:˺pg7A[yf`#N"w#$9EX/>YEX / >YEX / >YEX/>Y9 99 +X!Y +X!Y01'#"'#3632'4&#"327'76jonnYsq q㹜TSRYEX/>Y +X!Y01#!#!3#BȹPBv//EX/>YEX/>Y +X!Y01!#!3B _:<|^ 9 /EX/>YEX/>Y +X!Y 9/   +X!Y +X!Y01!3 #'265&&###!0B<ε/a:^ 9 /EX/>YEX/>Y +X!Y 9/   +X!Y +X!Y01!32'6654&###!> lbu0xpbȆ!y:&Qa=:&QD&,Q#:&Q`cEX/>YEX / >YEX/>YEX / >Yа//]] +X!Y9а01 ###5##3333pPhhMCNr:|EX / >YEX/>YEX / >YEX/>Y а/]]q]/]or  +X!Y 9а01 ###5##33533Zw2ee*:3:6DmEX/>YEX / >YEX/>YEX / >Y9//]] +X!Y +X!Y 901##!5!33#%Vr~?>}:EX/>YEX / >YEX/>YEX / >Y а / ] ] q ]/ ]o r +X!Y +X!Y 901##!5!33#eUzkS36&,Q:&Q `EX/>YEX / >YEX/>YEX / >Yа//] +X!Y +X!Y01!!!#!#3i=">r_i: EX/>YEX / >YEX/>YEX / >Yа/o]]?qqrq]q]/]or +X!Y +X!Y01!!!#!#3K-eՙ_2:k9/EX/>YEX/>YEX/>Y9/ +X!Y +X!Y +X!Y013 #'265&&###!#!v<y2OAa:k9/EX/>YEX/>YEX/>Y9/  +X!Y +X!Y +X!Y0132'6654&###!#!"љ0|{e& }_:q(6789)EX / >YEX/>YEX/>Yа/9/  +X!Y +X!Y, +X!Y,9&,9( +X!Y3 +X!Y01"'#"$55463"327&5546632366554&#"׳u҄vF8yhvofhy}xubhycazIBBĬ"٦ a_4JHҲmO$/019%EX / >YEX/>YEX/>YEX/>Y9/   +X!Y +X!Y' +X!Y'9$ +X!Y"'$9, +X!Y01"'#"&5543"327&5463236754&"vśI].,OafIxF 9B:8 ^btsuz9&<Q):&\Q4]/EX/>YEX / >YEX/>Y +X!Yаааа  +X!Y01!5!53!!!33#!w_:M /EX/>YEX/>Y +X!Yа +X!Yа 01!5!#!33#!1](Ag&QFg_;&Q>P9EX/>YEX / >YEX / >Y 9/а +X!Y0133673##5"&'Wyxr26 !P[" ;P9EX / >YEX/>YEX/>Y9/ +X!Yа01!##5&&'33673ٺFSTE ̵C G9EX/>YEX/>YEX / >Y9/ +X!Y0133632#&&#"5.͘7L?%g&'9$EX/>YEX/>Y9/ +X!Yа а +X!Y# +X!Y01 5&&53463 !327!54&#"PW̳/@Q)[ŢZ}l]S-5Z!cN!u"#9EX / >YEX/>Y 9/] +X!Yа а +X!Y 9  +X!Y01"5&&53>32!327"!5&&xwep#oqp!0nMŒXʣ_9/EX/>YEX/>YEX/>Y9/а +X!Y +X!Y01!#333#'265&&'!d q:{ 9/EX/>YEX/>YEX/>Yа/]]q]/]qа +X!Y +X!Y01'654&'##333dp0[d]|9抒3:6/&t,:&K 9EX/>YEX/>YEX/>YEX/>Yа/_]]qoqqrqqOq]]/]?r  +X!Y +X!Y01!3#"'73265!#r<6%=AH4ng\K: 9EX/>YEX/>YEX/>YEX/>Yа/o]]?qqrq]q]/]or +X!Y +X!Y01!3#"'7265!#K񹫘<4<BH:+mh\'2:&,:&&1:&]a !9EX/>YEX/>Y 9 / +X!Y +X!Y  +X!Y01 # 5!5#"'7627!.dݥ=/!TYEu: X"h,j 9EX/>YEX / >Y +X!Yв 9/ а  +X!Y +X!Y01!5!#"&&5332654&##5vkkv{}irxiu(:] 9 /EX/>Y +X!Yв 9/ а  +X!Y +X!Y01!5!#"&&533265%#5 erބz}ɠvfqy":Kt&D&&@T;K:&O&&T]019K&<T)K:&\TWe R9 EX/>YEX/>Y9/  +X!Y  +X!Y013!"$5467!"ms=P*8Yg\ !9EX/>YEX/>Y9/ +X!Y в9 +X!Y01!"$54$7!376676'3#%!"GjXor@/={Dn8dn+,-9*EX/ >YEX/>YEX/>YEX/>Y9  +X!Y99" +X!Y( +X!Y0132336676'7#'#"5&#"327'dķj_NA)yىNlRS =MA_xнff1ޭ>6'f()9EX / >YEX!/!>Y( 9/ +X!Y  +X!Y9! +X!Y! 901536654!!5!36676'3#54&'kSAtA0uy{bEPO[ιXM@x1:'c()9EX/>YEX/>Y +X!Y9(9/ +X!Y +X!Y%901%36676'3#&'54##'36654&#!'!_pvB-縇zn}uܼX9pGWJU]J4R!` "#9/EX / >YEX/>Y" 9/ +X!Y  +X!Y9 +XY0153665!!5!3'67#&'54&#!aMjQk<wy}dFa@Hsn4~y: ` !"9/EX/>YEX/>Y!9/ +X!Y +X!Y9 +XY01'3654#!5!3'67#&'54#'lVbMiT g3gSI5La>Ht}!^Dp#e$%9EX/>YEX / >YEX/>Y +X!Y +X!Y  +X!Y 901!#57>7!32676'7"&5'Y?(]d4 _YO?).܉k`tͼff?::!e "#9EX / >YEX/>YEX/>Y  +X!Y +X!Y +X!Y 901!#57667!32676'3#"&'1A6UM ZOl{A0lxZ !`yP|yq9EX/>YEX/>YEX/>YEX/>Y +X!Y 9а/q_]]qoqqqOq]]/]r?r +X!Y0136676'7#&'!#3!]JB+{؊Beoͺbg'nM:9EX/>YEX/>YEX/>YEX/>Yа/o]]?qqrq]q]/]or +X!Y  +X!Y901!#3!336676'3#&'C\Ml|A0滧3:*!duSyv"I#$9EX / >YEX/>Y  +X!Y +X!Y 901"$'4$32&#"36676'3 ܇;bq5&{XDuϳ[[meNF 9EX/>YEX / >Y +X!Y 9 +X!Y01%6674'3#"5546632&#"Q`Zĭv֋`,cPYzrV2B:ܳ#GO9EX/>YEX/>Y +X!Yаа  +X!Y901!5!!366'7#&'%\LB+yىH`rnbgF:O9EX/>YEX/>Y +X!Yаа  +X!Y901!5!!36676'3#&'^Mqw@*蹪ct}<)r$*+9EX/>YEX / >Y +X!Y в% 9%/%]%q& +X!Y&%9а +X!Y0132653# $54%&&54$!2#4&#"3#Xϰx%­ıxtgV0eeugvu}~/K&TE,K:&TTop # /а/а/ а//013#3&5tYިPIBR[{U;_% % "FL@"Fff@ k+01!5!5!5!llkg`1x! 9EX/ >Y 9/01#546j]aHtf0G! 9EX/ >Y 9/01'6753i]aHd$; 9 / +X!Yа/01'6753i[cIvdeOg /а/01&&'5]jM_H@ah1&C<& ?$d1 9 / +X!Yа/ а / 01'6753'6753i[ci[aHl@HkF$ LEX/>YEX/>YEX / >YEX/>Y  +X!Yа01!#!5!3!$lp_vW`4~EX / >YEX / >YEX/>YEX/>YEX/>YEX/>Y +X!Y +X!Y аааа01!!#!5!!5!3!!!4jssj` v"  9/ +XY014632#"&5o\[rn^]oWpm]%WnoX/&&'XR,  9/  +X!Y014632#"&R66688666k-==--<<DW#'5CQRS9а&а(а6аIEX/>YEX/>Yа/а/а/ а /$9$/&9&/+ +X!Y2 +X!Y+9а2@а G +X!YN +X!Y014632632#"'#"&54632#"&5'326554&#"326554&#"326554&#"7MOOL ihhXJHVWIGYXIHVWIHWBXJGWVJHXeyyGxx{HBrB7OecUJOdcTJOefRJOddSNebUINfeSl /9/01#53'&sY/9/01#'َ{{;nj" //017'hhnBrB6 EX / >Y 01zT 9EX/>YEX/>YEX / >YEX/>Y 9  +X!Y0163 #&#"#Jn,{ m [h)!*+9EX/>YEX/>Y)9)/ +X!Y +X!Yа аа)а)а//] +X!Yа  +X!Y$а&01!!!536675'#53'#53'4632#4&#"!!!>M(2Ⱦ޿oi\SD[ `E}}Աk|}}6#&)EX/>YEX/>YEX / >YEX / >Y 9/а/]$а$/а/а/ +X!Yа#ааа/ а /а/ +X!Y а)ав& 9' 9013#3##!##535#533!3!'#35!%3'5#WbQa;aLwwh蘔Д(#)*9#EX/>YEX/>YEX/>YEX / >YEX/>Y +X!Y  +X!Yав!9!/ +X!Yа/' +X!Y01#327#"&5###!233332654&'#6A#4IF|~ɹybaAA &6WU#'+05:9;<99а9"а9'а9+а9-а93EX/>YEX / >YEX/>Y 9/а/а +X!Y  +X!Yа ааааааа а"а$а&а(а*а -в0 9 2в5 96в9 901333#3#####53'#5333337#37#3'#7#%7#3''Xe)fVXg)e[VHp#ql$ܮ"h7e52$˜˜$ : fEX/>YEX/>YEX / >YEX/>Y +X!Y9/  +X!Y 9/012#4&'!#3!2673eo>qg:Lx_:u~N_#$%9EX/>YEX / >Y# 9#/ +X!Y  +X!Y а#а#а//]  +X!Yаа +X!Y01!327#"#535#5332&#"!!!Qtfxx jmn"% |}#˼}#(EX / >YEX/>Y ( +X!Y$(9$/p$q$$ $] +X!Yа/pq ]  +X!Y!а!/p!q !] +X!Y аа/а$ а$ааа/01##535#535!23#3#!'!!!!2!&#!6kDm?YJT:0^p2,4^YV*iEX/>YEX / >Y +X!Yаа/а +X!Yаа/  +X!Y 901#3###'3667!7!&'!7!@.}.0/Qu i}k\ EX/>YEX/>Y9/а/] +X!Yаа аа а а +X!Yа а аааа +X!Y9/01#"'5755737765PldǦZooooYssss X]:]9EX/>YEX/>YEX / >YEX/>Y 9/  +X!Y а01#5&'##5753߹q!ڷ 4!m"pEX / >YEX/>Y 9/ +X!Yа а /  ]  +X!Yаа а  +X!Y01!##535#53!2!!!2654&'!OZ&z'59:;9а(а8EX / >YEX%/%>Y а/ 9*:J]  +X!Y +X!Y 96F]%]%а/%+ +X!Y2 +X!Y6% 96/8 %98/01#"&554632#4&#"326546  &5326554&#"'{z{yIBAMOA=LXJHVWIGYiinGo:MfRINeL:GGOecUJOdcTBrBhj!g"#9EX / >YEX/>Y 9/ +X!Yа +X!Yа  +X!Y01"&5#5276632366554&#"bnq_xΫkpYg0&g#$ƭ%kbcU{'RL()*9ааEX'/'>YEX%/%>YEX/>YEX"/">YEX / >Y аа/] +X!Y  +X!Y +X!Y!% 9& %901!5!46 #"&5326754&#"##33gu8_VT]_UT_T=]bkj`eakkcnqg8 nEX/>YEX / >YEX/>Y9/ 99в 9 а +XYа а01##33####5!ތ4ZppZ [!vwq8QNe9EX / >YEX/>Y 9/ +X!Y +X!Y 9  +X!Y01%#"&54632!327"!&wĬzs^r>nz*zqT''$EX/>Y01dS'&'$EX/>Y01cI'!'$EX/>Y01Y'#' $^EX/>Y01j2*^+,9# /EX/>Y 9/9  +X!Y +X!Y# +X!Y012.#"'763 #"554"32655'&&<]:i`1txސ䌟MDy;0Nn2֥#=Zj+(/EX/>Yа +X!Y01#!#!6<E 7/EX/>Y +X!Yа  +X!Y01!!55!!kaFAJҐB"EX/>Y +X!Y01!5!C?= 9/EX/>YEX/>Y9 +X!Y013##5!0;PtbN,<q=>9$а4EX/>YEX / >Yа/а/99   +X!Y) +X!Y0а 901#"&'#"&5546326632326775.#"%4&#"3265~߉PQ쐉ހ~߈QPPr4 rPs5 uP ܼ'*caܹ߽*a`޸K?9EX/ >YEX/>Y +X!Y +X!Y01#"'73254632&#"e9:.!=f a@9wEX/>YEX/>Y01Pf"s@9vEX/>YEX/>Y01+ 8 9EX/>YEX/>Y99013# pl')'%%$ny3:,EX/>YEX/>Yа/а01#3#38y?\_W  9 /а/@P]а/01'6753iHOHm\L[<&JJ,9EX/ >YEX/>YEX/>YEX/>YEX/>YEX/>Y +X!Y  +X!Yа013#5354632&#"3#!#3ʫϽp}qwiI\=2kk^U:<^EX/ >YEX/>YEX / >YEX/>Y +X!Y +X!Y а01&#"3###5356632#0|L繫e+ckUv=(<2'+EX/ >YEX/ >YEX / >YEX/>YEX/>YEX*/*>YEX)/)>YEX#/#>YEX'/'>Y ! +X!Y%аа  +X!Y013#5354632&#"!54632&#"3##!!#3竫@? /5ZbϽp}rwi޹po ibr\=2jl^UU:<2(lEX/ >YEX!/!>YEX(/(>Y!" +X!Y&аа!аа  +X!Yа(%аа 013#5354632&#"!56632#&#"3##!竫@? /5Zbe+|Lpo ibrv=(ckUU<&vEX!/! >YEX/>YEX/>YEX / >Yа%б +X!Y  +X!Yа! +X!Y01#327#"&5#53&''"##535463236A#4IF|~=f]ZaAA `p9,_TLͲMN9EXG/G >YEX/>YEXK/K>YEX@/@>YEX / >YEX,/,>YK +X!Y  +X!Y аG +X!Y@,9@  +X!Y:,@9:% +X!Y1,@9,4 +X!Y01#327#"&5#5354&#"#4&#"#"&&5332654&$&&54632&546323Ow#4MBvfbX\%berjS蹂qriqO`V,ʛ~ UruXF;ip|LLnXGCD>VyW\`]mUGKSаFаJаPаWа[аaаcаgаmаpаwа{аааа=/EXF/F>Y~I+z{+w+:+ =F9 /а/а/ а/P9P/o +X!YPo9  +X!Y% +X!Y)а)/.а./4 +X!Y=< +X!Y=kаgаcа>а<lаhаdа?а:AаF`а\аXаKбJ +X!YZа^аbаGаINаQ +X!Yv +X!Ywаzа{а~аа01#"&'5463232#4&#"32653#"&53326533!5353!#%5!#53254'5!!5!!5!5!!5!!5!3254&###535#53#53%#535#53#539df~heCbrT24JA@JJB@I\iRXm]h)6q(om56o\~gb[\ [\]v:<]qqqqqq"oooooobyx^u_|x^%IMT F-HENNEpENNEON]QS[6,;qqttSRJtttttt8qqqqqqP)~~~\s $(R++ +а!/%/+%а/!а/ 9 /9/01 4676654&#"36632#33#3#AD$J\:+98][/KR11::'J34@4_YEX/>Y +X!Yв99 +X!Y 01!!5654&#"#46 !,m@YEX/>Y9/ +X!Y01!#5%3cY9uP H9EX / >YEX/>Y  +X!Y +X!Y01#"&'54632'4#"327EµU TEX/>YEX/>Y9/ +X!Y +X!Y +X!Y01#"&54632#53$26754&#"e)#Oih|nװ?xO@Blm`!,eEX/>YEX / >Y*а*/*]*] +X!Y*9*9  +X!Y% +X!Y01 &5467&&546 4&#"3264&#"26cUbsqbU`bڜlknmt]^nopZV&&bc'&VXVnlX[dgeNdaQPbcB:9EX/>YEX/>Y +X!Y901#!5!F~$r e!"9EX/>YEX/>Y +X!Y9/9 +X!Y +X!Y01#6632#"&55!"264&4N߾@

YEX / >Y +X!Y 9/ +X!Y9 а  +X!Y01!!632#"&'332654&#"E%csī bpysiB)CJ0Ҵұ[Vqj*0 P9 EX / >YEX/>Y 9/ +X!Yа в 9013##!'3!5Bs/N& '(9EX/>YEX/>Y9/]q]/]or +X!Y а% +X!Y%9а  +X!Y0132654&#"#4632#"&5332654!#`zvlpb泼e[깃lpqcTS`[MO%@њOcb[NV 9EX/>YEX/>Y +X!Yв9  +X!Y в901!!56654&#"#4632!g]t^yöc~^ARipkκQA9EX/>YEX/>Y9/ +X!Y901!#5%3cc H9EX / >YEX/>Y  +X!Y +X!Y01#"'5432'#"32zrI᧨SG FEX/>YEX/>Y +X!Y9 +X!Y 901%!!5!5!/gqx|xy 1EX/>YEX/>YEX/>Y9013#38RXJC i&1 SEX/>YEX / >YEX/>YEX/>Y999 9013##3(usEKB1`9EX/>YEX/>YEX/>YEX / >YEX/>Y 9 9  9017373#'#3  Ƹ֮׷&P@w;PeskS1EX/>YEX/>YEX/>Y90173#3@77$^\kst =9EX/>YEX/>YEX/>Y  +X!Y01#"&'33265 Ӷy{ (/EX/>YEX/>Y +X!Y01!#!5!qs C%]EX / >YEX/>Y 9  а  +X!Y +X!Y а# +X!Y014&$'&54632#4&#"#"$53326#yVyq{8Vﺚ~*PXJ+bȜbkYPAXPe[ˢfr[% c9EX/>YEX/>YEX / >Y9/ +X!Y 9 +X!Y01!#!2#32654&##Z u~?Y Xm]dnY6W!O"#9EX/>YEX/>Y9 +X!Y +X!Y01%#"54632'4&#"3265Upf|6F$Fo 1>ϹU O 9  EX/>YEX/>Y 9 / +X!Y +X!Y01#!2#%!2654&'!C|wJǨjd`w`Z H9EX / >YEX/>Y  +X!Y +X!Y01#"5324&#"3265Z$2>4BX EEX/>YEX/>YEX/>YEX/>Y9901!##33X]lmw`9EX/>YEX/>YEX/>YEX/>YEX / >Y99 901 3###zrsqsZo)EX/>YEX/>Y +X!Y01%!!3CHW LEX/>YEX/>YEX/>YEX / >Y99 901#373#֓!Րz+M69EX/>YEX/>Y а  +X!Y013#"&533265Աۺqr\nŝŷ^fm_QEX/>YEX/>Y01!#3QX TEX/>YEX / >YEX/>YEX/>Y 9| / ] +X!Y01!#!#3!3X\c5b 9EX / >YEX/>Y 9/  9  +X!Y +X!Y +X!Y01%#"'532#&#"3275!5!5B &QіSS*Z'TJ CEX/>YEX/>Y а / ] +X!Y +X!Y01!#!!!K Cs+iEX / >YEX"/">Y" 9  а а  +X!Y +X!Y"а"&а") +X!Y014&$'&546753#4&#"#5&&53326#yV˦ƹyq{8Véߺ~*PXJ+bˆbkYPAXPe[”fr[0 cEX/>YEX/>Y9/ +X!Yа +X!Yаа +X!Y01!!!53677'#53'&632#4&#"!p8 O ˵ʹh`]h"oF"y{̷pw{ m9EX/>YEX / >Y 9 9/а/ +XY +XYаааа0133!!!#5!5!5!533M@yDxxKyt39EX/>YEX/>Y +X!Y01!#! S= 9EX/>YEX/>Y9 +X!Y01!!3'!Sɭ=C\^0`ZaEX/>YEX/>Y9|/`pq`p] +X!Y +X!Y +X!Y01!5!#"5324&#"3265Un2>4BS8 9EX/>YEX/>YEX/>Y9013#3#'ɭsj\^>K f 9а EX / >YEX/>Y +X!Y 9/] +X!Y  +X!Y01!!5!!5!!5!K CwC {ID@ 9EX/>YEX/>YEX/>Y +X!Y01!#!#!D ? E 9EX/>YEX/>Y +X!Yа  +X!Y01!!55!!owQWJ:__`^EX/>YEX/>Y9/в 9 /а  +X!Y +X!Yа01#5&$54$7534&'66?6 nn vr `]9EX/>YEX/>YEX/>YEX / >Y 9/а  +X!Y01$3#&'33ٺ3k4K-u~!^"#9EX/>YEX/>YEX / >Y +X!Yаа +X!Yа01%66554&#"!53&54323!>=&! :#˜&,n9EX/>YEX/>YEX/>Y +X!Yав9/ +X!Y +X!Y01!5!!632#52654&#"#}1ľmxy2`0 9EX / >YEX/>Y 9  +X!Y 9|/]`p]0q`pq +X!Y +X!Y 901#"546632#&&#"!!32670{~Ay'^ӻtïo' z!"9EX/>YEX/>YEX / >Y +X!Y  +X!Y9/ +X!Y +X!Y01!!#7766!!%!2654&#+^ M{;.`Q $;rsneu J-Yuc_p 9EX/>YEX/>YEX / >YEX/>Y 9|/] 9/  +X!Y +X!Y  +X!Y01!3!!!#3!2654&'CH$+s}nJYwa[q(.\9EX/>YEX / >YEX/>Y +X!Yав 9/ +X!Y01!5!!632#4&#"#}1dy2C P 9/EX/>YEX / >YEX/>YEX/>Y +X!Y 01!!#!3!3CGe  a9 EX / >YEX / >Y  +X!Y 9/   +X!Y +X!Y01!!2!!2654&'!+ s}nĥ wa[qY.]9 /EX/>YEX / >Y +X!Yаа  ааа +X!Y0177667!3#!#!!!)GG.Bd 1V T\9EX / >YEX / >YEX/>YEX/>YEX/>YEX/>Y 9|/]`p] +X!Yв9а 01####33333#cd,YY,  Q<G($)*9EX / >YEX/>Y  +X!Y 9' 9'/'/']']'']$ +X!Y$'9 9 +X!Y014&#"#4632#"&'&5332654%#536}nngvq[=yyPT]XOV)$[,.YV``Xa L 9EX/>YEX/>YEX/>YEX/>Y9 9013##3st, i 9EX/>YEX/>YEX/>YEX / >Y9|/]`p] +X!Y 901##333#jd5 '6O9EX/>YEX/>YEX/>Y +X!Y  +X!Y01#!#776676^ D)^P s^" D9EX/>YEX/>YEX/>Y9  +X!Y013"'72673-^%P&P\1I f0xEI 1; F 9/EX/>YEX / >YEX/>Y +X!Yа 01%3#!3!3DPGT =G9EX/>YEX/>YEX/>Y 9 / +X!Y01!##"&'33273߹~0py21 P 9EX/>YEX/>YEX / >YEX/>Y +X!Yа 01!!3!3!3Ĺ  uY 9/EX/>YEX / >YEX/>YEX/>Y +X!Yа а а 01%3#!3!3!3Ǯ͹T   a9EX/>YEX/>Y +X!Y 9 / +X!Y  +X!Y01!!5!!22654&#!* hQrsnJXuc_pYg& R9 EX/>YEX/>Y9/  +X!Y +X!Y01!3!22654&'!+Ps}nnJwa[qYK} 9EX/>YEX/>Y9 +X!Y 9| / ]` p ]0 q` p q +X!Y  +X!Y9013267!5!&&#"#6632#"&'A~xyotuλ!"#9EX/>YEX / >YEX/>YEX/>Y  9| /` p q ]` p ] +X!Y +X!Y +X!Y01#"'##336324&#"3265 ع$ BP c9EX/>YEX/>YEX / >Y9/  +X!Y 9 +X!Y013&&5467!#!!!"P"zqѹ. &hs!0|  R9EX/>YEX/>Y 9 / +X!Yа а  +X!Y01###53!!3"9EX/>YEX/>YEX/>YEX / >YEX / >YEX/>Y 9|/]`p]`pq +X!Y9 +X!Y в9013######33333c&zcd,YY,Z<T  Q<N9/EX / >YEX/>YEX / >YEX/>Y 9| /` p q ]` p ] +X!Y 9 +X!Y013####333AoiqjdRDT y 9EX/>YEX/>YEX / >YEX/>Y9|/]`p]`pqа +X!Y9 0135333###5##3DP<4qAP #9EX/>YEX / >YEX/>YEX / >Y9|/]`p]`pq +X!Y +X!Y 901##!5!33#i c4 `[#./09$EX / >YEX/>YEX/>YEX/>Y9/   +X!Y +X!Y& +X!Y&9!&9, +X!Y01"'# 53"327&54323654&#"[٦~62ϵͶ^vbj;<E*(!E'8ڲy8 &&D ]01&ql 9/EX/>YEX/>YEX / >YEX / >Y 9 9 9  +X!Y 901353###3(u1tsJTEKB&^ 9/EX/>YEX/>YEX/>Y +X!Y +X!Y а а а 01%3#!!5!!!3DPFT=P9EX / >YEX/>YEX/>Y 9/ +X!Yа01!##5&&'353673߹cighge! ɺm{x "1,G9EX/>YEX/>YEX/>Y9/  +X!Y013632#4&#"#~>1dy3k$l%&9EX/>YEX/>Y!9!/!] +X!Yа! а +X!Y +X!Y01"5&&53>32!3267"!54&Φ_fLP9<" ƨ^w ((/¤^ia 9EX/>YEX/>Y 9 / +X!Y +X!Y  +X!Y012#"5!54&#"'66267!G)R9AgH)/ơGp9EX/>YEX / >Y +X!Y9 9/ 9  +X!Y +X!Y901!5!#"&'&5332654&##58YYEX/>Y +X!Y 9|/]`p]`pq +X!Y  +X!Y01#"532267!"!&&Z v  $2>4wì0'()9EX/>YEX / >Y 9/q]Oqа/@ /?O]] +X!Y +X!Y   +X!Yааааав!9$ +X!Y01!!!!!!5367#535'#53'&632#4&#"nl $ ?˵ʹh`]hy]yjGy]y@̷pwB!"#9EX/>YEX/>Y!9!/!]! !] +X!Y +X!Y а! а!а/@ /?O]] +X!Y +X!Yа01!!27#"&'#535#536632&# !!!/h bhvo`Yy dymyym()*9ааEX'/'>YEX%/%>YEX/>YEX"/">YEX / >Y а /а/] +X!Y  +X!Y +X!Y!' 9& '901%!5!46 #"&5326554&#"##33n-4^WT^aSRa]PYji\RZhg^lm(f !9EX / >YEX/>Y 9/ +X!Yаа а /@   / ? ] ] +X!Yа а  +X!Y01%!#5#535#53!2!!%!2654&#!rp괴YP̨Yxbdz> &tEX/>YEX/>Y9|/] +X!Y 9& +X!Y&9  +X!Y& 90132654&#"#4632#"&5332654'# TJH?F9K|FBOCFIX=0-:3)b{yh7[)j}~k-<<3q6 JEX / >YEX/>Y 9/ +X!Yа в 9 9013##5!'33Pkky+f![dEX/>YEX / >Y +X!Y 9/ +X!Y9 а  +X!Y01!!632#"&'332654&#"p2AJy AHNJI;y|~ecKD>M+VQEX/>YEX / >Y +X!Y 9/ +X!Y  +X!Y01#632#"&55467"3264&(Hrv~3MS?=NGMwt3n, "TUO|L:3EX/>YEX/>Y +X!Y901#!5!];kEO (}EX/>YEX/>Y$9$/$$$]$$/$]$q$$r +X!Y$9 $9 +X!Y +X!Y01 &5467&546324&#"26"264&wJ@w}~N>?KL~L7??p?@Cv7;jyyjBa7vgvv:4::45::50.88\7I ]EX/>YEX/>Y9//] +X!Y +X!Y +X!Y01#"&54632526'2754&#"Eevs7{^*O<;LJ@A~y=dbGYа/@ ?O_o]а/?O_]а/@/?O_o]/  +X!Y +X!Y013#4632#"&732654&#"rdHDcaFHdU3$#00#%2rFa^IG\^E#21$&24 WEX/>YEX/>Y а / ] ] +X!Y +X!Y +X!Y01!!!!!!WkJN)7DEX&/&>YEX/>Y&)а)/ +X!Y&9/9/]7 +X!Y79 &90 +X!Y; +X!Y&B +X!Y01##"'3#"&5467&547&554632!32654&'#326554&":oxOI4z΍^T8sPGo<8YEX / >YEX/>YEX/>Y 9 9 +X!Y  +X!Y01%!"553 73#325&&#"l l"jquHk=$c 9EX/>YEX/>YEX/>Y9/ +X!Y 9 +X!Y01#!2#&'54&#%!265!!rA;9tcE=6x| iEX/>YEX/>YEX/>YEX / >Y9|/cs]3C]] +X!Y 901##333##Ur~> TEX/ >YEX/>YEX/>YEX / >Y9/ +X!Y 901##333#̀~;  LEX/>YEX/>YEX/>YEX / >Y99 901#333#r ckKy; LEX/ >YEX/>YEX/>YEX / >Y99 901##333#P+ u  H9EX/>YEX/>Y  +X!Y  +X!Y013!2!326554&#iƽM@`0N9EX / >YEX/>Y а  +X!Y +X!Y01#"546632#&&#"32670{~y'^ӻt˽jokEX/>YEX/>Y9/]/]] +X!Y9 +X!Y +X!Y013!2!2654#%32654'#_Xctszl|Q~!ebUčUSp GEX/>YEX/>YEX/>Y 9 / +X!Y 901!#3#!Fnߦؼs; /а/01#546+k;T;ScoM `/а/@ /?O_]  +X!Y а /а/а/@/?O_o]/01#"&533265%3#ਇOIGOpe_rr_7=?5/]]p]а/@ /?O] а / +X!Y +X!Yаа/@?O_o ]а/@ /?O]/01#"&&#"'46323265'3#`F5q"#/T`F/,#0x}JiB 3&KkK3&nX ]/]а/а//]/9/ а /а//]   /013#'#3#"ũ"ɍ^F ]/]//а/а//]9а// а /  / ]01#'#3#3FŪ"ϞUis/а//]9/аа/9|/@ /?O_]а/@ /?O_] в 9901#'#3'6654#72FũA;J<人|!C\XI;B<iF/а/а/@ /?]9/в9 а /? O ] а /@   / ? O _ ] а/  +X!Y  +X!Y01#'#%37#"&#"'46323265Fũ-`A6n(6M`@*|&4䞞>^G.?bF-3 9EX/>YEX/>Y +X!Y013!#!̹B0  `/а/@ /?O_]  +X!Y а /а/а/@/?O_o]/01#"&533265'3#ਇOIGO`f_rr_7=?5 f/а/@ /?O_]  +X!Y а /а/а/@/?O_o]в9901#"&533265''6654#72ʡJIELJBQD^rs]5>=6|;RNB2;>PEX / >Y016 EX / >Y 01[!EX/>Y01V"EX/>Y01:#EX/>Y01O$EX/>Yа01I%EX/>Y01~N  9EX / >YEX/>Y а  +X!Y +X!Y01#"$'54$32#&&#"3267/n}GDJ㣨7~"p #$9EX / >YEX/>Y 9/  +X!Y +X!Y" 9"/?"O"]""] +X!Y01%#"$'54$32#&&#"3267!5!C㰻֨!" xӅr*arG-NڕF:0F H9EX/>YEX/>Y  +X!Y  +X!Y013!23254#8>*$(~_"H#$9EX / >YEX/>Y  +X!Y +X!Y01#"$'54$324&#"325_⯫! n}xrqyJ7O5;~_&O'(9#EX/>YEX/>Y9 +X!Y# +X!Y01%#"$'54$32'4&#"325_9<"!n}xqqyZy F:P3;3EX/>YEX/>Y9/ +X!Y01!#5%3ɹ  V 9EX/>YEX/>Y +X!Yв99  +X!Y 01!!56774&#"#46632! } }fzx~xsT5TluplQ /EX/>Y +X!Yв 9/  +X!Y +X!Y901!5!#"'732654&##5tr4׹<vlgXʥg> LEX / >YEX/>YEX/>Y +X!Yа/ в 901%3##!53!ź< Im! 5eQ /EX/>Y +X!Y 9/ +X!Y9  +X!Y01!!676#"'732654&#"f~6o:әju"tt@reϤ:SJ&/EX/>Y +X!Y901#!5!W#? !~/а/@ /?O_]  +X!Y а /а/а/@ /?O]а/ +X!Y +X!Y!01#"&533265#"&#"'46323265ҡJHGJ`F:w,"0S`E0,#0_vv_6@@6 JiK3&KkK3&g!/а/а/01#3!`m9 EX / >YEX / >YEX/>YEX/>Y   +X!Yа/]] +X!Y +X!Y +X!Y  +X!Y01!!"53!!!!!7'"mc[l얯2>4 g B?%N/EX / >Y +X!Y 9/ 9 +X!Y   +X!Y01267#"546632#"'726754&#"߱wu҄v&zi"i~<2\RëKg ( /EX/>Y  +X!Y  а /01%#"'73255g;4C ; L,EX/>Y01sNEX/>Y01#MEX/>Y 01wKEX/>Y01vO,EX/>Y017HeEX/>Y01~EX/>Y01_SEX / >Y 01pEX/>Yа"01JTKe:Ke:U:EX/>Y01YZ:& U:!fEX/>YEX/>YEX/>Y +X!Y9//] +XY а  +X!Y01%32654&##5&#"#6632#"'RXarTNcke׵wh3{cbU'>Ub1x ;EX/>YEX/>Y +X!Y +X!Y01 5 '4&#"3267"<<> 4;3EX/>YEX/>Y +X!Y901#!5!@%H4f9 /EX / >YEX/>YEX/>Y 9 9  +X!Y +X!Y01#"'#3632'4&#"3264oɀpp񹣌PUË֪,\NK9EX/>YEX/>Y +X!Yаа +X!Y01%2673#"5546632#&&#"@cxnvۓhxZ^c* ڮiο![f9/EX/>YEX / >YEX / >Y 9  9  +X!Y +X!Y01466323#'#"&&'7327&#"[q΀oo|uRS&4x؟[VN&'(9 EX/>YEX/>YEX / >YEX/>Y9  +X!Y9 +X!Y$ +X!Y0143273#"&'732655#"5327&#"[oVH7?OoSS&272*2(8١ZDN8EX/>YEX / >Y +X!Y +X!Y0146632#"&&'732654&#"Z~咏' į`2Np9 EX / >YEX / >YEX/>YEX/>Y 9 9  +X!Y +X!Y01#"'#36324&#"3262nȁqt TS}}'ە[`Nm9EX/>YEX/>YEX/>YEX / >Y 9  9 +X!Y +X!Y0143273##"5327&#"[opVX%4r&x5ߓ]Ne9EX/>YEX/>Y9/]  +X!Y +X!Y +X!Y01"''46632!327"!54&q |݀$™x9s NtZrʠ`VN%#&'9# EX/>YEX/>YEX / >YEX/>Y9  +X!Y9 +X!Y# +X!Y0143273#"&'732655#"5327&#"`pRA7zo뺕RU%/-)I:2ӠWg&2,349,а,EX / >YEX/>YEX/>Y* 9! 9*!9!*9 +X!Y 9 9 99 9 0 +X!Y01"&54677'&54632653#''277654&#"NhKK]I E^ёjdLk?6BSHB8HVK6Ohlspo4taqK3I;TI]:F90YEX/>Y  9 / +X!Yа +X!Yаа  а а01!!573%MH U[,},,U 9EX / >YEX/>YEX/>Y 9/ +X!Y +X!Y 9/ +X!Y   +X!Y 901!!!!#!!!!5&& f) ;D-2 Y9 EX/>YEX / >Y 9/ 9/  +X!Y  +X!Y0133###32654&'ִwŦ*Zlb`w`Z'j()9а$EX/>YEX/>Y99 +X!Y!9"9$ +X!Y01#"'#7&53273&#"%4'3265քtK{E=Or4;Jj>Gp ?4Ngni;b\409EX / >YEX/>YEX/>YEX/>Y 9/] +X!Y 9/ +X!Yа аа01##!##5353!533!5![ZZ\[\OOKX[9EX / >YEX/>YEX/>YEX / >Y +X!Y 9 901"'73255#33<4 #@]K Qkm% iEX/>YEX/>Y9/]/]q +X!Yа +X!Y +X!Y013#53!2#32754'#3$)]ʦ]iEX/>YEX/>Y9/]/]q +X!Yа +X!Y +X!Y013#53!2#32754'#3$)]ʦ]l/EX/>YEX/>YEX/>Y/]]9/ +X!Yв9  +X!Y01#63 #&&#"##53533^{WioZ&ȹ}5up`Nҗ1NEX / >YEX/>Y 9/ +X!Yаа  +X!Y 01###53!5!!3-f,77Dp@vEX/>YEX/>Yа/ +X!Yа/] +X!Y  +X!Yааа013#3#327#"&5#535#536A 8IE|~@AA N6&%D06EX/>Y 016&%u6EX/>Y 016&%6EX/>Y01"&%:EX/>Y01&%j6EX/>Y01&%PAEX/>Y01&%'Z"wD&'yFB&)DBEX/>Y 01FB&)uBEX/>Y01FB&)BEX/>Y01F&)jBEX/>Y01B&-DBEX/>Y01QB&-u5BEX/>Y01FB&-@BEX/>Y01^&-jpBEX/>Y 01"&2:EX/>Y 01v 8&3DR8EX / >Y!01v 8&3u8EX / >Y"01v 8&38EX / >Y"01v $&3<EX / >Y#01v &3j8EX / >Y'0016&9D+6EX / >Y016&9u6EX/>Y016&96EX / >Y01&9j6EX / >Y#016&=u6EX/>Y 01m&EDEX/>Y* 01m&EudEX/>Y+ 01m&EnEX/>Y+01m&EjEX/>Y,01m&EjEX/>Y0901m[&E EX/>Y,601m_&E'\DN&Gy?]&IDEX/>Y 01]&IuTEX/>Y 01]&I^EX/>Y 01]&IjEX/>Y%.01g&DEX/>Y 017&uEX/>Y 01,&&EX/>Y01D&jVEX/>Y 01&RaEX/>Y01[4&SDEX/>Y 01[4&Su^EX/>Y 01[4&ShEX/>Y01[4&SdEX/>Y01[4&SjEX/>Y#,01&YDEX/>Y 01&YuVEX / >Y 01&Y`EX/>Y01&YjEX/>Y!01K&]uEX/>Y 01K&]jUEX/>Y 01&%p>EX/>Y 01m&EplEX/>Y*01&%7EX/>Y 01m&EEX/>Y+01OiEX/>YEX/>YEX/>YEX / >Y +X!Yа/9/ +X!Y901#327#"&547!#!-&:qN04 FZYg,P-[VHy,hVlsjmON-7EX/>YEX/>YEX/>YEX)/)>Yа/9 9 / +X!Y 9)$ +X!Y. +X!Y 3 +X!Y01%&'#"&54$3354&#"#46632#327#"&54'2675# $tqcsv&!:qN04 FZYgW#t&EUasdGQXX-[VHy,hVZHWbwW&'uWEX / >Y01\&Gu3EX/>Y 01wW&'WEX / >Y01\&G=EX/>Y 01w&'WEX / >Y#01\&GEX/>Y$01wW&'XEX / >Y!01\&GREX/>Y"01B&(CEX/>Y01_+&HHr]]qqr_rOq]O_]`]q]01F&)pJEX/>Y 01]&Ip\EX/>Y01F&)CEX/>Y01]&IEX/>Y!01F&)qBEX/>Y01]&I;EX/>Y%01OFzEX/>YEX/>YEX/>YEX/>Y9/ +X!Y +X!Y  +X!Y +X!Y01!!#327#"&547!!!!I:qN04 FZYg]-w-[VHy,hVi,]hN%-~EX/>YEX / >YEX/>Yа  +X!Y*9*/**] +X!Y" +X!Y%9& +X!Y01%3327#"&547&5546632!3267"!5&&Gs:qN04 FZYgb{݁#b3pn6-[VHy,hVlZ!!MPBFB&)CEX/>Y01]&IsEX/>Y"01zW&+WEX / >Y"01`V&KUEX/>Y'01z/&+XEX / >Y"01`V&KEX/>Y'01z&+WEX / >Y'01`V&K2EX/>Y,01z&+`V&K4+XEX/>Y*01B&,BEX/>Y01A&LA /01z.&-<FEX/>Y01`&"EX/>Y01l&-p>JEX/>Y01R&p$EX/>Y01C&-kCEX/>Y01)&QEX/>Y01Xx&- Oh&M&-BEX/>Y 01&-.-KJ&MN55&.|5EX/>Y01K9&3EX / >Y01X&/E &O1&0u&1EX/>Y014&PuEX/ >Y 01 &0lW U&P&0EX / >Y01&PVP]]/qq/?rr_orqOq]O_]`]r01&0&P86&2u6EX/>Y 01&Ru[EX/>Y 01 &2 N&R36&27EX/>Y01&RzEX/>Y01&R`/O]]01v &3p@EX / >Y!01[4&SpfEX/>Y01v &39EX / >Y"01[4&SEX/>Y01v 7&3k8EX / >Y&"01[4&SEX/>Y" 016&6u6EX/>Y01&VuEX / >Y 01 &6cS N&V6&67EX/>Y01c&VEX / >Y01Pr8&7u8EX/>Y)01_&WuQEX / >Y) 01Pr8&78EX/>Y)01_&W[EX / >Y)01PMr&7y_EN&Wy]Pr&7u_N&W3Pr8&79EX/>Y+01_&WpEX / >Y+011&8f V@&X1M&8y M@&Xy16&87EX/>Y 01 y&X]]O]01"&9:EX/>Y01&Y\EX / >Y01&9p>EX/>Y01&Yp^EX/>Y01&97EX / >Y01&YEX/>Y01&9KAEX / >Y 01[&Y EX/>Y015&9D6EX/>Y01 &YEX / >Y 01{ UEX/>YEX / >YEX/>Y в 9  +X!Y +X!Y01327#"&547"'33265N04 FZYgO!;r`Hy,hVaS&O:oEX/>YEX/>YEX/>YEX/>YEX / >Y +X!Yа/9 +X!Y01!327#"&547'#"&'33273:qN04 FZYglѭF-[VHy,hVjeE=6&;6EX/>Y01+&[$EX / >Y016&=6EX/>Y 01K&]%EX/>Y01&=j6EX/>Y01Vz6&>u6EX/>Y 01X&^u!EX/>Y 01Vz&>n6EX/>Y01X&^EX/>Y01Vz6&>7EX/>Y01X&^@EX/>Y01WB&uBEX/>Y01N|&uzEX/>Y@ 01v&uEX/>Y,01[z4&u7EX/>Y) 01&0&/x,qq/]rOq]_]01&0&/x6]Oqrrorqq_]/]01(&&E  ] ]01p&3DEX/>Y 01p&3udEX/>Y 01p&3nEX/>Y01p &3j"EX/>Y01p&3jEX/>Y01py&3)EX/>Y01p|&3' `J0&1yt&(DEX/>Y 01&(u7EX/>Y01&(AEX/>Y01&(jqEX/>Y01_&DEX/>Y01/&uEX/>Y01$&EX/>Y01<&jNEX/>Y 01X &"EX/>Y 01`Z&DEX / >Y01`Z&u}EX / >Y01`Z&EX / >Y 01`Z &"EX / >Y01`Z&jEX / >Y#,01t &DEX / >Y01t &u^EX/>Y01t &hEX / >Y01t &jEX / >Y"01 &u3EX/>Y 01p&3pl&EX/>Y 01p&3EX/>Y01OpiEX/>YEX/>YEX/>YEX / >Y +X!Yа/9/ +X!Y901#327#"&547!#!&:qN04 FZYghnxs-[VHy,hVl !`0&1uiEX / >Y01`0&1sEX / >Y!01`0&1PEX / >Y#01`0&1EX / >Y!01&01EX/>Y01&(p?&EX/>Y 01&(lEX/>Y01&(EX/>Y01O|EX/>YEX/>YEX/>Yа/]] +X!Y +X!Yа  +X!Y +X!Y01!!#327#"&547!!!!Wk=:qN04 FZYg-[VHy,hVi&(VEX/>Y01c5&qEX / >Y 01c5&EX / >Y 01c5&NEX / >Y%01c5&OX&EX/>Y01X &"EX/>Y01J&p&EX/>Y01!&IEX/>Y01Of&c&EX/>Y 01+ &EX/>Y01W&&uEX/>Y01&&~EX / >Y01&f7X&uEX/>Y 01X&lX&EX/>Y01`Z&p&EX / >Y01`Z&EX / >Y01`Z&EX / >Y"01%&u'EX/>Y01%& %&FEX/>Y01C&u>EX / >Y(01C&HEX / >Y*01CM&ySC&]EX / >Y*01(&(&PEX/>Y 01(O&y>t  &d"EX/>Y01t &pf&EX / >Y01t &EX / >Y01t y&)EX / >Y01t&EX/>Y01tt  UEX/>YEX/>YEX/>Y в 9  +X!Y +X!Y01327#"&547"&'33265 xo2lN04 FZYgZz0([RHy,hVhVθy{ 1&;EX/>Y01 &=EX/>Y 01 &jmEX/>Y01G&u3EX/>Y 01G&EX/>Y01G&REX/>Y01?&%)F?&)r7A&,=w@&-?&3/?&=d]?&2t&*EX / >Yа!01%&F)Vz>,w-/R12v 3418=9<^&-jpBEX/>Y 01&=j6EX/>Y01dw:&uEX/>Y$01c9&+EX/>Y(01a:&FEX/>Y01K%&*EX / >Y01t&!EX/>Yа'01?:[4NS`:v!:ZZLtInEX/>YEX/>YEX/>YEX/>Y999  +X!Y9 +X!Y012337#"&'#&#'6®X=DH/%[x>IkDDI/^rn&jEX / >Y01&jwEX/>Y#01[4:&SCEX/>Y01%&"EX/>Y01z"&SEX/>Y&01F&)jBEX/>Y010B&uBEX/>Y01Pr&d'(9EX/>YEX/>Y а +X!Y&9& +X!Yа" +X!Y01&&54$32#4&#"#"$&533264&VܖkcãGϘty}oY{f{os|uw-^&-jpBEX/>Y 015.,0&/u{0EX/>Y01M&CEX/>Y01%&0F)&1CEX/>Y 01R1,v 34w'189<mNE]NI&EX/>Y 01[4NS`NT\NK9EX/>YEX/>Y +X!Yаа +X!Y01%2673#"546632#&&#">cvntٔixZ]d'ڮi#K:]):\]&IjEX/>Y%.01G&uEX/>Y 01_NWhMD&jVEX/>Y 01KYN?&u;EX/>Y 01K&]PEX/>Y01=6&;D,6EX/>Y01+&[DEX / >Y 01=6&;u6EX/>Y01+&[uEX / >Y 01=&;j6EX/>Y#01+&[jTEX / >Y016&=D6EX/>Y 01K&]DEX/>Y 01g! #&K?&HEX / >Y010GR6&1u6EX/>Y01x&QuEX/>Y 01k&%mkN&EFB&)DBEX/>Y 01B&DmBEX/>Y 01]&IDEX/>Y 01&DEX/>Y 01Z!_(C:&9EX/>Y01 &EX/>Y 01[K@N&S]vK 0&3]PQj&QXRM&QCwQ&'Q\QN&GQR=.`:w-5&CEX / >Y01&_EX / >Y01w-&%7EX/>Y01m&EEX/>Y,01&%j6EX/>Y01m&EjEX/>Y0901WN|NF&)CEX/>Y01]&IEX/>Y!01]&XjEX/>Y'001bOb&jEX/>Y$-015&jBEX / >Y&01&jdEX / >Y&01Pj&jWEX / >Y0901X&j^EX / >Y.701&pJEX/>Y 01&puEX/>Y 01&j6BEX/>Y01&jEX/>Y01v &3j8EX / >Y'001[4&SjEX/>Y#,01g[4Ng&j'=EX / >Y'001[4&jEX/>Y$-01&j XEX/>Y'001d&j|EX/>Y'001M&pJEX/>Y01K&]p#EX/>Y01M&jBEX/>Y"01K&]jUEX/>Y 01MA&/BEX/>Y01K&]EX/>Y 01&j BEX / >Y#01g&jdEX / >Y!010&'-jBEX / >Y(01&'*jmEX / >Y(01_H&%mN&EJ&%FEX/>Y 01m&EEX/>Y)01&%7.EX/>Y 01m&E7hEX/>Y,201&%8=EX/>Y 01&E8lEX/>Y,101&%9EX/>Y 01mY&E9mEX/>Y*001&%:EX/>Y 01m&E:lEX/>Y*3016&%'6EX/>Y01m&E&nJEX/>Y-01&%<-EX/>Y01m&E<EX/>Y,901&%5-EX/>Y01m&E5EX/>Y,:01@&%==EX/>Y'01m &E=EX/>Y,E01&%PEEX/>Y01m&EPEX/>Y,:01&%'7EX/>Y01m&E'JEX/>Y,01F&) ]N&IF&)REX/>Y 01]&IEX/>Y01F.&)FEX/>Y01]&IZEX/>Y!01&)7:EX/>Y 01]&I7XEX/>Y!'01F&)8IEX/>Y 01&I8\EX/>Y!&01&)9'EX/>Y 01]I&I9]EX/>Y%01F&):EX/>Y 01]&I:\EX/>Y!(01FB&)'B EX/>Y01]&I&^EX/>Y 01&-dREX/>Y01&JEX/>Y01~&-k h&MM v &3[4N&Sv &3HEX / >Y.01[4&SEX/>Y*01v=&370EX / >Y# )01[&S7bEX/>Y%01G &38?EX / >Y! (014&S8fEX/>Y$01v &39EX / >Y! '01[S&S9gEX/>Y#01v &3:EX / >Y! *01[4&S:fEX/>Y&01v 8&3'8EX / >Y"01[4&S&hEX/>Y01e1&u1EX / >Y(01[&ueEX/>Y& 01e1&DN1EX / >Y'01[&DEX/>Y% 01e& AEX / >Y401[&EX/>Y201e&5EX / >Y)01[&kEX/>Y'01e7& [&&9:&YQ&9FEX / >Y01&YEX/>Y01B&uBEX/>Y01&ucEX/>Y 01B&DEBEX/>Y01&DEX / >Y 01&REX/>Y)01p&EX/>Y(01.&FEX/>Y01&iEX/>Y01& &&=:&]c&=FEX/>Y 01K&]JEX/>Y01"&=:EX/>Y 01K&]!EX/>Y01_&H'&GCd/]011&8Q?(:&Q&Qg;&Q0&QG:&Q?U&LQYcN&MQLdEX/>YEX / >Y 9/9/  +X!Yаа +X!Y  +X!Y01#!!#53533!2654&'Pj_PPݘ{dEX/>YEX / >Y 9/9/ +X!Y аа +X!Y  +X!Y01#!!#53533!2654&'Pj_PPݘ{0 PEX/>YEX/>Y 9 /z ] +X!Yа а  +X!Y01!##53!!!B Tm1G: KEX/>YEX/>Y 9 / +X!Yа а  +X!Y01!##53!!!xܺ $!ߗę1EX/>YEX/>YEX/>YEX/>Y9//]] +X!Y9/ +X!Y а в901###53533#33#7Ur7>(vEX/ >YEX/>YEX/>YEX/>Y9/ +X!Y9/ +X!Y а в901###53533#33#~; W 9EX/>YEX / >YEX/>Y9/ +X!Yв 901###53333۔Qz|Q  %.`:d 9EX/>YEX / >YEX/>YEX/>YEX/>Y +X!Y 9 а01###53333Jܿ k&R9dEX / >YEX/>YEX/>YEX/>Y 9/ +X!Y 9а в 901####53333Ĥk_]kb8{.):dEX / >YEX/>YEX/>YEX/>Y9/ +X!Y9а в 901####53333<AA֧ku>cM/&*&"Fff@]3^5P-0"dzW&+uWEX / >Y"01`V&KuKEX/>Y' 016&2Df6EX/>Y 01&RDEX/>Y 01 &%m2EX/>Y 019&EEX/>Y* .01_F,&)8>EX/>Y 01)&IEX/>Y #01 ,&->EX/>Y 01&EX/>Y 01v "&34EX / >Y!%0134&S EX/>Y !01U &6.2EX/>Y01&VdEX / >Y 01 &9h2EX / >Y01+&YEX/>Y 01?&d&&  &F&( _&H &(e]01_&Hi&, &L 0&/u{0EX/>Y01 A&OuDA /01&/Y &OeF&0 a&PN R&1 xN&Q &2$ N&R v &36 S*EX / >Y#ܲ#q#qO#q/#q701B&4u|BEX/>Y01`&TuEX / >Y 01&6 N&VJ Pr&7_N&W1&8 V@&X&96QEX/>Yܰ*01.&:FEX/>Y 01!&ZEX/>Y 01&: !:&ZM =&; +:&[S Vz&> X:&^b 2O&3Fqp&3c&(<&<&<d& X&<d& 7p32(GXQWwX`Z( &1<&jNEX/>Y 01 &jmEX/>Y01&(jqEX/>Y01&u4EX/>Y01CQ<&jNEX/>Y 01+MW&u%EX/>Y01" &gEX/>Y01p32(a&EX/>Y 01wX`ZD`01(&1GP)EX / >YEX/>YEX/>Y  +X!Y 9' 9|'/']'q']`'p']0'q`'p'q& +X!Y&'9в 9  +X!Y014&#"#4632#&&5332654%#536}nngvq˯yPT]XOV)$[[V``X_/EX / >YEX/>YEX/>Y  9| / ] +X!Y  а +X!Y01##!#3!33\g `V0ZEX/>YEX/>YEX/>Yаа +X!Y +X!Y01#&5546632#&&#"32670˩{~y`aӻt˽jo Qk&Qa&p&EX/>Y 01" &p:&EX/>Y01`5& &su`Z&uu}C&)1&D1&u11&jk &DO&%|mON&EYF&): ]ON&IOp&3W&(`:&M hexwalk-1.9.1/src/hexwalk/fonts/Courier.ttf0000664000175100017510000020532015002001047020222 0ustar carmixcarmixGDEFs@HOaisw~7&     " & 0 3 : D t !""""""""+"H"`"e% (29?AJPbjtx7&     & 0 2 9 D t !""""""""+"H"`"d%dTZrd L!C87g0-!ۇQnvltmnopqrs}uvwxywVdXgWfeYhZi[jTU\k]l_nbq'(ap^m`ocr` b#j#m2w 2  Q  X Y 6+p\)G"y#%W09".: !w"""#5#$ $t$%c%&E&&''(=()*+*++,,-=-p. .6../_/00d001)1p12e3g4~555,5>5P5b5t6%667 7717C7U7g7y778 88.8@8R8979I9[9m999:::::::;>>>>>>?q?}????@eAAAAAAAABBCCrD{DDDDEF+F=FIF[FgFyFFFFGGGHIJI\IhIJJKLQLcLoL{LLLLLLLM[MMMNNN#N/NANMN_NkNO}OOOOOOOOPP Q)RFRXRdRpR|RRRRRRRRS SSTTTTTTUUUUUVVNVVVWDWXX\XXXY'Y\YlYzYYYZZ[[\\Q\~^ ^k^__U__````aab>bcvdNe eeff!fgg'gggggghhh%hdhph|hiRi^iiiijjjj'jvjjjjjkillllm#m1memmmmmnnn&n6nFnVnfnnn~n DFLTgrekplatnLCAT :MOL (ROM       !aaltaaltaaltaaltaaltaaltcasecasecasecasecasecasefracfracfracfracfracfracloclloclloclordnordnordnordnordnordnsupssupssupssupssupssups T4f8kyky$2DR hvYv/O"Cinsw*+,-./01$ 4 2R $D, |z{xqrs$ ./vO'( TU:xqrskyky'($2CDRinsw *+,-./01TU     > *f L ($ $ J 6 ,T  4 4http://scripts.sil.org/OFLThis Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFLhttp://basicrecipe.comhttp://quoteunquoteapps.comAlan Dague-Greene, Quote-Unquote AppsQuote-Unquote AppsCourierPrime-RegularVersion 3.018Courier Prime Regular3.018;QUQA;CourierPrime-RegularRegularCourier PrimeCopyright 2015 The Courier Prime Project Authors (https://github.com/quoteunquoteapps/CourierPrime).<2)kt}2 PvPPPbPsPPFXPXPzF 2<Jf9%MCM%uH2F2o<5$" ._4      vPPPP2FXXXXXXFFFF<n(KMTHHHH2%2   vvvvPPPPPPbbbbPM9sPCPPP<FMFMFMXX>FPPPzuzuFHFHFHFHFH<!''p=b""~m2o<Qt*9zuPPFXzF<<auH22P( '_'59="pG  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~NULLuni00B2uni00B3uni03BCuni00B9AmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacron Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccentuni0122uni0123 Hcircumflex hcircumflexHbarhbarImacronimacronIogonekiogonekIJij Jcircumflex jcircumflexuni0136uni0137Lacutelacuteuni013Buni013CLcaronlcaronNacutenacuteuni0145uni0146NcaronncaronOmacronomacron Ohungarumlaut ohungarumlautRacuteracuteuni0156uni0157RcaronrcaronSacutesacute Scircumflex scircumflexuni021Auni021BTcarontcaronUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonekZacutezacute Zdotaccent zdotaccentuni0218uni0219uni0237uni03A9uni0394uni0162uni0163EbreveIbreveItildeLdotEngObreveTbarUtildeWacute Wcircumflex WdieresisWgrave YcircumflexYgraveebreveibreveitildeldotengobrevetbarutildewacute wcircumflex wdieresiswgrave ycircumflexygraveuni2074uni00ADuni2011uni00A0Eurouni20A9uni2215uni00B5minuteseconduni0326 uni0326.case acute.case breve.case caron.alt caron.case cedilla.casecircumflex.case dieresis.casedotaccent.case grave.casehungarumlaut.case macron.case ogonek.case ring.case tilde.case, UXEY KQKSZX4(Y`f UX%acc#b!!YC#DC`B-, `f-,#!#!-, dBCC ``BCB%CCTx #CCadPxC`B!e!CCB C#BC`B#PXeYC`B-,+CX#!#!CC#PXeY d P&Z( CEcEEX!%YR[X!#!X PPX!@Y 8PX!8YY  CEcEad(PX! CEcE 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY% CcRXK PX! CKPX!Kac CcbYYdaY+YY#PXeYY dC#BY-, E %ad CPX#B#B!!Y`-,#!#!+ dbB #BEX CEc C`Ec*! C +0%&QX`PaRYX#Y!Y @SX+!@Y#PXeY-, C+C`B-, #B# #Babfc`*- , E Ccb PX@`Yfc`D`- , CEB*!C`B- ,C#DC`B- , E +#C%` E#a d PX!0PX @YY#PXeY%#aDD`- , E +#C%` E#a d$PX@Y#PXeY%#aDD`-, #B EPX!#!Y*!-,EdaD-,` CJPX #BYCJRX #BY-, bfc c#aC` ` #B#-,KTXdDY$ e#x-,KQXKSXdDY!Y$e#x-,CUXCaB+YC%B%B%B# %PXC`%B #a*!#a #a*!C`%B%a*!YCGCG`b PX@`Yfc Ccb PX@`Yfc`#DC>C`B-,ETX#B E#B #`B #B `aBBB` C`#B++"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-+,# bfc`KTX# .]!!Y-,,# bfc`KTX# .q!!Y--,# bfc&`KTX# .r!!Y- ,+ETX#B E#B #`B `aBB`++"Y-!, +-", +-#, +-$, +-%, +-&, +-', +-(, +-), +-*, +-., <`-/, `` C#`C%a`.*!-0,/+/*-1, G Ccb PX@`Yfc`#a8# UX G Ccb PX@`Yfc`#a8!Y-2,ETXEB1*EX0Y"Y-3,+ETXEB1*EX0Y"Y-4, 5`-5,EBEcb PX@`Yfc+Ccb PX@`Yfc+D>#84*!-6, < G Ccb PX@`Yfc`Ca8-7,.<-8, < G Ccb PX@`Yfc`CaCc8-9,% . G#B%IG#G#a Xb!Y#B8*-:,#B%%G#G#a B C+e.# <8-;,#B%% .G#G#a #B B C+ `PX @QX  &YBB# C #G#G#a#F`Cb PX@`Yfc` + a C`d#CadPXCaC`Y%b PX@`Yfca# &#Fa8# CF% CG#G#a` Cb PX@`Yfc`# +#C`+%a%b PX@`Yfc&a %`d#%`dPX!#!Y# &#Fa8Y-<,#B & .G#G#a#<8-=,#B #B F#G+#a8->,#B%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%acc# Xb!Ycb PX@`Yfc`#.# <8#!Y-?,#B C .G#G#a ` `fb PX@`Yfc# <8-@,# .F%FCXPRYX +.0+-~,>+@+-,>+A+-,>+B+-,>+@+-,>+A+-,>+B+-,?+.0+-,?+@+-,?+A+-,?+B+-,?+@+-,?+A+-,?+B+-, EPXEX#!!YYB+e$PxEX0Y-K*9W@T6-#L ~g W _O9842(& 5 +#!"&5463!!6&547&546326632#"'#."""5- $""$& &*%C%%%!y  M hf MU LKPX@a$Ma#N@ia#NY@ %+#"&'&633#"&5546310;;BB;;B=""""#  <KOX@UG< !L   hg  (M)NLLLOLONMKJEC@?:853!$%##$!$+##32###"&547!#"&547#"&546337#"&546336632!663237!s"@""S,KS,K""@""Q,HQ,Hy@@a!''!!''!  !''!!''!7 7 { GPY@XO:9 (& LK PX@, Yi Y   ia $N@2 Y Yi Y   i aQY@QQHHQYQYHPHPGF%(#%( +54632#"'&'#"&55&'#"&554632&'&&5466354635654&'&'!_Q"))"")"<LPYWv!%%!|U"))"") qYFIQ[f!%g)(#Pn,),U "I-###tnZXL""U8###KVgSW}@"E< ( _SB", 2!1AQb@_i    i a (Ma)NBB22""BQBPJH2A2@:8"1"0*(&+#"&&5466332#"'&547$326654&&##"&&54663326654&&#~JJ~JJ~JJ~Jj2B''B''B''B'~JJ~JJ~JJ~J'B''B''B''B'J~JJ~JJ~JJ~J>'B''B''B''B'J~JJ~JJ~JJ~J'B''B''B''B'm>HK1PX@ 8HG#/L@ 8HG#/LYKPX@(ia (Ma#NK1PX@2ia (Ma#Ma)N@0ia (Ma#Ma)NYY@FD>=#4#$:$& +#"&55&#"676332##32##"''#"&&5467&54663327"))"Lm7Q*)*%( (""]$2mT""r0WiQf]cSd=.R5v[h'##Z/.N/4Y/Xm*%%z_z%%!aZ[eAtYT+kC4T0p& 6KPX@ _$N@WaQY@ $+#"&'&337#$7/2>2)aeJKPX'NvY+32#"'&&5467     z׉ye rr IRTIke IK PX*NvY+#"&'&547654'&5476632B؉z     I rptr  5T@0/'#LK*PX@(M+N@(NY@ 54$.%+%632#"''#"'&5477%&&5476632&5463-$% " **** " %$-*0*y !&5%..%5&! y #("-@*YgaQ$##$#+!2#!#"&5!"&5463!4639""%%""9%"%%""9%%9"t&@ LWaQ&&+#"5476633DH^&)2 " @W_O 4+#!"&5463!"""%%%%, @a#N %+#"&55463??HH??H,""""r6 LK PX@ *M'N@ vY@ '+#"&5476634`#(4#r  k,@)a(Ma)N&+#"&5463326654&&#iiiiOyDDyOOyDDyO鸸ꙙoӒnnӒo 0@-L(M`#N'#$4+$#!"&5463!#"'&547%632!"^""  y%%%%Z )" /l"LKPX@$pa(M`#N@%~a(M`#NY@/.$*5#+!54632#!"&5476654&#"#"&5547663`ek"))""J"\Kwmna"))"IZSmfm~##%%&^}H]m8n##'5;>K@H1Lia(Ma)N>=$$44$, +#"&'&54763232654&##"&546332654&#"#"&5546763^PI[eabO BN|vI""7rvvltQ"))" QdV}%&fm\D:* 19ufgk%%`\Ua'C##m X'%(6@3(Lg(M`#N'&%$!$4!$" +32##32#!"&546335!"&547663!F""""R"""" 2&kVN%%%%%%%!74F@CL~i_"Ma)N42#&$&"$ +#!632#"&'&547632326654&&#"#"&7663!". dsx]h~`O AKQx?;oJDl3"*# )%%8fuuj@7+ .6AuNJr@#$ ## ,<@9Lia(Ma)N,+%#&$$+6632#"&'&54$7326654&&#4Vnefym8MAtA?sLLr>=qN&3DJ^pl`d_ϭ4 7a?Fn>8gDEh9R LK PX@r_"M)N@_"M)NY@ #'+#"&547!#"&55463!V '$-&"))""% ##%+;D@ALia(Ma)N,,,;,:42+*$", +#"&&5467&&54663326654&&#326654&&#Ω`\J]pjttjp\J[`h>a88c<Ip??pIIp??pIW[Q(*bg^^gb*(Q[W-T83T00T38T-6a>>b77b>>a6,<@9Lia(Ma)N,+%#$$'+&5467$$7#"&&54663326654&&#Ƿ8M 4VnefyLr>=qNItA?sLd_ϭ &3DJ^pl`8gDEh97a?Fn> ,@)a%Ma#N %+&554632#&554632#??HH??HH??HH??Hp"""""""" *@'Lea%N %+&554632##"5476633??HH??HDH^p"""")2 }{@ LYaQ +32#"'&&5467! )`) ! +!!+ }  }:"R 0@-gW_O 4+#!"&5463!#!"&5463!"""""""R%%%%p%%%%{O@LYaQ'+#"'&547&5476329! )`) !   +!BB!+ '5x@  LKPX@&~a$Ma#N@$~ia#NY@(((5(4/-'&$,)+#"''&677>54&#"#"&5546763#"&55463֝SEm =? EP]-e\X"))" 66==66=O]V{[-00!:H1KZ%Y##["r""r"2g6JX[@X   L i   i iYaQKKKXKWRPJI'2&%.&$& +#"&'#"&&546632763232654&&#"3267632#"&&54$3326654&#-~FSA]4^?1Q.VUV*M(#KV`y}Z{E5 6Q{96!$4$$$4!$ +##32#!"&54633#"&'32#!"&54633#"&546332633s"26""""o +$$+ o""""61"" 0%%m%%%%3##:%%%%%%a!F5a+ LKPX@_ "Ma)N@_ "M_#M)NY@53%4!$4$#$ +###"'#32#!"&54633#"&5463323#"&5463!i"9%&5""""CM""y""D%%  7%%%%%%%%Xt,@)a(Ma)N&+#"&5463326654&&#n[[nn[[n鷷陙rԎrrӎrPX!*5@2g_"M_#N*($"!!$4!& +##32#!"&54633#"&5463!32654&##7cc""""""#֋^qq]%%%%%%~qsXt9I@2/L KK$PX@'ie a (Ma#NK&PX@%iie a (N@*iii a (NYY@:::I:HB@981%-##& +#"'6323267632#"&&'&&#"#"'&5477&5463326654&&#QO 9+E'(M+  :g3;%4E(lu!# o[[oo[[o  +$ 1." :#ϲ jȉiiȉjP<D?@<Li _ "Ma#NDB?=<:!$4!)4> +332##"&'&'&&'&&##32#!"&54633#"&5463!3 54&##]8%,'3""H>""D""pp""D%%n%%%%~%% '-@*L_"M)N'%"$4##$+###"&'#"&5463!2###"&5463!"M 3,+3 L""v""25d""N%%#"%%%%t%%4a+$ LKPX@_ "M%M)N@_ "M)NY@42$#$4#$#$ +###"'#"&'#"&5463!2##632#"&5463!"6)(RS')1""X""d: #h|""D%%$AEA#%%%%L/!%%2C@@=:)L _ "M_#NCA=;974"$4"$4"$ +##32#!"&5463332#!"&54633#"&5463!2###"&5463!_"AZ:""""mS"""">]E""X""Y<""0%%N%%%%m%%%%%%%%<%%<27@4)L_ "M_#N20"$4"$4"$ +##32#!"&54633#"&5463!2###"&5463!s"D""""F""N""]A""0%%%%%%d/%%%%g%%#%6@3~_"M`#N%##5#+!4632#!"&547!#"&5463! i"))""" "))""%P ##%%##=%Jf\)@&gW_O$54+#!"&5463!2#!!I"b""""G!''!%!%!''!wr6LK PX@ *M'N@ vY@ '+#"&'&54639#4(#`4(r k f\(@%gW_O!$5+#!"&5463!!"&5463!e"b""G""\%%!''!!''!(dD@Lv'+D#"&'#"'&&547663 44     O| dD@W_O%$+D#!"&5463! * ****9+dD@v+D#"'%&547632+!"\n ') .:KPX@76L@76LYKPX@) ia +Ma#NKPX@3 ia +Ma#Ma)N@1 ia +Ma#Ma)NYY@///:/953.-#$%$44 +332##"&'#"&&5463254&#"#"'&5476633275&&#&B#""@A]RkeXⳟmyKI! %Tae[ǠDOrO%%A?HNE[3Ua[*% 0#,/OVIQm%M %5LKPX@#_$M a+Ma)NK PX@-_$M a+M_#Ma)NK1PX@+i a+M_#Ma)N@)i a+M_#Ma)NYYY@&&&5&4.,%#!$5&$ +632#"&'##"&54633#"&54633326654&&#C|pp|b?"""Rf""OOYYCCY %1u۔uXRP%%%%%PhhPUccU2C@@.La+Ma+Ma)N21&'#&%%+#"&54&&#"3267632#"&&5466325463""))"@Y`VQ`\G PrxzۍY4")###=^4V`aV96)#86/.$$$$5 +546332###"&'&54763232655#"&&54663326654&&#?"""Re`U'' NO||pp|OCCYYOOYXRP%%%wZ!'7 rɜoЌoO[[OJ``JM ;mLK PX@$ _  $Ma+M_#N@"   ia+M_#NY@;9!$4$#$4$% +663232#!"&546334&#"32#!"&54633#"&54633aAc[HR""""\RPUX\""""R\"" %agOc%%%%Yhbj%%%%%%IS"e-fS")-C ?u@ =,LK PX@%_$M _%M _#N@#i _%M _#NY@?><:4$4!$4#$4 +$#!"&5463332#!"&54633#"&546332#"&5463!2##3j"""HI""""o"""}G""N"";P:%%%%*%%%%%%%P%%%%w? GK PX@_$M_#N@g_#NY@ !$4#+!2#!"&5463!!"&5463!A""""9""h %%%%%%%PK1PXHBLHBLYKPX@ a  %M _#NK1PX@* a  +M _ %M _#N@' a  +M _ %M _#NYY@POKIFD?%%%PEEWc%%%PEEWc%%%%%%%c^_\Y;yXM;K1PX8L8LYKPX@a %M_#NK1PX@& a  +M_%M_#N@$ a  +M_%M_#NYY@;:4!$4$#$4$ +32#!"&546334&#"32#!"&54633#"&5463326632HR""""\RPUX\""""Rf"""BfOc%%%%Yhbj%%%%%%%xflH,@)a+Ma)N&+#"&&54663326654&&#}}܉}}܉aPPaaPPa|݋||݋|UbbUUbbU%|M)9& LKPX@$ a %Ma)M_'NK1PX@/ a +M _%Ma)M_'N@, a +M_%Ma)M_'NYY@***9*820)(4!$4"& +#"'32#!"&54633#"&546332663326654&&#pp|""X""fR"""?bcOOYYCCYu۔uu%%%%%%%PRXPhhPUccU|)9LKPX@$ a %Ma)M_'NK1PX@/ a +M _%Ma)M_'N@, a +M_%Ma)M_'NYY@***9*820)("$4!$5 +546332##32#!"&54633#"&&54663326654&&#?"""Rf""X""|pp|OCCYYOOYXRP%%%%%%%u۔uUccUPhhPR0v@ ,LKPX@!a%M_#N@+a+M_%M_#NY@0/4!$4$# +#"'&#"!2#!"&54633#"&546332>3D( % 18ZuQ""|"""""0K(&9}u%%%%%%%XHLQ@NH!La+Ma+Ma)Ma)NLKFD31-+&$#% +#"'&&#"#"&'#"&55463232654&'&&'&&'&&5466325463"")"+~am)(!WEaw5PY[zl="))"") $t|,)#[F^~5IQ[fa:")##RCE> (  nZZJ<=8###`XTF",  gSW}@:4-#uH-6@3g(Ma)N-,$#'##$# +!2#!3267632#"&5#"&54633463"""eObCE" !NS""")#%%rj6- . 1?y%%,#Hx3LKPX@_%Ma#NK1PX@$_%M_#Ma)N@"_%M_#Ma)NYY@31$%4$%4# +32##"&55#"&&5#"&54633232665#"&54633R"""Bf[HR"""RPUX""%0%%%yflOc%%%Yhbj%%2'-@*L_%M)N'%"$4##$+###"&'#"&5463!2###"&5463!}"?7105>""b""W"":%%""%%%%t%%6:@7-&L_ %M)N64#$$4#&#$ +###"&'#"&'#"&5463!2##6632#"&5463!" '&+1 3+&& ""&""{&?e""%%$"N"$%%%%()F%%FC@@=:)L _ %M_#NCA=;974"$4"$4"$ +##32#!"&5463332#!"&54633#"&5463!2##7#"&5463!_"AA3""""`O""""2EG""X""L7""0%%%%%%%%%%U7%%%%%%2e.4@1%L_%Ma-N.,"$4$#$$ +##&547>7#"&5463!2###"&5463!}">gA|o#&5`q_E?""b"" Y"":%%G%/A6%%%%2%%%K PX@#rp_%M`#NK PX@$r~_%M`#N@%~_%M`#NYY@%##5#+!54632#!"&547!#"&55463!"))"""c9"))""%^##%%##%\;h@ 6 LK PX@iea*N@!iiYaQY@;:1/+) $+#"32#"&5477654&#"&54632654''&5463"jy1o~q"" ""\!''!:{dHx4 %n y t!''!#{ qq!''!~t J r .K PX@ *M'N@ vY@ %+#"&5463""))"")r###S#\;e@ ,LK PX@iea*N@!iiYaQY@;:64$)$)+32#"#"&54632654''&54675&&776&&#"&5463"" ""q~o1yj""\ J t~!''!qq {#!''!t y n% 4xHd{:!''!6%LdD@A  LYiaQ%$"$'"$+D327632#"&'&&#"#"'&547663e@:H'UF /N:dB8J&UF /N*(" T L[*(!!T L[ TLKPX@a%Ma'N@ea%NY@ %+&554632#&76632##$;;BB;;BX10""""= :Cc@?2!>3LK PX@ia$N@ YiaQY*%).)+#"&55.546675463254632#"&54&'667632$ B_!%%!~fh|!%%!An("))""))"ohH8@uNMuAG#2@ ""Ѓ"" =/<####Qm i 6+)[ \S^@ .#G3LK&PX@3  i a  (Ma#Ma)N@7  i a  (Ma#Ma)M)NY@^]VTPN$-#%$($' +#"&55&#"!2#!632327632#"&'&&#"#"'&5476654'#"&54633'&&54663ĤE"))"Nu7T,6""FD 7(>$JM   :e03+2B&hu   o[""_$$Ud71'##Z//Q1*N:,*%%  8 +% 1%  eV%%#Ib:\Uoc]Q7GI@F)%73 LYiiaQDB<:-+(&#!##%+%#"''#"'#"'&5477&547'&5476326327632$326654&&#"FggHHggHHBwMMwBBwMMwBCCffCCffxCCxKKxCCxK<TX@UKL  g g  _ "M_#NTRNLJHDA=;:8421/!$4!$!$!$+##32##!2#!32#!"&546335!"&5463!'#"&54633'#"&5463!2###"&5463!s"Dz""l'""""""""'l""{F""N""]A""0%%%%%%%%%%%%%%%%%%g%%r RK PX@a*Ma'N@iYaQY@ %+#"&5463#"&5463""))""))""))"")r###W####W#=O@ F6LK PX@ rpd_"NKPX@!r~d_"N@"~d_"NYY@=;+)&$#%+#"&55#"#!"&5546323254&'%&&5467&54663!6654&'%&'"))"AA&STDF@}Z""))"AASTCG@}ZZ04&9-04>)%##l4U(3zS@d316Gl=%##l4U(3zS@c407Gl=0(9!#-0(9!&)5OS 4dD@)YaQ %+D#"&55463 #"&55463((77((7((77((7S$$$$$$$$$KgdD@\~   i   iiYaQ  K JDB:853/-)(& +D#"$54$3326654&&##"'&&#"3267632#"&&54663 ssЅssЅ<]* %A&OffO&A% *]-[PP[檪椤xᎎ ⎎ဘ (qiiq( SjjS .8X@U65L i ia3Ma5N///8/742.-$%#45 +332##"&'#"&&5463254&#"#"'&5476633275&#12O NzFfNR:> !CKG>wmrz /,m3dGzv3>D-!  ho04uE>6M%@"W_O#%+#"&5!"&5463!"))"+"",M%v##F%%4H6=FkdD@`&)L  i   igYaQ FD@> = ;6410.,& +D#"&&54663326654&&##"''##"&5463332654&##{{܋{{܋o``oo``oP\1?:YJjX8854_6ꎎ뉉뎎djvwkkwvj/T6>V`p/+)."R 'dD@W_O 4+D#!"&5463!""" !''!!''!&7dD@,iYaQ&+D#"&&54663326654&&#ZKKLLKKL'C''C''C''C'KLLKKLLK'C''C''C''C'r"f->@;gi W _O - +'$$##$# +!2#!#"&55!"&5463!5463#!"&5463!9""%%""9%"""f"%%""%%"%%%% 6/l"LKPX@$pa2M`3N@%~a2M`3NY@/.%)5# +!54632#!"5476654&#"#"&5547663DOTB $$/L95PJ*U" $$;I6?tMM}FNH'1P1:Eg'+.6;O@L.Lia2Ma5N;:$$34$* +#"&'&54763232654&##"546332654&#"#"&5547663GpBIJ; 3s6Zb_Y4,'TVXNOD $$9G6#:?:=?n "#dD@Lv' +D32#"'&547"!\)'  r-7@4 LMMaMN-+%54%5+##"&55#"'##"&546332326654633!''?edC!))!!))!Y]L_!)###bz/####Zgfeo#f] ,@)_"M-N ##$+###"&5##"&5.54663!@"D"))""))"uci{%%##t##OSgjR 5+_(b |dD LK PX@(riYbR@)iYbRY@ $$$+D#"&'&54763232654&#"&553f|yD3+g/3:6>'p^KWh -!! ͍470@- L2M_3N'##4 +#!"54633#"'&547%63232̩ - `!!?!'X " T*@'ia5N& +#"&&54663326654&&#ѭcckkcckFm<mEEn==mFEm>"r/NQodD@dP B L J   g  Y   i b ROO00OQOQ0N0MJH##&,#"1+D#!"5433#"'&547763232$#"'&547632###"&55!"&546766323#C**   Lj  n[=-[54J > 1!  y (r/]dD@DL JKPX@;   p g  i  W ` PK1PX@<    ~ g  i  W ` P@B  ~   ~ g  i  W ` PYY@000]0\YXRP%)6,#"1 +D#!"5433#"'&547763232$#"'&547632#!"547%6654&#"#"&55476632!5463C**   Lj  b)#(0+B>$F1=oBF 54J p 1}-< (D)19Vz !$tb@j9A"s;MlodD@.Ao e LKPX@N   iii Y  i b  R@T~   iii Y  i b  RY@$NNnmNlNkca^\YWSQGF>=;:$$34$*+D#"&'&54763232654&##"546332654&#"#"&554766332#"'&54732###"&55!"&54676633\o<^7==|1 *`-KROJ,$!FHJAC80x; j -[[=s2[:d3S>cq  '727-405125\  1!  y]  5y@ (LKPX@&~a%Mb'N@#~fa%NY@54-+'% %+&554632#&&54667763232754632#Q66==66=SEm =? EP]-e\X"))" "r""r"O]V{[-00!:H1KZ%Y##[ "$C 5+ "$s 5+ "$* 5+ ;"$0 5+ a"$i 5+ #"$. 5+r@DK PX@:r r g  g  _ "M ` #N@<   g  g  _ "M ` #NY@ AAADADCB@>:8751.!5#$!%+#"&55!32##!54632#!"&5#32#!"&54633#"&5463!3I"))""""))""B"HX""""2c""%##%%c##%%2%%%%%%v(EQ@0% LK PX@=   r  ifa(Ma(N@>      ifa(Ma(NY@PNKI%%%+$$$ +$6#"&'&54763232654&#"&55&&5463254632#"&54&&#"3267632Eef|yD3+g/3:6>'l^2"))""))"=~]l]XlcHq]^KWh -!! @;:####DpCrԎr:7'PL"(C  5+PL"(s 5+PL"(* 5+PLa"(i 5+",C 5+",s 5+",* 5+a",i 5+2t!5@@=i_ "M _#N"""5"431-+*(!!$!$6 +#!"&54633#"&54633#"&5463!6654&&##32##3)""p""p""```w""%%%%s%%i͓j%%hF;"10 5+Xt"2C 5+Xt"2s 5+Xt"2* 5+Xt;"20 5+Xta"2i 5+' @&La+N,$, +32#"'#"'&547&547632Xt%.7t@ 76,+ LKPX@ $Ma(Ma)N@ a(Ma)NY@&&1/&.&--*+#"'#"'&5477&&546327632&#326654'RYCG{M%XBGzNɧ[IUpqqn[JQ߆So ~Q߅Rp rԎx;Yrӎx:F"8C 5+F"8s 5+F"8* 5+Fa"8i 5+<'s < 5+n0*3A@>g_ "M _%M_#N31-+*(!$4!&!$ +##32##32#!"&54633#"&5463!32654&##"uRRu"""""" mtpq%%|U_^T%%%%%%cZXi(%9εLKPX@ a$Ma)NK PX@*a$M_#Ma)NK1PX@(i_#Ma)N@&i_#Ma)NYYY@98$5*$$,+#"&54632654&#"&54676654&#"##"&546334663V\Rl{fy2!"~v""bgumfs"""Yr%[b[+)zv[!,%"zrz!$$  pZ^ko%%%'n_"DC>"Dst"D*-"D0S"Di"D.K8?Je@b5L  i a +M a)N@@99@J@JFD9?9><;87&###'#!$+#!3267632#"'#"&&546354&#"#"'&547632663!&&#326655"q0P*7HQ0QNv@8K-V.{D(qGEN ,BB$<38[5"%)46CM@vPeb"#jt9;hulqdd9@9e?d(R@1& LK PX@=   r  ifa+Ma+N@>      ifa+Ma+NY@QOLJ%%%+$$$ +$6#"&'&54763232654&#"&55.54663254632#"&54&&#"3267632 Feef|yD3+g/3:6>'zczۍY4"))""))"@Y`VQ`\G#5A]^KWh -!! }~A<<####=^4V`aV96)C"HC>C"HsCt"H*CS"Hi I"eCI"esIt"e*IS"ei@43C@3( LKPX@($M$Ma%Ma)NK PX@&i$M$Ma)N@#ia)NYY@444C4B.&%&$+#"&&546632&'#"&'&5477&'&54763276326654&&#"3@{؇{{؇yvI +-M%"}` +ZOO^^OO^;urrΆrMxkZ!8'- =EY!<8L\\LL\\LM-"Q0H"RCH"RsHt"R*H-"R0HS"Rin" )A@>igYaQ)(#! % +#"&55463#!"&5463!#"&554631188118"""1188118"h""h"k%%%%"h""h"Tx%.7j@ 10(' LK"PX@+Ma+Ma)M)N@a+Ma)NY@ '%$+$)+#"&'#"'&5477&5466327632&#"$'32665xlU}܉V>mmU}܉V=l)PnaP)'OoaPi{|3/ij{|2/hL7UbdL88UbHx"XC Hx"XsHxt"X*HxS"Xi2e"\s%|M (8LK PX@,_ $M a+Ma)M_'N@* i a+Ma)M_'NY@)))8)71/(&!$4"&$ +632#"'32#!"&54633#"&54633326654&&#C|pp|""X""fR""OOYYCCY %1u۔uu%%%%%%PhhPUccU2eS"\i 'n$ 5+"Dn j"$, 5+\"D, (GKJ KKPX@*  ge _ "M a #N@1  ge _ "M a #NY@IHGEA?<953$4!$%'1$+327632#"&5467#"&54633'!32#!"&54633#"&5463!232##!#M*#4= KY]kPL~""RSy""""8K""o(1 a="">[Sz7#&6hWIF%%%%%%%%"&%%(FRpKPX@ RG LKPX@ RG L@ RG   LYYKPX@0  i ea+M a)NKPX@:  i ea+M a#M a)NKPX@A     i  ea+M a#M a)N@?     i  ea+Ma#M a)NYYY@QOKIEC><851/(&#! FF +32#"&5467&'#"&&5463254&#"#"'&5476632332##327&&#"327Q KY]k^Y;RkeXⳟmyKI! %TaB#""YM*#4=DOse[Ǡ6hWOL"GHNE[3Ua[*% 0#,/rO%%Sz7#&OVIQvE's& 5+"FsvE'*(& 5+t"* FvEa'-& 5+S"F- vE"&+ 5+v"F+ Pt"'+ 5+0 $5E@ / LKPX@0a $Ma $M  a+Ma#NK PX@:a $Ma $M  a+M_#Ma)NK1PX@2W  i  a+M_#Ma)N@0W  i  a+M_#Ma)NYYY@666E6D><53-+$""&$4# +32##"&55#"&&546632#"&54633 #"&547633326654&&#R"""fmccmb"" =R"vi77iJNt??tN %%%%Ku۔u%% $ j UccUPiiPPt!5@@=i_ "M _#N"""5"431-+*(!!$!$6 +#!"&54633#"&54633#"&5463!6654&&##!2#!3)""pb""bp""```w""%%!''!q%%i͓j!''!n 7GO@    LKPX@- i_$M a%M a#NKPX@8 i_$M a%M _#M a)NK PX@6 i  i_$M _#M a)NK1PX@4g i  i _#M a)N@1g i  i_#M  a)NYYYY@888G8F@>76#4!$"&%4!+32##"&55#"&&5466325!"&5463!5#"&54633232#6654&&#"3R"""<\vjjvy""/"""m""1JJSSx??xS%%%FMSm΋m%%F%%%%%I__INYYNPL'n( 5+C"nHPLa'-( 5+CS"-HP(LUK PX@B r  g  ie_"Ma#M a#NKPX@C   g  ie_"Ma#M a#N@J    g  ie_"Ma#M a#NYY@USNLIHGFCA<:76%4!$%'1$+327632#"&5467!"&54633#"&5463!2#"&55!!54632#"&55!!54632##M*#4= KY]kPL@""ff""j""))"((((+"))""Sz7#&6hWIF%%%%%##[####[h##%(C7>N@K-Lge a +Ma)N888>8=;:76&(,#"% +#!32676323276#"&5467#"&&54663!&&#n",\D# ,=VK*#7:KY]kOKKCpz؋{cuχ"/' 5( 9Qz5$' #'hWGD tږy}osyPL"(+ 5+Cv"H+b'** 5+ft"J*bj"*,  5+f\"J,ba'- * 5+fS"J-b"*f?O@@ 5 (LKPX@4 i a %M a#Ma-NK$PX@? i a +M _%M a#Ma-NK1PX@= i  i a +M _%Ma-N@: i  i  a +M_%Ma-NYYY@$@@@O@NHF?>8620,+$"6+##"54763546332###"&'&54763232655#"&&54663326654&&#"?"tu,)?"""Re`U'' NO||pp|OCCYYOOY  #&XRP%%%wZ!'7 rɜoЌoO[[OJ``JP|"+* 5+M'*rK r5+UYb@_g  _ "M a %M _#NVVVYVYXWUSOMLKJHDA=;:8421/4!$4!$!$+##32##32#!"&54633!32#!"&54633#"&546335#"&5463!2##!5#"&5463!!5_"Hz""zH""""\\""""Hz""zH"":""\\"":0%%%%t%%%%h%%%%%%%%%%%%qll MDLKPX@.   g _ $M a %M _#NK PX@,   g  i _ $M _#N@*  i   g  i _#NYY@MLHFCA=;85!$!$4$#$4+$#!"&546334&#"32#!"&54633#"&546335#"&54633232##66323j"""\RPUX\""""R""\"""""Ac[HR%%%%Yhbj%%%%B%%F%%%%%agOcX",n 5+I"en(9iKPX@!e_"M _#N@(e_"M _#NY@98$4!$%'1%$ +$#!327632#"&5467!"&5463!!"&5463!2#!!"YM*#4= KY]kPL""""""%%Sz7#&6hWIF%%%%%%m(IS CKPX@+e a*M _ %M _#NK PX@2e a*M _ %M _#N@0  ie _ %M _#NYY@ CB?<8653/-(& % +&554632##!327632#"&5467!"&5463!#"&5463!2!3((77((7"YM*#4= KY]kPL""9""T"AO$$$$9%%Sz7#&6hWIF%%%%%0a",- 5+E7LKPX@& _ "M a#NK1PX@1 _ "M _#M a)N@. _ "M_#M a)NYY@ E C?=:842+)&$!$4!$+##32#!"&54633#"&5463! ###"&'&546323265#"&5463!"V`""""`V""B"GBz-"))"&>>9""j%%m%%%%%%%%{7.####AH%%9f1S 7WC LK PX@:   a*M _ %M_#M a - N@8   i _ %M_#M a - NY@.888W8UQOLJGF?=751/.,(%! %+#"&55463 #"&5546332#!"&54633#"&54633 #"&'&5476323265#"&5463!((77((7((77((7""""{""J@(% kbO""6S$$$$$$$$I%0%%%%%%%o'&4?jr@%%s'*- 5+ft"*n)P".C "NPL's6/ 5+?'srO r5+PL"/? "OPr"/i 5+h "O_<L:N@K1'L~~_ "M`#N:8'#$5##$ +##7632!4632#!"&54633#"'&5477#"&5463!" "))"""" բ""*%%%bI##s%%%8\%%%? 1n@ ( LK PX@$_$M+M`#N@"g+M`#NY@1/'#$4'%+7632!2#!"&5463!#"'&5477!"&5463! A""""9 ""h %[r%%%%%w%%%F's1 5+M"QsF"1M"QF"1+ 5+Mv"Q+Xt"2n 5+H"nRXt"21 5+Ov"1R>r+4K PX@/rrg _ "M`#N@1g _ "M`#NY@,,,4,432+)5#$!% +#"&55!32##!54632#!"&5463!I"))""""))"" ~~UUi%##%%c##%  kˏkF&-9X@U#Lg a +M a)N..''.9.842'-',*)&%$#'#!$+#!3267632#"&'#"&54632663!&&#32654&#"q0P*7HNz(KK(zNEN ,BBKKOOKKO"%)46EEFFhulqP's5 5+R"s2UP"5R"UTP"5+ 5+Rv"U+)"6s 5+"Vs)'*6 5+t"*V()j@K %#LK PX@Hrp~f a  (M a  (Ma)Ma)NK PX@Ip~f a  (M a  (Ma)Ma)N@J~~f a  (M a  (Ma)Ma)NYY@\ZWUPNIG#%)$$$ +$6#"&'&54763232654&#"&55&'#"&5463232654&'&&'&&'&&54663254632#"'&&#")Xzef|yD3+g/3:6>'_"))"")+)?<&ZNRo/PYcqX:"))"")&0ony*'#^OVe1dq[\^KWh -!! kN##,#*t|n[?O${dgQD:=###[_fV)8)}(k@L %#LK PX@Hrp~f a  +M a  +Ma)Ma)NK PX@Ip~f a  +M a  +Ma)Ma)N@J~~f a  +M a  +Ma)Ma)NYY@][XVQOJH$%)$$$ +$6#"&'&54763232654&#"&55&'#"&55463232654&'&&'&&'&&54663254632#"'&&#"Sqef|yD3+g/3:6>'\"))"") $t|,)#[F^~5IQ[fa:"))"")"+~am)(!WEaw5PYM\^KWh -!! \8###`XTF",  gSW}@:4-###RCE> (  nZ)"6+ 5+v"V+zR"7uH"WzR"7+ 5+uHx"W  5+F'n8 5+Hx"nXFj"8, 5+Hx\"X,F#"8. 5+Hx"X.F"81 5+Hxv"X1F(GmKPX@"e _ "Ma)N@)e _ "Ma)NY@GEA?#$4#%'1)$ +##327632#"&5467#"&5#"&5463!2##3265#"&5463!i">d`fX*#4= KY]kDA >""D""pp""D%%n-\;#&6hWD@%%%%~%%H(xL!KPX@ LK1PX@  L@  LYYKPX@" e_%Ma )NKPX@, e_%M a #Ma)NK1PX@3    e_%M a #Ma)N@1    e_%M a #Ma)NYYY@KICB><9620,*%" LL +32#"&5467&&55#"&&5#"&54633232665#"&54633232##327K KY]kQMBf[HR"""RPUX"""R""YM*#4=6hWJFyflOc%%%Yhbj%%%0%%Sz7#&<a"<i 5+#"=s 5+"]s#a'-= 5+S"]- #"=+ 5+l"]+ 5+!%7@  LK PX@-ge a  $N@3   igYaQY@76$###$## +#"'&#"32###"'&5476323267#"&546337663a)([[LU ""Cra)([[LU B""% '<\_%%e '<\_%%)"6"Vf 4@1 L_%Ma-N #$%+#"&'&5476323265!"&5463!jSN! "ECbOY""%o?1 . -6jr@%%'t(dD@ Lv%+D#"''#"'&547763$t 'v(dD@ Lv%+D''&5476327632#B$ /\.dD@# LYaQ#&+D#"&'&54676323267632 " dPQd " Sq||qGDDGOS 'dD@YaQ %+D#"&55463((77((7S$$$$p)\7dD@,iYaQ&+D#"&&5466332654&#q@@qEEq@@qE4>>44>>4@qEEq@@qEEq@>44>>44>()MdDKPX@YbR@YbRY'1$+D327632#"&54673[*#4= KY]ka[B<#&6hWQN>-'dDK1PX@ "L@ "LYK1PX@YiaQ@#YiaQY@'&#$'#$+D3267632#"&'&&#"#"'&5476639(#0 =! 0m5#9(#0 =! 0m5#"" >="" >==Ov#&dD@ Lv'''%+D#"'&5477632#"'&5477632    G  bj!%@"_MN!#33$+####"&5!##"&5#"&5463!M"W!))!P!))!W""!''!+##+##!''!" @W_O 4+#!"&5463!"""%%%% @W_O 4+#!"&5463!"v""%%%%- LK PX@ $N@ vY&&+&547632##4#e + + B(#- LKPX@ $N@ vY&&+#"&5476335#e + ?+ (#&61 15+ #5 5#6 6&#77 ")@&_%Ma(N$##$#+32###"&5#"&546335463""%%""%"%%D""%%""1K PX@ gg a  (NKPX@"g_%M a  (NKPX@ gg a  (NKPX@"g_%M a  (N@ gg a  (NYYYY@10$!$##$!$# +32##32###"&55#"&546335#"&546335463""""%%""""%"%%%%""%%%%"~cNU @YaQ %+#"&5463mm{{mm{U.44..4.4.m_ )/@,a#N)(#! % +$#"&55463 #"&55463 #"&554631188118118811811881182<!1M]m}@zJ <L  i    ia(M  a)N^^NN22""^m^lfdN]N\VT2M2LHF@>:8"1"0*(&+#"&&5466332#"'&547$326654&&##"&'#"&&546632663326654&&# 326654&&#~JJ~JJ~JJ~Jj2B''B''B''B'0~JJ~J@m$%l@J~JJ~J@l%$m@7B''B''B''B'{B''B''B''B'J~JJ~JJ~JJ~J>'B''B''B''B'J~JJ~J8017J~JJ~J8118'B''B''B''B''B''B''B''B'?@La+N, +32#"'&547   2W  WC@ La+N,%+#"'&547&547632C    2C o]V@Lv+32#"'&547 j V 1<*#:d  LK PX@'  Y  aQK PX@(  W aQK PX@'  Y  aQKPX@(  W aQKPX@'  Y  aQKPX@(  W aQKPX@'  Y  aQKPX@(  W aQKPX@'  Y  aQKPX@(  W aQKPX@'  Y  aQ@(  W aQYYYYYYYYYYY@$$$:$842/-*(#"%&&% +#"&'#"&''#"&7663263###"&5#"&5463!!""] &' ^""!"2 2"""""~*#D#$$##+ !!##|!!Q{5)@&aM_N54$:*4&+32#!"&5476654&&#"#!"&54633&&5463g"""[nn["""gP!''!$*4 VkkƅV 4*$!''!P &3I@F0LiiYaQ'''3'2.,&%1&&( +#"&&546632654&#"#"&'&547633667&&#o<6CɍkYgpq*@S  [jr>p\m1geҜpo\fuckbnX!'>qK^qose8 @M_N7+#!"&547663!1 e""i 2)J"%%"v '@$W_O35+##"&5!##"&5463!!))!!))!"%##$##(%!.@+LgW_O!4&$+#!!2#!"&547&5463!"H S""" "!''!kO!''!% #%" @W_O 4+#!"&5463!"""%%%%tP*@'LWaQ4#'+#"&'#"&54633266325 2++3""X #"!''!H%g'3H@E*$ L  iYaQ(((3(2.,'&" &$& +#"&'#"&&5466326633267&&# 32654&#IIOgAAgOIIOg@@g]OOBIj67iIk55kIBOOBgLQQLcYYcLQQLcZZcXCCXPKKPQJKPXCCXf+9@6~iYaQ+*#&#+#"'&#"#"&'&&54763232654663ӏ?"kirYqI?"kirYq:3|d:3K|d6'aa8Ȱ5+85+D"H7@ *LK PX@+pqh W _O@)h W _OY@76$&#$!$&#$ +#!#"'&5477#"&54633!"&5463!7663232##!"=| 'S""""} 'S""|%%%%%%%%r"g'2@/ LW_O'%? +32#"'&&5467#!"&5463!%0e0%E"""g0&&0" $$ "%%%%r"g'2@/LW_O'%8'+#"'&547%%&547632#!"&5463!%0e0%"""4$$ 0&&0%%%%@Lv*+#"&'&547663-&-))-'-)#  ## #M*%9K(LK PX@* ga$M a#NKPX@,a$M_ %M a#NKPX@* ga$M a#NKPX@,a$M_ %M a#NK PX@* ga$M a#N@(i g a#NYYYYY@9853##$#3$4 +$#!"&54633!##"&5#"&5463354632#"'&#"!23";""_""""0$ n"%%%%Zb%%%%g30 91Z%b9%8LK PX@"ga$M a#NKPX@$a$M_%M a#NKPX@"ga$M a#NKPX@$a$M_%M a#NK PX@"ga$M a#N@ ig a#NYYYYY@87#$#3$""$4 +$#!"&54633&#"32####"&5#"&54633546323w"""wzg""""""YKs%%%%(Z%%b%%%%g' $z(RJ LK PX@> r~~f  _ "M _ #N@? ~~f  _ "M _ #NY@JHCA>=<:64$$$$!%+#"&5!32##6#"&'&54763232654&#"&55#"&54633!#"&5463!5"))"""ef|yD3+g/3:6>'"""))""Z%##5m%%q^KWh -!! %%##y%u(HN@ ' LK PX@=   rp~   gf(M a)NK PX@>   p~   gf(M a)N@?   ~~   gf(M a)NYY@MKHFCA=;#$($$$ +$##6#"&'&54763232654&#"&55&&5#"&546334632!2#!3267632H!NSef|yD3+g/3:6>'a["""))"""eObCE" 1?[^KWh -!!  y%%,##%%rj6- .PLj"(, 5+j",, 5+;'0, 5+PL$4C@@ i_ "M`#N%%%4%3-+$"!$5#$ +##!4632#!"&54633#"&5463!#"&&54663""))""""""*UA&&A&&A&&A&%%mI##s%%%%%&A&&A&&A&&A&FfDR@O:L _ "M_#Ma-NDB><4!$4&##$ +###"&'&54763232655#32#!"&54633#"&5463323#"&5463!i"9:x5' " `Q??""""CM""y""D%%^#/(JSu%%%%%%%%Xtj"2, 5+zR;D@A g  _  "M_#N;942/.$!$4!$!% +#"&5!32##32#!"&54633#"&54633!#"&5463!5"))""""""""""))""Z%##5/%%%%%%:%%##y%F;'08 5+":s  5+":* 5+a":i 5+":C 5+<"<*  5+<"<C  5+C\"H,I'@$_%M_#N!$4#+!2#!"&5463!#"&5463!A""""9""T%0%%%%%%I\"e,I-"e0- "O-h  5+af?K1PX@ < L@ < LYKPX@+a %M_#Ma-NK1PX@5 a  +M_%M_#Ma-N@3 a  +M_%M_#Ma-NYY@?>4!$4$%#& +#"&'&54763232654&#"32#!"&54633#"&546332663FH:x5' " `Q?;RPUX\""""Rf"""BfOc #/(JSYhbj%%%%%%%xflH\"R,uH?A@>   g  i(M a)N><9742!$##$!$#% +$#"&55#"&546335#"&546334632!2#!!2#!3267632H!NS"""""))"""e""ObCE" 1?m%%%%,##%%%%`rj6- .Hx-"X0"Zst"Z*S"Zi"ZC2et"\*2e"\C6!2@/!Li2M3N ##$# +32###"&55!"&5467663!6mm$$  {$6 B!!''  ?u @W_O 4+#!"&5463!"j""%%%%"/#@@3#AAPYVd@aR L  i  i a (M a (Ma)NVUPNLJFD@>:8'#"$$$"%%+#"&54&&#"!2#!!2#!3267632#"&'#"&54633&547#"&5463366325463$""))";vSf"""":""h[H^l)a""PQ""d+T0")###CqC}t%%)7(&%%x98'ABѻ%%$+;$%%@:9#(V?K PX@1rg  g  _  "M_#N@2g  g  _  "M_#NY@?=97640.$4!$!$!%+#"&55!!2#!!2#!32#!"&546335#"&54633#"&5463!9"))"Y""""H""""""""%##%%%%%%%%%%w%%HKN LKPX@) i _ "M %M)N@,   i _ "M)NY@ NMKJHGFD@=976520$4!$#$#$+###"'#"&'#"&54633#"&5463!2##376323#"&5463!2##3##"N)(RS')K""m(1""X""&: #'|""D""6)st5/%%$AEA#;%%-%%%%X/_-%%%% ll .@ Lv'+#"&5476633Z#)3#.  #rtK@ L"N(%+#"'&5476632K  .i  #~8~ n-dD@" LYaQ6+D&5476332#+"?"tu,   & n%@" LYaQ6+&5476332#+"?"tu,   &s 5+=j, 5+^  4 LK PX@ a$N@YaQY&&+#"&547633 =R"v  $ j '+ 5+_(bw'* 5+5]ai 5+]a- 5+9+C 5+=O1 5+"`n 5+()/p7\#. 5+L;0 5+hexwalk-1.9.1/src/hexwalk/main.cpp0000664000175100017510000000755515005675407016430 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "hexwalkmain.h" int main(int argc, char *argv[]) { Q_INIT_RESOURCE(hexwalk); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication app(argc, argv); app.setApplicationName("HexWalk"); app.setOrganizationName("HexWalk"); app.setWindowIcon(QIcon(":images/hexwalk.ico")); // set style app.setStyle(QStyleFactory::create("Fusion")); // increase font size for better reading QString fontPath1=":/fonts/Roboto.ttf"; QString fontPath2=":/fonts/Courier.ttf"; int fontId = QFontDatabase::addApplicationFont(fontPath1); QFontDatabase::addApplicationFont(fontPath2); //if (fontId != -1) //{ QFont font("Roboto"); font.setPointSize(font.pointSize()-2); app.setFont(font); //} /*QFont defaultFont = QApplication::font(); defaultFont.setPointSize(defaultFont.pointSize()+2); app.setFont(defaultFont);*/ // modify palette to dark QPalette darkPalette; darkPalette.setColor(QPalette::Window,QColor(53,53,53)); darkPalette.setColor(QPalette::WindowText,Qt::white); darkPalette.setColor(QPalette::Disabled,QPalette::WindowText,QColor(127,127,127)); darkPalette.setColor(QPalette::Base,QColor(42,42,42)); darkPalette.setColor(QPalette::AlternateBase,QColor(66,66,66)); darkPalette.setColor(QPalette::ToolTipBase,Qt::white); darkPalette.setColor(QPalette::ToolTipText,Qt::black); darkPalette.setColor(QPalette::Text,Qt::white); darkPalette.setColor(QPalette::Disabled,QPalette::Text,QColor(127,127,127)); darkPalette.setColor(QPalette::Dark,QColor(35,35,35)); darkPalette.setColor(QPalette::Shadow,QColor(20,20,20)); darkPalette.setColor(QPalette::Button,QColor(53,53,53)); darkPalette.setColor(QPalette::ButtonText,Qt::white); darkPalette.setColor(QPalette::Disabled,QPalette::ButtonText,QColor(127,127,127)); darkPalette.setColor(QPalette::BrightText,Qt::red); darkPalette.setColor(QPalette::Link,QColor(42,130,218)); darkPalette.setColor(QPalette::Highlight,QColor(42,130,218)); darkPalette.setColor(QPalette::Disabled,QPalette::Highlight,QColor(80,80,80)); darkPalette.setColor(QPalette::HighlightedText,Qt::white); darkPalette.setColor(QPalette::Disabled,QPalette::HighlightedText,QColor(127,127,127)); app.setPalette(darkPalette); // Identify locale and load translation if available QString locale = QLocale::system().name(); QTranslator translator; translator.load(QString("hexwalk_") + locale); app.installTranslator(&translator); QCommandLineParser parser; parser.addPositionalArgument("file", "File to open"); parser.addHelpOption(); parser.process(app); /*MainWindow *mainWin = new MainWindow; if(!parser.positionalArguments().isEmpty()) mainWin->loadFile(parser.positionalArguments().at(0)); mainWin->show();*/ HexWalkMain *hexwalkWin = new HexWalkMain; if(!parser.positionalArguments().isEmpty()) hexwalkWin->loadFile(parser.positionalArguments().at(0)); hexwalkWin->show(); return app.exec(); } hexwalk-1.9.1/src/hexwalk/stringsdialog.ui0000644000175100017510000001664514561356105020203 0ustar carmixcarmix StringsDialog 0 0 775 550 HexWalk - Strings search Search Type: UTF-8 UTF-16 Minimum length: 3 100 5 Maximum length: 3 100 32 Qt::Horizontal 40 20 Options Upper case [A-Z] true Symbols [!"%-_?#] Lower case [a-z] true Start from beginning true Numbers[0-9] true Spaces Results Find: Next Qt::Horizontal 40 20 &Search F3 true &Close Qt::Vertical 20 40 pbSearch pbCancel pbCancel clicked() StringsDialog hide() 360 134 364 162 hexwalk-1.9.1/src/hexwalk/hexwalkmain.cpp0000664000175100017510000010164215005675407020004 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include "hexwalkmain.h" #include "ui_hexwalkmain.h" HexWalkMain::HexWalkMain(QWidget *parent) : QMainWindow(parent), ui(new Ui::HexWalkMain) { ui->setupUi(this); setAcceptDrops( true ); init(); setCurrentFile(""); QFont font("Courier",10); ui->binTextedit->setFont(font); ui->asciiTextEdit->setFont(font); ui->decTextedit->setFont(font); ui->floatTextedit_le->setFont(font); ui->floatTextedit_be->setFont(font); ui->hexTextedit->setFont(font); ui->intleTextedit->setFont(font); ui->selTextedit->setFont(font); } QString HexWalkMain::binToStr(QByteArray bin) { QString outString; for(int i=0;i=127) { outString += QString("."); } else if(bin.at(i) == '<') { outString += QString("<"); } else if(bin.at(i) == '>') { outString += QString(">"); } else if(bin.at(i) == '&') { outString += QString("&"); } else { outString += QString(bin.at(i)); } } return outString; } void HexWalkMain::init() { setAttribute(Qt::WA_DeleteOnClose); appSettings = new QSettings("hexwalk","hexwalk"); //appSettings->clear(); isUntitled = true; hexEdit = ui->widget; connect(hexEdit, SIGNAL(overwriteModeChanged(bool)), this, SLOT(setOverwriteMode(bool))); connect(hexEdit, SIGNAL(dataChanged()), this, SLOT(dataChanged())); searchDialog = new SearchDialog(hexEdit, this); advancedSearchDialog = new AdvancedSearchDialog(hexEdit,this); optionsDialog = new OptionsDialog(appSettings,this); connect(optionsDialog,SIGNAL(accepted()),this,SLOT(updateOptions())); entropyDialog = new EntropyDialog(hexEdit,this); analysisDialog = new binanalysisdialog(hexEdit,this); hashDialog = new HashDialog(this); diffDialog = new DiffDialog(this); tagsDialog = new TagsDialog(hexEdit,this); stringsDialog = new StringsDialog(hexEdit,this); byteMapDialog = new ByteMapDialog(hexEdit,this); //disasmDialog = new DisasmDialog(hexEdit,this); disasmWidget = new DisasmWidget(hexEdit,this); converterWidget = new ConverterWidget(this); createActions(); createMenus(); createToolBars(); createStatusBar(); readSettings(); setUnifiedTitleAndToolBarOnMac(true); } HexWalkMain::~HexWalkMain() { delete ui; } void HexWalkMain::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(openAct); fileMenu->addAction(saveAct); fileMenu->addAction(saveAsAct); fileMenu->addAction(saveReadable); fileMenu->addAction(closeAct); recentFilesMenu = fileMenu->addMenu(tr("Open Recent")); for(auto i = 0; i < 5; ++i) recentFilesMenu->addAction(recentFileActionList.at(i)); updateRecentActionList(); fileMenu->addMenu(recentFilesMenu); fileMenu->addSeparator(); fileMenu->addAction(exitAct); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(undoAct); editMenu->addAction(redoAct); editMenu->addAction(copyAct); editMenu->addAction(pasteAct); editMenu->addAction(cutAct); editMenu->addAction(saveSelectionReadable); editMenu->addSeparator(); editMenu->addAction(advancedFindAct); editMenu->addAction(findAct); editMenu->addAction(overwriteAct); editMenu->addAction(optionsAct); analysisMenu = menuBar()->addMenu(tr("&Analysis")); analysisMenu->addAction(entropyAct); analysisMenu->addAction(binaryAct); analysisMenu->addAction(diffAct); analysisMenu->addAction(tagsAct); analysisMenu->addAction(stringsAct); analysisMenu->addAction(byteMapAct); analysisMenu->addAction(disasmAct); toolsMenu = menuBar()->addMenu(tr("&Tools")); toolsMenu->addAction(converterAct); toolsMenu->addAction(hashAct); helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(aboutAct); } void HexWalkMain::createStatusBar() { // Address Label lbAddressName = new QLabel(); lbAddressName->setText(tr("Address:")); statusBar()->addPermanentWidget(lbAddressName); lbAddress = new QLabel(); lbAddress->setFrameShape(QFrame::Panel); lbAddress->setFrameShadow(QFrame::Sunken); lbAddress->setMinimumWidth(100); statusBar()->addPermanentWidget(lbAddress); connect(hexEdit, SIGNAL(currentAddressChanged(qint64)), this, SLOT(setAddress(qint64))); // Size Label lbSizeName = new QLabel(); lbSizeName->setText(tr("Size:")); statusBar()->addPermanentWidget(lbSizeName); lbSize = new QLabel(); lbSize->setFrameShape(QFrame::Panel); lbSize->setFrameShadow(QFrame::Sunken); lbSize->setMinimumWidth(70); statusBar()->addPermanentWidget(lbSize); connect(hexEdit, SIGNAL(currentSizeChanged(qint64)), this, SLOT(setSize(qint64))); // Overwrite Mode Label lbOverwriteModeName = new QLabel(); lbOverwriteModeName->setText(tr("Mode:")); statusBar()->addPermanentWidget(lbOverwriteModeName); lbOverwriteMode = new QLabel(); lbOverwriteMode->setFrameShape(QFrame::Panel); lbOverwriteMode->setFrameShadow(QFrame::Sunken); lbOverwriteMode->setMinimumWidth(70); statusBar()->addPermanentWidget(lbOverwriteMode); setOverwriteMode(hexEdit->overwriteMode()); statusBar()->showMessage(tr("Ready"), 2000); } void HexWalkMain::createActions() { openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); connect(openAct, SIGNAL(triggered()), this, SLOT(open())); closeAct = new QAction(tr("&Close..."), this); closeAct->setShortcuts(QKeySequence::Close); closeAct->setStatusTip(tr("Close current file")); connect(closeAct, SIGNAL(triggered()), this, SLOT(close())); saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); saveAsAct = new QAction(tr("Save &As..."), this); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); saveReadable = new QAction(tr("Save &Readable..."), this); saveReadable->setStatusTip(tr("Save document in readable form")); connect(saveReadable, SIGNAL(triggered()), this, SLOT(saveToReadableFile())); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); undoAct = new QAction(QIcon(":/images/undo.png"), tr("&Undo"), this); undoAct->setShortcuts(QKeySequence::Undo); connect(undoAct, SIGNAL(triggered()), hexEdit, SLOT(undo())); redoAct = new QAction(QIcon(":/images/redo.png"), tr("&Redo"), this); redoAct->setShortcuts(QKeySequence::Redo); connect(redoAct, SIGNAL(triggered()), hexEdit, SLOT(redo())); copyAct = new QAction( tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); connect(copyAct, SIGNAL(triggered()), hexEdit, SLOT(copyText())); pasteAct = new QAction(tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); connect(pasteAct, SIGNAL(triggered()), hexEdit, SLOT(pasteText())); cutAct = new QAction( tr("&Cut"), this); cutAct->setShortcuts(QKeySequence::Cut); connect(cutAct, SIGNAL(triggered()), hexEdit, SLOT(cutText())); saveSelectionReadable = new QAction(tr("&Save Selection Readable..."), this); saveSelectionReadable->setStatusTip(tr("Save selection in readable form")); connect(saveSelectionReadable, SIGNAL(triggered()), this, SLOT(saveSelectionToReadableFile())); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); findAct = new QAction(tr("&Find/Replace"), this); findAct->setShortcuts(QKeySequence::FindPrevious); findAct->setStatusTip(tr("Show the Dialog for finding and replacing")); connect(findAct, SIGNAL(triggered()), this, SLOT(showSearchDialog())); overwriteAct = new QAction(tr("&Overwrite/Insert mode"), this); overwriteAct->setShortcut(QKeySequence(Qt::Key_Insert)); overwriteAct->setStatusTip(tr("Toggle overwrite/insert mode")); connect(overwriteAct, SIGNAL(triggered()), this, SLOT(toggleOverwriteMode())); optionsAct = new QAction(tr("&Options"), this); optionsAct->setStatusTip(tr("Options")); connect(optionsAct, SIGNAL(triggered()), this, SLOT(showOptionsDialog())); findNextAct = new QAction(tr("Find &next"), this); findNextAct->setShortcuts(QKeySequence::FindNext); findNextAct->setStatusTip(tr("Find next occurrence of the searched pattern")); connect(findNextAct, SIGNAL(triggered()), this, SLOT(findNext())); advancedFindAct = new QAction(QIcon(":/images/find.png"),tr("Advanced Find"), this); advancedFindAct->setShortcuts(QKeySequence::Find); advancedFindAct->setStatusTip(tr("Advanced find tool")); connect(advancedFindAct, SIGNAL(triggered()), this, SLOT(showAdvancedSearchDialog())); entropyAct = new QAction(QIcon(":/images/entropy.png"),tr("Entropy"), this); entropyAct->setShortcut(Qt::CTRL|Qt::Key_E); entropyAct->setStatusTip(tr("Calculate entropy of file")); connect(entropyAct, SIGNAL(triggered()), this, SLOT(showEntropyDialog())); diffAct = new QAction(QIcon(":/images/diff.png"),tr("Diff Analysis"), this); diffAct->setStatusTip(tr("do diff compare byte to byte")); connect(diffAct, SIGNAL(triggered()), this, SLOT(showDiffDialog())); binaryAct = new QAction(QIcon(":/images/binary.png"),tr("Binary Analysis"), this); binaryAct->setStatusTip(tr("make binary analysis with Binwalk")); connect(binaryAct, SIGNAL(triggered()), this, SLOT(showBinaryDialog())); converterAct = new QAction(tr("Number Converter"), this); converterAct->setStatusTip(tr("Useful number converter")); connect(converterAct, SIGNAL(triggered()), this, SLOT(showConverterWidget())); hashAct = new QAction(tr("Hash Calculator"), this); hashAct->setStatusTip(tr("Hash Calculator")); connect(hashAct, SIGNAL(triggered()), this, SLOT(showHashDialog())); tagsAct = new QAction(QIcon(":/images/tags.png"),tr("Byte Patterns"), this); tagsAct->setStatusTip(tr("Byte Patterns")); connect(tagsAct, SIGNAL(triggered()), this, SLOT(showTagsDialog())); stringsAct = new QAction(QIcon(":/images/strings.png"),tr("Search Strings"), this); stringsAct->setStatusTip(tr("Search Strings")); connect(stringsAct, SIGNAL(triggered()), this, SLOT(showStringsDialog())); byteMapAct = new QAction(QIcon(":/images/bytemap.png"),tr("ByteMap"), this); byteMapAct->setStatusTip(tr("Byte Map")); connect(byteMapAct, SIGNAL(triggered()), this, SLOT(showByteMap())); disasmAct = new QAction(QIcon(":/images/disasm.png"),tr("Disasm"), this); disasmAct->setStatusTip(tr("Disassembler")); connect(disasmAct, SIGNAL(triggered()), this, SLOT(showDisasm())); QAction* recentFileAction = 0; for(auto i = 0; i < 5; ++i){ recentFileAction = new QAction(this); recentFileAction->setVisible(false); connect(recentFileAction, SIGNAL(triggered()),this, SLOT(openRecent())); recentFileActionList.append(recentFileAction); } } void HexWalkMain::toggleOverwriteMode(){ if(hexEdit->overwriteMode() == true) { hexEdit->setOverwriteMode(false); } else { hexEdit->setOverwriteMode(true); } } void HexWalkMain::openRecent(){ QAction *action = qobject_cast(sender()); if (action) loadFile(action->data().toString()); } void HexWalkMain::createToolBars() { fileToolBar = addToolBar(tr("File")); fileToolBar->setObjectName("file"); fileToolBar->addAction(openAct); fileToolBar->addAction(saveAct); editToolBar = addToolBar(tr("Edit")); editToolBar->setObjectName("edit"); editToolBar->addAction(undoAct); editToolBar->addAction(redoAct); editToolBar->addAction(advancedFindAct); analysisToolBar = addToolBar(tr("Analysis")); analysisToolBar->setObjectName("analysis"); analysisToolBar->addAction(entropyAct); analysisToolBar->addAction(binaryAct); analysisToolBar->addAction(diffAct); analysisToolBar->addAction(tagsAct); analysisToolBar->addAction(stringsAct); analysisToolBar->addAction(byteMapAct); analysisToolBar->addAction(disasmAct); analysisToolBar->addSeparator(); gotoLbl = new QLabel(); gotoLbl->setText("Go To: "); gotoLbl->setFixedHeight(25); analysisToolBar->addWidget(gotoLbl); gotoText = new QLineEdit(); gotoText->setFixedHeight(25); gotoText->setFixedWidth(80); gotoText->setText(tr("0")); connect(gotoText,SIGNAL(returnPressed()),SLOT(gotoAddress())); analysisToolBar->addWidget(gotoText); analysisToolBar->addSeparator(); widthLbl = new QLabel(); widthLbl->setText("Width: "); widthLbl->setFixedHeight(25); analysisToolBar->addWidget(widthLbl); widthText = new QLineEdit(); widthText->setFixedHeight(25); widthText->setFixedWidth(40); widthText->setText(tr("16")); connect(widthText,SIGNAL(returnPressed()),SLOT(setWidth())); analysisToolBar->addWidget(widthText); //infoToolBar = addToolBar(tr("Info")); } void HexWalkMain::setFileActionsEnabled(bool enabled) { QAction* all[] = {diffAct, entropyAct, binaryAct, hashAct, tagsAct,stringsAct,byteMapAct}; for (auto act: all) { act->setEnabled(enabled); } } void HexWalkMain::setCurrentFile(const QString &fileName) { curFile = QFileInfo(fileName).canonicalFilePath(); isUntitled = fileName.isEmpty(); setWindowModified(false); if (fileName.isEmpty()) { setWindowFilePath("HexWalk"); this->setWindowTitle("HexWalk"); setFileActionsEnabled(false); } else { setWindowFilePath(curFile + " - HexWalk"); this->setWindowTitle("HexWalk [" + curFile + "]"); setFileActionsEnabled(true); } } void HexWalkMain::loadFile(const QString &fileName) { hexfile.setFileName(fileName); if (!hexEdit->setData(hexfile)) { QMessageBox::warning(this, tr("HexWalk"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } setCurrentFile(fileName); statusBar()->showMessage(tr("File loaded"), 2000); emit fileLoaded(); } /*****************************************************************************/ /* Private Slots */ /*****************************************************************************/ void HexWalkMain::about() { QString title = tr("About HexWalk"); QString text = tr("HexWalk %1 is an HEX editor/viewer/analyzer.
" "It is open source and it is based on QT, qhexedit2, binwalk.
" "Sources at Github.
") .arg(APP_VERSION); QMessageBox msgBox(title, text, QMessageBox::Information, 0, 0, 0, this); msgBox.setTextFormat(Qt::RichText); QIcon icon = msgBox.windowIcon(); QSize size = icon.actualSize(QSize(64, 64)); msgBox.setIconPixmap(icon.pixmap(size)); msgBox.exec(); } void HexWalkMain::dataChanged() { setWindowModified(hexEdit->isModified()); } void HexWalkMain::updateOptions() { readSettings(); } void HexWalkMain::adjustForCurrentFile(const QString &filePath){ currentFilePath = filePath; setWindowFilePath(currentFilePath); QStringList recentFilePaths = appSettings->value("recentFiles").toStringList(); recentFilePaths.removeAll(filePath); recentFilePaths.prepend(filePath); while (recentFilePaths.size() > 5) recentFilePaths.removeLast(); appSettings->setValue("recentFiles", recentFilePaths); // see note updateRecentActionList(); } void HexWalkMain::updateRecentActionList(){ QStringList recentFilePaths = appSettings->value("recentFiles").toStringList(); auto itEnd = 0u; if(recentFilePaths.size() <= 5) itEnd = recentFilePaths.size(); else itEnd = 5; for (auto i = 0u; i < itEnd; ++i) { QString strippedName = QFileInfo(recentFilePaths.at(i)).fileName(); recentFileActionList.at(i)->setText(strippedName); recentFileActionList.at(i)->setData(recentFilePaths.at(i)); recentFileActionList.at(i)->setVisible(true); } for (auto i = itEnd; i < 5; ++i) recentFileActionList.at(i)->setVisible(false); } void HexWalkMain::open() { QString fileName = QFileDialog::getOpenFileName(this); if (!fileName.isEmpty()) { adjustForCurrentFile(fileName); loadFile(fileName); } } void HexWalkMain::close() { QFile empty; hexEdit->setData(empty); setCurrentFile(""); } void HexWalkMain::writeSettings() { appSettings->setValue("pos", pos()); appSettings->setValue("size", size()); appSettings->setValue("mainWindowGeometry", saveGeometry()); appSettings->setValue("mainWindowState", saveState()); } void HexWalkMain::findNext() { searchDialog->findNext(); } bool HexWalkMain::saveFile(const QString &fileName) { QString tmpFileName = fileName + ".~tmp"; QApplication::setOverrideCursor(Qt::WaitCursor); QFile file(tmpFileName); bool ok = hexEdit->write(file); if (QFile::exists(fileName)) ok = QFile::remove(fileName); if (ok) { file.setFileName(tmpFileName); ok = file.copy(fileName); if (ok) ok = QFile::remove(tmpFileName); } QApplication::restoreOverrideCursor(); if (!ok) { QMessageBox::warning(this, tr("HexWalk"), tr("Cannot write file %1.") .arg(fileName)); return false; } setCurrentFile(fileName); statusBar()->showMessage(tr("File saved"), 2000); return true; } QString HexWalkMain::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } bool HexWalkMain::save() { if (isUntitled) { return saveAs(); } else { QMessageBox msgBox; msgBox.setText("Do you want to save your changes?"); msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Save); int ret = msgBox.exec(); switch (ret) { case QMessageBox::Save: // Save was clicked return saveFile(curFile); break; case QMessageBox::Cancel: // Cancel was clicked break; default: // should never be reached break; } } return 0; } bool HexWalkMain::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), curFile); if (fileName.isEmpty()) return false; return saveFile(fileName); } void HexWalkMain::saveSelectionToReadableFile() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save To Readable File")); if (!fileName.isEmpty()) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("HexWalk"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } QApplication::setOverrideCursor(Qt::WaitCursor); file.write(hexEdit->selectionToReadableString().toLatin1()); QApplication::restoreOverrideCursor(); statusBar()->showMessage(tr("File saved"), 2000); } } void HexWalkMain::saveToReadableFile() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save To Readable File")); if (!fileName.isEmpty()) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("HexWalk"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } QApplication::setOverrideCursor(Qt::WaitCursor); file.write(hexEdit->toReadableString().toLatin1()); QApplication::restoreOverrideCursor(); statusBar()->showMessage(tr("File saved"), 2000); } } void HexWalkMain::updateInfo() { int selSize = hexEdit->selectedDataBa().size(); ui->selTextedit->setText(QString::number(selSize,10)); if(selSize > 0) { ui->asciiTextEdit->setText(binToStr(hexEdit->selectedDataBa())); ui->hexTextedit->setText(hexEdit->selectedData().toUpper()); if(selSize <= 8) { converterWidget->update(hexEdit->selectedData().toUpper()); if(selSize == 4 || selSize == 8) { qint64 num = hexEdit->selectedData().toULongLong(NULL,16); QByteArray baValue = hexEdit->selectedDataBa(); if(selSize == 4) { float *numf; numf = (float *)# ui->floatTextedit_be->setText(QString::number(*numf)); std::reverse(baValue.begin(),baValue.end()); num = baValue.toHex().toULongLong(NULL,16); numf = (float *)# ui->floatTextedit_le->setText(QString::number(*numf)); } else { double *numf; numf = (double *)# ui->floatTextedit_be->setText(QString::number(*numf)); std::reverse(baValue.begin(),baValue.end()); num = baValue.toHex().toULongLong(NULL,16); numf = (double *)# ui->floatTextedit_le->setText(QString::number(*numf)); } } else { ui->floatTextedit_le->setText("-"); ui->floatTextedit_be->setText("-"); } QByteArray baValue = hexEdit->selectedDataBa(); if(ui->signedcb->isChecked()) { if(selSize < 5) { ui->decTextedit->setText(QString("%1").arg((signed int)hexEdit->selectedData().toUInt(NULL,16))); std::reverse(baValue.begin(),baValue.end()); ui->intleTextedit->setText(QString("%1").arg((signed int)baValue.toHex().toUInt(NULL,16))); } else { ui->decTextedit->setText(QString("%1").arg((signed long long)hexEdit->selectedData().toULongLong(NULL,16))); std::reverse(baValue.begin(),baValue.end()); ui->intleTextedit->setText(QString("%1").arg((signed long long)baValue.toHex().toULongLong(NULL,16))); } } else { ui->decTextedit->setText(QString("%1").arg(hexEdit->selectedData().toULongLong(NULL,16))); std::reverse(baValue.begin(),baValue.end()); ui->intleTextedit->setText(QString("%1").arg(baValue.toHex().toULongLong(NULL,16))); } ui->binTextedit->setText(QString("%1").arg(hexEdit->selectedData().toULongLong(NULL,16),8,2,QLatin1Char('0'))); } else { ui->decTextedit->setText("-"); ui->floatTextedit_le->setText("-"); ui->intleTextedit->setText("-"); ui->binTextedit->setText("-"); ui->hexTextedit->setText("-"); ui->asciiTextEdit->setText("-"); } } } void HexWalkMain::setAddress(qint64 address) { lbAddress->setText(QString("%1(%2)").arg(address, 1, 16).arg(address,1,10)); if(hexEdit->getSize() > 0) { if(address < hexEdit->getSize()) { if(hexEdit->selectedDataBa().size() > 0) { updateInfo(); } else { ui->hexTextedit->setText(QString("%1").arg(uchar(hexEdit->dataAt(address,1).at(0)),2,16,QLatin1Char('0')).toUpper()); ui->decTextedit->setText(QString("%1").arg(uchar(hexEdit->dataAt(address,1).at(0)),3,10)); ui->intleTextedit->setText(QString("%1").arg(uchar(hexEdit->dataAt(address,1).at(0)),3,10)); ui->binTextedit->setText(QString("%1").arg(uchar(hexEdit->dataAt(address,1).at(0)),8,2,QLatin1Char('0'))); } } } } void HexWalkMain::setOverwriteMode(bool mode) { appSettings->setValue("OverwriteMode", mode); if (mode) lbOverwriteMode->setText(tr("Overwrite")); else lbOverwriteMode->setText(tr("Insert")); } void HexWalkMain::setSize(qint64 size) { lbSize->setText(QString("%1").arg(size)); } void HexWalkMain::showSearchDialog() { searchDialog->show(); } void HexWalkMain::showAdvancedSearchDialog() { advancedSearchDialog->show(); } void HexWalkMain::showOptionsDialog() { optionsDialog->show(); } void HexWalkMain::showDiffDialog() { if(curFile.length() == 0) { QMessageBox::warning(this, tr("HexWalk"), tr("You must select a file first.") ); } else { diffFile = QFileDialog::getOpenFileName(this); if (!diffFile.isEmpty()) { diffDialog->setFiles(curFile,diffFile); diffDialog->show(); } } } void HexWalkMain::showEntropyDialog() { if(curFile.length() == 0) { QMessageBox::warning(this, tr("HexWalk"), tr("You must select a file first.") ); } else { entropyDialog->show(); entropyDialog->calculate(); } } void HexWalkMain::showBinaryDialog() { if(curFile.length() == 0) { QMessageBox::warning(this, tr("HexWalk"), tr("You must select a file first.") ); } else { analysisDialog->show(); analysisDialog->analyze(curFile); } } void HexWalkMain::showConverterWidget() { converterWidget->show(); } void HexWalkMain::gotoAddress() { qint64 destPos = 2*(gotoText->text().toLongLong(NULL,16)); hexEdit->setCursorPosition(destPos); hexEdit->ensureVisible(); } void HexWalkMain::setWidth() { int value =widthText->text().toInt(); if (value <= 0) { value = 8; widthText->setText(QString("%1").arg(value)); } else if(value > 64) { value = 64; widthText->setText(QString("%1").arg(value)); } appSettings->setValue("BytesPerLine",value); hexEdit->setBytesPerLine(value); } void HexWalkMain::showHashDialog() { if(curFile.length() == 0) { QMessageBox::warning(this, tr("HexWalk"), tr("You must select a file first.") ); } else { hashDialog->show(); hashDialog->calculate(curFile); } } void HexWalkMain::showTagsDialog() { if(curFile.length() == 0) { QMessageBox::warning(this, tr("HexWalk"), tr("You must select a file first.") ); } else { tagsDialog->show(); } } void HexWalkMain::showStringsDialog() { if(curFile.length() == 0) { QMessageBox::warning(this, tr("HexWalk"), tr("You must select a file first.") ); } else { stringsDialog->show(); } } void HexWalkMain::readSettings() { if(appSettings->value("BytesPerLine").toInt()<=0) { appSettings->setValue("AddressArea",true); appSettings->setValue("AsciiArea",true); appSettings->setValue("Highlighting",true); appSettings->setValue("OverwriteMode",true); appSettings->setValue("ReadOnly",false); appSettings->setValue("HighlightingColor",QColor("#540c00")); appSettings->setValue("AddressAreaColor",QColor("#545454")); appSettings->setValue("SelectionColor",QColor("#0998c7")); appSettings->setValue("WidgetFont",QFont("Courier",12)); appSettings->setValue("AddressFontColor",QColor("#f0f0f0")); appSettings->setValue("AsciiAreaColor",QColor("#424242")); appSettings->setValue("AsciiFontColor",QColor("#00ff5e")); appSettings->setValue("HexFontColor",QColor("#00ff5e")); appSettings->setValue("AddressAreaWidth",6); appSettings->setValue("BytesPerLine",16); appSettings->setValue("HexCaps",true); appSettings->setValue("HexFontColor",QColor("#00ff5e")); appSettings->setValue("pos", pos()); appSettings->setValue("size", size()); appSettings->setValue("mainWindowGeometry", saveGeometry()); appSettings->setValue("mainWindowState", saveState()); appSettings->sync(); } else { restoreGeometry(appSettings->value("mainWindowGeometry").toByteArray()); restoreState(appSettings->value("mainWindowState").toByteArray()); int bytesperline = appSettings->value("BytesPerLine").toInt(); if( bytesperline > 0 && bytesperline < 64 ) { hexEdit->setBytesPerLine(bytesperline); widthText->setText(QString("%1").arg(bytesperline)); } else{ bytesperline = 16; hexEdit->setBytesPerLine(bytesperline); widthText->setText(QString("%1").arg(bytesperline)); } QPoint pos = appSettings->value("pos", QPoint(200, 200)).toPoint(); QSize size = appSettings->value("size", QSize(610, 460)).toSize(); move(pos); resize(size); } hexEdit->setAddressArea(appSettings->value("AddressArea").toBool()); hexEdit->setAsciiArea(appSettings->value("AsciiArea").toBool()); hexEdit->setHighlighting(appSettings->value("Highlighting").toBool()); hexEdit->setOverwriteMode(appSettings->value("OverwriteMode").toBool()); hexEdit->setReadOnly(appSettings->value("ReadOnly").toBool()); hexEdit->setHighlightingColor(appSettings->value("HighlightingColor").value()); hexEdit->setAddressAreaColor(appSettings->value("AddressAreaColor").value()); hexEdit->setSelectionColor(appSettings->value("SelectionColor").value()); hexEdit->setFont(appSettings->value("WidgetFont").value()); hexEdit->setAddressFontColor(appSettings->value("AddressFontColor").value()); hexEdit->setAsciiAreaColor(appSettings->value("AsciiAreaColor").value()); hexEdit->setAsciiFontColor(appSettings->value("AsciiFontColor").value()); hexEdit->setHexFontColor(appSettings->value("HexFontColor").value()); hexEdit->setAddressWidth(appSettings->value("AddressAreaWidth").toInt()); hexEdit->setBytesPerLine(appSettings->value("BytesPerLine").toInt()); hexEdit->setHexCaps(appSettings->value("HexCaps", true).toBool()); } /*****************************************************************************/ /* Protected methods */ /*****************************************************************************/ void HexWalkMain::closeEvent(QCloseEvent *) { writeSettings(); } void HexWalkMain::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) event->accept(); } void HexWalkMain::dropEvent(QDropEvent *event) { if (event->mimeData()->hasUrls()) { QList urls = event->mimeData()->urls(); QString filePath = urls.at(0).toLocalFile(); adjustForCurrentFile(filePath); loadFile(filePath); event->accept(); } } void HexWalkMain::on_signedcb_clicked() { updateInfo(); } void HexWalkMain::showByteMap() { byteMapDialog->showByteMapDialog(); } void HexWalkMain::showDisasm() { disasmWidget->show(); } hexwalk-1.9.1/src/hexwalk/hexwalk.qrc0000664000175100017510000000116715002001047017117 0ustar carmixcarmix images/save.png images/undo.png images/redo.png images/find.png images/hexwalk.ico images/binary.png images/entropy.png images/open.png images/diff.png images/tags.png images/strings.png images/bytemap.png images/disasm.png fonts/Courier.ttf fonts/Roboto.ttf hexwalk-1.9.1/src/hexwalk/entropychart.cpp0000664000175100017510000000362015005675407020213 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "entropychart.h" #include EntropyChart::EntropyChart(QWidget *parent): QChartView(parent) { } void EntropyChart::mousePressEvent(QMouseEvent * event){ auto curPoint = QCursor::pos(); curPoint = this->mapFromGlobal(curPoint); auto pickVal = this->mapToScene(curPoint); pickVal = this->chart()->mapFromScene(curPoint); pickVal = this->chart()->mapToValue(curPoint,this->chart()->series().at(0)); emit rubberBandEvent(); emit mousePressed(qint64(pickVal.x())); QChartView::mousePressEvent(event); } void EntropyChart::resizeEvent(QResizeEvent *event){ emit rubberBandEvent(); QChartView::resizeEvent(event); } void EntropyChart::mouseReleaseEvent(QMouseEvent *event){ emit rubberBandEvent(); QChartView::mouseReleaseEvent(event); } void EntropyChart::mouseMoveEvent(QMouseEvent * event){ auto curPoint = QCursor::pos(); curPoint = this->mapFromGlobal(curPoint); auto pickVal = this->mapToScene(curPoint); pickVal = this->chart()->mapFromScene(curPoint); pickVal = this->chart()->mapToValue(curPoint,this->chart()->series().at(0)); emit mouseMoved(qint64(pickVal.x())); QChartView::mouseMoveEvent(event); } hexwalk-1.9.1/src/hexwalk/edittagdialog.cpp0000664000175100017510000001032515005675407020272 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "edittagdialog.h" #include "ui_edittagdialog.h" #include #include "../qhexedit/colortag.h" #include EditTagDialog::EditTagDialog(BytePattern * bytePtr,QWidget *parent ) : QDialog(parent), ui(new Ui::EditTagDialog) { bytePattern = bytePtr; ui->setupUi(this); } EditTagDialog::~EditTagDialog() { delete ui; } void EditTagDialog::colorGen() { QRandomGenerator prng(time(0)); QColor color(prng.generate()%256,prng.generate()%256,prng.generate()%256); if(color.isValid()) { QString qss = QString("background-color: %1").arg(color.name()); ui->colorButton->setStyleSheet(qss); } editedTagIdx = -1; } void EditTagDialog::loadTag(int row) { ColorTag tag = bytePattern->colorTag.at(row); QString qss = QString("background-color: %1").arg(QString::fromStdString(tag.color)); ui->colorButton->setStyleSheet(qss); ui->nameEdit->setText(QString::fromStdString(tag.name)); ui->offsetEdit->setText(QString::fromStdString(tag.obj.offset)); ui->lengthEdit->setText(QString::fromStdString(tag.obj.size)); if(tag.type == BE_t) { ui->typeCombo->setCurrentIndex(BE_t-1); } else if(tag.type == LE_t) { ui->typeCombo->setCurrentIndex(LE_t-1); } else if(tag.type == STRING_t) { ui->typeCombo->setCurrentIndex(STRING_t-1); } else { ui->typeCombo->setCurrentIndex(HEX_t-1); } editedTagIdx = row; } void EditTagDialog::on_colorButton_clicked() { QColor color = QColorDialog::getColor(); if(color.isValid()) { QString qss = QString("background-color: %1").arg(color.name()); ui->colorButton->setStyleSheet(qss); } } void EditTagDialog::on_applyButton_clicked() { YMLObj obj; BPerrors error = E_NONE; obj.color = ui->colorButton->palette().button().color().name().toStdString(); obj.name = ui->nameEdit->text().toStdString(); obj.offset = ui->offsetEdit->text().toStdString(); obj.size = ui->lengthEdit->text().toStdString(); obj.type = tagStrings[ui->typeCombo->currentIndex() +1 ]; if(!bytePattern->isValidColor(obj.color)) { error = E_WRONGCOLOR; } else if(!bytePattern->isValidName(obj.name)) { error = E_WRONGNAME; } else if(bytePattern->isDuplicatedName(obj.name,editedTagIdx)) { error = E_DUPNAME; } else if(obj.offset.length() == 0) { error = E_EMPTYOFFSET; } else if(obj.size.length() == 0) { error = E_EMPTYSIZE; } QString error_string; if(error != E_NONE) { switch(error) { case E_WRONGNAME: error_string = QString("Wrong name passed "); break; case E_WRONGTYPE: error_string = QString("Wrong type passed "); break; case E_WRONGREF: error_string = QString("Wrong reference passed" ); break; case E_WRONGCOLOR: error_string = QString("Wrong color passed"); break; case E_DUPNAME: error_string = QString("Duplicated name"); break; default: error_string = QString("Error code %1").arg(error); } QMessageBox::warning(this, tr("HexWalk"), error_string ); } else { if(editedTagIdx >= 0) { bytePattern->updateElement(editedTagIdx,obj); editedTagIdx = -1; } else { bytePattern->addElement(obj); } emit tagReady(); this->hide(); } } hexwalk-1.9.1/src/hexwalk/hashdialog.ui0000664000175100017510000001643714570654654017450 0ustar carmixcarmix HashDialog 0 0 800 230 800 230 800 230 HexWalk - Hash Calculator 40 30 61 18 MD5: 40 70 61 18 SHA1: 40 110 67 18 SHA256: 110 27 681 21 255 255 255 255 255 255 255 255 255 255 255 255 false QFrame::Box QFrame::Sunken 1 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 110 67 681 21 255 255 255 255 255 255 255 255 255 255 255 255 false QFrame::Box QFrame::Sunken Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 110 107 681 21 255 255 255 255 255 255 255 255 255 255 255 255 false QFrame::Box QFrame::Sunken Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 110 140 681 23 24 20 180 88 26 Stop 700 180 88 26 Close hexwalk-1.9.1/src/hexwalk/resultType.h0000664000175100017510000000201015005675407017306 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef RESULTTYPE_H #define RESULTTYPE_H #include #include typedef struct Result_S{ qint64 cursor; QString hexdatastr; QString datastr; }Result_S; typedef struct BinwalkResult_S{ qint64 cursor; QString datastr; }BinwalkResult_S; #endif // RESULTTYPE_H hexwalk-1.9.1/src/hexwalk/diffdialog.cpp0000664000175100017510000001400015005675407017553 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "diffdialog.h" #include "ui_diffdialog.h" #include #include DiffDialog::DiffDialog(QWidget *parent) : QDialog(parent), ui(new Ui::DiffDialog) { ui->setupUi(this); } DiffDialog::~DiffDialog() { delete ui; } void DiffDialog::trackCursor1() { int scrollpos = ui->hexEdit1->verticalScrollBar()->value(); ui->hexEdit2->verticalScrollBar()->setValue(scrollpos); } void DiffDialog::trackCursor2() { int scrollpos = ui->hexEdit2->verticalScrollBar()->value(); ui->hexEdit1->verticalScrollBar()->setValue(scrollpos); } void DiffDialog::setFiles(QString file1str, QString file2str) { QSettings settings; ui->hexEdit1->setAddressArea(settings.value("AddressArea").toBool()); ui->hexEdit1->setAsciiArea(settings.value("AsciiArea").toBool()); ui->hexEdit1->setHighlighting(settings.value("Highlighting").toBool()); ui->hexEdit1->setOverwriteMode(settings.value("OverwriteMode").toBool()); ui->hexEdit1->setReadOnly(settings.value("ReadOnly").toBool()); ui->hexEdit1->setHighlightingColor(settings.value("HighlightingColor").value()); ui->hexEdit1->setAddressAreaColor(settings.value("AddressAreaColor").value()); ui->hexEdit1->setSelectionColor(settings.value("SelectionColor").value()); ui->hexEdit1->setFont(settings.value("WidgetFont").value()); ui->hexEdit1->setAddressFontColor(settings.value("AddressFontColor").value()); ui->hexEdit1->setAsciiAreaColor(settings.value("AsciiAreaColor").value()); ui->hexEdit1->setAsciiFontColor(settings.value("AsciiFontColor").value()); ui->hexEdit1->setHexFontColor(settings.value("HexFontColor").value()); ui->hexEdit1->setAddressWidth(settings.value("AddressAreaWidth").toInt()); ui->hexEdit1->setBytesPerLine(settings.value("BytesPerLine").toInt()); ui->hexEdit1->setHexCaps(settings.value("HexCaps", true).toBool()); ui->hexEdit2->setAddressArea(settings.value("AddressArea").toBool()); ui->hexEdit2->setAsciiArea(settings.value("AsciiArea").toBool()); ui->hexEdit2->setHighlighting(settings.value("Highlighting").toBool()); ui->hexEdit2->setOverwriteMode(settings.value("OverwriteMode").toBool()); ui->hexEdit2->setReadOnly(settings.value("ReadOnly").toBool()); ui->hexEdit2->setHighlightingColor(settings.value("HighlightingColor").value()); ui->hexEdit2->setAddressAreaColor(settings.value("AddressAreaColor").value()); ui->hexEdit2->setSelectionColor(settings.value("SelectionColor").value()); ui->hexEdit2->setFont(settings.value("WidgetFont").value()); ui->hexEdit2->setAddressFontColor(settings.value("AddressFontColor").value()); ui->hexEdit2->setAsciiAreaColor(settings.value("AsciiAreaColor").value()); ui->hexEdit2->setAsciiFontColor(settings.value("AsciiFontColor").value()); ui->hexEdit2->setHexFontColor(settings.value("HexFontColor").value()); ui->hexEdit2->setAddressWidth(settings.value("AddressAreaWidth").toInt()); ui->hexEdit2->setBytesPerLine(settings.value("BytesPerLine").toInt()); ui->hexEdit2->setHexCaps(settings.value("HexCaps", true).toBool()); file1.setFileName(file1str); file2.setFileName(file2str); ui->hexEdit1->setData(file1); ui->hexEdit2->setData(file2); connect(ui->hexEdit1,SIGNAL(currentAddressChanged(qint64)),this,SLOT(trackCursor1(qint64))); connect(ui->hexEdit2,SIGNAL(currentAddressChanged(qint64)),this,SLOT(trackCursor2(qint64))); } void DiffDialog::on_nextDiffBtn_clicked() { progrDialog = new QProgressDialog("Task in progress...","Cancel",0,100,this); progrDialog->setValue(0); progrDialog->setModal(true); progrDialog->show(); qint64 pos = ui->hexEdit1->cursorPosition(); progrDialog->setValue(100.0*(double)(pos/2)/ui->hexEdit1->getSize()); int idx = 0; while(pos/2 < ui->hexEdit1->getSize()) { QByteArray data1 = ui->hexEdit1->dataAt(pos/2,1024); QByteArray data2 = ui->hexEdit2->dataAt(pos/2,1024); if(!data1.compare(data2)) { pos+=2*1024; } else { if(ui->hexEdit2->dataAt(pos/2,1)!=ui->hexEdit1->dataAt(pos/2,1)) { ui->hexEdit2->setCursorPosition(pos); ui->hexEdit1->ensureVisible(); ui->hexEdit2->ensureVisible(); if(idx != 0) break; } pos+=2; } ui->hexEdit1->setCursorPosition(pos); idx++; if(progrDialog->wasCanceled()) { break; } progrDialog->setValue((int)(100.0*(double)(pos/2)/ui->hexEdit1->getSize())); QCoreApplication::processEvents(); } progrDialog->hide(); } void DiffDialog::on_exitBtn_clicked() { this->hide(); } void DiffDialog::on_prevDiffBtn_clicked() { qint64 pos = ui->hexEdit1->cursorPosition(); int idx = 0; while(pos > 0) { if(ui->hexEdit2->dataAt(pos/2,1)!=ui->hexEdit1->dataAt(pos/2,1)) { ui->hexEdit2->setCursorPosition(pos); ui->hexEdit1->ensureVisible(); ui->hexEdit2->ensureVisible(); if(idx != 0) break; } pos-=2; ui->hexEdit1->setCursorPosition(pos); idx++; } } hexwalk-1.9.1/src/hexwalk/advancedsearchdialog.h0000664000175100017510000000523215005675407021252 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ADVANCEDSEARCHDIALOG_H #define ADVANCEDSEARCHDIALOG_H #include #include #include #include #include #include "../qhexedit/qhexedit.h" #include "resultType.h" namespace Ui { class AdvancedSearchDialog; } class FindAllWorker; class TableModel : public QAbstractTableModel { Q_OBJECT public: TableModel(QObject *parent = 0); void populateData(const QList &resultsData); void clearData(); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; private: QList tm_cursor; QList tm_contenthex; QList tm_content; }; class AdvancedSearchDialog : public QDialog { Q_OBJECT public: explicit AdvancedSearchDialog(QHexEdit *hexEdit, QWidget *parent = 0); ~AdvancedSearchDialog(); qint64 findNext(); void findAll(); Ui::AdvancedSearchDialog *ui; QHexEdit *_hexEdit; QProgressDialog * progrDialog; private slots: void on_pbFind_clicked(); void on_resultsTableView_clicked(const QModelIndex &index); void on_pbFindAll_clicked(); void on_pbCancel_clicked(); void on_cbCase_clicked(); void on_cbFindFormat_currentIndexChanged(int index); void on_cbBackwards_clicked(); void on_cbBegin_clicked(); void on_cbRegex_clicked(); private: void setData(); QByteArray getContent(int comboIndex, const QString &input); qint64 replaceOccurrence(qint64 idx, const QByteArray &replaceBa); QByteArray _findBa; QList resultslist; TableModel *model = NULL; QString binToStr(QByteArray bin); }; #endif // ADVANCEDSEARCHDIALOG_H hexwalk-1.9.1/src/hexwalk/optionsdialog.ui0000664000175100017510000003024515003360722020167 0ustar carmixcarmix OptionsDialog Qt::ApplicationModal 0 0 374 754 HexWalk - Options Flags Address Area Overwrite Mode Highlighting Ascii Area ReadOnly 0 0 Colors and Fonts Highlighting Color 100 0 16777215 16777215 QFrame::Panel QFrame::Sunken Selection Color 100 0 16777215 16777215 QFrame::Panel QFrame::Sunken Address Area Color 100 0 16777215 16777215 QFrame::Panel QFrame::Sunken Address Font Color 100 0 16777215 16777215 QFrame::Panel QFrame::Sunken ASCII Area Color 100 0 16777215 16777215 QFrame::Panel QFrame::Sunken ASCII Font Color 100 0 16777215 16777215 QFrame::Panel QFrame::Sunken Hex Font Color 100 0 16777215 16777215 QFrame::Panel QFrame::Sunken Widget Font 0 0 Courier New 10 01 23 45 67 89 ab cd ef Address Area Address Area Width 1 6 4 Hex Area Bytes per Line 1 32 16 Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults pbHighlightingColor pbAddressAreaColor buttonBox buttonBox accepted() OptionsDialog accept() 222 154 157 168 buttonBox rejected() OptionsDialog reject() 290 160 286 168 hexwalk-1.9.1/src/hexwalk/binanalysisdialog.h0000664000175100017510000000444115005675407020634 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BINANALYSISDIALOG_H #define BINANALYSISDIALOG_H #include #include #include #include "resultType.h" #include "../qhexedit/qhexedit.h" namespace Ui { class binanalysisdialog; } class BinTableModel : public QAbstractTableModel { Q_OBJECT public: BinTableModel(QObject *parent = 0); void populateData(const QList &resultsData); void clearData(); int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; private: QList tm_cursor; QList tm_content; }; class binanalysisdialog : public QDialog { Q_OBJECT public: explicit binanalysisdialog(QHexEdit *hexEdit,QWidget *parent = nullptr); ~binanalysisdialog(); void analyze(QString filename); QHexEdit *_hexEdit; private slots: void on_binwalkTableView_clicked(const QModelIndex &index); void on_closeBtn_clicked(); void kill_process(); void renderAnalysis(int status_code); void on_extractAllBtn_clicked(); private: Ui::binanalysisdialog *ui; QList resultslist; BinTableModel *model = NULL; QString curFile; QProgressDialog * progrDialog; QProcess * binwalkProcess; int processType = 0; }; #endif // BINANALYSISDIALOG_H hexwalk-1.9.1/src/hexwalk/images/0000755000175100017510000000000015002001047016203 5ustar carmixcarmixhexwalk-1.9.1/src/hexwalk/images/open.png0000644000175100017510000000403114561356105017671 0ustar carmixcarmixPNG  IHDR szzgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATXíW[Pgb/nٛκ;{z:vTpuֶT mQB!@Hs$!grB GTx~0X}g/>ߗ]v uH W*e`[ '3">vH~Y2ϭB9DQ臆={XSR,::NI1>I,`]YSMM4 1y`Ż?ū)LOϮ׼tCO3@{=.4W S2^5C`\&K|H$8As''H׻ "U77N,V>V:q,k,'6?F}oY1~ Z{?0L(CF&e-,!4{Z;~m$~CF=5iu?PZlY]/sq 1% cbjC'ݼ-Ӱ;3&SXO!,CPF BBsZ*tȼE lϛ'Ào%Q(/bM$"R-BySt < ] /yƪԳs LŔbK˫#7G<<b~/=/-:C(QNܿ}3i 3Th58 X\3>GelAC'b ER$nPD΋J~ m['Ѡe")(Ȑx5 >c f]KcNzI1N[;|%jJ0("3 t.| J*qQF@7 jH7'@L{RE qAAͷ]lC(N#KQWHoXQG `4QɫgA@?noiқ*/ru)S)+vQŕky8n3cjs@"mDžPt +4X$ |J8aVU;:!z/]&o8=cn*F׃H:381 ^QO`+] 9g=JUmCeS@%`+njǩD9|6ZZ8/95j'zLIdnFڍv9,9=NrG ;Fc9=pOJnX,P(@!F.[! o<<5iEX?7Ǎ: !p5U!4[7*4nI:rsm$Jesp)>|c.2*\"]~M 6tvw䈶"I m2JxLKIõ.|me6Y\Q{ %&6ǝՂ^NEXx]\UPuTA/ rjQCO-H/5z-Wxܯ\u˯Ev2g`§ҩ;P 9 /"mak^2/f_=IENDB`hexwalk-1.9.1/src/hexwalk/images/hexwalk256.png0000644000175100017510000005366314561356105020647 0ustar carmixcarmixPNG  IHDR\rfzTXtRaw profile type exifx͚Wv߱ /9,wZR̃[31_ΛJ-g˿b7>lO[k5<48{;}y}||@\ٮ^Q|V˧[[u:TC9eW"m,sigvJO@vgN~,},B1!}poI%S`un߃16s[2e`W}w妫r9c>w~sNJyyu!PH;QsC`a`b$ODt+5!ډBBr}q8Vә9 3ӹbn$.|{O9 zr(NbLOPC=SJ9TSK=˹dp/ĒJ.JƚjjoLF?Z띋vF|sFÏ0H#2hOgƙfef_~hWYuշ۔Ҏ;ˮ~(Ntiw-}saiw؟IBi1Tfnbf L͎Knޯn&oνΦDz8۹r9;;_%Y}4JS8 v.6~?δghzjЫkaO~%Cz kdzPZɌYRP#z xO m [kxYzOP'>Nu րK t1|5n p lD^nRT!8X,/ ߩ[? 7V"/jύNp;^n\9ᶇF(@[?:XZ˜c`VT(u"K5T);ESL%toPt t!Ij=՝ 9QWR#f5LhJmN~T>#\µ6N\ L˧ NyN2¥9 hq(ԁ1m-:Mt f3C%>te՝+6("K!G^eu@VB\%0s 4%;f*lB,ߕ 0 z E w@"<ޔ 6:Ә` #P- &QƙL!'Gni=e d,>H|!8 CVV^%9VA9ߕL̠Xtcn?Гe6*0+:Q#M_󜛲܀/!e{AAC*|",^ ڀ-r$0Ap36LV8(v0"j$8JH~wx#&g+*H6#Z ,(<' ZxAN\Ҝް4* ;@Wr?tIT9%kzj Vi⮆( `TfJۄ p?q0oo6+LO3blO)D]A(X-NQRbQD|&vt䗕hO dž7 Ȅb@nmNh(6 ΅d8d  ۯMj {X`T3 .4VnhB83WQZ mpH1C KD =&eזh=DQakr53,Cxb'_ D,Lg4aQΟa`)GP) fһ@+zF(d$,-(όHrG0YLC}! Om%s`1ޏ a>C 15(^)Pzq`DY( x&1UBHy,!2P0 N#Bq]`hҝ&N&w1-R>wdN9u(pDjF?{?|B_R 2T%8/6(hK5W1T(p/dyDE\43$PCKR[>o]f%L[;fq1Ph2Bwb|'JvRt RGk̔ivfײn*"`ȼwѨ4DJ^S0U*8g5%T1U?5X ߿1#o]^Qk?pp(G35È/[3d"Ev :-,Rw2=ba\XBuU;*Ri ]& T`&Z h.0@Tgj * I(v hBW "UFQABJ EquU{%Mt:9 aQ2HqX*;YweIڰ $*((D?BZԹAG>+ ׺AC>%-Ʃ:Ϥ.f)A% Hύ NR^NM{mxq_U.D_LndZrߛc.QePh>*M@Uj 0pEzǻ_V& .@n0CLYˆOs00.ia0\/fzmDjljQ'@GzʖteGآ}[aЩ[.[y& W r-  PG41hM+7 y,` E܍}":v|s|!5=B \pj^3Meg^ߊ & F̊4)q0 ~"+v~GF&M;gTQtprjځ03UQs\$!kJM$Z~8~*DU ->`;KE2{[lJ{>/+<jkQ!KLeKg'-80ӊD򁂀պ&xٙ] Pbc_=㢰,t*c$)/ 4w@hUL[pb%[}v]BQ©d nho4֪嵓Z\gR{0 'I6 |H 893U?E4dqeVAYV%IRX̀!X;\xt \ALҏ#pbMu?jup SI!uVj +uQrYA˯oaq6i#h-T;pf*(FEIB建uY?I0sut'o3"b HBq=@ BzORhWC0ˊֻ7<1|烟G~E{?m׮F@T~< \4Sۘ :0faKk,-AD$DeCR9zc̈́nZ쎸~ZZx>yM*O[$$ JwNU_c'>XEAO6O|:; 5$U` L? ϵ%`j)ɁUcru[{,k-WsI)GmaEGwMZ\ZCЮLOkMlA-$BB!+0BkRQkUql`R䙻x̋߾.4p{3W2U&kG那3Y%b}Tɕ{.b ,9QNVTtPQޠ&)UG@(8nȵ^r৯I<<`5 ΀E;8Frs>NC]tu=E:rhE:yoDs6 R6#dD!ITxLH5_CNKT]"ލ*pKm0 ]qH`^Z 7;L`1cZ.:H(AL- =q1'Zrc1o|h;Ch|p$̝N5H<s< _W"մଇE%tTl "mimuS4ۃzJHONhqz N<!F.y&'ejɚM,Ғ3pBԢI;]N}!CO-]+~t[O뙼rH䬭dF}5WW0k_xvةo-܀has.+Iᤌɷ9MX6)Kimx~;|Ѻ%ee NT(}ZI / aAu}E+C[;?!A .>#)A- a y,F2-yƆw U,诫wpJmZ ۿz5zÝ<+)(g!9r.c/rǽLS,jOrQ «X#Qu" l/$]76w+lhuyWa k3d4;/xkԘUaPնOs~9苑N`abRw8PF'CY@Jm VF>iRr6-K/qe!AԶ?9IP]3l)fy1lk)]ڡL#%CEO`&XiCCPICC profilex}=H@_SKU*" ␡bATQX Ъɥ_Ф!Iqq\ ~,V\uupW'E)iExwqe]YF23U Ѓ1%fbEx?G3nX3y8ĊB|N&;.#yi <~Fߔ@Z>N4u|^wywwgoip:rF.6 iTXtXML:com.adobe.xmp 5TbKGD pHYs.#.#x?vtIME +mUtEXtCommentCreated with GIMPW IDATx^yx+wy3%Klvl/眜p')mJý-t^hKi.@[RJp^.m^^ڲ^rℜ}-ɖ]sg>\.obQ%q$jP(‚prhh@bAOOvfտ ݥBOcnI&D"6$4ۅRn#AJMc `zzZY[[AH>! xc&/qz Gloo o`0Hczxf``||\;͈,,< D;_[[S>X֚p:p8B`<WS6^Œ u*J E?^@!Qv8NxjjJ]1ܒDCc`Y|('Ig7,Ҏo4$Smc6/_(yo )$Hȶf8R^*($Y pGGG%?h8z&]: Zh6"15GbPvd "kLJh3|^L{憔}۲@WWcF8j8̞h,~2~ EO>%IwQ DoMkѵmu5 t!3r&UEQj+-Yqj*(x.(KKKZ\ C{GFFztt.50ڜ@0 N~UO`k訖$߸IlpO N' H ᐆ(_}]kUCf^'zf]i*9I/xWb.(p8RjH>@$"?^а&wE݋7]VRrUC=$IPE_M)1v+R)ԤVtgn^}_p^/|>vx<Xa.рTd4+++Ϻ28Il.9Ouc^sy hS݂1ЀTx1X,%d /mUAwDr !ϖb8NAIX'АT0Ƽ>-շ$I WMwNX(5lpIX9XaqTmzzz`S 1ępܱ%hwvvV~&78]&"aop}xnq])?.`/1Gbx,q_ő$ ,kbbΏB*Q^dM1moWpLEX+Fv 1׾~G܎|a^R5y?cؖ.(>Op+++j@pJN8(X[[[V\taIw1fM[HJz9ƶ;ۖBA@AnlnmŎEoOIlZZZ}ɑ\__fﯢ6{eVeSrZBSCx##X,tuiH6)VP|&ec01ook l;^_|EPώ#bnE`1>O.//#NeRP/'Y>yysHXO>S^i?~?A1 O*+Ifffu'1j)c9;Jr9O@7OgɇZ'zT*JC(|65J/o5pXrqfR@^1ł8ɨUʎo` /..jE?`hhib@2E8)os%.Ҁ477Y E"uQ ?<9rՂbUz0>`*u, Z[[.Wcp'*9^{f&%&U{*uWxr٬ O~ثܝ/@j@ssט}b@$Xf+ZTsTw4fj0_qՃp8p8a|O3Hأ. mm{Ǎ)T9o<RY^^V"M"c|;_m@k4NB<{@@ eY!.p8q|~[3??d2 RvsrJlci>D;*ՠ1! @˴ `llL;VWz*pXȲٌaX$}Gcƃ\Gr@T[ fW8L0ŦH%vs},շQ8bjjJRq:BZpkkK}|]%9ɭvBVeM=B[X|Iٸ%d,-ڷ1H#<333Bwhhnz]P~ofMrΟL&cze˂5E(+zObU0;R3/:::n?t`X@*R#?7vvkk\XX0[Pm7 xo3cl6eh5^tkkkB/C0t7-1^QҰpWfqiAU/1Ks XܸkA7ta؉ DgggNWWW]L0so$IW{cU8U 0=4%a9.cpk{Q$onC-q֕r㰶&wɤ t:f.d1Ea7`Zo:Ƶk״c#qfffxg[rXw? yqn[{X*vauJaZo1HE:`[[[xgBӿ|Ou콽*HP$a܆#Ax \|Yb1\zU[Al[:g{gjmuD'ե}s+b$z;n\]]EWW9o<0>Lb (F|!}˼/ kk9( zzz} ӞօmE1ѽ 1}HKK |>p:I|[͌H>|D"!h Vk wze6UĦȸkW`_Zg׮]ڷ8zzzZe$WCS]0ֿ* oSo[ϧ9kI !IҋFFF>6::ZU@V/~r=S D"FMZ{03VSm|"<_8B௿_Ӌ|:NagUÚclN7`PK Z[[(spD*`tCX/--n%4ghf}xi{<A8a?fM}WTjhp.H$HE'5]߹V^EJxqÐT]]]BOVq*R~.ewvqih^X@kƅ} &Ewd2B^v obsΙ'F 333jKc/+ixD*8eCCC\.(@B- r+ 8[}I<S/c4+v]s>OP]^^6[P܁ywfێg`-a֦r (PI͂Fꪪ5BUn;$Iࠐ[7MAB}_ nYݟ{7Z$ǎg izkttfIU.`r p>ߓMwfΛl͸pʧ.¶fc}}^'L K^a!cRvړ9OcwyGGqFM Y\Ϊ|Y;}y[Rrd2*@/_)U3RKBE*K1222N:$IWNfR5BA qېv i[p< N|kY1AMxoss3UMA`1F[IDATz<Yv5\.|>/8?22򏣣JUum9Wc`! 677sff>fN)q@8RKoΎ ^-z ="cqqQ{Ey87?]jϑop82>0e r+<<,Vim+,q , Rʔ?߱v[8׵uww4?S [_ af>ˑJ0::כp7C5W8G @eEA az@ޑ!ȰnXfrքO{\j>2, m1N#ZP,C4EKKK# Q9} cS,*˲(L0NOOXW+m1'+TSp? h&iҒ0gppPl69&n٬qRvŘvy'P7X5I 2w:B/ЇoTQ=ۅ)%𣌱4a](OX,!dVڊ8 ́pO$ծB3qz$IxEE(cMus2]N 8XLA|EUgRIΟMMMB0wmmM-Rv*:@*bnt:-j H$"hvuu60Irڿ?;4k\ۊV# Zd?H`||\$Iu;݇0kXLRE 35r|I/IPN8oۅ|ii 잨f]N!*F{{֝RaYʮfsk|־fb?sssࠖYrS#A/{c>5s<?BtӮ٤YH [pX,{R)AŖ)zחgI7EQpod6`0() xXvWsss3e.p8IϺ/!($I`\Nl֖BP5ZէNV7Ԁjs~P԰ ! (Bc,›hvXWE}1Zځ|[Z[[($ T>.rAphhH#x&''zt:e9#9cnm@*ڧbC@/NYVf1O }9JV],-- S/^Hi?G8nV9cV]/_x9AQ~?臦@arhm]91c,i xwt:mPQEwPq]91~:7֐M e6Mlllb D㲲"uvZ~n]O`#h'XZZҎeYV-k:Y /y= )Stuu ^ Am55CodS70m-(onn -$N =3G -IAHvuu <k="!8҂QyvB?n".e8@&  W&|^ x|OA1vӂo$ ڲ8?L ױiGJ8|Xq?:bXi+Tfn?өgPBrgy ! `qujc% u8<;.KH at(vU!%93 <r*`nnVq-+I~8#G{a8jbppP;OBh4*O%fԤ,.Jrƴcͦ{|O8?@!qp.u+@cɦ&[pmm҂t: ۭӋ္G@9aFS@P]üs^Z4]%D"Cu  i`0t|]94i_oRAfDPѭpr |l6DDD똍 DQWM}s% Ip5Ҷ˚d,I $w3=T}M_|T |N`rBnWQ:{ a`=O|I|KK .]Tڰ߻}.{P_ MW=.5‚Vp-@97v`$auD:<:- 9BF(ԘSZ>~5Zy1 Рpl6H$}cD"B௳SRvDž@c }'PC٬ p8 _WL>@9g6 yZԖ(R~_:Ia ބfs(Rv'@ >B0YaА*9{"|L8RZDvvvWSSRvF @}o[PZfffw݊A#Ap%&P|Qz@imm MMMQ@r9ܸm^Ϗ!y\ llA9N5q-eW ż) XR0e޸ H1*L$SO=q%!Hx\ID.Tޟ* 90>  $ 133[V=!@s> -$ !񘛛۬r+iX0U'WVVh H&޿Y] @ <%IRS<<333BUWvA6ՄQxr];_<8h4pxTa!@?j'166\Δթ& E_=,.  ɲ\ZZ>,TTer``@}sUVqc @҂I&Bbpw @wH$Hy,,,6lpVVV9<< r5H8.  HiU])ǂsR֍(~E+sk.@86ar !HtlllRPHe_44NٴL0b{bbD"{dYVR6fCzĉa_XX9rכm#<`U DZZZԇ? e.7Z`"XLXW_9aכ 90GaHkgQhp ͆Q1c/@srAAAAT Nc}%O?M}rĉJ:3%                        h(?3?G8IENDB`hexwalk-1.9.1/src/hexwalk/images/redo.png0000644000175100017510000000225414561356105017666 0ustar carmixcarmixPNG  IHDR szziCCPICC profile(}=H@_[KU*v鐡bATTJ[UKIC(X:8* .N.RBmVbLjD\W+1В,\=<|,s`0#1M77g7M>qExB ?r]rsf/ bx?oC@[{@ZeϴrFbKGD pHYs B(xtIME 9 :IDATX=hAo&)4 a ኻpiŀ`Gg " ZQ!)D[!7))G> fw.y7o("GML.\.K,:,`.r ӕJ 0??wXE)~EʝAZOwS Lv?fYO4|.liBz`Gk sb6 D@ "?Z+^10"ڋ՗ "z~lll=4jg|B\,J[1:9zWR8JTڲmiat*<ϻm?0u`"UJ,HDo;pq{Ƒ6Nj zdۈ 4RWh*:pMk}4n1bZRyp6RSIZ΂239s\.$ m^A3oFw\Ztg~LmA80V}cK8*)ߕR#aI8v7/BwSfT*r"%f( uX,.715fA{I^nBA7i0eu8rkNu[pPBY{6A$0}2ElY ;'(ŪzewϹd5̂NH4C+ lDe: .Wo?4!ĐBmt#s8])Rfxx;cB΋,-~ K\Ғ ҧ/D**U+Ήk7R5B-ܑj]zC5Uֻj&S11v<74bbZf&BCI](P :(wY+dWt (wۉju|mQ m8H5 -fy|nsa뱓>YVr>:?c4l{¼|YU .M{<|>,&;.#i ~Fߔn5>N u|E^xwOgoihr7< iTXtXML:com.adobe.xmp =1$bKGDC pHYs  tIME 2IDATX]he3n &菕vTDm!}fIf'̃>bQPC uPAPib:yz}A'u\u~N ه8(ɶWa=B`1}@#%}=ϒl+K:,6~#6p90/t׆lq>=!(W}E/Б$ :&/Q*Gl~= m4-^n^N>LCe.;>I,qIlZ |{ Uv`]@K5**}I N`Et:.I,1`8k{907d 9'~3>,i(,oSɂpR7%4Kc]`+O S.tޒQICr^d p@4duŤr:pdGF7?zA޺m \]&6' p6W⢉U8HgYng1&v@SX>4%nBnԆ4&6UO lzUU@6`k"Z۰_RlKI`()٦2y4\TD4NI+ i@/R5Ĉ/$UliMy!24nnNvD!sZҷuHci| kFD *b;%7?Jp LZ;nFG{2% ׊2~}G#G!Imq!ٰ+b{]Gϩ mw-7IO⡹nn#qa6%(ϛ=7+ N< ۣEbk $q})t-OϕDvO#8  KXXv2IENDB`hexwalk-1.9.1/src/hexwalk/images/hexwalk16.png0000644000175100017510000001376114561356105020554 0ustar carmixcarmixPNG  IHDRazTXtRaw profile type exifxڭWY( s6!ts 6Y]]3K0IHpY1H/6|swiŐۭ=0}ٛ3vJh!=_hS{ȯ~bZ-{gm`fv3YXh983B'ۜqOҍs o8Vhp'q' x (4Qҗ3?w44P71v=-(\XϸǸ/{gQ#/6@{osQǔ<5܌Q']@tADetX`܍7$Mb TYbBlqW[v⪋`FWܮW@V;~ct|B1O oQ5]l.GtsI%"# + -.eB``4[$h٨b zA`oa3Zk@ q `yOD<b$ #B0pbǞ3GNE)1FI84Mx(")a fmvg!sYr*OJ(\bNUr kRS3 TjQ [lRպS{ӅF'rFl)VZnmo.qV#8x=7nѹcYG5POmc%Q?aVvԭ5*j aAC.$ѭOՙ nò:WXIcfwT$"X!~Sq?K NAPx$S5ӸGkt qzWVrfE.AJ?l\@g 1%NމJ[ EQHrw(2.nƅ\~CRzYJ^_ \ %2{ڋG׬tf`M<K3]>vC=o ?e6r c I=']yI% 8<^*qp`YIqj8;_QXN*=R8rO_o?)osp`޷ßXP;[fzTXtRaw profile type iptcx=J 0 }EO Is$C_Eewڑ`3 ^\>K-bI3J> T,%h(iCCPICC profilex}=H@_SKU*" ␡bATQX Ъɥ_Ф!Iqq\ ~,V\uupW'E)iExwqe]YF23U Ѓ1%fbEx?G3nX3y8ĊB|N&;.#yi <~Fߔ@Z>N4u|^wywwgoip:rF.6 iTXtXML:com.adobe.xmp bKGD pHYs.#.#x?vtIME ,:<tEXtCommentCreated with GIMPWSIDAT8OMKTQs_YTpɱТMFLc ڴ  & Lt] D l",L=/ +~< 77/( ˌVAk8677V ǒ +kԈm9#vGE(BRbm Vbi'^Z뺣*޽|_KTZqubbRJJi4??/1NRJp$r h[J)4﹮+[JbR5&R[f 8z7mh!0;ӝ+ǑXHjGR麑VR.!ױUtwaztS,}- 'kT**bXbFuh<"9w:&c)!;8缫'!Ķ,kr1@.d~y;"R TISPϑ_8ba#l6Oj 1!HlDFMh#87 xv׹M-VRA@ 9H$1Z8 3_Ԉ\IENDB`hexwalk-1.9.1/src/hexwalk/images/find.png0000644000175100017510000000243314561356105017654 0ustar carmixcarmixPNG  IHDR szziCCPICC profile(}=H@_[KU*v鐡bATTJ[UKIC(X:8* .N.RBmVbLjD\W+1В,\=<|,s`0#1M77g7M>qExB ?r]rsf/ bx?oC@[{@ZeϴrFbKGD pHYs B(xtIME -cIDATXKTQǿͼ(22$aEA.)͠A+ lQ藋J$ZH ¼\8IdCTX2NDbK:%2SݶmSQ,t-qdkk're6@ae!yFf&0 z !N0K ʡh4)Fq+ܝ- 9F( @4A%ϵ8`3, -q]+iYl @D *߰o۶U5.*YLf'q]̻nM\ꜻUlNDtXsDĞZZZ>jjrrrk%sJr=$zf{ezT!"XuR]4Mܼ y_!{<Q(/c˲n8dwE4m!cDty +ԌT "ŲA"IDu̬:!4x=PJm, dNO7Qn3sm[qVdM*d2˹g=3b@W勆ap8 `5oC13DŽ(Q[1\ "u=VOJ^J cmc]†lH;[IENDB`hexwalk-1.9.1/src/hexwalk/images/undo.png0000644000175100017510000000227114561356105017701 0ustar carmixcarmixPNG  IHDR szziCCPICC profile(}=H@_[KU*v鐡bATTJ[UKIC(X:8* .N.RBmVbLjD\W+1В,\=<|,s`0#1M77g7M>qExB ?r]rsf/ bx?oC@[{@ZeϴrFbKGD pHYs B(xtIME (4IDATX1hAnsE%A= &(ٽK(.DL%"viDHE HDB`onSX%ڈ$y.lrrvȮ`Λy߼yfׅX9flSQu}m˲Ҝ&$?qg:ϗz={D^Bk2s_B1:DZrYdS˲"H0) = L@GQ2 >}<"hQسѾ(8cM˂deYi" G1 \ӭ $1"p, L5ennNtwwRxEN9j88˔=rܱ%JbKGDC pHYs B(xtIME6(;]IDATXkQ?XoC!D7CNAP (-h,9 -i*9PPۃ͡l<8 f7?t dz|N J(M`ADNT1n*+"^UM6PY*{ڧu o5UM*f;^Y>H h4^og# C'u:m|T 38{N3HDvzV_Z4F"7n)*e'p"Hkww<  ٲ"pDi96#M`$垂-TuƮc׫jZO"r9 HH $sN'dc`0,q$ s9fM6E ҡM`َ'o;@U'Tu80WI3`%?7̥EfxE`+"a:p\{zknZ>i@dTsZmCDG.up7> :E9 O?RTB?z0:̀a~qХ>>___B```QQQ===``````````b`:4.%.%.%.%.%.%.%.%.%.%.%;6`a``````````???PPP```]]]c888YYY``````````b`0'2+`a``````````ZZZ777]]]k``````KKKFFF`````````````b`0'2+`a`````````````HHHJJJ``````ZZZ666]]]`````````````b`94.$.$.$&,".$.$;6`a`````````````]]]666YYY``````%EEEMMM```````````````````b``b``b``b`GC [wZ`b``b``b```````````````````OOOCCC```.```VVV888___``````````````````````````````GD [v[```````````````````````````___:::TTT```___B>>>TTT`````````````````````````````````GD [v[``````````````````````````````VVV<<<^^^Q```PPP???````````````````````````````````````GD [v[`````````````````````````````````BBBNNN``` UUUBBB```]]]g888YYY````````````````````````````````````GD [v[`````````````````````````````````[[[666[[[x```]]]`````````````````````````````````````````````````````````KKKGGG```````````````````````````````````````GD [v[````````````````````````````````````JJJHHH``````VVVKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKYYY===WWW```````````````````````````````````````GD [v[````````````````````````````````````^^^333^^^e```]]]e888LLLOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOKKK:::RRR@@@```````````````````````````````````````GD [v[````````````````````````````````````TTT>>>___<```KKKGGG```````````````````````````````````````````````````DDDOOO===UUU````````````````````````````````````GD [v[`````````````````````````````````___888VVV``````YYY666]]]```````````````````````````````````````````````````\\\666UUU999___`````````````````````````````````GD [v[`````````````````````````````````LLLFFF```#```(DDDNNN`````````````````````````````````````````````````````````LLLHHHFFFNNN`````````````````````````````````GD [v[``````````````````````````````\\\666ZZZ``````UUU999___``````````````````_f_SRHED@IFUS_d_``````````````````^^^888VVV666]]]``````````````````Y}Y?;?:?:1) [v[``````````````````````````````CCCMMM``` ___H===UUU``````````````````VT0'3+XW``````````````````SSS???LLLGGG``````````````````UT [v[```````````````````````````WWW:::^^^VUUU```PPP@@@``````````````````US#&WV``````````````````???SSS888YYY```````````````UT [v[````````````````````````___;;;SSS``````]]]l777ZZZ```````````````]n]+! 0(_h^```````````````YYY888SSS???```````````````^l]OM@<( [v[````````````````````````PPPBBB___1```JJJHHH``````````````````IF&TR^i^RQ$MK``````````````````GGGMMM>>>TTT`````````````````````^j^NL-#  ![u[`````````````````````]]]666XXX``````YYY666]]]```````````````_c_.%IG`````````FC4-`a````````````````]]]666UUU888___````````````````````````_d_^j^^j^^i^`a``````````````````````HHHJJJ``````,CCCPPP``````````````````XX  Z{Y`````````XW [u[``````````````````OOOEEEGGGMMM`````````````````````````````````````````````````````````ZZZ888\\\k``````TTT999___``````````````````NL)_c_`````````_g^#RQ``````````````````___999TTT666]]]``````````````````````````````````````````````````````???PPP```___O<<>>___C```NNNBBB````````````````````````A=93`````````````a`3+FC````````````````````````AAAPPP999UUU[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[888VVV```___;;;;XXX````````````````````````?:;5`````````````a`5.D@````````````````````````[[[777VVV===================================================LLL```"```IIIIII````````````````````````?;:5`````````````a`5-DA````````````````````````XXX:::___R```(```(```(```(```(```(```(```(```(```(```(```(```(```(```(```(```(`````````\\\p777[[[`````````````````````C?71`````````````a`1)HE`````````````````````___<<9C?`a````````````````UUU===___I```]]]k777ZZZ```````````````^l]94>9_g^```````````````___999UUU``````OOO???``````````````````_e_NL5." #70PN`c_``````````````````MMMEEE```'___D>>>TTT``````````````````````a`_g^]p\_f_`a``````````````````````\\\666ZZZ``````UUU888___``````````````````````````````````````````````````````EEELLL``````+DDDNNN```````````````````````````````````````````````````XXX999^^^]---```ZZZ666\\\`````````````````````````````````````````````___<<'3ď\]~\tXa##6ۘ x8 Y[r5_kiFH 2@jH~?ɵFyTBr[09&b@m]QcngJk+u`ZK}uK`I ɑ4Bx?o@p C]-h<ۿg"rI{ bKGD pHYs B(xtIME cY IDATX]hU3nDDc񡨰M]?SA b I*"RDئZk֍db 6U RR;cvߗbMZ!m;߹g=XE y[6Le.{ Cr |%I@rIE I>`x6h$XkeyVaI<cl'iI6;{ӹ\nK` 9dm6HI> urÒ% ॖf訤 ġ1$u]tkkk䝒8t@|R!nw9L8EQW6=*$-7I0W} , }2)>(IZIOFI?IEU$=^}@݂Rӓhnno]K0ng:>bŊI;GGGAð>HܼCt:{-ьU*C@ITuk&)}dg 6211p>I/UTKz@׮`/rjfI7?ᩎ 48sD8y, ýi$xڵѬ?5>|T%d/pcߔ* Xb*i ۓW^jp+1f%AR?j*|>67%]V]wĉ0 {D$RڃVQYryc^d#3r}P*%$ pdwǂ X_,'>]vN5ػ」;v<:̗7XSڠkg|p?0x.ory #ӟd}k@E@xp,#˲m00aP|#%"+Օs΃* ,I Iw:琷Ղv+m(r8 㯼IkFؽ{k놮ZVmQg5 ,# /#&|#!Я'aa%% 4M:ólc V_)Fara-р: TIO4/!g iXvj#wPE x:Tx3x$wh6h߱R^DM_ 8ňKvRPZ0}@Ű&WU.2p}Ʉ-Jsf+7QW?תd~')Ü wl 55Y1{X0+WVU!ѐS,-޸Wj'WڣU<_o|w__sl}5ځ?MKFIENDB`hexwalk-1.9.1/src/hexwalk/images/hexwalk64.png0000644000175100017510000002630614561356105020556 0ustar carmixcarmixPNG  IHDR@@iqzTXtRaw profile type exifx͚W#DYB@ˁ<`?Aꮮ1ɓ$3 3s4Cp&\RM'P]K~ )rܼO8y>guqLb_׿z}oDkxt@ gs3wϊgEeks<3P >́ஜS{qWsj{zA^.u-oŻ^ׯȻp|8'd >m϶_m=ar[x[_mvܿq_VT>fvWԇ_ɫ{ϲ:Bbk+vYܖxe~#yU^j tZ;mۮ9`-tn8|Qy~Bd bsؽbϼL7l!Jgre>'[9cU޶b]NY29s)5m?rǃ񘹰v{GlyYyl#!&{e粵رI@׭&td[9dssOZ}'qM g !Z1S̱[IRN}9s.V| %Tr)V]|6FnݸǞz3ˆ#<ʨM7$L32l.BiWZyUWۄ;λkWzk;s~ a'Q>c.X<gW<ѱ(L+۾}ṟ̈́{u ~O6Exd9F<4Wh?Ϳ@=2}Ew{zvU$A@ ޮB'w{DWjۊvmZdbN]GlIk(}N$Vg%5 ;ir?1{7~w[ F3}^tfFM7˽nO<3]ky_ir]+3]}B/eSsʆ{}:_Q9D6cbfbWcc[+٣k&O \d^=FY~ֺA((8`lSj):ùXOֱ-Z|Mg eOERo^U.o簕ljIvuʶW}] X.6-)ׁK95[0}_s8[ FrufXmf,o:ceeĞ瞫9Cºs; ?;X));!h|nj'S4.'=>ǘ5*]Z]_il 8dYdKʋ>Agq\ܳZI۲`ONl81fٱ[X̓&skj~0ZݨsXs6\mݓe-8I-# :g˹6N@Yq {d묌ï`S@5 [Q6/1Bl52w '[X5l|5<D  Yl[5k(Z'b'`~-?+)R~3,sD+h/J k^5+PnR6Mo5RZpyvX0ZJ Ip[/A顈n]+SlD2n? @muV=zr -"t$Pe>+xP޾ Q^4uO$f2/мD7jW98rT17,{nDv2!k8#_! ri_ WR.hFKg&%rkhX?Qn֠FZlx;7BQj ;ֵJ{QQCZ|8k䟆N$Lը DCk(o(9" Bpa ]ENBF?zs0Lց~}ղP&| ~ )&1 fQʞ ⸴T"yi3yXPM聣z$ 1Q.rG^yNe6TNyUPLwU lHF0_ΨjHlY O+ b4$1Id(]"+Ij#&` Pyga᳻%;±_Gz>dk-#{^N:vtS눆-gRIE I~r2M'"Vj]tq i&\nqq-bڟI֪Q'H}TT/n* ̳UML4d)!L.;6G4 T)%u "E*Ks7%Y0" N,QSEEjIOE )kau (ѝ⌁l[QA 6Yu:/>i'9OaF$(J>iWSOT]-d*ɶ;i0XeRֱ퀓Y(#U8#$F@fVMCkTMLHwż-Z8]YʣQ\nQfü[1C)82>on7&xy>!]jPʄ&rIK"ɸ͘NV7D:j]ʾRC̃ (ՃJ-RUZ˞:RT2 9+q2I8< EAIhA}1_OV!:7iP H?)]귚fi$7$~z|g>':&)rO.LtYEYe\dyWsW:2'~,w܈Voi5:6ح oda8)оI6P`WUw}}ZRj5r:j~EaFƊsj jftw%ox s {3>,FUfP^"n)7c&J!.[=ÊrNܛSngCG?3AĘguEȟAŢQ#UfNϠqbl.  ޻Hhkj׬zi-BF(g[x7IY'mWrl^kW+I'גe%Ut?ti {6OuvZyGTu4oM HϦ`~dᴰZ=-zZ~钭3XuJ5,1SV_q] is|5sJP$&;.#yi <~Fߔ@Z>N4u|^wywwgoip:rF.6 iTXtXML:com.adobe.xmp dbKGD pHYs.#.#x?vtIME ,7^tEXtCommentCreated with GIMPW IDATx^[lW33ݝ{q(%i7$$PETjEATʥ*PU*BۗڇC"TP"(H6&m.wޛ~9UUOa驩$= @qx^r](l`0xbjj?;^H r]( 3;%Ij !w|>5<0 P(x<~\U{w ]BRDXN(L&yb t @),B!0LPP@3x^$=zʝAq !}l\.֒Of0GԑFUЧc=?o:(]NQVK`vIU;fX?pC/_""x{R" ,C\0JM&`2LLL6whv!@O?q:A=xlPo.)ck1HM)Bbh3!jR)D8yaci_,ʣhaX`0\.4!Ĩ)6{~Y4] p` j˷56[_CU?8z[Q=U~?fm]6nB[,Vݮ=C5]MlCo9`7l1fZ˅t:cB_SͬRz,wAi8\FHlMYSF5ènxO2TLUVm#,BLl9Z,]q>el}Eκy(h`Y@,ONNNN C,kz۹f6y720cZ]l6 FP(%l}ŵ ,ˏ\.30 svL&i5ǻiGwmX ~H `nnl6?E$Iz9XIjNzN岞 T&;3=fz B*h4P(bk:V3Sv7 ü^D"TX0ڃ[Te*O3/QJD 2|lrag!$I(3͵e=-Ĩ\ˀN˨#|-TCѰqH9t.(( z H$74S b1(:ָ`DX?o2*2mx-Uޛ p`yy.KS 5Pfu0] p mnZiso*qEJ1 n}mتb1A,..B/ UډƒJjBX4; IRn@QTҾwv  Nr[BiB` v{W׿T?WZ4}СCsFP4sݚCaG(в #~8{ |b~~~ e%G! 01}S,c5xG\fEرc/:cp8pZ}PQd06#qcRt: APTp8mi\?ॸ]Zo+Un?@$I=ϯx4M$IXV \+`0```TaBcgh4>xƴw-$2z7ln|^,?#0]$Iʜ>}y,l\.f㸮T>sÏ㸩Rf3hxvc6Q*XJ{@:!fzf]r>R)xhRh4 Wev@$j6ZLKm?٤!d2DQjL ZK%:,n$mV?FYKf 1W> [J"~9^rcc'VFV^bdRߵ[uay3Ӣciaހ[_]G09rh'5ď\]~\pX!##[ x8 [R5_i)B #2*@ "jH~?ɵFyBr[3?9&@m ]^cۮgJk5`jS uS`I ɑ4|x?o@ת[c@Zey4wr~CbKGD pHYs B(xtIME 38_IDATXMkQSFhk s.aE@ԝ+B~.\F("R$Bq Mqsdf2}a~<_% }S~ f~`!abfZUWrw@UXD MfnIp9?9 @D|6IthKA:ֳ@">h? KvcU}ͻDԛffv+W|sfCDv}<fޝjv0453*rl^+Jn[YaA߿ QV1*>!:}"we-: 0Bkc~cx-(F7yĪT*'S4Sy33+ԡ؛ua3J,aϮIENDB`hexwalk-1.9.1/src/hexwalk/images/binary.png0000644000175100017510000000256714561356105020230 0ustar carmixcarmixPNG  IHDR szziCCPICC profile(}=H@_[KU*v鐡bATTJ[UKIC(X:8* .N.RBmVbLjD\W+1В,\=<|,s`0#1M77g7M>qExB ?r]rsf/ bx?oC@[{@ZeϴrFbKGD pHYs B(xtIME !TDsEsIDATXWMEqjrq mUܘ] QBG=(DOxP/Fr2Fн]?MHGŃlX]Kqvze^U{`c8~ZDtoYM9j"PC[ԣeSG1ա" 䧾dwnV@ T=|_L( ?g R:SU?p^k^in$84ʎ(Yp8wTpuC)EvyGIj U'%O yja>EUTEdec <`S1Z$gY6׽D$_EjAkoc>q[ j!>Htt~,"&q+o8np?GFF>|hywuZE̲15?;|bcI/}/|$?j#;yOMM]Z*&$ MSs[~l65li4+++)3111u-//1%9mYp]|E\=""s$$φakkko{IlӃL^7Ż,9@[ƘCF1hG$ pgeA|h4ZVAZ>$ɽ}n]:g+Cc+ƍ1(.kgD^0)",mSJ)Ͳu_c3~.˞-l%"qn}܆iHd[!.+N !q](I /7,d7IENDB`hexwalk-1.9.1/src/hexwalk/images/entropy.png0000644000175100017510000000161114561356105020431 0ustar carmixcarmixPNG  IHDR szziCCPICC profile(}=H@_[KU*v鐡bATTJ[UKIC(X:8* .N.RBmVbLjD\W+1В,\=<|,s`0#1M77g7M>qExB ?r]rsf/ bx?oC@[{@ZeϴrFbKGD pHYs B(xtIME 80/ۅIDATX1KPm%@k;m*V Ppr\,Hth%Hӂ,/ NN^^nLV,-hwEA "jw\J@W$"nx\eVZHH1K5nMR0'Zd(ljZ><𸏀GuRɁ` եx4m`0hiS:pi=1!"/I^F;"P$Y\؝|8k ϟcZ`_|~B2E]IENDB`hexwalk-1.9.1/src/hexwalk/images/hexwalk32.png0000644000175100017510000001705214561356105020547 0ustar carmixcarmixPNG  IHDR szzzTXtRaw profile type exifx͘Y y A\8@){a2$J)Q Po/>쒰m9_|RK-(zݟ~Jg{>/>އDT?>GDۗ5BuY^b4e֜ErF\-[̷'6k@鮁:0>o~A)P؇0B<*X0anx'w(+p%r:cm\W0!g[;)D夹@=Eh8onu2 HAB_G_%=yDCnx/&QcTsmp=BbhZTJIOI!(IDDșK6K*Rr)Vƚ\KUmEMKCTy2rrj=ԥ^z># yQG:Ìn"gu/ҒWYuӖwuoTP ؔ7j.57; B ^  !Q-gzC AcR-wAw o6Q;I"U5T2{7S'곆>ehi SpeWu# w\a|? WLGcu 4\'a"+S"$bȠ"~sM4KXENKW,u \q0w.|[+JrYfI36Wg>Uv- -ӋޚgpUm*ŖG=9;[& 2jv!,ѤـF ^*vSKֽӅ’x rQFs)-j@ޤ UOhQW+;t =42CufdĜ;-i& EnC] ̂Gijcᒎ&  fN-c\FEE`o8 r|֩M|/a軌eR0rٍlmH]6|'.EZmi@I»W7WW/Gv`~Sj#B7?X5lIZ2Nv;%`Co"[ԲZ>h-,Ss(GDewΫLUDeѶ&ܗj'\:\JXÒ'j :t䴐SKnͭ<:Nbj.hQrHhmS$[ |{KoeI$M8V@v5`҄GsAƂ[e?6ORBHW ʴJ|y=\`m9vĭεY|=ZGߕL.WۖDžxU#Uth+)Phj.pǬ:6nR]gZRu5CJ5F kc)}R(me#x5`yq|l$"r^`.,}@4+k@@:E$87XUwYi5ީr61Y`#+vaI$ @W]4_#4n2 )C7 (_08g\,FHɫ fk /9ZZ;ߵpn=Uj~p9Rcjjx+]gz7Вv 1@1YNۣ㶬'hO*M;iu^u?]^he~Gl;?(/3ns_49B3!B[O#[2-v:Cj,rPYaӰ.328ĆHMwDڕɸ@A Wҽ5wY7TeJvyCl[q-ezTXtRaw profile type iptcx=JA0 >-9Ic)]3l)p3LN͏h:;EN*JS_JʒeKiCCPICC profilex}=H@_SKU*" ␡bATQX Ъɥ_Ф!Iqq\ ~,V\uupW'E)iExwqe]YF23U Ѓ1%fbEx?G3nX3y8ĊB|N&;.#yi <~Fߔ@Z>N4u|^wywwgoip:rF.6 iTXtXML:com.adobe.xmp k~bKGD pHYs.#.#x?vtIME ,%4vtEXtCommentCreated with GIMPWIDATXG[lU2]fRPŀqƒ(FLp b&}A/'B)aШDP1B)ŝΙs.-+&K&s088VJ6߻Yy\~0!m;[Zd۶mq|#PH)Q(NR`͛]v%}7SJD KBVQR(DQ4aÆr޽{y;}77Oa:`k)/_euK. omr@EQ.mhLsU L݉Td!p]燆Z3y={PrgP3H>⯲Xk7VGZ9m>!@mB~O'I47 *5U86iT*Jw޽ͶM.߿_]mK\RDÈ9S ԍx1 jb[l9N릑[Uu۶ͦ)$d5b@+qm?Յ25JB{kکmG0^ (<+L(#ƢjD]Iy^169}nyu)=^U.P\E!K\!(8h.`mhSLWn6>aic.ApclaH$1&Ncr9O`'K@b52(H 8 |'L;N-i#0 $'O\.7d2&qL+ur)Vj5!d_ݾ}Z~8\)c,_9'q#9=i144rO&v˼hy^u75222"yZmn!˲oHXusl/KDN$7Q:IR}'q:xaڶAw‰ (!w?CjZ7MU4 @غufl֚ 4* _f DX`Qz2g}S/]gyY}JdO$eaOoZ:}0+K 9A$~ qX,ulSE(_ȹpVjuOPA[pXD)Q*]#Daǟ"L 0ṛ ߳5nR(tGͺmv?WZ_m3Z.ۚ\COdH%}SZ8}4-Qǻ{;oOk~?ErplbKGD pHYs B(xtIME  a )IDATXWKTQ}X&B, %%.tAP H !wa#EAnj&!;ѦMIZM9di3#u^32u-=s].!`Lt23_d}jP~[֞R>hGc|B mT`M !&TlE>[kBtBipd̬=3ƌ(Z{WJ9Vo9KpZKZ[Dtz*LR% WCCL&sg=ϛZQ=3o\'7o,Cnd2anmɳKn5Ƽ`%hΑ > ,o%"QD)u ^;!J)d29` bݒG"hRj"ܞ^"RDk)e2wL}1f ^cLrd]Y@cZ뗎ʢں)lO*N!JXky1!D˲:FRDԴ+C2Xt qUHNADu 矺vJ-wp"D"c|J0^DYkYuv^qgǹJZ]cFJ){5]]]7r<ω]~2, mIENDB`hexwalk-1.9.1/src/hexwalk/diffdialog.h0000664000175100017510000000250715005675407017231 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DIFFDIALOG_H #define DIFFDIALOG_H #include #include #include namespace Ui { class DiffDialog; } class DiffDialog : public QDialog { Q_OBJECT public: explicit DiffDialog(QWidget *parent = nullptr); ~DiffDialog(); void setFiles(QString file1, QString file2); QFile file1; QFile file2; private slots: void trackCursor1(); void trackCursor2(); void on_nextDiffBtn_clicked(); void on_exitBtn_clicked(); void on_prevDiffBtn_clicked(); private: Ui::DiffDialog *ui; QProgressDialog *progrDialog; }; #endif // DIFFDIALOG_H hexwalk-1.9.1/src/hexwalk/disasmwidget.ui0000664000175100017510000001211415005675407020006 0ustar carmixcarmix DisasmWidget 0 0 280 550 0 0 280 200 524284 524287 true Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea DISASM 10 100 131 29 Arch: 80 70 111 25 Little Endian Big Endian 130 38 141 25 10 36 131 29 Selected: 130 2 141 25 10 130 261 371 0 0 0 10 8 QAbstractScrollArea::AdjustToContents QAbstractItemView::NoEditTriggers false QListView::Adjust 80 100 111 25 x86/64 x86/32 ARM32 ARM32/THUMB ARM64 MIPS 200 70 71 51 Disasm 10 70 131 29 Endian: 10 0 131 29 Base Address: hexwalk-1.9.1/src/hexwalk/hexwalkmain.ui0000664000175100017510000002576715005675407017654 0ustar carmixcarmix HexWalkMain 0 0 944 786 0 0 600 600 HexWalk QMainWindow::AllowNestedDocks|QMainWindow::AnimatedDocks true 0 0 true 0 0 600 160 Info 560 90 61 31 Hex: 140 60 51 31 IntBE: 140 90 51 31 IntLE: 140 120 51 31 Bin: 630 90 281 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 200 60 311 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 200 90 311 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 200 120 711 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 560 30 61 31 FloatLE: 630 30 281 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 200 30 61 31 ASCII: 260 30 251 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 20 30 121 31 Selected bytes: 140 30 41 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 20 70 88 24 Signed 630 60 281 31 QFrame::Box QFrame::Sunken Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse 560 60 61 31 FloatBE: Exit QHexEdit QWidget

../qhexedit/qhexedit.h
1 hexwalk-1.9.1/src/hexwalk/entropydialog.h0000664000175100017510000000321215005675407020013 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ENTROPYDIALOG_H #define ENTROPYDIALOG_H #include #include #include #include "../qhexedit/qhexedit.h" #include "entropychart.h" namespace Ui { class EntropyDialog; } class EntropyDialog : public QDialog { Q_OBJECT public: explicit EntropyDialog(QHexEdit * hexedit,QWidget *parent = nullptr); ~EntropyDialog(); void calculate(); public slots: void mousePressed(qint64 value); void mouseMoved(qint64 address); void limitZoomOut(); void refresh(); private slots: void on_buttonBox_clicked(QAbstractButton *button); void on_entropyChart_mousePressed(qint64 ); private: Ui::EntropyDialog *ui; QHexEdit * _hexed; double blockEntropy(QByteArray * data); EntropyChart *entropyView; QProgressDialog *progrDialog; QLineSeries *series = NULL; QPointF findClosestPoint(QLineSeries* lineSeries, qreal x); }; #endif // ENTROPYDIALOG_H hexwalk-1.9.1/src/hexwalk/tagsdialog.cpp0000664000175100017510000002207115005675407017610 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "tagsdialog.h" #include "ui_tagsdialog.h" #include #include #include #include #include TagsDialog::TagsDialog(QHexEdit * hexedit,QWidget *parent) : QDialog(parent), ui(new Ui::TagsDialog) { ui->setupUi(this); hexEdit = hexedit; bytePattern = new BytePattern(hexEdit); edittagDialog = new EditTagDialog(bytePattern,this); edittagDialog->hide(); connect(edittagDialog,SIGNAL(tagReady()),this,SLOT(triggerUpdate())); connect(parent,SIGNAL(fileLoaded()),this,SLOT(triggerUpdate())); ui->tableWidget->setColumnCount(6); ui->tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("Name")); ui->tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("Color")); ui->tableWidget->setHorizontalHeaderItem(2,new QTableWidgetItem("Offset")); ui->tableWidget->setHorizontalHeaderItem(3,new QTableWidgetItem("Size")); ui->tableWidget->setHorizontalHeaderItem(4,new QTableWidgetItem("Type")); ui->tableWidget->setHorizontalHeaderItem(5,new QTableWidgetItem("Value")); ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); hexEdit->colorTag = &(bytePattern->colorTag); } QString TagsDialog::binToStr(QByteArray bin) { QString outString; for(int i=0;i=127) { outString += QString("."); } else if(bin.at(i) == '<') { outString += QString("<"); } else if(bin.at(i) == '>') { outString += QString(">"); } else if(bin.at(i) == '&') { outString += QString("&"); } else { outString += QString(bin.at(i)); } } return outString; } void TagsDialog::changeColor() { QColor color = QColorDialog::getColor(); } TagsDialog::~TagsDialog() { delete ui; } void TagsDialog::on_addBtn_clicked() { edittagDialog->show(); edittagDialog->colorGen(); } void TagsDialog::triggerUpdate() { bytePattern->resolveReferences(); updateTable(); hexEdit->ensureVisible(); } void TagsDialog::triggerFileUpdate() { analyzePattern(); } void TagsDialog::updateTable() { while(ui->tableWidget->rowCount() > 0) { ui->tableWidget->removeRow(0); } //ui->tableWidget->clearContents(); for(int i=0; i< bytePattern->colorTag.length();i++) { ColorTag tmpTag = bytePattern->colorTag.at(i); ui->tableWidget->insertRow(ui->tableWidget->rowCount()); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,0,new QTableWidgetItem(QString::fromStdString(tmpTag.name))); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,1,new QTableWidgetItem(" ")); ui->tableWidget->item(ui->tableWidget->rowCount()-1,1)->setBackground(QColor(QString::fromStdString(tmpTag.color))); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,2,new QTableWidgetItem(QString::fromStdString(tmpTag.obj.offset))); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,3,new QTableWidgetItem(QString::fromStdString(tmpTag.obj.size))); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,4,new QTableWidgetItem(QString::fromStdString(tagStrings[tmpTag.type]))); QByteArray baValue = tmpTag.data; if(baValue.length() > 8 && (tmpTag.type == LE_t || tmpTag.type == BE_t)) { baValue.truncate(8); } else if(baValue.length() > 16) { baValue.truncate(16); } if(tmpTag.type == HEX_t) { ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,5,new QTableWidgetItem(QString(baValue.toHex()).toUpper())); } else if(tmpTag.type == STRING_t) { ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,5,new QTableWidgetItem(binToStr(baValue))); } else if(tmpTag.type == LE_t) { bool ok; std::reverse(baValue.begin(),baValue.end()); ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,5,new QTableWidgetItem(QString("%1").arg(baValue.toHex().toInt(&ok,16)))); if(!ok) { ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,5,new QTableWidgetItem("Error")); } } else if(tmpTag.type == BE_t) { bool ok; ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,5,new QTableWidgetItem(QString("%1").arg(baValue.toHex().toInt(&ok,16)))); if(!ok) { ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,5,new QTableWidgetItem("Error")); } } } } void TagsDialog::analyzePattern() { bytePattern->ymlParser.loadFile(curFileTag.toStdString()); bytePattern->colorTag.clear(); for(int i=0 ; i<(int)bytePattern->ymlParser.ymlobj.size() ; i++) { int ret =bytePattern->addElement(bytePattern->ymlParser.ymlobj.at(i)); if(ret) { QString error_string; switch(ret) { case E_WRONGNAME: error_string = QString("Wrong name passed at element %1").arg(i); break; case E_WRONGTYPE: error_string = QString("Wrong type passed at element %1").arg(i); break; case E_WRONGREF: error_string = QString("Wrong reference passed at element %1").arg(i); break; case E_WRONGCOLOR: error_string = QString("Wrong color passed at element %1").arg(i); break; case E_DUPNAME: error_string = QString("Duplicated name passed at element %1").arg(i); break; case E_EMPTYOFFSET: error_string = QString("Empty offset passed at element %1").arg(i); break; case E_EMPTYSIZE: error_string = QString("Empty size passed at element %1").arg(i); break; default: error_string = QString("Error code %1 at element %2").arg(ret).arg(i); } QMessageBox::warning(this, tr("HexWalk"), error_string ); return; } } updateTable(); hexEdit->update(); hexEdit->ensureVisible(); return; } void TagsDialog::on_loadBtn_clicked() { curFileTag = QFileDialog::getOpenFileName(this,"Tag selection","patterns","YML (*.yml)"); if (curFileTag.isEmpty()) return; analyzePattern(); } void TagsDialog::on_tableWidget_clicked(const QModelIndex &index) { hexEdit->indexOf("",bytePattern->colorTag.at(index.row()).pos,false,false); hexEdit->setSelection(bytePattern->colorTag.at(index.row()).pos*2 + bytePattern->colorTag.at(index.row()).size*2); hexEdit->setCursorPosition(bytePattern->colorTag.at(index.row()).pos*2); hexEdit->ensureVisible(); } void TagsDialog::on_saveBtn_clicked() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save To YML File")); if(!fileName.isEmpty()) { bytePattern->ymlParser.ymlobj.clear(); for(int i=0;icolorTag.length();i++) { bytePattern->ymlParser.ymlobj.push_back(bytePattern->colorTag.at(i).obj); } bytePattern->ymlParser.saveFile(fileName.toStdString()); QMessageBox::information(this, tr("HexWalk"), tr("Tag file saved successfully") ); } } void TagsDialog::on_delBtn_clicked() { QModelIndexList selection = ui->tableWidget->selectionModel()->selectedRows(); // Multiple rows can be selected for(int i=0; i< selection.count(); i++) { QModelIndex index = selection.at(i); bytePattern->delElement(index.row()); ui->tableWidget->removeRow(index.row()); hexEdit->update(); hexEdit->ensureVisible(); } } void TagsDialog::on_tableWidget_doubleClicked(const QModelIndex &index) { edittagDialog->show(); edittagDialog->loadTag(index.row()); } void TagsDialog::on_resetBtn_clicked() { bytePattern->reset(); updateTable(); hexEdit->update(); hexEdit->ensureVisible(); } void TagsDialog::on_closeBtn_clicked() { this->hide(); } hexwalk-1.9.1/src/hexwalk/tagsdialog.h0000664000175100017510000000377415005675407017266 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef TAGSDIALOG_H #define TAGSDIALOG_H #include #include "edittagdialog.h" #include "../qhexedit/qhexedit.h" #include "../qhexedit/tagparser.hpp" #include #include #include #include "../qhexedit/bytepattern.h" namespace Ui { class TagsDialog; } class TagsDialog : public QDialog { Q_OBJECT public: explicit TagsDialog(QHexEdit * hexedit,QWidget *parent = nullptr); void changeColor(); ~TagsDialog(); void updateTable(); bool isOperator(char c); int performOperation(char operation, int operand1, int operand2); int evaluateExpression(const string& expression); void analyzePattern(); BytePattern *bytePattern; QString curFileTag; private slots: void on_addBtn_clicked(); void triggerUpdate(); void triggerFileUpdate(); void on_loadBtn_clicked(); void on_tableWidget_clicked(const QModelIndex &index); void on_saveBtn_clicked(); void on_delBtn_clicked(); void on_tableWidget_doubleClicked(const QModelIndex &index); void on_resetBtn_clicked(); void on_closeBtn_clicked(); private: Ui::TagsDialog *ui; EditTagDialog * edittagDialog; QHexEdit * hexEdit; QString binToStr(QByteArray bin); void substVariables(string line,int idx); }; #endif // TAGSDIALOG_H hexwalk-1.9.1/src/hexwalk/bytemap.cpp0000664000175100017510000002661715005675407017145 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "bytemap.h" #include #include #include #include #include ByteMap::ByteMap(QWidget *parent) : QAbstractScrollArea(parent) { connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); _pxHeight = 3; _pxWidth = 3; _bytesPerLine = 256; _currentPos = 0; setMouseTracking(true); } void ByteMap::loadBytes(QHexEdit * hexedit) { verticalScrollBar()->setValue(0); _hexedit = hexedit; adjust(); viewport()->repaint(); } void ByteMap::adjust() { _rowsShown = ((viewport()->height()-_pxHeight)/_pxHeight); int lineCount = (int)(_hexedit->getSize() / (qint64)_bytesPerLine) + 1; verticalScrollBar()->setRange(0, lineCount - _rowsShown); verticalScrollBar()->setPageStep(_rowsShown); } QColor ByteMap::_jetColor(int value) { // Calculate the RGB components float rf[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.00588235294117645,0.02156862745098032,0.03725490196078418,0.05294117647058827,0.06862745098039214,0.084313725490196,0.1000000000000001,0.115686274509804,0.1313725490196078,0.1470588235294117,0.1627450980392156,0.1784313725490196,0.1941176470588235,0.2098039215686274,0.2254901960784315,0.2411764705882353,0.2568627450980392,0.2725490196078431,0.2882352941176469,0.303921568627451,0.3196078431372549,0.3352941176470587,0.3509803921568628,0.3666666666666667,0.3823529411764706,0.3980392156862744,0.4137254901960783,0.4294117647058824,0.4450980392156862,0.4607843137254901,0.4764705882352942,0.4921568627450981,0.5078431372549019,0.5235294117647058,0.5392156862745097,0.5549019607843135,0.5705882352941174,0.5862745098039217,0.6019607843137256,0.6176470588235294,0.6333333333333333,0.6490196078431372,0.664705882352941,0.6803921568627449,0.6960784313725492,0.7117647058823531,0.7274509803921569,0.7431372549019608,0.7588235294117647,0.7745098039215685,0.7901960784313724,0.8058823529411763,0.8215686274509801,0.8372549019607844,0.8529411764705883,0.8686274509803922,0.884313725490196,0.8999999999999999,0.9156862745098038,0.9313725490196076,0.947058823529412,0.9627450980392158,0.9784313725490197,0.9941176470588236,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9862745098039216,0.9705882352941178,0.9549019607843139,0.93921568627451,0.9235294117647062,0.9078431372549018,0.892156862745098,0.8764705882352941,0.8607843137254902,0.8450980392156864,0.8294117647058825,0.8137254901960786,0.7980392156862743,0.7823529411764705,0.7666666666666666,0.7509803921568627,0.7352941176470589,0.719607843137255,0.7039215686274511,0.6882352941176473,0.6725490196078434,0.6568627450980391,0.6411764705882352,0.6254901960784314,0.6098039215686275,0.5941176470588236,0.5784313725490198,0.5627450980392159,0.5470588235294116,0.5313725490196077,0.5156862745098039,0.5}; float gf[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.001960784313725483,0.01764705882352935,0.03333333333333333,0.0490196078431373,0.06470588235294117,0.08039215686274503,0.09607843137254901,0.111764705882353,0.1274509803921569,0.1431372549019607,0.1588235294117647,0.1745098039215687,0.1901960784313725,0.2058823529411764,0.2215686274509804,0.2372549019607844,0.2529411764705882,0.2686274509803921,0.2843137254901961,0.3,0.3156862745098039,0.3313725490196078,0.3470588235294118,0.3627450980392157,0.3784313725490196,0.3941176470588235,0.4098039215686274,0.4254901960784314,0.4411764705882353,0.4568627450980391,0.4725490196078431,0.4882352941176471,0.503921568627451,0.5196078431372548,0.5352941176470587,0.5509803921568628,0.5666666666666667,0.5823529411764705,0.5980392156862746,0.6137254901960785,0.6294117647058823,0.6450980392156862,0.6607843137254901,0.6764705882352942,0.692156862745098,0.7078431372549019,0.723529411764706,0.7392156862745098,0.7549019607843137,0.7705882352941176,0.7862745098039214,0.8019607843137255,0.8176470588235294,0.8333333333333333,0.8490196078431373,0.8647058823529412,0.8803921568627451,0.8960784313725489,0.9117647058823528,0.9274509803921569,0.9431372549019608,0.9588235294117646,0.9745098039215687,0.9901960784313726,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9901960784313726,0.9745098039215687,0.9588235294117649,0.943137254901961,0.9274509803921571,0.9117647058823528,0.8960784313725489,0.8803921568627451,0.8647058823529412,0.8490196078431373,0.8333333333333335,0.8176470588235296,0.8019607843137253,0.7862745098039214,0.7705882352941176,0.7549019607843137,0.7392156862745098,0.723529411764706,0.7078431372549021,0.6921568627450982,0.6764705882352944,0.6607843137254901,0.6450980392156862,0.6294117647058823,0.6137254901960785,0.5980392156862746,0.5823529411764707,0.5666666666666669,0.5509803921568626,0.5352941176470587,0.5196078431372548,0.503921568627451,0.4882352941176471,0.4725490196078432,0.4568627450980394,0.4411764705882355,0.4254901960784316,0.4098039215686273,0.3941176470588235,0.3784313725490196,0.3627450980392157,0.3470588235294119,0.331372549019608,0.3156862745098041,0.2999999999999998,0.284313725490196,0.2686274509803921,0.2529411764705882,0.2372549019607844,0.2215686274509805,0.2058823529411766,0.1901960784313728,0.1745098039215689,0.1588235294117646,0.1431372549019607,0.1274509803921569,0.111764705882353,0.09607843137254912,0.08039215686274526,0.06470588235294139,0.04901960784313708,0.03333333333333321,0.01764705882352935,0.001960784313725483,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; float bf[] = {0.5,0.5156862745098039,0.5313725490196078,0.5470588235294118,0.5627450980392157,0.5784313725490196,0.5941176470588235,0.6098039215686275,0.6254901960784314,0.6411764705882352,0.6568627450980392,0.6725490196078432,0.6882352941176471,0.7039215686274509,0.7196078431372549,0.7352941176470589,0.7509803921568627,0.7666666666666666,0.7823529411764706,0.7980392156862746,0.8137254901960784,0.8294117647058823,0.8450980392156863,0.8607843137254902,0.8764705882352941,0.892156862745098,0.907843137254902,0.9235294117647059,0.9392156862745098,0.9549019607843137,0.9705882352941176,0.9862745098039216,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9941176470588236,0.9784313725490197,0.9627450980392158,0.9470588235294117,0.9313725490196079,0.915686274509804,0.8999999999999999,0.884313725490196,0.8686274509803922,0.8529411764705883,0.8372549019607844,0.8215686274509804,0.8058823529411765,0.7901960784313726,0.7745098039215685,0.7588235294117647,0.7431372549019608,0.7274509803921569,0.7117647058823531,0.696078431372549,0.6803921568627451,0.6647058823529413,0.6490196078431372,0.6333333333333333,0.6176470588235294,0.6019607843137256,0.5862745098039217,0.5705882352941176,0.5549019607843138,0.5392156862745099,0.5235294117647058,0.5078431372549019,0.4921568627450981,0.4764705882352942,0.4607843137254903,0.4450980392156865,0.4294117647058826,0.4137254901960783,0.3980392156862744,0.3823529411764706,0.3666666666666667,0.3509803921568628,0.335294117647059,0.3196078431372551,0.3039215686274508,0.2882352941176469,0.2725490196078431,0.2568627450980392,0.2411764705882353,0.2254901960784315,0.2098039215686276,0.1941176470588237,0.1784313725490199,0.1627450980392156,0.1470588235294117,0.1313725490196078,0.115686274509804,0.1000000000000001,0.08431372549019622,0.06862745098039236,0.05294117647058805,0.03725490196078418,0.02156862745098032,0.00588235294117645,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int r = (int)(255.0*rf[value]); int g = (int)(255.0*gf[value]); int b = (int)(255.0*bf[value]); return QColor(r, g, b); } void ByteMap::showEvent(QShowEvent *event) { // Call the base class implementation QAbstractScrollArea::showEvent(event); // Perform actions that depend on the correct size of the viewport here // Example: Print the correct viewport size adjust(); } void ByteMap::paintEvent(QPaintEvent *event) { QPainter painter(viewport()); QColor pixCol; int value = verticalScrollBar()->value(); qint64 _bPosFirst = (qint64)value * _bytesPerLine; for(int i=0;i<_rowsShown;i++) { QByteArray rowdata = _hexedit->dataAt(_bPosFirst+i*_bytesPerLine,_bytesPerLine); for(int k=0;k _hexedit->getSize() ) { break; } unsigned char pix = rowdata.at(k); if (colored) { pixCol = _jetColor(pix); } else { pixCol = QColor(pix,pix,pix); } painter.fillRect(QRect(k*_pxHeight, i*_pxHeight, _pxHeight, _pxHeight), pixCol); if(_hexedit->getSelectionEnd() - _hexedit->getSelectionBegin() > 0) { qint64 tpos = _bPosFirst+i*_bytesPerLine + k; if(tpos >= _hexedit->getSelectionBegin() && tpos < _hexedit->getSelectionEnd()) { painter.fillRect(QRect(k*_pxHeight, i*_pxHeight, _pxHeight, _pxHeight), QColor(100,100,240,180)); } } } } if(verticalScrollBar()->value()*_bytesPerLine + mPoint.x()/_pxHeight+_bytesPerLine*mPoint.y()/_pxHeight < _hexedit->getSize()) painter.fillRect(QRect(mPoint.x(), mPoint.y(), _pxHeight, _pxHeight), QColor(255,255,0)); } qint64 ByteMap::cursorPosition(QPoint pos){ qint64 actPos = (qint64)(pos.x()/_pxHeight) + (qint64)(pos.y()/_pxHeight)*_bytesPerLine+(qint64)verticalScrollBar()->value()*_bytesPerLine; return actPos; } void ByteMap::setCursorPosition(qint64 actpos){ _currentPos = actpos; } qint64 ByteMap::getCurrentPosition(){ return _currentPos; } void ByteMap::mouseMoveEvent(QMouseEvent *event){ viewport()->update(); mPoint = event->pos(); qint64 actPos = cursorPosition(event->pos()); if (actPos >= 0) { setCursorPosition(actPos); emit mouseEvent(); } } void ByteMap::mousePressEvent(QMouseEvent *event){ viewport()->update(); qint64 actPos = cursorPosition(event->pos()); if (actPos >= 0) { setCursorPosition(actPos); emit mousePress(); } } void ByteMap::setBytesPerLine(int value){ _bytesPerLine = value; if(_bytesPerLine > 512) { _pxHeight = 2; _pxWidth = 2; } else { _pxHeight = 3; _pxWidth = 3; } } hexwalk-1.9.1/src/hexwalk/bytemapdialog.cpp0000664000175100017510000000502315005675407020311 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "bytemapdialog.h" #include "ui_bytemapdialog.h" ByteMapDialog::ByteMapDialog(QHexEdit * hexedit,QWidget *parent) : QDialog(parent), ui(new Ui::ByteMapDialog) { ui->setupUi(this); _hexedit = hexedit; connect(ui->byteMap,SIGNAL(mouseEvent()),this,SLOT(updatePos())); connect(ui->byteMap,SIGNAL(mousePress()),this,SLOT(gotoAddress())); connect(parent,SIGNAL(fileLoaded()),this,SLOT(refresh())); ui->byteMap->setBytesPerLine(256); ui->spinCols->setValue(256); ui->byteMap->colored = ui->colorBox->isChecked(); setFixedWidth(48+256*3); } ByteMapDialog::~ByteMapDialog() { delete ui; } void ByteMapDialog::showByteMapDialog() { ui->byteMap->loadBytes(_hexedit); this->show(); this->update(); } void ByteMapDialog::refresh() { ui->byteMap->loadBytes(_hexedit); } void ByteMapDialog::updatePos() { if(ui->byteMap->getCurrentPosition() < _hexedit->getSize()) { ui->edtAddress->setText(QString::asprintf("%02llX (%lld)",ui->byteMap->getCurrentPosition(),ui->byteMap->getCurrentPosition())); ui->edtValue->setText(QString::asprintf("%02X (%u)",(unsigned char)(_hexedit->dataAt(ui->byteMap->getCurrentPosition(),1).at(0)),(unsigned char)(_hexedit->dataAt(ui->byteMap->getCurrentPosition(),1).at(0)))); } } void ByteMapDialog::gotoAddress() { _hexedit->setCursorPosition(2*ui->byteMap->getCurrentPosition()); _hexedit->ensureVisible(); } void ByteMapDialog::on_spinCols_valueChanged(int arg1) { ui->byteMap->setBytesPerLine(arg1); if(arg1 > 512) { setFixedWidth(32+arg1*2); } else { setFixedWidth(48+arg1*3); } } void ByteMapDialog::on_closeBtn_clicked() { this->hide(); } void ByteMapDialog::on_colorBox_stateChanged(int arg1) { ui->byteMap->colored = ui->colorBox->isChecked(); } hexwalk-1.9.1/src/hexwalk/binanalysisdialog.ui0000644000175100017510000000262414561356105021016 0ustar carmixcarmix binanalysisdialog 0 0 1024 378 1024 0 1024 16777215 HexWalk - Binary Analysis 0 10 881 361 910 10 93 29 Extract All 910 50 93 29 Close hexwalk-1.9.1/src/hexwalk/disasmwidget.cpp0000664000175100017510000000663715005675407020170 0ustar carmixcarmix/* * Copyright (C) 2025 Carmix * * This file is part of HexWalk. * * HexWalk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HexWalk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "disasmwidget.h" #include "ui_disasmwidget.h" #include void DisasmWidget::capst(void) { csh handle; cs_insn *insn; size_t count; QString message; ui->lstDisasm->clear(); QByteArray selectedHex = _hexedit->selectedDataBa(); qint64 addrBase = _hexedit->cursorPosition()/2 - selectedHex.size(); ui->edtBaseAddr->setText(QString("%1").arg(addrBase,2,16,QLatin1Char('0')).toUpper()); ui->edtSelected->setText(QString("%1").arg(selectedHex.size())); cs_arch arch = CS_ARCH_X86; uint32_t mode_int = CS_MODE_64; cs_mode mode = CS_MODE_64; uint32_t endianness = CS_MODE_LITTLE_ENDIAN; if(ui->comboEndian->currentText().contains("Little")) { endianness = CS_MODE_LITTLE_ENDIAN; } else { endianness = CS_MODE_BIG_ENDIAN; } if(ui->comboBox->currentText().contains("x86/64")) { arch = CS_ARCH_X86; mode_int = CS_MODE_64; } else if(ui->comboBox->currentText().contains("x86/32")) { arch = CS_ARCH_X86; mode_int = CS_MODE_32; } else if(ui->comboBox->currentText() == "ARM32") { arch = CS_ARCH_ARM; mode_int = CS_MODE_ARM; } else if(ui->comboBox->currentText() == "ARM32/THUMB") { arch = CS_ARCH_ARM; mode_int = CS_MODE_THUMB; } else if(ui->comboBox->currentText().contains("ARM64")) { arch = CS_ARCH_ARM64; mode_int = CS_MODE_ARM; } else if(ui->comboBox->currentText().contains("MIPS")) { arch = CS_ARCH_MIPS; mode_int = CS_MODE_MIPS32; } mode = (cs_mode) (mode_int | endianness); if (cs_err ret = cs_open(arch, mode , &handle)) { message.sprintf("Invalid mode (e.g. x86 can't be Big Endian)"); ui->lstDisasm->addItem(message); return; } count = cs_disasm(handle, (const uint8_t*)selectedHex.data(), selectedHex.size(), addrBase, 0, &insn); if (count > 0) { size_t j; for (j = 0; j < count; j++) { message.sprintf("0x%llX: %s %s", insn[j].address, insn[j].mnemonic, insn[j].op_str); ui->lstDisasm->addItem(message); } cs_free(insn, count); } else { message.sprintf("ERROR: Failed to disassemble given code!\n"); ui->lstDisasm->addItem(message); } cs_close(&handle); } DisasmWidget::DisasmWidget(QHexEdit * hexedit,QWidget *parent) : QDockWidget(parent), ui(new Ui::DisasmWidget) { ui->setupUi(this); _hexedit = hexedit; hide(); } DisasmWidget::~DisasmWidget() { delete ui; } void DisasmWidget::on_btnDisasm_clicked() { capst(); } void DisasmWidget::refresh() { capst(); } hexwalk-1.9.1/src/qhexedit/0000775000175100017510000000000015005675407015134 5ustar carmixcarmixhexwalk-1.9.1/src/qhexedit/QHexEditPlugin.h0000664000175100017510000000164215005675407020142 0ustar carmixcarmix#ifndef QHEXEDITPLUGIN_H #define QHEXEDITPLUGIN_H #include #if QT_VERSION < QT_VERSION_CHECK(5,0,0) #include #else #include #endif class QHexEditPlugin : public QObject, public QDesignerCustomWidgetInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) Q_PLUGIN_METADATA(IID "com.qt-project.Qt.QHexEditPlugin") #endif public: QHexEditPlugin(QObject * parent = 0); bool isContainer() const; bool isInitialized() const; QIcon icon() const; QString domXml() const; QString group() const; QString includeFile() const; QString name() const; QString toolTip() const; QString whatsThis() const; QWidget *createWidget(QWidget *parent); void initialize(QDesignerFormEditorInterface *core); private: bool initialized; }; #endif hexwalk-1.9.1/src/qhexedit/qhexedit.cpp0000664000175100017510000011672115005675407017463 0ustar carmixcarmix#include #include #include #include #include #include #include "qhexedit.h" #include // ********************************************************************** Constructor, destructor QHexEdit::QHexEdit(QWidget *parent) : QAbstractScrollArea(parent) , _addressArea(true) , _addressWidth(4) , _asciiArea(true) , _bytesPerLine(16) , _hexCharsInLine(47) , _highlighting(true) , _overwriteMode(true) , _readOnly(false) , _hexCaps(false) , _dynamicBytesPerLine(false) , _editAreaIsAscii(false) , _chunks(new Chunks(this)) , _cursorPosition(0) , _lastEventSize(0) , _undoStack(new UndoStack(_chunks, this)) { #ifdef Q_OS_WIN32 setFont(QFont("Courier", 10)); #else setFont(QFont("Monospace", 10)); #endif setAddressAreaColor(this->palette().alternateBase().color()); setHighlightingColor(QColor(0xff, 0xff, 0x99, 0xff)); setSelectionColor(this->palette().highlight().color()); setAddressFontColor(QPalette::WindowText); setAsciiAreaColor(this->palette().alternateBase().color()); setAsciiFontColor(QPalette::WindowText); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QAbstractScrollArea::customContextMenuRequested, this, &QHexEdit::showContextMenu); connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor())); connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjust())); connect(_undoStack, SIGNAL(indexChanged(int)), this, SLOT(dataChangedPrivate(int))); _cursorTimer.setInterval(500); _cursorTimer.start(); _scrollMult = 1; setAddressWidth(4); setAddressArea(true); setAsciiArea(true); setOverwriteMode(true); setHighlighting(true); setReadOnly(false); init(); } QHexEdit::~QHexEdit() { } // ********************************************************************** Properties void QHexEdit::setAddressArea(bool addressArea) { _addressArea = addressArea; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } bool QHexEdit::addressArea() { return _addressArea; } void QHexEdit::setAddressAreaColor(const QColor &color) { _addressAreaColor = color; viewport()->update(); } QColor QHexEdit::addressAreaColor() { return _addressAreaColor; } void QHexEdit::setAddressFontColor(const QColor &color) { _addressFontColor = color; viewport()->update(); } QColor QHexEdit::addressFontColor() { return _addressFontColor; } void QHexEdit::setAsciiAreaColor(const QColor &color) { _asciiAreaColor = color; viewport()->update(); } QColor QHexEdit::asciiAreaColor() { return _asciiAreaColor; } void QHexEdit::setAsciiFontColor(const QColor &color) { _asciiFontColor = color; viewport()->update(); } QColor QHexEdit::asciiFontColor() { return _asciiFontColor; } void QHexEdit::setHexFontColor(const QColor &color) { _hexFontColor = color; viewport()->update(); } QColor QHexEdit::hexFontColor() { return _hexFontColor; } void QHexEdit::setAddressOffset(qint64 addressOffset) { _addressOffset = addressOffset; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } qint64 QHexEdit::addressOffset() { return _addressOffset; } void QHexEdit::setAddressWidth(int addressWidth) { _addressWidth = addressWidth; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } qint64 QHexEdit::getSize() { return _chunks->size(); } int QHexEdit::addressWidth() { qint64 size = _chunks->size(); int n = 1; if (size > Q_INT64_C(0x100000000)){ n += 8; size /= Q_INT64_C(0x100000000);} if (size > 0x10000){ n += 4; size /= 0x10000;} if (size > 0x100){ n += 2; size /= 0x100;} if (size > 0x10){ n += 1;} if (n > _addressWidth) return n; else return _addressWidth; } void QHexEdit::setAsciiArea(bool asciiArea) { if (!asciiArea) _editAreaIsAscii = false; _asciiArea = asciiArea; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } bool QHexEdit::asciiArea() { return _asciiArea; } void QHexEdit::setBytesPerLine(int count) { _bytesPerLine = count; _hexCharsInLine = count * 3 - 1; adjust(); setCursorPosition(_cursorPosition); viewport()->update(); } int QHexEdit::bytesPerLine() { return _bytesPerLine; } qint64 QHexEdit::firstByteAddress() { return _bPosFirst; } void QHexEdit::setCursorPosition(qint64 position) { // 1. delete old cursor _blink = false; viewport()->update(_cursorRect); viewport()->update(_cursorRect2); // 2. Check, if cursor in range? if (position > (_chunks->size() * 2 - 1)) position = _chunks->size() * 2 - (_overwriteMode ? 1 : 0); if (position < 0) position = 0; // 3. Calc new position of cursor _bPosCurrent = position / 2; _pxCursorY = ((position / 2 - _bPosFirst) / _bytesPerLine + 1) * _pxCharHeight; int x = (position % (2 * _bytesPerLine)); if (_editAreaIsAscii) { _pxCursorX = x / 2 * _pxCharWidth + _pxPosAsciiX; _pxCursorX2 = (((x / 2) * 3) + (x % 2)) * _pxCharWidth + _pxPosHexX; _cursorPosition = position & 0xFFFFFFFFFFFFFFFE; } else { _pxCursorX = (((x / 2) * 3) + (x % 2)) * _pxCharWidth + _pxPosHexX; _pxCursorX2 = x / 2 * _pxCharWidth + _pxPosAsciiX; _cursorPosition = position; } if (_overwriteMode) { _cursorRect = QRect(_pxCursorX - horizontalScrollBar()->value(), _pxCursorY + _pxCursorWidth, _pxCharWidth, _pxCursorWidth); _cursorRect2 = QRect(_pxCursorX2 - horizontalScrollBar()->value(), _pxCursorY + _pxCursorWidth, _pxCharWidth, _pxCursorWidth); } else { _cursorRect = QRect(_pxCursorX - horizontalScrollBar()->value(), _pxCursorY - _pxCharHeight + 4, _pxCursorWidth, _pxCharHeight); _cursorRect2 = QRect(_pxCursorX2 - horizontalScrollBar()->value(), _pxCursorY + _pxCursorWidth, _pxCharWidth, _pxCursorWidth); } // 4. Immediately draw new cursor _blink = true; viewport()->update(_cursorRect); viewport()->update(_cursorRect2); emit currentAddressChanged(_bPosCurrent); } qint64 QHexEdit::cursorPosition(QPoint pos) { // Calc cursor position depending on a graphical position qint64 result = -1; int posX = pos.x() + horizontalScrollBar()->value(); int posY = pos.y() - 3; if ((posX >= _pxPosHexX) && (posX < (_pxPosHexX + (1 + _hexCharsInLine) * _pxCharWidth))) { _editAreaIsAscii = false; int x = (posX - _pxPosHexX) / _pxCharWidth; x = (x / 3) * 2 + x % 3; int y = (posY / _pxCharHeight) * 2 * _bytesPerLine; result = _bPosFirst * 2 + x + y; } else if (_asciiArea && (posX >= _pxPosAsciiX) && (posX < (_pxPosAsciiX + (1 + _bytesPerLine) * _pxCharWidth))) { _editAreaIsAscii = true; int x = 2 * (posX - _pxPosAsciiX) / _pxCharWidth; int y = (posY / _pxCharHeight) * 2 * _bytesPerLine; result = _bPosFirst * 2 + x + y; } return result; } qint64 QHexEdit::cursorPosition() { return _cursorPosition; } void QHexEdit::setData(const QByteArray &ba) { _data = ba; _bData.setData(_data); setData(_bData); } QByteArray QHexEdit::data() { return _chunks->data(0, -1); } void QHexEdit::setHighlighting(bool highlighting) { _highlighting = highlighting; viewport()->update(); } bool QHexEdit::highlighting() { return _highlighting; } void QHexEdit::setHighlightingColor(const QColor &color) { _brushHighlighted = QBrush(color); _penHighlighted = QPen(viewport()->palette().color(QPalette::WindowText)); viewport()->update(); } QColor QHexEdit::highlightingColor() { return _brushHighlighted.color(); } void QHexEdit::setOverwriteMode(bool overwriteMode) { _overwriteMode = overwriteMode; emit overwriteModeChanged(overwriteMode); } bool QHexEdit::overwriteMode() { return _overwriteMode; } void QHexEdit::setSelectionColor(const QColor &color) { _brushSelection = QBrush(color); _penSelection = QPen(Qt::white); viewport()->update(); } QColor QHexEdit::selectionColor() { return _brushSelection.color(); } bool QHexEdit::isReadOnly() { return _readOnly; } void QHexEdit::setReadOnly(bool readOnly) { _readOnly = readOnly; } void QHexEdit::setHexCaps(const bool isCaps) { if (_hexCaps != isCaps) { _hexCaps = isCaps; viewport()->update(); } } bool QHexEdit::hexCaps() { return _hexCaps; } void QHexEdit::setDynamicBytesPerLine(const bool isDynamic) { _dynamicBytesPerLine = isDynamic; resizeEvent(NULL); } bool QHexEdit::dynamicBytesPerLine() { return _dynamicBytesPerLine; } // ********************************************************************** Access to data of qhexedit bool QHexEdit::setData(QIODevice &iODevice) { bool ok = _chunks->setIODevice(iODevice); init(); dataChangedPrivate(); return ok; } QByteArray QHexEdit::dataAt(qint64 pos, qint64 count) { return _chunks->data(pos, count); } bool QHexEdit::write(QIODevice &iODevice, qint64 pos, qint64 count) { return _chunks->write(iODevice, pos, count); } // ********************************************************************** Char handling void QHexEdit::insert(qint64 index, char ch) { _undoStack->insert(index, ch); refresh(); } void QHexEdit::remove(qint64 index, qint64 len) { _undoStack->removeAt(index, len); refresh(); } void QHexEdit::replace(qint64 index, char ch) { _undoStack->overwrite(index, ch); refresh(); } // ********************************************************************** ByteArray handling void QHexEdit::insert(qint64 pos, const QByteArray &ba) { _undoStack->insert(pos, ba); refresh(); } void QHexEdit::replace(qint64 pos, qint64 len, const QByteArray &ba) { _undoStack->overwrite(pos, len, ba); refresh(); } // ********************************************************************** Utility functions void QHexEdit::ensureVisible() { if (_cursorPosition < (_bPosFirst * 2)) verticalScrollBar()->setValue((int)(_cursorPosition / 2 / _bytesPerLine/_scrollMult)); if (_cursorPosition > ((_bPosFirst + (qint64)((_rowsShown - 1)*_bytesPerLine) * 2))) verticalScrollBar()->setValue((int)(((_cursorPosition / 2 / _bytesPerLine) - _rowsShown + 1)/_scrollMult)); if (_pxCursorX < horizontalScrollBar()->value()) horizontalScrollBar()->setValue(_pxCursorX); if ((_pxCursorX + _pxCharWidth) > (horizontalScrollBar()->value() + viewport()->width())) horizontalScrollBar()->setValue(_pxCursorX + _pxCharWidth - viewport()->width()); viewport()->update(); } qint64 QHexEdit::indexOf(const QByteArray &ba, qint64 from, bool isRegex,bool isCaseInsensitive) { qint64 pos = _chunks->indexOf(ba, from,isRegex,isCaseInsensitive); if (pos > -1) { qint64 curPos = pos*2; setCursorPosition(curPos + _chunks->matchSize*2); resetSelection(curPos); setSelection(curPos + _chunks->matchSize*2); ensureVisible(); } return pos; } bool QHexEdit::isModified() { return _modified; } qint64 QHexEdit::lastIndexOf(const QByteArray &ba, qint64 from) { qint64 pos = _chunks->lastIndexOf(ba, from); if (pos > -1) { qint64 curPos = pos*2; setCursorPosition(curPos - 1); resetSelection(curPos); setSelection(curPos + ba.length()*2); ensureVisible(); } return pos; } void QHexEdit::redo() { _undoStack->redo(); setCursorPosition(_chunks->pos()*2); refresh(); } QString QHexEdit::selectionToReadableString() { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); return toReadable(ba); } QString QHexEdit::selectedData() { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); return ba; } QByteArray QHexEdit::selectedDataBa() { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); return ba; } void QHexEdit::setFont(const QFont &font) { QFont theFont(font); theFont.setStyleHint(QFont::Monospace); QWidget::setFont(theFont); QFontMetrics metrics = fontMetrics(); #if QT_VERSION > QT_VERSION_CHECK(5, 11, 0) _pxCharWidth = metrics.horizontalAdvance(QLatin1Char('A'))+1; #else _pxCharWidth = metrics.width(QLatin1Char('A'))+1; #endif _pxCharHeight = metrics.height(); _pxGapAdr = _pxCharWidth / 2; _pxGapAdrHex = _pxCharWidth; _pxGapHexAscii = 2 * _pxCharWidth; _pxCursorWidth = _pxCharHeight / 7; _pxSelectionSub = _pxCharHeight / 5; viewport()->update(); } QString QHexEdit::toReadableString() { QByteArray ba = _chunks->data(); return toReadable(ba); } void QHexEdit::undo() { _undoStack->undo(); setCursorPosition(_chunks->pos()*2); refresh(); } // ********************************************************************** Handle events void QHexEdit::keyPressEvent(QKeyEvent *event) { // Cursor movements if (event->matches(QKeySequence::MoveToNextChar)) { qint64 pos = _cursorPosition + 1; if (_editAreaIsAscii) pos += 1; setCursorPosition(pos); resetSelection(pos); } if (event->matches(QKeySequence::MoveToPreviousChar)) { qint64 pos = _cursorPosition - 1; if (_editAreaIsAscii) pos -= 1; setCursorPosition(pos); resetSelection(pos); } if (event->matches(QKeySequence::MoveToEndOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)) + (2 * _bytesPerLine) - 1; setCursorPosition(pos); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)); setCursorPosition(pos); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousLine)) { setCursorPosition(_cursorPosition - (2 * _bytesPerLine)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextLine)) { setCursorPosition(_cursorPosition + (2 * _bytesPerLine)); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToNextPage)) { setCursorPosition(_cursorPosition + (((_rowsShown - 1) * 2 * _bytesPerLine))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToPreviousPage)) { setCursorPosition(_cursorPosition - (((_rowsShown - 1) * 2 * _bytesPerLine))); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToEndOfDocument)) { setCursorPosition(_chunks->size() * 2 ); resetSelection(_cursorPosition); } if (event->matches(QKeySequence::MoveToStartOfDocument)) { setCursorPosition(0); resetSelection(_cursorPosition); } // Select commands if (event->matches(QKeySequence::SelectAll)) { resetSelection(0); setSelection(2 * _chunks->size() + 1); } if (event->matches(QKeySequence::SelectNextChar)) { qint64 pos = _cursorPosition + 1; if (_editAreaIsAscii) pos += 1; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousChar)) { qint64 pos = _cursorPosition - 1; if (_editAreaIsAscii) pos -= 1; setSelection(pos); setCursorPosition(pos); } if (event->matches(QKeySequence::SelectEndOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)) + (2 * _bytesPerLine) - 1; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfLine)) { qint64 pos = _cursorPosition - (_cursorPosition % (2 * _bytesPerLine)); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousLine)) { qint64 pos = _cursorPosition - (2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextLine)) { qint64 pos = _cursorPosition + (2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectNextPage)) { qint64 pos = _cursorPosition + (((viewport()->height() / _pxCharHeight) - 1) * 2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectPreviousPage)) { qint64 pos = _cursorPosition - (((viewport()->height() / _pxCharHeight) - 1) * 2 * _bytesPerLine); setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectEndOfDocument)) { qint64 pos = _chunks->size() * 2; setCursorPosition(pos); setSelection(pos); } if (event->matches(QKeySequence::SelectStartOfDocument)) { qint64 pos = 0; setCursorPosition(pos); setSelection(pos); } // Edit Commands if (!_readOnly) { /* Cut */ if (event->matches(QKeySequence::Cut)) { QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); if (_overwriteMode) { qint64 len = getSelectionEnd() - getSelectionBegin(); replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); } else { remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); } setCursorPosition(2 * getSelectionBegin()); resetSelection(2 * getSelectionBegin()); } else /* Paste */ if (event->matches(QKeySequence::Paste)) { QClipboard *clipboard = QApplication::clipboard(); QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); if (_overwriteMode) { ba = ba.left(std::min(ba.size(), (_chunks->size() - _bPosCurrent))); replace(_bPosCurrent, ba.size(), ba); } else insert(_bPosCurrent, ba); setCursorPosition(_cursorPosition + 2 * ba.size()); resetSelection(getSelectionBegin()); } else /* Delete char */ if (event->matches(QKeySequence::Delete)) { if (getSelectionBegin() != getSelectionEnd()) { _bPosCurrent = getSelectionBegin(); if (_overwriteMode) { QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); replace(_bPosCurrent, ba.size(), ba); } else { remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin()); } } else { if (_overwriteMode) replace(_bPosCurrent, char(0)); else remove(_bPosCurrent, 1); } setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } else /* Backspace */ if ((event->key() == Qt::Key_Backspace) && (event->modifiers() == Qt::NoModifier)) { if (getSelectionBegin() != getSelectionEnd()) { _bPosCurrent = getSelectionBegin(); setCursorPosition(2 * _bPosCurrent); if (_overwriteMode) { QByteArray ba = QByteArray(getSelectionEnd() - getSelectionBegin(), char(0)); replace(_bPosCurrent, ba.size(), ba); } else { remove(_bPosCurrent, getSelectionEnd() - getSelectionBegin()); } resetSelection(2 * _bPosCurrent); } else { bool behindLastByte = false; if ((_cursorPosition / 2) == _chunks->size()) behindLastByte = true; _bPosCurrent -= 1; if (_overwriteMode) replace(_bPosCurrent, char(0)); else remove(_bPosCurrent, 1); if (!behindLastByte) _bPosCurrent -= 1; setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } } else /* undo */ if (event->matches(QKeySequence::Undo)) { undo(); } else /* redo */ if (event->matches(QKeySequence::Redo)) { redo(); } else if ((QApplication::keyboardModifiers() == Qt::NoModifier) || (QApplication::keyboardModifiers() == Qt::KeypadModifier) || (QApplication::keyboardModifiers() == Qt::ShiftModifier) || (QApplication::keyboardModifiers() == (Qt::AltModifier | Qt::ControlModifier)) || (QApplication::keyboardModifiers() == Qt::GroupSwitchModifier)) { /* Hex and ascii input */ int key = 0; QString text = event->text(); if (!text.isEmpty()) { if (_editAreaIsAscii) key = (uchar)text.at(0).toLatin1(); else key = int(text.at(0).toLower().toLatin1()); } if ((((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f')) && _editAreaIsAscii == false) || (key >= ' ' && _editAreaIsAscii)) { if (getSelectionBegin() != getSelectionEnd()) { if (_overwriteMode) { qint64 len = getSelectionEnd() - getSelectionBegin(); replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); } else { remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); _bPosCurrent = getSelectionBegin(); } setCursorPosition(2 * _bPosCurrent); resetSelection(2 * _bPosCurrent); } // If insert mode, then insert a byte if (_overwriteMode == false) if ((_cursorPosition % 2) == 0) insert(_bPosCurrent, char(0)); // Change content if (_chunks->size() > 0) { char ch = key; if (!_editAreaIsAscii){ QByteArray hexValue = _chunks->data(_bPosCurrent, 1).toHex(); if ((_cursorPosition % 2) == 0) hexValue[0] = key; else hexValue[1] = key; ch = QByteArray().fromHex(hexValue)[0]; } replace(_bPosCurrent, ch); if (_editAreaIsAscii) setCursorPosition(_cursorPosition + 2); else setCursorPosition(_cursorPosition + 1); resetSelection(_cursorPosition); } } } } /* Copy */ if (event->matches(QKeySequence::Copy)) { QByteArray ba; if(!_editAreaIsAscii) { ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); } else { ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); for (int i = 0; i < ba.length(); i++) { if(ba.at(i) < 32 || ba.at(i) > 126) { ba[i] = '.'; } } } QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); } // Switch between insert/overwrite mode if ((event->key() == Qt::Key_Insert) && (event->modifiers() == Qt::NoModifier)) { setOverwriteMode(!overwriteMode()); setCursorPosition(_cursorPosition); } // switch from hex to ascii edit if (event->key() == Qt::Key_Tab && !_editAreaIsAscii){ _editAreaIsAscii = true; setCursorPosition(_cursorPosition); } // switch from ascii to hex edit if (event->key() == Qt::Key_Backtab && _editAreaIsAscii){ _editAreaIsAscii = false; setCursorPosition(_cursorPosition); } refresh(); QAbstractScrollArea::keyPressEvent(event); } void QHexEdit::mouseMoveEvent(QMouseEvent * event) { _blink = false; viewport()->update(); qint64 actPos = cursorPosition(event->pos()); if (actPos >= 0) { setCursorPosition(actPos); setSelection(actPos); } } void QHexEdit::mousePressEvent(QMouseEvent * event) { _blink = false; viewport()->update(); qint64 cPos = cursorPosition(event->pos()); if (cPos >= 0) { if (event->button() != Qt::RightButton) resetSelection(cPos); setCursorPosition(cPos); } } void QHexEdit::paintEvent(QPaintEvent *event) { QPainter painter(viewport()); int pxOfsX = horizontalScrollBar()->value(); if (event->rect() != _cursorRect) { int pxPosStartY = _pxCharHeight; // draw some patterns if needed painter.fillRect(event->rect(), viewport()->palette().color(QPalette::Base)); if (_addressArea) { painter.fillRect(QRect(-pxOfsX, event->rect().top(), _pxPosHexX - _pxGapAdrHex/2, height()), _addressAreaColor); } if (_asciiArea) { int linePos = _pxPosAsciiX - (_pxGapHexAscii / 2); painter.setPen(Qt::gray); painter.drawLine(linePos - pxOfsX, event->rect().top(), linePos - pxOfsX, height()); } painter.setPen(viewport()->palette().color(QPalette::WindowText)); // paint address area if (_addressArea) { QString address; for (int row=0, pxPosY = _pxCharHeight; row <= (_dataShown.size()/_bytesPerLine); row++, pxPosY +=_pxCharHeight) { address = QString("%1").arg(_bPosFirst + row*_bytesPerLine + _addressOffset, _addrDigits, 16, QChar('0')); painter.setPen(QPen(_addressFontColor)); painter.drawText(_pxPosAdrX - pxOfsX, pxPosY, hexCaps() ? address.toUpper() : address); } } // paint hex and ascii area QPen colStandard = QPen(viewport()->palette().color(QPalette::WindowText)); painter.setBackgroundMode(Qt::TransparentMode); for (int row = 0, pxPosY = pxPosStartY; row <= _rowsShown; row++, pxPosY +=_pxCharHeight) { QByteArray hex; int pxPosX = _pxPosHexX - pxOfsX; int pxPosAsciiX2 = _pxPosAsciiX - pxOfsX; qint64 bPosLine = row * _bytesPerLine; for (int colIdx = 0; ((bPosLine + colIdx) < _dataShown.size() && (colIdx < _bytesPerLine)); colIdx++) { QColor c = viewport()->palette().color(QPalette::Base); painter.setPen(QPen(_hexFontColor)); qint64 posBa = _bPosFirst + bPosLine + colIdx; if ((getSelectionBegin() <= posBa) && (getSelectionEnd() > posBa)) { c = _brushSelection.color(); painter.setPen(_penSelection); } else { if (_highlighting) if (_markedShown.at((int)(posBa - _bPosFirst))) { c = _brushHighlighted.color(); painter.setPen(_penHighlighted); } } // render hex value QRect r; if (colIdx == 0) r.setRect(pxPosX, pxPosY - _pxCharHeight + _pxSelectionSub, 2*_pxCharWidth, _pxCharHeight); else r.setRect(pxPosX - _pxCharWidth, pxPosY - _pxCharHeight + _pxSelectionSub, 3*_pxCharWidth, _pxCharHeight); painter.fillRect(r,c); QRect tagrect; if(colorTag) { for(int i=0;isize();i++) { ColorTag tag0 = colorTag->at(i); if(posBa >= tag0.pos && posBa < (tag0.pos + tag0.size)) { if (colIdx == 0) tagrect.setRect(pxPosX, pxPosY - _pxCharHeight + _pxSelectionSub, 2*_pxCharWidth, _pxCharHeight); else tagrect.setRect(pxPosX - _pxCharWidth, pxPosY - _pxCharHeight + _pxSelectionSub, 3*_pxCharWidth, _pxCharHeight); QColor tempColor = QColor(QString::fromStdString(tag0.color)); tempColor.setAlpha(80); painter.fillRect(tagrect, QBrush(tempColor)); } } } hex = _hexDataShown.mid((bPosLine + colIdx) * 2, 2); painter.drawText(pxPosX, pxPosY, hexCaps()?hex.toUpper():hex); pxPosX += 3*_pxCharWidth; // render ascii value if (_asciiArea) { if (c == viewport()->palette().color(QPalette::Base)) c = _asciiAreaColor; int ch = (uchar)_dataShown.at(bPosLine + colIdx); if ( ch < ' ' || ch > '~' ) ch = '.'; r.setRect(pxPosAsciiX2, pxPosY - _pxCharHeight + _pxSelectionSub, _pxCharWidth, _pxCharHeight); painter.fillRect(r, c); painter.setPen(QPen(_asciiFontColor)); painter.drawText(pxPosAsciiX2, pxPosY, QChar(ch)); pxPosAsciiX2 += _pxCharWidth; } } } painter.setBackgroundMode(Qt::TransparentMode); painter.setPen(viewport()->palette().color(QPalette::WindowText)); } // _cursorPosition counts in 2, _bPosFirst counts in 1 int hexPositionInShowData = _cursorPosition - 2 * _bPosFirst; // due to scrolling the cursor can go out of the currently displayed data if ((hexPositionInShowData >= 0) && (hexPositionInShowData <= _hexDataShown.size()) ) { // paint cursor if (_readOnly) { QColor color = viewport()->palette().dark().color(); painter.fillRect(QRect(_pxCursorX - pxOfsX, _pxCursorY - _pxCharHeight + _pxSelectionSub, _pxCharWidth, _pxCharHeight), color); } else { if (_blink && hasFocus()) { painter.fillRect(_cursorRect, this->palette().color(QPalette::WindowText)); painter.fillRect(_cursorRect2, this->palette().color(QPalette::WindowText)); } } if (_editAreaIsAscii) { // every 2 hex there is 1 ascii int asciiPositionInShowData = hexPositionInShowData / 2; if(asciiPositionInShowData <_dataShown.size()) { int ch = (uchar)_dataShown.at(asciiPositionInShowData); if (ch < ' ' || ch > '~') ch = '.'; painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, QChar(ch)); } } else { painter.drawText(_pxCursorX - pxOfsX, _pxCursorY, hexCaps() ? _hexDataShown.mid(hexPositionInShowData, 1).toUpper() : _hexDataShown.mid(hexPositionInShowData, 1)); } } // emit event, if size has changed if (_lastEventSize != _chunks->size()) { _lastEventSize = _chunks->size(); emit currentSizeChanged(_lastEventSize); } } void QHexEdit::resizeEvent(QResizeEvent *) { if (_dynamicBytesPerLine) { int pxFixGaps = 0; if (_addressArea) pxFixGaps = addressWidth() * _pxCharWidth + _pxGapAdr; pxFixGaps += _pxGapAdrHex; if (_asciiArea) pxFixGaps += _pxGapHexAscii; // +1 because the last hex value do not have space. so it is effective one char more int charWidth = (viewport()->width() - pxFixGaps ) / _pxCharWidth + 1; // 2 hex alfa-digits 1 space 1 ascii per byte = 4; if ascii is disabled then 3 // to prevent devision by zero use the min value 1 setBytesPerLine(std::max(charWidth / (_asciiArea ? 4 : 3),1)); } adjust(); } bool QHexEdit::focusNextPrevChild(bool next) { if (_addressArea) { if ( (next && _editAreaIsAscii) || (!next && !_editAreaIsAscii )) return QWidget::focusNextPrevChild(next); else return false; } else { return QWidget::focusNextPrevChild(next); } } // ********************************************************************** Handle selections void QHexEdit::resetSelection() { _bSelectionBegin = _bSelectionInit; _bSelectionEnd = _bSelectionInit; } void QHexEdit::resetSelection(qint64 pos) { pos = pos / 2 ; if (pos < 0) pos = 0; if (pos > _chunks->size()) pos = _chunks->size(); _bSelectionInit = pos; _bSelectionBegin = pos; _bSelectionEnd = pos; } void QHexEdit::setSelection(qint64 pos) { pos = pos / 2; if (pos < 0) pos = 0; if (pos > _chunks->size()) pos = _chunks->size(); if (pos >= _bSelectionInit) { _bSelectionEnd = pos; _bSelectionBegin = _bSelectionInit; } else { _bSelectionBegin = pos; _bSelectionEnd = _bSelectionInit; } } qint64 QHexEdit::getSelectionBegin() { return _bSelectionBegin; } qint64 QHexEdit::getSelectionEnd() { return _bSelectionEnd; } // ********************************************************************** Private utility functions void QHexEdit::init() { _undoStack->clear(); setAddressOffset(0); resetSelection(0); setCursorPosition(0); verticalScrollBar()->setValue(0); _modified = false; } void QHexEdit::adjust() { // recalc Graphics if (_addressArea) { _addrDigits = addressWidth(); _pxPosHexX = _pxGapAdr + _addrDigits*_pxCharWidth + _pxGapAdrHex; } else _pxPosHexX = _pxGapAdrHex; _pxPosAdrX = _pxGapAdr; _pxPosAsciiX = _pxPosHexX + _hexCharsInLine * _pxCharWidth + _pxGapHexAscii; // set horizontalScrollBar() int pxWidth = _pxPosAsciiX; if (_asciiArea) pxWidth += _bytesPerLine*_pxCharWidth; horizontalScrollBar()->setRange(0, pxWidth - viewport()->width()); horizontalScrollBar()->setPageStep(viewport()->width()); // set verticalScrollbar() _rowsShown = ((viewport()->height()-4)/_pxCharHeight); qint64 lineCount = _chunks->size() / (qint64)_bytesPerLine + 1; if(lineCount >= 1024*1024*1024){ _scrollMult = ceil(lineCount/(1024*1024*1024)); } else { _scrollMult = 1; } verticalScrollBar()->setRange(0, (lineCount - _rowsShown)/_scrollMult); verticalScrollBar()->setPageStep(_rowsShown); qint64 value = (qint64)verticalScrollBar()->value()*_scrollMult; _bPosFirst = value * _bytesPerLine; _bPosLast = _bPosFirst + (qint64)(_rowsShown * _bytesPerLine) - 1; if (_bPosLast >= _chunks->size()) _bPosLast = _chunks->size() - 1; readBuffers(); setCursorPosition(_cursorPosition); } void QHexEdit::dataChangedPrivate(int) { _modified = _undoStack->index() != 0; adjust(); emit dataChanged(); } void QHexEdit::refresh() { ensureVisible(); readBuffers(); } void QHexEdit::readBuffers() { _dataShown = _chunks->data(_bPosFirst, _bPosLast - _bPosFirst + _bytesPerLine + 1, &_markedShown); _hexDataShown = QByteArray(_dataShown.toHex()); } QString QHexEdit::toReadable(const QByteArray &ba) { QString result; for (int i=0; i < ba.size(); i += 16) { QString addrStr = QString("%1").arg(_addressOffset + i, addressWidth(), 16, QChar('0')); QString hexStr; QString ascStr; for (int j=0; j<16; j++) { if ((i + j) < ba.size()) { hexStr.append(" ").append(ba.mid(i+j, 1).toHex()); char ch = ba[i + j]; if ((ch < 0x20) || (ch > 0x7e)) ch = '.'; ascStr.append(QChar(ch)); } } result += addrStr + " " + QString("%1").arg(hexStr, -48) + " " + QString("%1").arg(ascStr, -17) + "\n"; } return result; } void QHexEdit::updateCursor() { if (_blink) _blink = false; else _blink = true; viewport()->update(_cursorRect); } void QHexEdit::showContextMenu(const QPoint &pos) { QMenu contextMenu; if(!_editAreaIsAscii) { if(getSelectionEnd() - getSelectionBegin()> 0) { QAction *copyAction = contextMenu.addAction("Copy"); connect(copyAction, &QAction::triggered, this, &QHexEdit::copyText); QAction *cutAction = contextMenu.addAction("Cut"); connect(cutAction, &QAction::triggered, this, &QHexEdit::cutText); } QAction *pasteAction = contextMenu.addAction("Paste"); connect(pasteAction, &QAction::triggered, this, &QHexEdit::pasteText); contextMenu.exec(mapToGlobal(pos)); } } void QHexEdit::copyText(){ QByteArray ba; if(!_editAreaIsAscii) { ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); } else { ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); for (int i = 0; i < ba.length(); i++) { if(ba.at(i) < 32 || ba.at(i) > 126) { ba[i] = '.'; } } } QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); } void QHexEdit::pasteText(){ QClipboard *clipboard = QApplication::clipboard(); QByteArray ba = QByteArray().fromHex(clipboard->text().toLatin1()); if (_overwriteMode) { ba = ba.left(std::min(ba.size(), (_chunks->size() - _bPosCurrent))); replace(_bPosCurrent, ba.size(), ba); } else insert(_bPosCurrent, ba); setCursorPosition(_cursorPosition + 2 * ba.size()); resetSelection(getSelectionBegin()); } void QHexEdit::cutText(){ QByteArray ba = _chunks->data(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()).toHex(); for (qint64 idx = 32; idx < ba.size(); idx +=33) ba.insert(idx, "\n"); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(ba); if (_overwriteMode) { qint64 len = getSelectionEnd() - getSelectionBegin(); replace(getSelectionBegin(), (int)len, QByteArray((int)len, char(0))); } else { remove(getSelectionBegin(), getSelectionEnd() - getSelectionBegin()); } setCursorPosition(2 * getSelectionBegin()); resetSelection(2 * getSelectionBegin()); } hexwalk-1.9.1/src/qhexedit/chunks.cpp0000664000175100017510000002230715005675407017137 0ustar carmixcarmix#include "chunks.h" #include #define NORMAL 0 #define HIGHLIGHTED 1 #define BUFFER_SIZE 0x10000 #define CHUNK_SIZE 0x1000 #define READ_CHUNK_MASK Q_INT64_C(0xfffffffffffff000) // ***************************************** Constructors and file settings Chunks::Chunks(QObject *parent): QObject(parent) { QBuffer *buf = new QBuffer(this); setIODevice(*buf); } Chunks::Chunks(QIODevice &ioDevice, QObject *parent): QObject(parent) { setIODevice(ioDevice); } bool Chunks::setIODevice(QIODevice &ioDevice) { _ioDevice = &ioDevice; bool ok = _ioDevice->open(QIODevice::ReadOnly); if (ok) // Try to open IODevice { _size = _ioDevice->size(); _ioDevice->close(); } else // Fallback is an empty buffer { QBuffer *buf = new QBuffer(this); _ioDevice = buf; _size = 0; } _chunks.clear(); _pos = 0; return ok; } // ***************************************** Getting data out of Chunks QByteArray Chunks::data(qint64 pos, qint64 maxSize, QByteArray *highlighted) { qint64 ioDelta = 0; int chunkIdx = 0; Chunk chunk; QByteArray buffer; // Do some checks and some arrangements if (highlighted) highlighted->clear(); if (pos >= _size) return buffer; if (maxSize < 0) maxSize = _size; else if ((pos + maxSize) > _size) maxSize = _size - pos; _ioDevice->open(QIODevice::ReadOnly); while (maxSize > 0) { chunk.absPos = LLONG_MAX; bool chunksLoopOngoing = true; while ((chunkIdx < _chunks.count()) && chunksLoopOngoing) { // In this section, we track changes before our required data and // we take the editdet data, if availible. ioDelta is a difference // counter to justify the read pointer to the original data, if // data in between was deleted or inserted. chunk = _chunks[chunkIdx]; if (chunk.absPos > pos) chunksLoopOngoing = false; else { chunkIdx += 1; qint64 count; qint64 chunkOfs = pos - chunk.absPos; if (maxSize > ((qint64)chunk.data.size() - chunkOfs)) { count = (qint64)chunk.data.size() - chunkOfs; ioDelta += CHUNK_SIZE - chunk.data.size(); } else count = maxSize; if (count > 0) { buffer += chunk.data.mid(chunkOfs, (int)count); maxSize -= count; pos += count; if (highlighted) *highlighted += chunk.dataChanged.mid(chunkOfs, (int)count); } } } if ((maxSize > 0) && (pos < chunk.absPos)) { // In this section, we read data from the original source. This only will // happen, whe no copied data is available qint64 byteCount; QByteArray readBuffer; if ((chunk.absPos - pos) > maxSize) byteCount = maxSize; else byteCount = chunk.absPos - pos; maxSize -= byteCount; _ioDevice->seek(pos + ioDelta); readBuffer = _ioDevice->read(byteCount); buffer += readBuffer; if (highlighted) *highlighted += QByteArray(readBuffer.size(), NORMAL); pos += readBuffer.size(); } } _ioDevice->close(); return buffer; } bool Chunks::write(QIODevice &iODevice, qint64 pos, qint64 count) { if (count == -1) count = _size; bool ok = iODevice.open(QIODevice::WriteOnly); if (ok) { for (qint64 idx=pos; idx < count; idx += BUFFER_SIZE) { QByteArray ba = data(idx, BUFFER_SIZE); iODevice.write(ba); } iODevice.close(); } return ok; } // ***************************************** Set and get highlighting infos void Chunks::setDataChanged(qint64 pos, bool dataChanged) { if ((pos < 0) || (pos >= _size)) return; int chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].dataChanged[(int)posInBa] = char(dataChanged); } bool Chunks::dataChanged(qint64 pos) { QByteArray highlighted; data(pos, 1, &highlighted); return bool(highlighted.at(0)); } // ***************************************** Search API qint64 Chunks::indexOf(const QByteArray &ba, qint64 from,bool isRegex,bool isCaseInsensitive) { qint64 result = -1; QByteArray buffer; matchSize = 0; for (qint64 pos=from; (pos < _size) && (result < 0); pos += BUFFER_SIZE) { buffer = data(pos, BUFFER_SIZE + ba.size() - 1); int findPos = -1; if (isRegex) { try { std::string regex = ba.toStdString(); std::string buf = buffer.toStdString(); int icase = 0; if(isCaseInsensitive) { icase = std::regex_constants::icase; } std::regex re(regex,(std::regex_constants::syntax_option_type)icase); std::smatch match; if (std::regex_search(buf, match, re)) { findPos = match.position(0); matchSize = match.str(0).size(); } } catch (std::regex_error& e) { // std::cerr << "Regex syntax error:" << std::endl << e.what() << std::endl; } } else { findPos = buffer.indexOf(ba); matchSize = ba.size(); } if (findPos >= 0) result = pos + (qint64)findPos; } return result; } qint64 Chunks::lastIndexOf(const QByteArray &ba, qint64 from) { qint64 result = -1; QByteArray buffer; for (qint64 pos=from; (pos > 0) && (result < 0); pos -= BUFFER_SIZE) { qint64 sPos = pos - BUFFER_SIZE - (qint64)ba.size() + 1; if (sPos < 0) sPos = 0; buffer = data(sPos, pos - sPos); int findPos = buffer.lastIndexOf(ba); if (findPos >= 0) result = sPos + (qint64)findPos; } return result; } // ***************************************** Char manipulations bool Chunks::insert(qint64 pos, char b) { if ((pos < 0) || (pos > _size)) return false; int chunkIdx; if (pos == _size) chunkIdx = getChunkIndex(pos-1); else chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].data.insert(posInBa, b); _chunks[chunkIdx].dataChanged.insert(posInBa, char(1)); for (int idx=chunkIdx+1; idx < _chunks.size(); idx++) _chunks[idx].absPos += 1; _size += 1; _pos = pos; return true; } bool Chunks::overwrite(qint64 pos, char b) { if ((pos < 0) || (pos >= _size)) return false; int chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].data[(int)posInBa] = b; _chunks[chunkIdx].dataChanged[(int)posInBa] = char(1); _pos = pos; return true; } bool Chunks::removeAt(qint64 pos) { if ((pos < 0) || (pos >= _size)) return false; int chunkIdx = getChunkIndex(pos); qint64 posInBa = pos - _chunks[chunkIdx].absPos; _chunks[chunkIdx].data.remove(posInBa, 1); _chunks[chunkIdx].dataChanged.remove(posInBa, 1); for (int idx=chunkIdx+1; idx < _chunks.size(); idx++) _chunks[idx].absPos -= 1; _size -= 1; _pos = pos; return true; } // ***************************************** Utility functions char Chunks::operator[](qint64 pos) { return data(pos, 1).at(0); } qint64 Chunks::pos() { return _pos; } qint64 Chunks::size() { return _size; } int Chunks::getChunkIndex(qint64 absPos) { // This routine checks, if there is already a copied chunk available. If os, it // returns a reference to it. If there is no copied chunk available, original // data will be copied into a new chunk. int foundIdx = -1; int insertIdx = 0; qint64 ioDelta = 0; for (int idx=0; idx < _chunks.size(); idx++) { Chunk chunk = _chunks[idx]; if ((absPos >= chunk.absPos) && (absPos < (chunk.absPos + chunk.data.size()))) { foundIdx = idx; break; } if (absPos < chunk.absPos) { insertIdx = idx; break; } ioDelta += chunk.data.size() - CHUNK_SIZE; insertIdx = idx + 1; } if (foundIdx == -1) { Chunk newChunk; qint64 readAbsPos = absPos - ioDelta; qint64 readPos = (readAbsPos & READ_CHUNK_MASK); _ioDevice->open(QIODevice::ReadOnly); _ioDevice->seek(readPos); newChunk.data = _ioDevice->read(CHUNK_SIZE); _ioDevice->close(); newChunk.absPos = absPos - (readAbsPos - readPos); newChunk.dataChanged = QByteArray(newChunk.data.size(), char(0)); _chunks.insert(insertIdx, newChunk); foundIdx = insertIdx; } return foundIdx; } #ifdef MODUL_TEST int Chunks::chunkSize() { return _chunks.size(); } #endif hexwalk-1.9.1/src/qhexedit/colortag.cpp0000664000175100017510000000000015005675407017440 0ustar carmixcarmixhexwalk-1.9.1/src/qhexedit/colortag.h0000664000175100017510000000071415005675407017121 0ustar carmixcarmix#ifndef COLORTAG_H #define COLORTAG_H #include #include "tagparser.hpp" #include typedef enum TagType_e { UNDEFINED_t, STRING_t, BE_t, LE_t, HEX_t }TagType_e; const string tagStrings[]={"undefined","string","beint","leint","hex"}; class ColorTag{ public: string name; int64_t pos; int64_t size; string color; TagType_e type; QByteArray data; YMLObj obj; }; #endif // COLORTAG_H hexwalk-1.9.1/src/qhexedit/chunks.h0000664000175100017510000000406015005675407016600 0ustar carmixcarmix#ifndef CHUNKS_H #define CHUNKS_H /** \cond docNever */ /*! The Chunks class is the storage backend for QHexEdit. * * When QHexEdit loads data, Chunks access them using a QIODevice interface. When the app uses * a QByteArray interface, QBuffer is used to provide again a QIODevice like interface. No data * will be changed, therefore Chunks opens the QIODevice in QIODevice::ReadOnly mode. After every * access Chunks closes the QIODevice, that's why external applications can overwrite files while * QHexEdit shows them. * * When the the user starts to edit the data, Chunks creates a local copy of a chunk of data (4 * kilobytes) and notes all changes there. Parallel to that chunk, there is a second chunk, * which keep track of which bytes are changed and which not. * */ #include #include struct Chunk { QByteArray data; QByteArray dataChanged; qint64 absPos; }; class Chunks: public QObject { Q_OBJECT public: // Constructors and file settings Chunks(QObject *parent); Chunks(QIODevice &ioDevice, QObject *parent); bool setIODevice(QIODevice &ioDevice); // Getting data out of Chunks QByteArray data(qint64 pos=0, qint64 count=-1, QByteArray *highlighted=0); bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1); // Set and get highlighting infos void setDataChanged(qint64 pos, bool dataChanged); bool dataChanged(qint64 pos); // Search API qint64 indexOf(const QByteArray &ba, qint64 from,bool isRegex,bool isCaseInsensitive); qint64 lastIndexOf(const QByteArray &ba, qint64 from); // Char manipulations bool insert(qint64 pos, char b); bool overwrite(qint64 pos, char b); bool removeAt(qint64 pos); // Utility functions char operator[](qint64 pos); qint64 pos(); qint64 size(); int matchSize = 0; private: int getChunkIndex(qint64 absPos); QIODevice * _ioDevice; qint64 _pos; qint64 _size; QList _chunks; #ifdef MODUL_TEST public: int chunkSize(); #endif }; /** \endcond docNever */ #endif // CHUNKS_H hexwalk-1.9.1/src/qhexedit/commands.cpp0000664000175100017510000001015515005675407017443 0ustar carmixcarmix#include "commands.h" #include // Helper class to store single byte commands class CharCommand : public QUndoCommand { public: enum CCmd {insert, removeAt, overwrite}; CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, QUndoCommand *parent=0); void undo(); void redo(); bool mergeWith(const QUndoCommand *command); int id() const { return 1234; } private: Chunks * _chunks; qint64 _charPos; bool _wasChanged; char _newChar; char _oldChar; CCmd _cmd; }; CharCommand::CharCommand(Chunks * chunks, CCmd cmd, qint64 charPos, char newChar, QUndoCommand *parent) : QUndoCommand(parent) , _chunks(chunks) , _charPos(charPos) , _wasChanged(false) , _newChar(newChar) , _oldChar('\0') , _cmd(cmd) { } bool CharCommand::mergeWith(const QUndoCommand *command) { const CharCommand *nextCommand = static_cast(command); bool result = false; if (_cmd != CharCommand::removeAt) { if (nextCommand->_cmd == overwrite) if (nextCommand->_charPos == _charPos) { _newChar = nextCommand->_newChar; result = true; } } return result; } void CharCommand::undo() { switch (_cmd) { case insert: _chunks->removeAt(_charPos); break; case overwrite: _chunks->overwrite(_charPos, _oldChar); _chunks->setDataChanged(_charPos, _wasChanged); break; case removeAt: _chunks->insert(_charPos, _oldChar); _chunks->setDataChanged(_charPos, _wasChanged); break; } } void CharCommand::redo() { switch (_cmd) { case insert: _chunks->insert(_charPos, _newChar); break; case overwrite: _oldChar = (*_chunks)[_charPos]; _wasChanged = _chunks->dataChanged(_charPos); _chunks->overwrite(_charPos, _newChar); break; case removeAt: _oldChar = (*_chunks)[_charPos]; _wasChanged = _chunks->dataChanged(_charPos); _chunks->removeAt(_charPos); break; } } UndoStack::UndoStack(Chunks * chunks, QObject * parent) : QUndoStack(parent) { _chunks = chunks; _parent = parent; this->setUndoLimit(1000); } void UndoStack::insert(qint64 pos, char c) { if ((pos >= 0) && (pos <= _chunks->size())) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos, c); this->push(cc); } } void UndoStack::insert(qint64 pos, const QByteArray &ba) { if ((pos >= 0) && (pos <= _chunks->size())) { QString txt = QString(tr("Inserting %1 bytes")).arg(ba.size()); beginMacro(txt); for (int idx=0; idx < ba.size(); idx++) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::insert, pos + idx, ba.at(idx)); this->push(cc); } endMacro(); } } void UndoStack::removeAt(qint64 pos, qint64 len) { if ((pos >= 0) && (pos < _chunks->size())) { if (len==1) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::removeAt, pos, char(0)); this->push(cc); } else { QString txt = QString(tr("Delete %1 chars")).arg(len); beginMacro(txt); for (qint64 cnt=0; cnt= 0) && (pos < _chunks->size())) { QUndoCommand *cc = new CharCommand(_chunks, CharCommand::overwrite, pos, c); this->push(cc); } } void UndoStack::overwrite(qint64 pos, int len, const QByteArray &ba) { if ((pos >= 0) && (pos < _chunks->size())) { QString txt = QString(tr("Overwrite %1 chars")).arg(len); beginMacro(txt); removeAt(pos, len); insert(pos, ba); endMacro(); } } hexwalk-1.9.1/src/qhexedit/bytepattern.h0000664000175100017510000000264715005675407017657 0ustar carmixcarmix#ifndef BYTEPATTERN_H #define BYTEPATTERN_H #include "qhexedit.h" #include #include #include #include #include "colortag.h" #include "tagparser.hpp" #include class BPException: public std::exception{ private: std::string message; public: BPException(std::string msg):message(msg) {} std::string what(){ return message; } }; enum BPerrors { E_NONE = 0, E_WRONGNAME = -1, E_WRONGTYPE = -2, E_WRONGREF = -3, E_WRONGCOLOR = -4, E_EMPTYOFFSET = -5, E_EMPTYSIZE = -6, E_DUPNAME = -7, }; class BytePattern{ public: BytePattern(QHexEdit * qhexptr); bool isOperator(char c); int performOperation(char operation, int operand1, int operand2); int evaluateExpression(const string& expression); int updateTags(); int addElement(YMLObj obj); bool isDigit(string str); QList colorTag; int resolveReferences(); void reset(); int delElement(int idx); int updateElement(int idx,YMLObj obj); YMLParser ymlParser; bool isValidName(std::string name); bool isValidColor(std::string name); bool isDuplicatedName(std::string name,int excluded_idx); private: vector tokenizeString(const string& input, const string& delimiters); std::string hexToDecimal(const std::string& hexString); bool isHexString(std::string x); QHexEdit *hexEdit; }; #endif // BYTEPATTERN_H hexwalk-1.9.1/src/qhexedit/qhexedit.sip0000664000175100017510000000423115005675407017464 0ustar carmixcarmix%Module(name=qhexedit) %Import QtCore/QtCoremod.sip %Import QtGui/QtGuimod.sip %If (Qt_5_0_0 -) %Import QtWidgets/QtWidgetsmod.sip %End class QHexEdit : QAbstractScrollArea { %TypeHeaderCode #include "../qhexedit/qhexedit.h" %End public: explicit QHexEdit(QWidget *parent /TransferThis/ = 0); virtual ~QHexEdit(); bool setData(QIODevice &); QByteArray dataAt(qint64, qint64=-1); bool write(QIODevice &iODevice, qint64=0, qint64=-1); void insert(qint64, char); void remove(qint64, qint64); void replace(qint64, char); void insert(qint64, QByteArray &); void replace(qint64, qint64, QByteArray &); bool addressArea(); bool addressWidth(); bool asciiArea(); qint64 cursorPosition(QPoint); void ensureVisible(); qint64 indexOf(QByteArray &, qint64); bool isModified(); bool highlighting(); qint64 lastIndexOf(QByteArray &, qint64); QString selectionToReadableString(); QString selectedData(); void setFont(const QFont &); QString toReadableString(); QColor addressAreaColor(); void setAddressAreaColor(const QColor &); QColor addressFontColor(); void setAddressFontColor(const QColor &); QColor asciiAreaColor(); void setAsciiAreaColor(const QColor &); QColor asciiFontColor(); void setAsciiFontColor(const QColor &); QColor hexFontColor(); void setHexFontColor(const QColor &); qint64 addressOffset(); void setAddressOffset(qint64); qint64 cursorPosition(); void setCursorPosition(qint64); QByteArray data(); void setData(const QByteArray &); QColor highlightingColor(); void setHighlightingColor(const QColor &); bool overwriteMode(); void setOverwriteMode(bool); bool isReadOnly(); void setReadOnly(bool); QColor selectionColor(); void setSelectionColor(const QColor &); public slots: void redo(); void setAddressArea(bool); void setAddressWidth(int); void setAsciiArea(bool); void setHighlighting(bool); void undo(); signals: void currentAddressChanged(qint64); void currentSizeChanged(qint64); void dataChanged(); void overwriteModeChanged(bool); }; hexwalk-1.9.1/src/qhexedit/license.txt0000664000175100017510000006364115005675407017331 0ustar carmixcarmix GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it!hexwalk-1.9.1/src/qhexedit/bytepattern.cpp0000664000175100017510000003137615005675407020213 0ustar carmixcarmix#include "bytepattern.h" #include #include BytePattern::BytePattern(QHexEdit * qhexptr) { hexEdit = qhexptr; } using namespace std; std::vector BytePattern::tokenizeString(const std::string& input, const std::string& delimiters) { std::vector tokens; std::istringstream iss(input); std::string token; while (std::getline(iss, token, ' ')) { std::string sanitizedToken; // Remove spaces from the token for (char c : token) { if (c != ' ') { sanitizedToken += c; } } // Split the sanitized token based on delimiters size_t start = 0; size_t end = sanitizedToken.find_first_of(delimiters); while (end != std::string::npos) { tokens.push_back(sanitizedToken.substr(start, end - start)); start = end + 1; end = sanitizedToken.find_first_of(delimiters, start); } if (start < sanitizedToken.length()) { tokens.push_back(sanitizedToken.substr(start)); } } return tokens; } void BytePattern::reset(){ colorTag.clear(); } bool BytePattern::isHexString(std::string x) { std::regex hexRegex("^0x[0-9A-Fa-f]+$"); if (!std::regex_match(x, hexRegex)) { return false; } return true; } std::string BytePattern::hexToDecimal(const std::string& hexString) { std::string hexValue = hexString.substr(2); std::stringstream ss; ss << std::hex << hexValue; int decimalValue; ss >> decimalValue; std::stringstream resultStream; resultStream << decimalValue; std::string decimalString = resultStream.str(); return decimalString; } /*Search for possible references to resolve*/ int BytePattern::resolveReferences(){ bool ok; int pos; bool found = false; for(int i=0;i foundTokens = tokenizeString(tag.obj.offset,"+-*/()"); for(int k=0;k<(int)foundTokens.size();k++) { string token = foundTokens.at(k); if(!isDigit(token)){ //token is not a number, might be a variable if(isHexString(token)) { pos = tag.obj.offset.find(token); string decString = hexToDecimal(token); tag.obj.offset.replace(pos,token.length(),decString); } else { found = false; for(int j=0;j foundTokens = tokenizeString(tag.obj.size,"+-*/()"); for(int k=0 ; k<(int)foundTokens.size();k++) { string token = foundTokens.at(k); if(!isDigit(token)){ //token is not a number, might be a variable if(isHexString(token)) { pos = tag.obj.size.find(token); string decString = hexToDecimal(token); tag.obj.size.replace(pos,token.length(),decString); } else { found = false; for(int j=0;j 8) { reqSize = 8; } else { reqSize = outsize; } } else { if(outsize > 16) { reqSize = 16; } else { reqSize = outsize; } } colorTag[i].data = hexEdit->dataAt(colorTag[i].pos,reqSize); //qInfo()<<"NAME:"< 0) { if(name[0] >='0' && name[0] <= '9') { //name can't start with a number return false; } if(strspn( name.c_str(), "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ) == name.size()) { return true; } } } return false; } bool BytePattern::isDuplicatedName(std::string name,int excluded_idx) { for(int i=0;i operandStack; stack operatorStack; for (size_t i = 0; i < expression.length(); ++i) { // Ignore whitespaces if (expression[i] == ' ') continue; // If the character is a digit, parse the entire number if (isdigit(expression[i])) { int operand = 0; while (isdigit(expression[i])) { operand = operand * 10 + (expression[i] - '0'); ++i; } i--; operandStack.push(operand); } // If the character is an operator else if (isOperator(expression[i])) { while (!operatorStack.empty() && operatorStack.top() != '(' && ((expression[i] != '*' && expression[i] != '/') || (operatorStack.top() != '+' && operatorStack.top() != '-'))) { int operand2 = operandStack.top(); operandStack.pop(); int operand1 = operandStack.top(); operandStack.pop(); char op = operatorStack.top(); operatorStack.pop(); int result = performOperation(op, operand1, operand2); operandStack.push(result); } operatorStack.push(expression[i]); } // If the character is an opening parenthesis else if (expression[i] == '(') { operatorStack.push(expression[i]); } // If the character is a closing parenthesis else if (expression[i] == ')') { while (!operatorStack.empty() && operatorStack.top() != '(') { int operand2 = operandStack.top(); operandStack.pop(); int operand1 = operandStack.top(); operandStack.pop(); char op = operatorStack.top(); operatorStack.pop(); int result = performOperation(op, operand1, operand2); operandStack.push(result); } operatorStack.pop(); // Pop the opening parenthesis } } while (!operatorStack.empty()) { int operand2 = operandStack.top(); operandStack.pop(); int operand1 = operandStack.top(); operandStack.pop(); char op = operatorStack.top(); operatorStack.pop(); int result = performOperation(op, operand1, operand2); operandStack.push(result); } return operandStack.top(); } hexwalk-1.9.1/src/qhexedit/commands.h0000664000175100017510000000263215005675407017111 0ustar carmixcarmix#ifndef COMMANDS_H #define COMMANDS_H /** \cond docNever */ #include #include "chunks.h" /*! CharCommand is a class to provid undo/redo functionality in QHexEdit. A QUndoCommand represents a single editing action on a document. CharCommand is responsable for manipulations on single chars. It can insert. overwrite and remove characters. A manipulation stores allways two actions 1. redo (or do) action 2. undo action. CharCommand also supports command compression via mergeWith(). This enables the user to perform an undo command e.g. 3 steps in a single command. If you for example insert a new byt "34" this means for the editor doing 3 steps: insert a "00", overwrite it with "03" and the overwrite it with "34". These 3 steps are combined into a single step, insert a "34". The byte array oriented commands are just put into a set of single byte commands, which are pooled together with the macroBegin() and macroEnd() functionality of Qt's QUndoStack. */ class UndoStack : public QUndoStack { Q_OBJECT public: UndoStack(Chunks *chunks, QObject * parent=0); void insert(qint64 pos, char c); void insert(qint64 pos, const QByteArray &ba); void removeAt(qint64 pos, qint64 len=1); void overwrite(qint64 pos, char c); void overwrite(qint64 pos, int len, const QByteArray &ba); private: Chunks * _chunks; QObject * _parent; }; /** \endcond docNever */ #endif // COMMANDS_H hexwalk-1.9.1/src/qhexedit/qhexedit.pro0000664000175100017510000000054215005675407017472 0ustar carmixcarmix greaterThan(QT_MAJOR_VERSION, 4): QT += widgets QT += core gui TEMPLATE = lib VERSION = 4.2.0 DEFINES += QHEXEDIT_EXPORTS HEADERS = \ qhexedit.h \ chunks.h \ commands.h SOURCES = \ qhexedit.cpp \ chunks.cpp \ commands.cpp Release:TARGET = qhexedit Debug:TARGET = qhexeditd unix:DESTDIR = /usr/lib win32:DESTDIR = ../lib hexwalk-1.9.1/src/qhexedit/tagparser.hpp0000664000175100017510000000105015005675407017631 0ustar carmixcarmix#ifndef TAGPARSER_HPP #define TAGPARSER_HPP #include #include #include using namespace std; enum Parser_States { START, INSIDE_OBJ }; class YMLObj { public: string name; string size; string offset; string color; string type; }; class YMLParser { public: YMLParser(); int loadFile(string filename); void saveFile(std::string filename); vector ymlobj; private: bool isComment(std::string line); std::string removeSpaces(std::string input); }; #endif hexwalk-1.9.1/src/qhexedit/QHexEditPlugin.cpp0000664000175100017510000000326515005675407020500 0ustar carmixcarmix#include "QHexEditPlugin.h" #include "qhexedit.h" #include QHexEditPlugin::QHexEditPlugin(QObject * parent) : QObject(parent) { initialized = false; } bool QHexEditPlugin::isContainer() const { return false; } bool QHexEditPlugin::isInitialized() const { return initialized; } QIcon QHexEditPlugin::icon() const { return QIcon(); } QString QHexEditPlugin::domXml() const { return "\n" " \n" " \n" " \n" " 0\n" " 0\n" " 100\n" " 100\n" " \n" " \n" " \n" " QHexEditWidget\n" " \n" " \n" " QHexEdit widget allow to edit the data in hex view.\n" " \n" " \n" "\n"; } QString QHexEditPlugin::group() const { return "Input Widgets"; } QString QHexEditPlugin::includeFile() const { return "qhexedit.h"; } QString QHexEditPlugin::name() const { return "QHexEdit"; } QString QHexEditPlugin::toolTip() const { return ""; } QString QHexEditPlugin::whatsThis() const { return ""; } QWidget * QHexEditPlugin::createWidget(QWidget *parent) { return new QHexEdit(parent); } void QHexEditPlugin::initialize(QDesignerFormEditorInterface * /*core*/) { if (initialized) return; initialized = true; } #if QT_VERSION < QT_VERSION_CHECK(5,0,0) Q_EXPORT_PLUGIN2(QHexEditPlugin, QHexEditPlugin) #endif hexwalk-1.9.1/src/qhexedit/qhexedit.h0000664000175100017510000004333215005675407017125 0ustar carmixcarmix#ifndef QHEXEDIT_H #define QHEXEDIT_H #include #include #include #include "chunks.h" #include "commands.h" #include "colortag.h" #ifdef QHEXEDIT_EXPORTS #define QHEXEDIT_API Q_DECL_EXPORT #elif QHEXEDIT_IMPORTS #define QHEXEDIT_API Q_DECL_IMPORT #else #define QHEXEDIT_API #endif /** \mainpage QHexEdit is a binary editor widget for Qt. \version Version 0.8.9 \image html qhexedit.png */ /** QHexEdit is a hex editor widget written in C++ for the Qt (Qt4, Qt5) framework. It is a simple editor for binary data, just like QPlainTextEdit is for text data. There are sip configuration files included, so it is easy to create bindings for PyQt and you can use this widget also in python 2 and 3. QHexEdit takes the data of a QByteArray (setData()) and shows it. You can use the mouse or the keyboard to navigate inside the widget. If you hit the keys (0..9, a..f) you will change the data. Changed data is highlighted and can be accessed via data(). Normally QHexEdit works in the overwrite mode. You can set overwrite mode(false) and insert data. In this case the size of data() increases. It is also possible to delete bytes (del or backspace), here the size of data decreases. You can select data with keyboard hits or mouse movements. The copy-key will copy the selected data into the clipboard. The cut-key copies also but deletes it afterwards. In overwrite mode, the paste function overwrites the content of the (does not change the length) data. In insert mode, clipboard data will be inserted. The clipboard content is expected in ASCII Hex notation. Unknown characters will be ignored. QHexEdit comes with undo/redo functionality. All changes can be undone, by pressing the undo-key (usually ctr-z). They can also be redone afterwards. The undo/redo framework is cleared, when setData() sets up a new content for the editor. You can search data inside the content with indexOf() and lastIndexOf(). The replace() function is to change located subdata. This 'replaced' data can also be undone by the undo/redo framework. QHexEdit is based on QIODevice, that's why QHexEdit can handle big amounts of data. The size of edited data can be more then two gigabytes without any restrictions. */ class QHEXEDIT_API QHexEdit : public QAbstractScrollArea { Q_OBJECT /*! Property address area switch the address area on or off. Set addressArea true (show it), false (hide it). */ Q_PROPERTY(bool addressArea READ addressArea WRITE setAddressArea) /*! Property address area color sets (setAddressAreaColor()) the background color of address areas. You can also read the color (addressAreaColor()). */ Q_PROPERTY(QColor addressAreaColor READ addressAreaColor WRITE setAddressAreaColor) /*! Property address font color sets (setAddressFontColor()) the text color of address areas. You can also read the color (addressFontColor()). */ Q_PROPERTY(QColor addressFontColor READ addressFontColor WRITE setAddressFontColor) /*! Property ascii area color sets (setAsciiAreaColor()) the backgorund color of ascii areas. You can also read the color (asciiAreaColor()). */ Q_PROPERTY(QColor asciiAreaColor READ asciiAreaColor WRITE setAsciiAreaColor) /*! Property ascii font color sets (setAsciiFontColor()) the text color of ascii areas. You can also read the color (asciiFontColor()). */ Q_PROPERTY(QColor asciiFontColor READ asciiFontColor WRITE setAsciiFontColor) /*! Property hex font color sets (setHexFontColor()) the text color of hex areas. You can also read the color (hexFontColor()). */ Q_PROPERTY(QColor hexFontColor READ hexFontColor WRITE setHexFontColor) /*! Property addressOffset is added to the Numbers of the Address Area. A offset in the address area (left side) is sometimes useful, whe you show only a segment of a complete memory picture. With setAddressOffset() you set this property - with addressOffset() you get the current value. */ Q_PROPERTY(qint64 addressOffset READ addressOffset WRITE setAddressOffset) /*! Set and get the minimum width of the address area, width in characters. */ Q_PROPERTY(int addressWidth READ addressWidth WRITE setAddressWidth) /*! Switch the ascii area on (true, show it) or off (false, hide it). */ Q_PROPERTY(bool asciiArea READ asciiArea WRITE setAsciiArea) /*! Set and get bytes number per line.*/ Q_PROPERTY(int bytesPerLine READ bytesPerLine WRITE setBytesPerLine) /*! Property cursorPosition sets or gets the position of the editor cursor in QHexEdit. Every byte in data has two cursor positions: the lower and upper Nibble. Maximum cursor position is factor two of data.size(). */ Q_PROPERTY(qint64 cursorPosition READ cursorPosition WRITE setCursorPosition) /*! Property data holds the content of QHexEdit. Call setData() to set the content of QHexEdit, data() returns the actual content. When calling setData() with a QByteArray as argument, QHexEdit creates a internal copy of the data If you want to edit big files please use setData(), based on QIODevice. */ Q_PROPERTY(QByteArray data READ data WRITE setData NOTIFY dataChanged) /*! That property defines if the hex values looks as a-f if the value is false(default) or A-F if value is true. */ Q_PROPERTY(bool hexCaps READ hexCaps WRITE setHexCaps) /*! Property defines the dynamic calculation of bytesPerLine parameter depends of width of widget. set this property true to avoid horizontal scrollbars and show the maximal possible data. defalut value is false*/ Q_PROPERTY(bool dynamicBytesPerLine READ dynamicBytesPerLine WRITE setDynamicBytesPerLine) /*! Switch the highlighting feature on or of: true (show it), false (hide it). */ Q_PROPERTY(bool highlighting READ highlighting WRITE setHighlighting) /*! Property highlighting color sets (setHighlightingColor()) the background color of highlighted text areas. You can also read the color (highlightingColor()). */ Q_PROPERTY(QColor highlightingColor READ highlightingColor WRITE setHighlightingColor) /*! Property overwrite mode sets (setOverwriteMode()) or gets (overwriteMode()) the mode in which the editor works. In overwrite mode the user will overwrite existing data. The size of data will be constant. In insert mode the size will grow, when inserting new data. */ Q_PROPERTY(bool overwriteMode READ overwriteMode WRITE setOverwriteMode) /*! Property selection color sets (setSelectionColor()) the background color of selected text areas. You can also read the color (selectionColor()). */ Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor) /*! Property readOnly sets (setReadOnly()) or gets (isReadOnly) the mode in which the editor works. In readonly mode the the user can only navigate through the data and select data; modifying is not possible. This property's default is false. */ Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) /*! Set the font of the widget. Please use fixed width fonts like Mono or Courier.*/ Q_PROPERTY(QFont font READ font WRITE setFont) public: /*! Creates an instance of QHexEdit. \param parent Parent widget of QHexEdit. */ QHexEdit(QWidget *parent=0); // Access to data of qhexedit /*! Sets the data of QHexEdit. The QIODevice will be opened just before reading and closed immediately afterwards. This is to allow other programs to rewrite the file while editing it. */ bool setData(QIODevice &iODevice); /*! Gives back the data as a QByteArray starting at position \param pos and delivering \param count bytes. */ QByteArray dataAt(qint64 pos, qint64 count=-1); /*! Gives back the data into a \param iODevice starting at position \param pos and delivering \param count bytes. */ bool write(QIODevice &iODevice, qint64 pos=0, qint64 count=-1); // Char handling /*! Inserts a char. \param pos Index position, where to insert \param ch Char, which is to insert The char will be inserted and size of data grows. */ void insert(qint64 pos, char ch); /*! Removes len bytes from the content. \param pos Index position, where to remove \param len Amount of bytes to remove */ void remove(qint64 pos, qint64 len=1); /*! Replaces a char. \param pos Index position, where to overwrite \param ch Char, which is to insert The char will be overwritten and size remains constant. */ void replace(qint64 pos, char ch); // ByteArray handling /*! Inserts a byte array. \param pos Index position, where to insert \param ba QByteArray, which is to insert The QByteArray will be inserted and size of data grows. */ void insert(qint64 pos, const QByteArray &ba); /*! Replaces \param len bytes with a byte array \param ba \param pos Index position, where to overwrite \param ba QByteArray, which is inserted \param len count of bytes to overwrite The data is overwritten and size of data may change. */ void replace(qint64 pos, qint64 len, const QByteArray &ba); // Utility functions /*! Calc cursor position from graphics position * \param point from where the cursor position should be calculated * \return Cursor position */ qint64 cursorPosition(QPoint point); /*! return address of current first byte shown */ qint64 firstByteAddress(); /*! Ensure the cursor to be visbile */ void ensureVisible(); /*! Get current file size */ qint64 getSize(); /*! Find first occurrence of ba in QHexEdit data * \param ba Data to find * \param from Point where the search starts * \param isRegex regex on off switch * \param isCaseSensitive case sensitive on off switch * \return pos if found, else -1 */ qint64 indexOf(const QByteArray &ba, qint64 from, bool isRegex, bool isCaseSensitive); /*! Returns if any changes where done on document * \return true when document is modified else false */ bool isModified(); /*! Find last occurrence of ba in QHexEdit data * \param ba Data to find * \param from Point where the search starts * \return pos if fond, else -1 */ qint64 lastIndexOf(const QByteArray &ba, qint64 from); /*! Gives back a formatted image of the selected content of QHexEdit */ QString selectionToReadableString(); /*! Return the selected content of QHexEdit as QString HEX */ QString selectedData(); /*! Return the selected content of QHexEdit as QByteArray */ QByteArray selectedDataBa(); /*! Set Font of QHexEdit * \param font */ void setFont(const QFont &font); /*! Gives back a formatted image of the content of QHexEdit */ QString toReadableString(); QList *colorTag = NULL; public slots: /*! Redoes the last operation. If there is no operation to redo, i.e. there is no redo step in the undo/redo history, nothing happens. */ void redo(); /*! Undoes the last operation. If there is no operation to undo, i.e. there is no undo step in the undo/redo history, nothing happens. */ void undo(); signals: /*! Contains the address, where the cursor is located. */ void currentAddressChanged(qint64 address); /*! Contains the size of the data to edit. */ void currentSizeChanged(qint64 size); /*! The signal is emitted every time, the data is changed. */ void dataChanged(); /*! The signal is emitted every time, the overwrite mode is changed. */ void overwriteModeChanged(bool state); /*! \cond docNever */ public: ~QHexEdit(); // Properties bool addressArea(); void setAddressArea(bool addressArea); QColor addressAreaColor(); void setAddressAreaColor(const QColor &color); QColor addressFontColor(); void setAddressFontColor(const QColor &color); QColor asciiAreaColor(); void setAsciiAreaColor(const QColor &color); QColor asciiFontColor(); void setAsciiFontColor(const QColor &color); QColor hexFontColor(); void setHexFontColor(const QColor &color); qint64 addressOffset(); void setAddressOffset(qint64 addressArea); int addressWidth(); void setAddressWidth(int addressWidth); bool asciiArea(); void setAsciiArea(bool asciiArea); int bytesPerLine(); void setBytesPerLine(int count); qint64 cursorPosition(); void setCursorPosition(qint64 position); QByteArray data(); void setData(const QByteArray &ba); void setHexCaps(const bool isCaps); bool hexCaps(); void setDynamicBytesPerLine(const bool isDynamic); bool dynamicBytesPerLine(); bool highlighting(); void setHighlighting(bool mode); QColor highlightingColor(); void setHighlightingColor(const QColor &color); bool overwriteMode(); void setOverwriteMode(bool overwriteMode); bool isReadOnly(); void setReadOnly(bool readOnly); QColor selectionColor(); void setSelectionColor(const QColor &color); void resetSelection(qint64 pos); // set selectionStart and selectionEnd to pos void resetSelection(); // set selectionEnd to selectionStart void setSelection(qint64 pos); // set min (if below init) or max (if greater init) qint64 getSelectionBegin(); qint64 getSelectionEnd(); protected: // Handle events void keyPressEvent(QKeyEvent *event); void mouseMoveEvent(QMouseEvent * event); void mousePressEvent(QMouseEvent * event); void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *); virtual bool focusNextPrevChild(bool next); private: // Handle selections // Private utility functions void init(); void readBuffers(); QString toReadable(const QByteArray &ba); private slots: void adjust(); // recalc pixel positions void dataChangedPrivate(int idx=0); // emit dataChanged() signal void refresh(); // ensureVisible() and readBuffers() void updateCursor(); // update blinking cursor void showContextMenu(const QPoint &pos); void copyText(); void pasteText(); void cutText(); private: // Name convention: pixel positions start with _px int _pxCharWidth, _pxCharHeight; // char dimensions (dependend on font) int _pxPosHexX; // X-Pos of HeaxArea int _pxPosAdrX; // X-Pos of Address Area int _pxPosAsciiX; // X-Pos of Ascii Area int _pxGapAdr; // gap left from AddressArea int _pxGapAdrHex; // gap between AddressArea and HexAerea int _pxGapHexAscii; // gap between HexArea and AsciiArea int _pxCursorWidth; // cursor width int _pxSelectionSub; // offset selection rect int _pxCursorX; // current cursor pos int _pxCursorX2; // current cursor2 pos int _pxCursorY; // current cursor pos // Name convention: absolute byte positions in chunks start with _b qint64 _bSelectionBegin; // first position of Selection qint64 _bSelectionEnd; // end of Selection qint64 _bSelectionInit; // memory position of Selection qint64 _bPosFirst; // position of first byte shown qint64 _bPosLast; // position of last byte shown qint64 _bPosCurrent; // current position // variables to store the property values bool _addressArea; // left area of QHexEdit QColor _addressAreaColor; QColor _asciiAreaColor; QColor _addressFontColor; QColor _asciiFontColor; QColor _hexFontColor; int _addressWidth; bool _asciiArea; qint64 _addressOffset; int _bytesPerLine; int _hexCharsInLine; bool _highlighting; bool _overwriteMode; QBrush _brushSelection; QPen _penSelection; QBrush _brushHighlighted; QPen _penHighlighted; bool _readOnly; bool _hexCaps; bool _dynamicBytesPerLine; // other variables bool _editAreaIsAscii; // flag about the ascii mode edited int _addrDigits; // real no of addressdigits, may be > addressWidth bool _blink; // help get cursor blinking QBuffer _bData; // buffer, when setup with QByteArray Chunks *_chunks; // IODevice based access to data QTimer _cursorTimer; // for blinking cursor qint64 _cursorPosition; // absolute position of cursor, 1 Byte == 2 tics QRect _cursorRect; // physical dimensions of cursor QRect _cursorRect2; // physical dimensions of cursor QByteArray _data; // QHexEdit's data, when setup with QByteArray QByteArray _dataShown; // data in the current View QByteArray _hexDataShown; // data in view, transformed to hex qint64 _lastEventSize; // size, which was emitted last time QByteArray _markedShown; // marked data in view bool _modified; // Is any data in editor modified? int _rowsShown; // lines of text shown int _scrollMult; UndoStack * _undoStack; // Stack to store edit actions for undo/redo /*! \endcond docNever */ }; #endif // QHEXEDIT_H hexwalk-1.9.1/src/qhexedit/qhexeditplugin.pro0000664000175100017510000000135415005675407020713 0ustar carmixcarmix#! [0] #! [1] greaterThan(QT_MAJOR_VERSION, 4) { QT += widgets uiplugin } lessThan(QT_MAJOR_VERSION, 5) { CONFIG += designer } CONFIG += plugin #! [0] TARGET = $$qtLibraryTarget($$TARGET) #! [2] TEMPLATE = lib #! [1] #! [2] QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/designer #! [3] HEADERS = \ qhexedit.h \ chunks.h \ commands.h \ QHexEditPlugin.h SOURCES = \ qhexedit.cpp \ chunks.cpp \ commands.cpp \ QHexEditPlugin.cpp #! [3] # install target.path = $$[QT_INSTALL_PLUGINS]/designer sources.files = $$SOURCES $$HEADERS *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/designer/QHexEditPlugin INSTALLS += target symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) hexwalk-1.9.1/src/qhexedit/tagparser.cpp0000664000175100017510000001215315005675407017632 0ustar carmixcarmix#include #include #include #include #include "tagparser.hpp" #include YMLParser::YMLParser() { } void YMLParser::saveFile(std::string filename) { //qInfo()<<"Filename: "< 2 && pos != string::npos) { std::string key = line.substr(2,pos - 2); std::string value = line.substr(pos+1); value.erase(remove(value.begin(), value.end(), ' '), value.end()); cout<<"KEY: "<