├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── UsermodeProgram ├── Driver.h ├── Maths.h ├── stdafx.cpp ├── stdafx.h └── targetver.h └── hidden ├── Hidden.sln ├── Hidden ├── Configs.c ├── Configs.h ├── Device.c ├── Device.h ├── DeviceAPI.h ├── Driver.c ├── Driver.h ├── ExcludeList.c ├── ExcludeList.h ├── FsFilter.c ├── FsFilter.h ├── Helper.c ├── Helper.h ├── PsMonitor.c ├── PsMonitor.h ├── PsRules.c ├── PsRules.h ├── PsTable.c ├── PsTable.h ├── RegFilter.c └── RegFilter.h └── HiddenCLI ├── Commands.cpp ├── Commands.h ├── Connection.cpp ├── Connection.h ├── Helper.cpp ├── Helper.h ├── HiddenCLI.cpp ├── Hide.cpp ├── Hide.h ├── Ignore.cpp ├── Ignore.h ├── Protect.cpp ├── Protect.h ├── Query.cpp ├── Query.h ├── State.cpp ├── State.h └── cli.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | old shit bypass for EAC BE. 2 | -------------------------------------------------------------------------------- /UsermodeProgram/Driver.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stdafx.h" 3 | 4 | #define READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 5 | #define WRITE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 6 | #define SET_ID_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 7 | #define GET_MODULE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 8 | #define IO_READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 9 | 10 | namespace Offset { 11 | DWORD_PTR GameManager = 0x47F00D0; 12 | DWORD_PTR EntityList = 0xC0; 13 | 14 | DWORD_PTR Entity = 0x0008; 15 | DWORD_PTR EntityRef = 0x20; 16 | 17 | DWORD_PTR EntityInfo = 0x18; 18 | DWORD_PTR MainComponent = 0xB8; 19 | DWORD_PTR ChildComponent = 0x8; 20 | DWORD_PTR Health = 0x108; 21 | 22 | DWORD_PTR PlayerInfo = 0x2A0; 23 | DWORD_PTR PlayerInfoDeref = 0x0; 24 | DWORD_PTR PlayerTeamId = 0x140; 25 | DWORD_PTR PlayerName = 0x158; 26 | 27 | DWORD_PTR FeetPosition = 0x1C0; 28 | DWORD_PTR HeadPosition = 0x160; 29 | 30 | DWORD_PTR WeaponComp = 0x38; 31 | DWORD_PTR WeaponProcessor = 0xF0; 32 | DWORD_PTR Weapon = 0x0; 33 | DWORD_PTR WeaponInfo = 0x110; 34 | DWORD_PTR Spread = 0x2A0; 35 | DWORD_PTR Recoil = 0x2D8; 36 | DWORD_PTR Recoil2 = 0x354; 37 | DWORD_PTR Recoil3 = 0x304; 38 | DWORD_PTR AdsRecoil = 0x330; 39 | 40 | DWORD_PTR Renderer = 0x47A4930; 41 | DWORD_PTR GameRenderer = 0x0; 42 | DWORD_PTR EngineLink = 0xd8; 43 | DWORD_PTR Engine = 0x218; 44 | DWORD_PTR Camera = 0x38; 45 | 46 | DWORD_PTR ViewTranslastion = 0x1A0; 47 | DWORD_PTR ViewRight = 0x170; 48 | DWORD_PTR ViewUp = 0x180; 49 | DWORD_PTR ViewForward = 0x190; 50 | DWORD_PTR FOVX = 0x1B0; 51 | DWORD_PTR FOVY = 0x1C4; 52 | } 53 | 54 | typedef struct _READ_MEM 55 | { 56 | DWORD64 address; 57 | DWORD64 response; 58 | ULONG size; 59 | 60 | } READ_MEM, *PREAD_MEM; 61 | 62 | typedef struct _WRITE_MEM 63 | { 64 | DWORD64 address; 65 | float value; 66 | ULONG size; 67 | 68 | } WRITE_MEM, *PWRITE_MEM; 69 | 70 | class Wrappers 71 | { 72 | public: 73 | HANDLE hDriver; 74 | 75 | Wrappers(LPCSTR RegistryPath) 76 | { 77 | hDriver = CreateFileA(RegistryPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); 78 | } 79 | 80 | 81 | DWORD64 RPM(DWORD64 address, SIZE_T size) 82 | { 83 | READ_MEM read; 84 | 85 | read.address = address; 86 | read.size = size; 87 | 88 | if (DeviceIoControl(hDriver, READ_REQUEST, &read, sizeof(read), &read, sizeof(read), 0, 0)) 89 | return (DWORD64)read.response; 90 | else 91 | return false; 92 | } 93 | 94 | 95 | bool WPM(DWORD64 address, float value, SIZE_T size) 96 | { 97 | DWORD bytes; 98 | WRITE_MEM write; 99 | 100 | write.address = address; 101 | write.value = value; 102 | write.size = size; 103 | 104 | if (DeviceIoControl(hDriver, WRITE_REQUEST, &write, sizeof(write), 0, 0, &bytes, NULL)) 105 | return true; 106 | else 107 | return false; 108 | } 109 | 110 | 111 | DWORD SetTargetPid(DWORD PID) 112 | { 113 | DWORD Bytes; 114 | 115 | if (DeviceIoControl(hDriver, SET_ID_REQUEST, &PID, sizeof(PID), 0, 0, &Bytes, NULL)) 116 | return true; 117 | else 118 | return false; 119 | } 120 | 121 | DWORD64 GetMainModule() 122 | { 123 | DWORD64 MainModule; 124 | 125 | if (DeviceIoControl(hDriver, GET_MODULE_REQUEST, 0, 0, &MainModule, sizeof(MainModule), 0, 0)) 126 | return MainModule; 127 | else 128 | return false; 129 | } 130 | }; -------------------------------------------------------------------------------- /UsermodeProgram/Maths.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define M_PI 3.14159265358979323846264338327950288419716939937510 6 | 7 | 8 | class Vector2 9 | { 10 | public: 11 | Vector2() : x(0.f), y(0.f) 12 | { 13 | 14 | } 15 | 16 | Vector2(float _x, float _y) : x(_x), y(_y) 17 | { 18 | 19 | } 20 | ~Vector2() 21 | { 22 | 23 | } 24 | 25 | float x; 26 | float y; 27 | }; 28 | 29 | 30 | class Vector3 31 | { 32 | public: 33 | Vector3() : x(0.f), y(0.f), z(0.f) 34 | { 35 | 36 | } 37 | 38 | Vector3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) 39 | { 40 | 41 | } 42 | ~Vector3() 43 | { 44 | 45 | } 46 | 47 | float x; 48 | float y; 49 | float z; 50 | 51 | inline float Dot(Vector3 v) 52 | { 53 | return x * v.x + y * v.y + z * v.z; 54 | } 55 | 56 | inline float Distance(Vector3 v) 57 | { 58 | return float(sqrtf(powf(v.x - x, 2.0) + powf(v.y - y, 2.0) + powf(v.z - z, 2.0))); 59 | } 60 | 61 | Vector3 operator+(Vector3 v) 62 | { 63 | return Vector3(x + v.x, y + v.y, z + v.z); 64 | } 65 | 66 | Vector3 operator-(Vector3 v) 67 | { 68 | return Vector3(x - v.x, y - v.y, z - v.z); 69 | } 70 | 71 | Vector3 operator*(float number) const 72 | { 73 | return Vector3(x * number, y * number, z * number); 74 | } 75 | }; 76 | 77 | 78 | class Vector4 79 | { 80 | public: 81 | Vector4() : x(0.f), y(0.f), z(0.f), w(0.f) 82 | { 83 | 84 | } 85 | 86 | Vector4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) 87 | { 88 | 89 | } 90 | ~Vector4() 91 | { 92 | 93 | } 94 | 95 | float x; 96 | float y; 97 | float z; 98 | float w; 99 | }; -------------------------------------------------------------------------------- /UsermodeProgram/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x1-1/Battleye-VAC-EAC-Kernel-Bypass/0d8c1b80de27dcbbe232d7a3120bc3d13aafdc4d/UsermodeProgram/stdafx.cpp -------------------------------------------------------------------------------- /UsermodeProgram/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x1-1/Battleye-VAC-EAC-Kernel-Bypass/0d8c1b80de27dcbbe232d7a3120bc3d13aafdc4d/UsermodeProgram/stdafx.h -------------------------------------------------------------------------------- /UsermodeProgram/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x1-1/Battleye-VAC-EAC-Kernel-Bypass/0d8c1b80de27dcbbe232d7a3120bc3d13aafdc4d/UsermodeProgram/targetver.h -------------------------------------------------------------------------------- /hidden/Hidden.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27004.2009 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Hidden", "Hidden\Hidden.vcxproj", "{3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Release|Win32 = Release|Win32 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Debug|Win32.Build.0 = Debug|Win32 18 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Debug|Win32.Deploy.0 = Debug|Win32 19 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Debug|x64.ActiveCfg = Debug|x64 20 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Debug|x64.Build.0 = Debug|x64 21 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Debug|x64.Deploy.0 = Debug|x64 22 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Release|Win32.ActiveCfg = Release|Win32 23 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Release|Win32.Build.0 = Release|Win32 24 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Release|Win32.Deploy.0 = Release|Win32 25 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Release|x64.ActiveCfg = Release|x64 26 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Release|x64.Build.0 = Release|x64 27 | {3E4BBCD0-DC35-4825-9A8D-8686CDFAA6A8}.Release|x64.Deploy.0 = Release|x64 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | GlobalSection(ExtensibilityGlobals) = postSolution 33 | SolutionGuid = {C5D83A86-0F54-4BDA-AC4B-ADEB0BBB4B23} 34 | EndGlobalSection 35 | EndGlobal 36 | -------------------------------------------------------------------------------- /hidden/Hidden/Configs.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x1-1/Battleye-VAC-EAC-Kernel-Bypass/0d8c1b80de27dcbbe232d7a3120bc3d13aafdc4d/hidden/Hidden/Configs.c -------------------------------------------------------------------------------- /hidden/Hidden/Configs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | NTSTATUS InitializeConfigs(PUNICODE_STRING RegistryPath); 6 | NTSTATUS DestroyConfigs(); 7 | 8 | BOOLEAN CfgGetDriverState(); 9 | BOOLEAN CfgGetStealthState(); 10 | 11 | enum CfgMultiStringTables { 12 | HideFilesTable, 13 | HideDirsTable, 14 | HideRegKeysTable, 15 | HideRegValuesTable, 16 | IgnoreImagesTable, 17 | ProtectImagesTable, 18 | MaxTableEntries, 19 | }; 20 | 21 | typedef VOID(NTAPI*CfgMultiStringCallback)(PUNICODE_STRING str, PVOID Params); 22 | 23 | NTSTATUS CfgEnumConfigsTable(enum CfgMultiStringTables Table, CfgMultiStringCallback Callback, PVOID Params); 24 | -------------------------------------------------------------------------------- /hidden/Hidden/Device.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x1-1/Battleye-VAC-EAC-Kernel-Bypass/0d8c1b80de27dcbbe232d7a3120bc3d13aafdc4d/hidden/Hidden/Device.c -------------------------------------------------------------------------------- /hidden/Hidden/Device.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS InitializeDevice(PDRIVER_OBJECT DriverObject); 4 | NTSTATUS DestroyDevice(); 5 | -------------------------------------------------------------------------------- /hidden/Hidden/DeviceAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define DEVICE_NAME L"\\Device\\discordexp" 3 | #define DOS_DEVICES_LINK_NAME L"\\DosDevices\\discordexp" 4 | #define DEVICE_WIN32_NAME L"\\\\.\\discordexp" 5 | #define HID_IOCTL_SET_DRIVER_STATE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 0), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 6 | #define HID_IOCTL_GET_DRIVER_STATE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 1), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 7 | 8 | #define HID_IOCTL_SET_STEALTH_MODE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 2), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 9 | 10 | #define HID_IOCTL_ADD_HIDDEN_OBJECT CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 60), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 11 | #define HID_IOCTL_REMOVE_HIDDEN_OBJECT CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 61), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 12 | #define HID_IOCTL_REMOVE_ALL_HIDDEN_OBJECTS CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 62), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 13 | 14 | #define HID_IOCTL_ADD_OBJECT CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 70), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 15 | #define HID_IOCTL_GET_OBJECT_STATE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 71), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 16 | #define HID_IOCTL_SET_OBJECT_STATE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 72), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 17 | #define HID_IOCTL_REMOVE_OBJECT CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 73), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 18 | #define HID_IOCTL_REMOVE_ALL_OBJECTS CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800 + 74), METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 19 | enum Hid_ObjectTypes { 20 | RegKeyObject, 21 | RegValueObject, 22 | FsFileObject, 23 | FsDirObject, 24 | PsExcludedObject, 25 | PsProtectedObject, 26 | }; 27 | 28 | #pragma pack(push, 4) 29 | typedef struct _Hid_DriverStatusPacket { 30 | unsigned short state; 31 | unsigned short reserved; 32 | } Hid_DriverStatus, *PHid_DriverStatus; 33 | 34 | typedef struct _Hid_HideObjectPacket { 35 | unsigned short objType; 36 | unsigned short dataSize; 37 | } Hid_HideObjectPacket, *PHid_HideObjectPacket; 38 | 39 | typedef struct _Hid_UnhideObjectPacket { 40 | unsigned short objType; 41 | unsigned short reserved; 42 | unsigned long long id; 43 | } Hid_UnhideObjectPacket, *PHid_UnhideObjectPacket; 44 | 45 | typedef struct _Hid_UnhideAllObjectsPacket { 46 | unsigned short objType; 47 | unsigned short reserved; 48 | } Hid_UnhideAllObjectsPacket, *PHid_UnhideAllObjectsPacket; 49 | 50 | typedef struct _Hid_AddPsObjectPacket { 51 | unsigned short objType; 52 | unsigned short dataSize; 53 | unsigned short inheritType; 54 | unsigned short applyForProcesses; 55 | } Hid_AddPsObjectPacket, *PHid_AddPsObjectPacket; 56 | 57 | typedef struct _Hid_GetPsObjectInfoPacket { 58 | unsigned short objType; 59 | unsigned short inheritType; 60 | unsigned short enable; 61 | unsigned short reserved; 62 | unsigned long procId; 63 | } Hid_GetPsObjectInfoPacket, *PHid_GetPsObjectInfoPacket; 64 | 65 | typedef Hid_GetPsObjectInfoPacket Hid_SetPsObjectInfoPacket; 66 | typedef Hid_GetPsObjectInfoPacket* PHid_SetPsObjectInfoPacket; 67 | 68 | typedef struct _Hid_RemovePsObjectPacket { 69 | unsigned short objType; 70 | unsigned short reserved; 71 | unsigned long long id; 72 | } Hid_RemovePsObjectPacket, *PHid_RemovePsObjectPacket; 73 | 74 | typedef struct _Hid_RemoveAllPsObjectsPacket { 75 | unsigned short objType; 76 | unsigned short reserved; 77 | } Hid_RemoveAllPsObjectsPacket, *PHid_RemoveAllPsObjectsPacket; 78 | 79 | typedef struct _Hid_StatusPacket { 80 | unsigned int status; 81 | unsigned int dataSize; 82 | union { 83 | unsigned long long id; 84 | unsigned long state; 85 | } info; 86 | } Hid_StatusPacket, *PHid_StatusPacket; 87 | 88 | #pragma pack(pop) 89 | -------------------------------------------------------------------------------- /hidden/Hidden/Driver.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x1-1/Battleye-VAC-EAC-Kernel-Bypass/0d8c1b80de27dcbbe232d7a3120bc3d13aafdc4d/hidden/Hidden/Driver.c -------------------------------------------------------------------------------- /hidden/Hidden/Driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID EnableDisableDriver(BOOLEAN enabled); 4 | BOOLEAN IsDriverEnabled(); 5 | 6 | extern ULONG ProtectedProgramPID; 7 | extern ULONG LsassPID; 8 | extern ULONG CsrssPID; 9 | extern ULONG CsrssSecondPID; 10 | -------------------------------------------------------------------------------- /hidden/Hidden/ExcludeList.c: -------------------------------------------------------------------------------- 1 | #include "ExcludeList.h" 2 | #define EXCLUDE_ALLOC_TAG 'LcxE' 3 | 4 | typedef struct _EXCULE_FILE_PATH { 5 | UNICODE_STRING fullPath; 6 | UNICODE_STRING dirName; 7 | UNICODE_STRING fileName; 8 | } EXCULE_FILE_PATH, *PEXCULE_FILE_PATH; 9 | 10 | typedef struct _EXCLUDE_FILE_LIST_ENTRY { 11 | LIST_ENTRY list; 12 | ULONGLONG guid; 13 | ULONGLONG parentGuid; 14 | EXCULE_FILE_PATH path; 15 | } EXCLUDE_FILE_LIST_ENTRY, *PEXCLUDE_FILE_LIST_ENTRY; 16 | 17 | typedef struct _EXCLUDE_FILE_CONTEXT { 18 | LIST_ENTRY listHead; 19 | FAST_MUTEX listLock; 20 | ULONGLONG guidCounter; 21 | UINT32 childCounter; 22 | UINT32 type; 23 | } EXCLUDE_FILE_CONTEXT, *PEXCLUDE_FILE_CONTEXT; 24 | 25 | NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, UINT32 Type, PExcludeEntryId EntryId, ExcludeEntryId ParentId); 26 | 27 | BOOLEAN FillDirectoryFromPath(PEXCULE_FILE_PATH path, PUNICODE_STRING filePath); 28 | 29 | unsigned int GetCrc32(void* buf, unsigned int size, unsigned int ivect); 30 | 31 | NTSTATUS RtlDowncaseUnicodeString( 32 | PUNICODE_STRING DestinationString, 33 | _In_ PCUNICODE_STRING SourceString, 34 | _In_ BOOLEAN AllocateDestinationString 35 | ); 36 | 37 | // ========================================================================================== 38 | 39 | NTSTATUS InitializeExcludeListContext(PExcludeContext Context, UINT32 Type) 40 | { 41 | PEXCLUDE_FILE_CONTEXT cntx; 42 | 43 | if (Type >= ExcludeMaxType) 44 | { 45 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %d\n", Type); 46 | return STATUS_INVALID_MEMBER; 47 | } 48 | 49 | cntx = (PEXCLUDE_FILE_CONTEXT)ExAllocatePoolWithTag(NonPagedPool, sizeof(EXCLUDE_FILE_CONTEXT), EXCLUDE_ALLOC_TAG); 50 | if (!cntx) 51 | { 52 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %p\n", Context); 53 | return STATUS_ACCESS_DENIED; 54 | } 55 | 56 | InitializeListHead(&cntx->listHead); 57 | ExInitializeFastMutex(&cntx->listLock); 58 | cntx->guidCounter = 1; 59 | cntx->childCounter = 0; 60 | cntx->type = Type; 61 | 62 | *Context = cntx; 63 | 64 | return STATUS_SUCCESS; 65 | } 66 | 67 | VOID DestroyExcludeListContext(ExcludeContext Context) 68 | { 69 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 70 | RemoveAllExcludeListEntries(Context); 71 | ExFreePoolWithTag(cntx, EXCLUDE_ALLOC_TAG); 72 | } 73 | 74 | NTSTATUS AddExcludeListFile(ExcludeContext Context, PUNICODE_STRING FilePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) 75 | { 76 | return AddExcludeListEntry(Context, FilePath, ExcludeFile, EntryId, ParentId); 77 | } 78 | 79 | NTSTATUS AddExcludeListDirectory(ExcludeContext Context, PUNICODE_STRING DirPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) 80 | { 81 | return AddExcludeListEntry(Context, DirPath, ExcludeDirectory, EntryId, ParentId); 82 | } 83 | 84 | NTSTATUS AddExcludeListRegistryKey(ExcludeContext Context, PUNICODE_STRING KeyPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) 85 | { 86 | return AddExcludeListEntry(Context, KeyPath, ExcludeRegKey, EntryId, ParentId); 87 | } 88 | 89 | NTSTATUS AddExcludeListRegistryValue(ExcludeContext Context, PUNICODE_STRING ValuePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId) 90 | { 91 | return AddExcludeListEntry(Context, ValuePath, ExcludeRegValue, EntryId, ParentId); 92 | } 93 | 94 | NTSTATUS AddExcludeListEntry(ExcludeContext Context, PUNICODE_STRING FilePath, UINT32 Type, PExcludeEntryId EntryId, ExcludeEntryId ParentId) 95 | { 96 | enum { MAX_PATH_SIZE = 1024 }; 97 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 98 | PEXCLUDE_FILE_LIST_ENTRY entry, head; 99 | UNICODE_STRING temp; 100 | SIZE_T size; 101 | 102 | if (cntx->type != Type) 103 | { 104 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %d != %d\n", cntx->type, Type); 105 | return STATUS_INVALID_MEMBER; 106 | } 107 | 108 | if (FilePath->Length == 0 || FilePath->Length >= MAX_PATH_SIZE) 109 | { 110 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata : %d\n", (UINT32)FilePath->Length); 111 | return STATUS_ACCESS_DENIED; 112 | } 113 | 114 | // Allocate and fill new list entry 115 | 116 | size = sizeof(EXCLUDE_FILE_LIST_ENTRY) + FilePath->Length + sizeof(WCHAR); 117 | entry = ExAllocatePoolWithTag(NonPagedPool, size, EXCLUDE_ALLOC_TAG); 118 | if (entry == NULL) 119 | { 120 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata : %p\n", cntx); 121 | return STATUS_ACCESS_DENIED; 122 | } 123 | 124 | RtlZeroMemory(entry, size); 125 | 126 | temp.Buffer = (PWCH)((PCHAR)entry + sizeof(EXCLUDE_FILE_LIST_ENTRY)); 127 | temp.Length = 0; 128 | temp.MaximumLength = FilePath->Length; 129 | 130 | RtlCopyUnicodeString(&temp, FilePath); 131 | 132 | if (!FillDirectoryFromPath(&entry->path, &temp)) 133 | { 134 | ExFreePoolWithTag(entry, EXCLUDE_ALLOC_TAG); 135 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata : %p\n", cntx); 136 | return STATUS_ACCESS_DENIED; 137 | } 138 | 139 | 140 | 141 | if (Type == ExcludeRegKey || Type == ExcludeRegValue) 142 | { 143 | 144 | head = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 145 | while (head != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 146 | { 147 | INT res = RtlCompareUnicodeString(&entry->path.fullPath, &head->path.fullPath, TRUE); 148 | if (res <= 0) 149 | break; 150 | 151 | head = (PEXCLUDE_FILE_LIST_ENTRY)head->list.Flink; 152 | } 153 | } 154 | else 155 | { 156 | head = (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead; 157 | } 158 | 159 | 160 | entry->parentGuid = ParentId; 161 | 162 | ExAcquireFastMutex(&cntx->listLock); 163 | 164 | if (entry->parentGuid) 165 | cntx->childCounter++; 166 | 167 | entry->guid = cntx->guidCounter++; 168 | InsertTailList((PLIST_ENTRY)head, (PLIST_ENTRY)entry); 169 | 170 | ExReleaseFastMutex(&cntx->listLock); 171 | 172 | *EntryId = entry->guid; 173 | 174 | return STATUS_SUCCESS; 175 | } 176 | 177 | NTSTATUS RemoveExcludeListEntry(ExcludeContext Context, ExcludeEntryId EntryId) 178 | { 179 | NTSTATUS status = STATUS_NOT_FOUND; 180 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 181 | PEXCLUDE_FILE_LIST_ENTRY entry; 182 | 183 | ExAcquireFastMutex(&cntx->listLock); 184 | 185 | entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 186 | while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 187 | { 188 | if (EntryId == entry->guid) 189 | { 190 | RemoveEntryList((PLIST_ENTRY)entry); 191 | ExFreePoolWithTag(entry, EXCLUDE_ALLOC_TAG); 192 | status = STATUS_SUCCESS; 193 | break; 194 | } 195 | 196 | entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; 197 | } 198 | 199 | if (cntx->childCounter) 200 | { 201 | entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 202 | while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 203 | { 204 | PEXCLUDE_FILE_LIST_ENTRY remove = entry; 205 | entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; 206 | 207 | if (EntryId == remove->parentGuid) 208 | { 209 | ASSERT(cntx->childCounter > 0); 210 | cntx->childCounter--; 211 | RemoveEntryList((PLIST_ENTRY)remove); 212 | ExFreePoolWithTag(remove, EXCLUDE_ALLOC_TAG); 213 | } 214 | 215 | } 216 | } 217 | 218 | ExReleaseFastMutex(&cntx->listLock); 219 | 220 | return status; 221 | } 222 | 223 | NTSTATUS RemoveAllExcludeListEntries(ExcludeContext Context) 224 | { 225 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 226 | PEXCLUDE_FILE_LIST_ENTRY entry; 227 | 228 | ExAcquireFastMutex(&cntx->listLock); 229 | 230 | entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 231 | while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 232 | { 233 | PEXCLUDE_FILE_LIST_ENTRY remove = entry; 234 | entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; 235 | if (remove->parentGuid) 236 | { 237 | ASSERT(cntx->childCounter > 0); 238 | cntx->childCounter--; 239 | } 240 | RemoveEntryList((PLIST_ENTRY)remove); 241 | ExFreePoolWithTag(remove, EXCLUDE_ALLOC_TAG); 242 | } 243 | 244 | ASSERT(cntx->childCounter == 0); 245 | 246 | ExReleaseFastMutex(&cntx->listLock); 247 | 248 | return STATUS_SUCCESS; 249 | } 250 | 251 | BOOLEAN CheckExcludeListFile(ExcludeContext Context, PCUNICODE_STRING Path) 252 | { 253 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 254 | PEXCLUDE_FILE_LIST_ENTRY entry; 255 | BOOLEAN result = FALSE; 256 | 257 | ExAcquireFastMutex(&cntx->listLock); 258 | 259 | entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 260 | while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 261 | { 262 | if (RtlCompareUnicodeString(&entry->path.fullPath, Path, TRUE) == 0) 263 | { 264 | result = TRUE; 265 | break; 266 | } 267 | 268 | entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; 269 | } 270 | 271 | ExReleaseFastMutex(&cntx->listLock); 272 | 273 | return result; 274 | } 275 | 276 | BOOLEAN CheckExcludeListDirectory(ExcludeContext Context, PCUNICODE_STRING Path) 277 | { 278 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 279 | PEXCLUDE_FILE_LIST_ENTRY entry; 280 | UNICODE_STRING Directory, dir; 281 | BOOLEAN result = FALSE; 282 | 283 | Directory = *Path; 284 | if (Directory.Length > 0 && Directory.Buffer[Directory.Length / sizeof(WCHAR) - 1] == L'\\') 285 | Directory.Length -= sizeof(WCHAR); 286 | 287 | ExAcquireFastMutex(&cntx->listLock); 288 | 289 | entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 290 | while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 291 | { 292 | dir = Directory; 293 | 294 | if (dir.Length >= entry->path.fullPath.Length) 295 | { 296 | BOOLEAN compare = TRUE; 297 | 298 | if (dir.Length > entry->path.fullPath.Length) 299 | { 300 | if (dir.Buffer[entry->path.fullPath.Length / sizeof(WCHAR)] != L'\\') 301 | compare = FALSE; 302 | else 303 | dir.Length = entry->path.fullPath.Length; 304 | } 305 | 306 | if (compare && RtlCompareUnicodeString(&entry->path.fullPath, &dir, TRUE) == 0) 307 | { 308 | result = TRUE; 309 | break; 310 | } 311 | } 312 | 313 | entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; 314 | } 315 | 316 | ExReleaseFastMutex(&cntx->listLock); 317 | 318 | return result; 319 | } 320 | 321 | BOOLEAN CheckExcludeListDirFile(ExcludeContext Context, PCUNICODE_STRING Dir, PCUNICODE_STRING File) 322 | { 323 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 324 | PEXCLUDE_FILE_LIST_ENTRY entry; 325 | UNICODE_STRING Directory; 326 | BOOLEAN result = FALSE; 327 | 328 | Directory = *Dir; 329 | 330 | if (Directory.Length > 0 && Directory.Buffer[Directory.Length / sizeof(WCHAR) - 1] == L'\\') 331 | Directory.Length -= sizeof(WCHAR); 332 | 333 | ExAcquireFastMutex(&cntx->listLock); 334 | 335 | entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 336 | while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 337 | { 338 | if (RtlCompareUnicodeString(&entry->path.dirName, &Directory, TRUE) == 0 339 | && RtlCompareUnicodeString(&entry->path.fileName, File, TRUE) == 0) 340 | { 341 | result = TRUE; 342 | break; 343 | } 344 | 345 | entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; 346 | } 347 | 348 | ExReleaseFastMutex(&cntx->listLock); 349 | 350 | return result; 351 | } 352 | 353 | BOOLEAN CheckExcludeListRegKey(ExcludeContext Context, PUNICODE_STRING Key) 354 | { 355 | return CheckExcludeListDirectory(Context, Key); 356 | } 357 | 358 | BOOLEAN CheckExcludeListRegKeyValueName(ExcludeContext Context, PUNICODE_STRING Key, PUNICODE_STRING Name, PUINT32 Increament) 359 | { 360 | PEXCLUDE_FILE_CONTEXT cntx = (PEXCLUDE_FILE_CONTEXT)Context; 361 | PEXCLUDE_FILE_LIST_ENTRY entry; 362 | UNICODE_STRING Directory; 363 | BOOLEAN result = FALSE; 364 | 365 | Directory = *Key; 366 | *Increament = 0; 367 | 368 | if (Directory.Length > 0 && Directory.Buffer[Directory.Length / sizeof(WCHAR)-1] == L'\\') 369 | Directory.Length -= sizeof(WCHAR); 370 | 371 | ExAcquireFastMutex(&cntx->listLock); 372 | 373 | entry = (PEXCLUDE_FILE_LIST_ENTRY)cntx->listHead.Flink; 374 | while (entry != (PEXCLUDE_FILE_LIST_ENTRY)&cntx->listHead) 375 | { 376 | if (RtlCompareUnicodeString(&entry->path.dirName, &Directory, TRUE) == 0) 377 | { 378 | INT res; 379 | 380 | res = RtlCompareUnicodeString(&entry->path.fileName, Name, TRUE); 381 | if (res == 0) 382 | { 383 | (*Increament)++; 384 | result = TRUE; 385 | break; 386 | } 387 | else if (res < 0) 388 | { 389 | (*Increament)++; 390 | } 391 | else if (res > 0) 392 | { 393 | break; 394 | } 395 | } 396 | 397 | entry = (PEXCLUDE_FILE_LIST_ENTRY)entry->list.Flink; 398 | } 399 | 400 | ExReleaseFastMutex(&cntx->listLock); 401 | 402 | return result; 403 | } 404 | 405 | // ========================================================================================== 406 | 407 | BOOLEAN FillDirectoryFromPath(PEXCULE_FILE_PATH path, PUNICODE_STRING filePath) 408 | { 409 | USHORT i, count; 410 | LPWSTR buffer = filePath->Buffer; 411 | 412 | count = filePath->Length / sizeof(WCHAR); 413 | if (count < 1) 414 | return FALSE; 415 | 416 | i = count; 417 | do 418 | { 419 | i--; 420 | 421 | if (buffer[i] == L'\\') 422 | { 423 | if (i + 1 >= count) 424 | return FALSE; 425 | 426 | path->fileName.Buffer = buffer + i + 1; 427 | path->fileName.Length = (count - i - 1) * sizeof(WCHAR); 428 | path->fileName.MaximumLength = path->fileName.Length; 429 | 430 | path->fullPath = *filePath; 431 | 432 | path->dirName.Buffer = filePath->Buffer; 433 | path->dirName.Length = i * sizeof(WCHAR); 434 | path->dirName.MaximumLength = path->dirName.Length; 435 | 436 | return TRUE; 437 | } 438 | } 439 | while (i > 0); 440 | 441 | return FALSE; 442 | } 443 | static const unsigned int g_crc32Table [256] = { 444 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 445 | 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 446 | 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 447 | 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 448 | 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 449 | 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 450 | 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 451 | 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 452 | 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 453 | 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 454 | 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 455 | 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 456 | 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 457 | 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 458 | 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 459 | 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 460 | 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 461 | 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 462 | 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 463 | 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 464 | 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 465 | 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 466 | 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 467 | 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 468 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 469 | 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 470 | 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 471 | 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 472 | 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 473 | 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 474 | 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 475 | 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 476 | 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 477 | 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 478 | 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 479 | 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 480 | 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 481 | }; 482 | 483 | unsigned int GetCrc32(void* buf, unsigned int size, unsigned int ivect) 484 | { 485 | unsigned char *src = (unsigned char*)buf; 486 | unsigned int crc = ~ivect; 487 | 488 | while (size--) 489 | crc = (crc >> 8) ^ g_crc32Table[(crc ^ *src++) & 0xFF]; 490 | 491 | return 0xFFFFFFFF ^ crc; 492 | } 493 | -------------------------------------------------------------------------------- /hidden/Hidden/ExcludeList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | enum ExcludeObjectType { 5 | ExcludeFile, 6 | ExcludeDirectory, 7 | ExcludeRegKey, 8 | ExcludeRegValue , 9 | ExcludeMaxType, 10 | }; 11 | 12 | typedef PVOID ExcludeContext; 13 | typedef ExcludeContext* PExcludeContext; 14 | 15 | typedef ULONGLONG ExcludeEntryId; 16 | typedef ExcludeEntryId* PExcludeEntryId; 17 | 18 | typedef ULONGLONG ExcludeEnumId; 19 | typedef ExcludeEnumId* PExcludeEnumId; 20 | 21 | NTSTATUS InitializeExcludeListContext(PExcludeContext Context, UINT32 Type); 22 | VOID DestroyExcludeListContext(ExcludeContext Context); 23 | 24 | NTSTATUS AddExcludeListFile(ExcludeContext Context, PUNICODE_STRING FilePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); 25 | NTSTATUS AddExcludeListDirectory(ExcludeContext Context, PUNICODE_STRING DirPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); 26 | NTSTATUS AddExcludeListRegistryKey(ExcludeContext Context, PUNICODE_STRING KeyPath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); 27 | NTSTATUS AddExcludeListRegistryValue(ExcludeContext Context, PUNICODE_STRING ValuePath, PExcludeEntryId EntryId, ExcludeEntryId ParentId); 28 | 29 | NTSTATUS RemoveExcludeListEntry(ExcludeContext Context, ExcludeEntryId EntryId); 30 | NTSTATUS RemoveAllExcludeListEntries(ExcludeContext Context); 31 | 32 | BOOLEAN CheckExcludeListFile(ExcludeContext Context, PCUNICODE_STRING Path); 33 | BOOLEAN CheckExcludeListDirectory(ExcludeContext Context, PCUNICODE_STRING Path); 34 | BOOLEAN CheckExcludeListDirFile(ExcludeContext Context, PCUNICODE_STRING Dir, PCUNICODE_STRING File); 35 | 36 | BOOLEAN CheckExcludeListRegKey(ExcludeContext Context, PUNICODE_STRING Key); 37 | BOOLEAN CheckExcludeListRegKeyValueName(ExcludeContext Context, PUNICODE_STRING Key, PUNICODE_STRING Name, PUINT32 Increament); 38 | -------------------------------------------------------------------------------- /hidden/Hidden/FsFilter.c: -------------------------------------------------------------------------------- 1 | // ========================================================================================= 2 | // Filesystem Minifilter 3 | // ========================================================================================= 4 | 5 | #include 6 | #include "ExcludeList.h" 7 | #include "FsFilter.h" 8 | #include "Helper.h" 9 | #include "PsMonitor.h" 10 | #include "Driver.h" 11 | #include "Configs.h" 12 | 13 | #define FSFILTER_ALLOC_TAG 'DHlF' 14 | 15 | NTSTATUS FilterSetup(PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType); 16 | 17 | FLT_PREOP_CALLBACK_STATUS FltCreatePreOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext); 18 | //FLT_POSTOP_CALLBACK_STATUS FltCreatePostOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags); 19 | FLT_PREOP_CALLBACK_STATUS FltDirCtrlPreOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext); 20 | FLT_POSTOP_CALLBACK_STATUS FltDirCtrlPostOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags); 21 | 22 | NTSTATUS CleanFileFullDirectoryInformation(PFILE_FULL_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName); 23 | NTSTATUS CleanFileBothDirectoryInformation(PFILE_BOTH_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName); 24 | NTSTATUS CleanFileDirectoryInformation(PFILE_DIRECTORY_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName); 25 | NTSTATUS CleanFileIdFullDirectoryInformation(PFILE_ID_FULL_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName); 26 | NTSTATUS CleanFileIdBothDirectoryInformation(PFILE_ID_BOTH_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName); 27 | NTSTATUS CleanFileNamesInformation(PFILE_NAMES_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName); 28 | 29 | 30 | const FLT_CONTEXT_REGISTRATION Contexts[] = { 31 | { FLT_CONTEXT_END } 32 | }; 33 | 34 | CONST FLT_OPERATION_REGISTRATION Callbacks[] = { 35 | { IRP_MJ_CREATE, 0, FltCreatePreOperation, NULL }, 36 | { IRP_MJ_DIRECTORY_CONTROL, 0, FltDirCtrlPreOperation, FltDirCtrlPostOperation }, 37 | { IRP_MJ_OPERATION_END } 38 | }; 39 | 40 | CONST FLT_REGISTRATION FilterRegistration = { 41 | sizeof(FLT_REGISTRATION), 42 | FLT_REGISTRATION_VERSION, 43 | FLTFL_REGISTRATION_DO_NOT_SUPPORT_SERVICE_STOP, 44 | Contexts, 45 | Callbacks, 46 | NULL, 47 | FilterSetup, 48 | NULL, 49 | NULL, 50 | NULL, 51 | NULL, 52 | NULL, 53 | NULL 54 | }; 55 | 56 | BOOLEAN g_fsMonitorInited = FALSE; 57 | PFLT_FILTER gFilterHandle = NULL; 58 | 59 | ExcludeContext g_excludeFileContext; 60 | ExcludeContext g_excludeDirectoryContext; 61 | 62 | CONST PWCHAR g_excludeFiles[] = { 63 | NULL 64 | }; 65 | CONST PWCHAR g_excludeDirs[] = { 66 | NULL 67 | }; 68 | 69 | NTSTATUS FilterSetup(PCFLT_RELATED_OBJECTS FltObjects, FLT_INSTANCE_SETUP_FLAGS Flags, DEVICE_TYPE VolumeDeviceType, FLT_FILESYSTEM_TYPE VolumeFilesystemType) 70 | { 71 | UNREFERENCED_PARAMETER(FltObjects); 72 | UNREFERENCED_PARAMETER(Flags); 73 | UNREFERENCED_PARAMETER(VolumeDeviceType); 74 | UNREFERENCED_PARAMETER(VolumeFilesystemType); 75 | 76 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata %d\n", (UINT32)KeGetCurrentIrql()); 77 | 78 | return STATUS_SUCCESS; 79 | } 80 | 81 | enum { 82 | FoundExcludeFile = 1, 83 | FoundExcludeDir = 2, 84 | }; 85 | 86 | FLT_PREOP_CALLBACK_STATUS FltCreatePreOperation( 87 | _Inout_ PFLT_CALLBACK_DATA Data, 88 | _In_ PCFLT_RELATED_OBJECTS FltObjects, 89 | _Flt_CompletionContext_Outptr_ PVOID *CompletionContext) 90 | { 91 | UINT32 disposition, options; 92 | PFLT_FILE_NAME_INFORMATION fltName; 93 | NTSTATUS status; 94 | BOOLEAN neededPrevent = FALSE; 95 | 96 | UNREFERENCED_PARAMETER(FltObjects); 97 | UNREFERENCED_PARAMETER(CompletionContext); 98 | 99 | if (!IsDriverEnabled()) 100 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 101 | 102 | 103 | 104 | if (IsProcessExcluded(PsGetCurrentProcessId())) 105 | { 106 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 107 | } 108 | 109 | options = Data->Iopb->Parameters.Create.Options & 0x00FFFFFF; 110 | disposition = (Data->Iopb->Parameters.Create.Options & 0xFF000000) >> 24; 111 | 112 | status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED, &fltName); 113 | if (!NT_SUCCESS(status)) 114 | { 115 | if (status != STATUS_OBJECT_PATH_NOT_FOUND) 116 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 117 | 118 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 119 | } 120 | 121 | if (!(options & FILE_DIRECTORY_FILE)) 122 | { 123 | // If it is create file event 124 | if (CheckExcludeListDirectory(g_excludeFileContext, &fltName->Name)) 125 | neededPrevent = TRUE; 126 | } 127 | 128 | // If it is create directory/file event 129 | if (!neededPrevent && CheckExcludeListDirectory(g_excludeDirectoryContext, &fltName->Name)) 130 | neededPrevent = TRUE; 131 | 132 | FltReleaseFileNameInformation(fltName); 133 | 134 | if (neededPrevent) 135 | { 136 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ, %p\n", &Data->Iopb->TargetFileObject->FileName, PsGetCurrentProcessId()); 137 | Data->IoStatus.Status = STATUS_NO_SUCH_FILE; 138 | return FLT_PREOP_COMPLETE; 139 | } 140 | 141 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 142 | } 143 | 144 | FLT_PREOP_CALLBACK_STATUS FltDirCtrlPreOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext) 145 | { 146 | UNREFERENCED_PARAMETER(FltObjects); 147 | UNREFERENCED_PARAMETER(CompletionContext); 148 | 149 | if (!IsDriverEnabled()) 150 | return FLT_POSTOP_FINISHED_PROCESSING; 151 | 152 | 153 | 154 | if (Data->Iopb->MinorFunction != IRP_MN_QUERY_DIRECTORY) 155 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 156 | 157 | switch (Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileInformationClass) 158 | { 159 | case FileIdFullDirectoryInformation: 160 | case FileIdBothDirectoryInformation: 161 | case FileBothDirectoryInformation: 162 | case FileDirectoryInformation: 163 | case FileFullDirectoryInformation: 164 | case FileNamesInformation: 165 | break; 166 | default: 167 | return FLT_PREOP_SUCCESS_NO_CALLBACK; 168 | } 169 | 170 | return FLT_PREOP_SUCCESS_WITH_CALLBACK; 171 | } 172 | 173 | FLT_POSTOP_CALLBACK_STATUS FltDirCtrlPostOperation(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags) 174 | { 175 | PFLT_PARAMETERS params = &Data->Iopb->Parameters; 176 | PFLT_FILE_NAME_INFORMATION fltName; 177 | NTSTATUS status; 178 | 179 | UNREFERENCED_PARAMETER(FltObjects); 180 | UNREFERENCED_PARAMETER(CompletionContext); 181 | UNREFERENCED_PARAMETER(Flags); 182 | 183 | if (!IsDriverEnabled()) 184 | return FLT_POSTOP_FINISHED_PROCESSING; 185 | 186 | if (!NT_SUCCESS(Data->IoStatus.Status)) 187 | return FLT_POSTOP_FINISHED_PROCESSING; 188 | 189 | 190 | 191 | if (IsProcessExcluded(PsGetCurrentProcessId())) 192 | { 193 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata %p\n", PsGetCurrentProcessId()); 194 | return FLT_POSTOP_FINISHED_PROCESSING; 195 | } 196 | 197 | status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED, &fltName); 198 | if (!NT_SUCCESS(status)) 199 | { 200 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 201 | return FLT_POSTOP_FINISHED_PROCESSING; 202 | } 203 | 204 | __try 205 | { 206 | status = STATUS_SUCCESS; 207 | 208 | switch (params->DirectoryControl.QueryDirectory.FileInformationClass) 209 | { 210 | case FileFullDirectoryInformation: 211 | status = CleanFileFullDirectoryInformation((PFILE_FULL_DIR_INFORMATION)params->DirectoryControl.QueryDirectory.DirectoryBuffer, fltName); 212 | break; 213 | case FileBothDirectoryInformation: 214 | status = CleanFileBothDirectoryInformation((PFILE_BOTH_DIR_INFORMATION)params->DirectoryControl.QueryDirectory.DirectoryBuffer, fltName); 215 | break; 216 | case FileDirectoryInformation: 217 | status = CleanFileDirectoryInformation((PFILE_DIRECTORY_INFORMATION)params->DirectoryControl.QueryDirectory.DirectoryBuffer, fltName); 218 | break; 219 | case FileIdFullDirectoryInformation: 220 | status = CleanFileIdFullDirectoryInformation((PFILE_ID_FULL_DIR_INFORMATION)params->DirectoryControl.QueryDirectory.DirectoryBuffer, fltName); 221 | break; 222 | case FileIdBothDirectoryInformation: 223 | status = CleanFileIdBothDirectoryInformation((PFILE_ID_BOTH_DIR_INFORMATION)params->DirectoryControl.QueryDirectory.DirectoryBuffer, fltName); 224 | break; 225 | case FileNamesInformation: 226 | status = CleanFileNamesInformation((PFILE_NAMES_INFORMATION)params->DirectoryControl.QueryDirectory.DirectoryBuffer, fltName); 227 | break; 228 | } 229 | 230 | Data->IoStatus.Status = status; 231 | } 232 | __finally 233 | { 234 | FltReleaseFileNameInformation(fltName); 235 | } 236 | 237 | return FLT_POSTOP_FINISHED_PROCESSING; 238 | } 239 | 240 | NTSTATUS CleanFileFullDirectoryInformation(PFILE_FULL_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName) 241 | { 242 | PFILE_FULL_DIR_INFORMATION nextInfo, prevInfo = NULL; 243 | UNICODE_STRING fileName; 244 | UINT32 offset, moveLength; 245 | BOOLEAN matched, search; 246 | NTSTATUS status = STATUS_SUCCESS; 247 | 248 | offset = 0; 249 | search = TRUE; 250 | 251 | do 252 | { 253 | fileName.Buffer = info->FileName; 254 | fileName.Length = (USHORT)info->FileNameLength; 255 | fileName.MaximumLength = (USHORT)info->FileNameLength; 256 | 257 | if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) 258 | matched = CheckExcludeListDirFile(g_excludeDirectoryContext, &fltName->Name, &fileName); 259 | else 260 | matched = CheckExcludeListDirFile(g_excludeFileContext, &fltName->Name, &fileName); 261 | 262 | if (matched) 263 | { 264 | BOOLEAN retn = FALSE; 265 | 266 | if (prevInfo != NULL) 267 | { 268 | if (info->NextEntryOffset != 0) 269 | { 270 | prevInfo->NextEntryOffset += info->NextEntryOffset; 271 | offset = info->NextEntryOffset; 272 | } 273 | else 274 | { 275 | prevInfo->NextEntryOffset = 0; 276 | status = STATUS_SUCCESS; 277 | retn = TRUE; 278 | } 279 | 280 | RtlFillMemory(info, sizeof(FILE_FULL_DIR_INFORMATION), 0); 281 | } 282 | else 283 | { 284 | if (info->NextEntryOffset != 0) 285 | { 286 | nextInfo = (PFILE_FULL_DIR_INFORMATION)((PUCHAR)info + info->NextEntryOffset); 287 | moveLength = 0; 288 | while (nextInfo->NextEntryOffset != 0) 289 | { 290 | moveLength += nextInfo->NextEntryOffset; 291 | nextInfo = (PFILE_FULL_DIR_INFORMATION)((PUCHAR)nextInfo + nextInfo->NextEntryOffset); 292 | } 293 | 294 | moveLength += FIELD_OFFSET(FILE_FULL_DIR_INFORMATION, FileName) + nextInfo->FileNameLength; 295 | RtlMoveMemory(info, (PUCHAR)info + info->NextEntryOffset, moveLength);//continue 296 | } 297 | else 298 | { 299 | status = STATUS_NO_MORE_ENTRIES; 300 | retn = TRUE; 301 | } 302 | } 303 | 304 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\\%wZ\n", &fltName->Name, &fileName); 305 | 306 | if (retn) 307 | return status; 308 | 309 | info = (PFILE_FULL_DIR_INFORMATION)((PCHAR)info + offset); 310 | continue; 311 | } 312 | 313 | offset = info->NextEntryOffset; 314 | prevInfo = info; 315 | info = (PFILE_FULL_DIR_INFORMATION)((PCHAR)info + offset); 316 | 317 | if (offset == 0) 318 | search = FALSE; 319 | } while (search); 320 | 321 | return STATUS_SUCCESS; 322 | } 323 | 324 | NTSTATUS CleanFileBothDirectoryInformation(PFILE_BOTH_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName) 325 | { 326 | PFILE_BOTH_DIR_INFORMATION nextInfo, prevInfo = NULL; 327 | UNICODE_STRING fileName; 328 | UINT32 offset, moveLength; 329 | BOOLEAN matched, search; 330 | NTSTATUS status = STATUS_SUCCESS; 331 | 332 | offset = 0; 333 | search = TRUE; 334 | 335 | do 336 | { 337 | fileName.Buffer = info->FileName; 338 | fileName.Length = (USHORT)info->FileNameLength; 339 | fileName.MaximumLength = (USHORT)info->FileNameLength; 340 | 341 | if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) 342 | matched = CheckExcludeListDirFile(g_excludeDirectoryContext, &fltName->Name, &fileName); 343 | else 344 | matched = CheckExcludeListDirFile(g_excludeFileContext, &fltName->Name, &fileName); 345 | 346 | if (matched) 347 | { 348 | BOOLEAN retn = FALSE; 349 | 350 | if (prevInfo != NULL) 351 | { 352 | if (info->NextEntryOffset != 0) 353 | { 354 | prevInfo->NextEntryOffset += info->NextEntryOffset; 355 | offset = info->NextEntryOffset; 356 | } 357 | else 358 | { 359 | prevInfo->NextEntryOffset = 0; 360 | status = STATUS_SUCCESS; 361 | retn = TRUE; 362 | } 363 | 364 | RtlFillMemory(info, sizeof(FILE_BOTH_DIR_INFORMATION), 0); 365 | } 366 | else 367 | { 368 | if (info->NextEntryOffset != 0) 369 | { 370 | nextInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)info + info->NextEntryOffset); 371 | moveLength = 0; 372 | while (nextInfo->NextEntryOffset != 0) 373 | { 374 | moveLength += nextInfo->NextEntryOffset; 375 | nextInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)nextInfo + nextInfo->NextEntryOffset); 376 | } 377 | 378 | moveLength += FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName) + nextInfo->FileNameLength; 379 | RtlMoveMemory(info, (PUCHAR)info + info->NextEntryOffset, moveLength);//continue 380 | } 381 | else 382 | { 383 | status = STATUS_NO_MORE_ENTRIES; 384 | retn = TRUE; 385 | } 386 | } 387 | 388 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\\%wZ\n", &fltName->Name, &fileName); 389 | 390 | if (retn) 391 | return status; 392 | 393 | info = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)info + offset); 394 | continue; 395 | } 396 | 397 | offset = info->NextEntryOffset; 398 | prevInfo = info; 399 | info = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)info + offset); 400 | 401 | if (offset == 0) 402 | search = FALSE; 403 | } while (search); 404 | 405 | return STATUS_SUCCESS; 406 | } 407 | 408 | NTSTATUS CleanFileDirectoryInformation(PFILE_DIRECTORY_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName) 409 | { 410 | PFILE_DIRECTORY_INFORMATION nextInfo, prevInfo = NULL; 411 | UNICODE_STRING fileName; 412 | UINT32 offset, moveLength; 413 | BOOLEAN matched, search; 414 | NTSTATUS status = STATUS_SUCCESS; 415 | 416 | offset = 0; 417 | search = TRUE; 418 | 419 | do 420 | { 421 | fileName.Buffer = info->FileName; 422 | fileName.Length = (USHORT)info->FileNameLength; 423 | fileName.MaximumLength = (USHORT)info->FileNameLength; 424 | 425 | if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) 426 | matched = CheckExcludeListDirFile(g_excludeDirectoryContext, &fltName->Name, &fileName); 427 | else 428 | matched = CheckExcludeListDirFile(g_excludeFileContext, &fltName->Name, &fileName); 429 | 430 | if (matched) 431 | { 432 | BOOLEAN retn = FALSE; 433 | 434 | if (prevInfo != NULL) 435 | { 436 | if (info->NextEntryOffset != 0) 437 | { 438 | prevInfo->NextEntryOffset += info->NextEntryOffset; 439 | offset = info->NextEntryOffset; 440 | } 441 | else 442 | { 443 | prevInfo->NextEntryOffset = 0; 444 | status = STATUS_SUCCESS; 445 | retn = TRUE; 446 | } 447 | 448 | RtlFillMemory(info, sizeof(FILE_DIRECTORY_INFORMATION), 0); 449 | } 450 | else 451 | { 452 | if (info->NextEntryOffset != 0) 453 | { 454 | nextInfo = (PFILE_DIRECTORY_INFORMATION)((PUCHAR)info + info->NextEntryOffset); 455 | moveLength = 0; 456 | while (nextInfo->NextEntryOffset != 0) 457 | { 458 | moveLength += nextInfo->NextEntryOffset; 459 | nextInfo = (PFILE_DIRECTORY_INFORMATION)((PUCHAR)nextInfo + nextInfo->NextEntryOffset); 460 | } 461 | 462 | moveLength += FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName) + nextInfo->FileNameLength; 463 | RtlMoveMemory(info, (PUCHAR)info + info->NextEntryOffset, moveLength);//continue 464 | } 465 | else 466 | { 467 | status = STATUS_NO_MORE_ENTRIES; 468 | retn = TRUE; 469 | } 470 | } 471 | 472 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\\%wZ\n", &fltName->Name, &fileName); 473 | 474 | if (retn) 475 | return status; 476 | 477 | info = (PFILE_DIRECTORY_INFORMATION)((PCHAR)info + offset); 478 | continue; 479 | } 480 | 481 | offset = info->NextEntryOffset; 482 | prevInfo = info; 483 | info = (PFILE_DIRECTORY_INFORMATION)((PCHAR)info + offset); 484 | 485 | if (offset == 0) 486 | search = FALSE; 487 | } while (search); 488 | 489 | return STATUS_SUCCESS; 490 | } 491 | 492 | NTSTATUS CleanFileIdFullDirectoryInformation(PFILE_ID_FULL_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName) 493 | { 494 | PFILE_ID_FULL_DIR_INFORMATION nextInfo, prevInfo = NULL; 495 | UNICODE_STRING fileName; 496 | UINT32 offset, moveLength; 497 | BOOLEAN matched, search; 498 | NTSTATUS status = STATUS_SUCCESS; 499 | 500 | offset = 0; 501 | search = TRUE; 502 | 503 | do 504 | { 505 | fileName.Buffer = info->FileName; 506 | fileName.Length = (USHORT)info->FileNameLength; 507 | fileName.MaximumLength = (USHORT)info->FileNameLength; 508 | 509 | if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) 510 | matched = CheckExcludeListDirFile(g_excludeDirectoryContext, &fltName->Name, &fileName); 511 | else 512 | matched = CheckExcludeListDirFile(g_excludeFileContext, &fltName->Name, &fileName); 513 | 514 | if (matched) 515 | { 516 | BOOLEAN retn = FALSE; 517 | 518 | if (prevInfo != NULL) 519 | { 520 | if (info->NextEntryOffset != 0) 521 | { 522 | prevInfo->NextEntryOffset += info->NextEntryOffset; 523 | offset = info->NextEntryOffset; 524 | } 525 | else 526 | { 527 | prevInfo->NextEntryOffset = 0; 528 | status = STATUS_SUCCESS; 529 | retn = TRUE; 530 | } 531 | 532 | RtlFillMemory(info, sizeof(FILE_ID_FULL_DIR_INFORMATION), 0); 533 | } 534 | else 535 | { 536 | if (info->NextEntryOffset != 0) 537 | { 538 | nextInfo = (PFILE_ID_FULL_DIR_INFORMATION)((PUCHAR)info + info->NextEntryOffset); 539 | moveLength = 0; 540 | while (nextInfo->NextEntryOffset != 0) 541 | { 542 | moveLength += nextInfo->NextEntryOffset; 543 | nextInfo = (PFILE_ID_FULL_DIR_INFORMATION)((PUCHAR)nextInfo + nextInfo->NextEntryOffset); 544 | } 545 | 546 | moveLength += FIELD_OFFSET(FILE_ID_FULL_DIR_INFORMATION, FileName) + nextInfo->FileNameLength; 547 | RtlMoveMemory(info, (PUCHAR)info + info->NextEntryOffset, moveLength);//continue 548 | } 549 | else 550 | { 551 | status = STATUS_NO_MORE_ENTRIES; 552 | retn = TRUE; 553 | } 554 | } 555 | 556 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\\%wZ\n", &fltName->Name, &fileName); 557 | 558 | if (retn) 559 | return status; 560 | 561 | info = (PFILE_ID_FULL_DIR_INFORMATION)((PCHAR)info + offset); 562 | continue; 563 | } 564 | 565 | offset = info->NextEntryOffset; 566 | prevInfo = info; 567 | info = (PFILE_ID_FULL_DIR_INFORMATION)((PCHAR)info + offset); 568 | 569 | if (offset == 0) 570 | search = FALSE; 571 | } while (search); 572 | 573 | return STATUS_SUCCESS; 574 | } 575 | 576 | NTSTATUS CleanFileIdBothDirectoryInformation(PFILE_ID_BOTH_DIR_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName) 577 | { 578 | PFILE_ID_BOTH_DIR_INFORMATION nextInfo, prevInfo = NULL; 579 | UNICODE_STRING fileName; 580 | UINT32 offset, moveLength; 581 | BOOLEAN matched, search; 582 | NTSTATUS status = STATUS_SUCCESS; 583 | 584 | offset = 0; 585 | search = TRUE; 586 | 587 | do 588 | { 589 | fileName.Buffer = info->FileName; 590 | fileName.Length = (USHORT)info->FileNameLength; 591 | fileName.MaximumLength = (USHORT)info->FileNameLength; 592 | 593 | if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) 594 | matched = CheckExcludeListDirFile(g_excludeDirectoryContext, &fltName->Name, &fileName); 595 | else 596 | matched = CheckExcludeListDirFile(g_excludeFileContext, &fltName->Name, &fileName); 597 | 598 | if (matched) 599 | { 600 | BOOLEAN retn = FALSE; 601 | 602 | if (prevInfo != NULL) 603 | { 604 | if (info->NextEntryOffset != 0) 605 | { 606 | prevInfo->NextEntryOffset += info->NextEntryOffset; 607 | offset = info->NextEntryOffset; 608 | } 609 | else 610 | { 611 | prevInfo->NextEntryOffset = 0; 612 | status = STATUS_SUCCESS; 613 | retn = TRUE; 614 | } 615 | 616 | RtlFillMemory(info, sizeof(FILE_ID_BOTH_DIR_INFORMATION), 0); 617 | } 618 | else 619 | { 620 | if (info->NextEntryOffset != 0) 621 | { 622 | nextInfo = (PFILE_ID_BOTH_DIR_INFORMATION)((PUCHAR)info + info->NextEntryOffset); 623 | moveLength = 0; 624 | while (nextInfo->NextEntryOffset != 0) 625 | { 626 | moveLength += nextInfo->NextEntryOffset; 627 | nextInfo = (PFILE_ID_BOTH_DIR_INFORMATION)((PUCHAR)nextInfo + nextInfo->NextEntryOffset); 628 | } 629 | 630 | moveLength += FIELD_OFFSET(FILE_ID_BOTH_DIR_INFORMATION, FileName) + nextInfo->FileNameLength; 631 | RtlMoveMemory(info, (PUCHAR)info + info->NextEntryOffset, moveLength);//continue 632 | } 633 | else 634 | { 635 | status = STATUS_NO_MORE_ENTRIES; 636 | retn = TRUE; 637 | } 638 | } 639 | 640 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\\%wZ\n", &fltName->Name, &fileName); 641 | 642 | if (retn) 643 | return status; 644 | 645 | info = (PFILE_ID_BOTH_DIR_INFORMATION)((PCHAR)info + offset); 646 | continue; 647 | } 648 | 649 | offset = info->NextEntryOffset; 650 | prevInfo = info; 651 | info = (PFILE_ID_BOTH_DIR_INFORMATION)((PCHAR)info + offset); 652 | 653 | if (offset == 0) 654 | search = FALSE; 655 | } while (search); 656 | 657 | return status; 658 | } 659 | 660 | NTSTATUS CleanFileNamesInformation(PFILE_NAMES_INFORMATION info, PFLT_FILE_NAME_INFORMATION fltName) 661 | { 662 | PFILE_NAMES_INFORMATION nextInfo, prevInfo = NULL; 663 | UNICODE_STRING fileName; 664 | UINT32 offset, moveLength; 665 | BOOLEAN search; 666 | NTSTATUS status = STATUS_SUCCESS; 667 | 668 | offset = 0; 669 | search = TRUE; 670 | 671 | do 672 | { 673 | fileName.Buffer = info->FileName; 674 | fileName.Length = (USHORT)info->FileNameLength; 675 | fileName.MaximumLength = (USHORT)info->FileNameLength; 676 | 677 | 678 | if (CheckExcludeListDirFile(g_excludeFileContext, &fltName->Name, &fileName)) 679 | { 680 | BOOLEAN retn = FALSE; 681 | 682 | if (prevInfo != NULL) 683 | { 684 | if (info->NextEntryOffset != 0) 685 | { 686 | prevInfo->NextEntryOffset += info->NextEntryOffset; 687 | offset = info->NextEntryOffset; 688 | } 689 | else 690 | { 691 | prevInfo->NextEntryOffset = 0; 692 | status = STATUS_SUCCESS; 693 | retn = TRUE; 694 | } 695 | 696 | RtlFillMemory(info, sizeof(FILE_NAMES_INFORMATION), 0); 697 | } 698 | else 699 | { 700 | if (info->NextEntryOffset != 0) 701 | { 702 | nextInfo = (PFILE_NAMES_INFORMATION)((PUCHAR)info + info->NextEntryOffset); 703 | moveLength = 0; 704 | while (nextInfo->NextEntryOffset != 0) 705 | { 706 | moveLength += nextInfo->NextEntryOffset; 707 | nextInfo = (PFILE_NAMES_INFORMATION)((PUCHAR)nextInfo + nextInfo->NextEntryOffset); 708 | } 709 | 710 | moveLength += FIELD_OFFSET(FILE_NAMES_INFORMATION, FileName) + nextInfo->FileNameLength; 711 | RtlMoveMemory(info, (PUCHAR)info + info->NextEntryOffset, moveLength);//continue 712 | } 713 | else 714 | { 715 | status = STATUS_NO_MORE_ENTRIES; 716 | retn = TRUE; 717 | } 718 | } 719 | 720 | DbgPrint("FsFilter1!" __FUNCTION__ ":hata: %wZ\\%wZ\n", &fltName->Name, &fileName); 721 | 722 | if (retn) 723 | return status; 724 | 725 | info = (PFILE_NAMES_INFORMATION)((PCHAR)info + offset); 726 | continue; 727 | } 728 | 729 | offset = info->NextEntryOffset; 730 | prevInfo = info; 731 | info = (PFILE_NAMES_INFORMATION)((PCHAR)info + offset); 732 | 733 | if (offset == 0) 734 | search = FALSE; 735 | } while (search); 736 | 737 | return STATUS_SUCCESS; 738 | } 739 | 740 | VOID LoadConfigFilesCallback(PUNICODE_STRING Str, PVOID Params) 741 | { 742 | ULONGLONG id; 743 | UNREFERENCED_PARAMETER(Params); 744 | AddHiddenFile(Str, &id); 745 | } 746 | 747 | VOID LoadConfigDirsCallback(PUNICODE_STRING Str, PVOID Params) 748 | { 749 | ULONGLONG id; 750 | UNREFERENCED_PARAMETER(Params); 751 | AddHiddenDir(Str, &id); 752 | } 753 | 754 | NTSTATUS InitializeFSMiniFilter(PDRIVER_OBJECT DriverObject) 755 | { 756 | NTSTATUS status; 757 | UNICODE_STRING str; 758 | UINT32 i; 759 | ExcludeEntryId id; 760 | 761 | DbgPrint("FsFilter1!" __FUNCTION__ ":hata %d\n", (UINT32)KeGetCurrentIrql()); 762 | 763 | // Initialize and fill exclude file\dir lists 764 | 765 | status = InitializeExcludeListContext(&g_excludeFileContext, ExcludeFile); 766 | if (!NT_SUCCESS(status)) 767 | { 768 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 769 | return status; 770 | } 771 | 772 | for (i = 0; g_excludeFiles[i]; i++) 773 | { 774 | RtlInitUnicodeString(&str, g_excludeFiles[i]); 775 | AddExcludeListFile(g_excludeFileContext, &str, &id, 0); 776 | } 777 | 778 | CfgEnumConfigsTable(HideFilesTable, &LoadConfigFilesCallback, NULL); 779 | 780 | status = InitializeExcludeListContext(&g_excludeDirectoryContext, ExcludeDirectory); 781 | if (!NT_SUCCESS(status)) 782 | { 783 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 784 | DestroyExcludeListContext(g_excludeFileContext); 785 | return status; 786 | } 787 | 788 | for (i = 0; g_excludeDirs[i]; i++) 789 | { 790 | RtlInitUnicodeString(&str, g_excludeDirs[i]); 791 | AddExcludeListDirectory(g_excludeDirectoryContext, &str, &id, 0); 792 | } 793 | 794 | CfgEnumConfigsTable(HideDirsTable, &LoadConfigDirsCallback, NULL); 795 | 796 | // Filesystem mini-filter initialization 797 | 798 | status = FltRegisterFilter(DriverObject, &FilterRegistration, &gFilterHandle); 799 | if (NT_SUCCESS(status)) 800 | { 801 | status = FltStartFiltering(gFilterHandle); 802 | if (!NT_SUCCESS(status)) 803 | { 804 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 805 | FltUnregisterFilter(gFilterHandle); 806 | } 807 | } 808 | 809 | if (!NT_SUCCESS(status)) 810 | { 811 | DestroyExcludeListContext(g_excludeFileContext); 812 | DestroyExcludeListContext(g_excludeDirectoryContext); 813 | return status; 814 | } 815 | 816 | g_fsMonitorInited = TRUE; 817 | 818 | return status; 819 | } 820 | 821 | NTSTATUS DestroyFSMiniFilter() 822 | { 823 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata%d\n", (UINT32)KeGetCurrentIrql()); 824 | 825 | if (!g_fsMonitorInited) 826 | return STATUS_NOT_FOUND; 827 | 828 | FltUnregisterFilter(gFilterHandle); 829 | gFilterHandle = NULL; 830 | 831 | DestroyExcludeListContext(g_excludeFileContext); 832 | DestroyExcludeListContext(g_excludeDirectoryContext); 833 | g_fsMonitorInited = FALSE; 834 | 835 | return STATUS_SUCCESS; 836 | } 837 | 838 | NTSTATUS AddHiddenFile(PUNICODE_STRING FilePath, PULONGLONG ObjId) 839 | { 840 | const USHORT maxBufSize = FilePath->Length + NORMALIZE_INCREAMENT; 841 | UNICODE_STRING normalized; 842 | NTSTATUS status; 843 | 844 | normalized.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, maxBufSize, FSFILTER_ALLOC_TAG); 845 | normalized.Length = 0; 846 | normalized.MaximumLength = maxBufSize; 847 | 848 | if (!normalized.Buffer) 849 | { 850 | DbgPrint("FsFilter1!" __FUNCTION__ ": hatar\n"); 851 | return STATUS_MEMORY_NOT_ALLOCATED; 852 | } 853 | 854 | status = NormalizeDevicePath(FilePath, &normalized); 855 | if (!NT_SUCCESS(status)) 856 | { 857 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%wZ\n", status, FilePath); 858 | ExFreePoolWithTag(normalized.Buffer, FSFILTER_ALLOC_TAG); 859 | return status; 860 | } 861 | 862 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%wZ\n", &normalized); 863 | status = AddExcludeListFile(g_excludeFileContext, &normalized, ObjId, 0); 864 | 865 | ExFreePoolWithTag(normalized.Buffer, FSFILTER_ALLOC_TAG); 866 | 867 | return status; 868 | } 869 | 870 | NTSTATUS RemoveHiddenFile(ULONGLONG ObjId) 871 | { 872 | return RemoveExcludeListEntry(g_excludeFileContext, ObjId); 873 | } 874 | 875 | NTSTATUS RemoveAllHiddenFiles() 876 | { 877 | return RemoveAllExcludeListEntries(g_excludeFileContext); 878 | } 879 | 880 | NTSTATUS AddHiddenDir(PUNICODE_STRING DirPath, PULONGLONG ObjId) 881 | { 882 | const USHORT maxBufSize = DirPath->Length + NORMALIZE_INCREAMENT; 883 | UNICODE_STRING normalized; 884 | NTSTATUS status; 885 | 886 | normalized.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, maxBufSize, FSFILTER_ALLOC_TAG); 887 | normalized.Length = 0; 888 | normalized.MaximumLength = maxBufSize; 889 | 890 | if (!normalized.Buffer) 891 | { 892 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 893 | return STATUS_MEMORY_NOT_ALLOCATED; 894 | } 895 | 896 | status = NormalizeDevicePath(DirPath, &normalized); 897 | if (!NT_SUCCESS(status)) 898 | { 899 | DbgPrint("FsFilter1!" __FUNCTION__ ": phata:%wZ\n", status, DirPath); 900 | ExFreePoolWithTag(normalized.Buffer, FSFILTER_ALLOC_TAG); 901 | return status; 902 | } 903 | 904 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%wZ\n", &normalized); 905 | status = AddExcludeListDirectory(g_excludeDirectoryContext, &normalized, ObjId, 0); 906 | ExFreePoolWithTag(normalized.Buffer, FSFILTER_ALLOC_TAG); 907 | 908 | return status; 909 | } 910 | 911 | NTSTATUS RemoveHiddenDir(ULONGLONG ObjId) 912 | { 913 | return RemoveExcludeListEntry(g_excludeDirectoryContext, ObjId); 914 | } 915 | 916 | NTSTATUS RemoveAllHiddenDirs() 917 | { 918 | return RemoveAllExcludeListEntries(g_excludeDirectoryContext); 919 | } 920 | -------------------------------------------------------------------------------- /hidden/Hidden/FsFilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | NTSTATUS InitializeFSMiniFilter(PDRIVER_OBJECT DriverObject); 6 | NTSTATUS DestroyFSMiniFilter(); 7 | 8 | NTSTATUS AddHiddenFile(PUNICODE_STRING FilePath, PULONGLONG ObjId); 9 | NTSTATUS RemoveHiddenFile(ULONGLONG ObjId); 10 | NTSTATUS RemoveAllHiddenFiles(); 11 | 12 | NTSTATUS AddHiddenDir(PUNICODE_STRING DirPath, PULONGLONG ObjId); 13 | NTSTATUS RemoveHiddenDir(ULONGLONG ObjId); 14 | NTSTATUS RemoveAllHiddenDirs(); 15 | -------------------------------------------------------------------------------- /hidden/Hidden/Helper.c: -------------------------------------------------------------------------------- 1 | #include "Helper.h" 2 | 3 | #define HELPER_ALLOC_TAG 'rplH' 4 | 5 | NTSTATUS QuerySystemInformation(SYSTEM_INFORMATION_CLASS Class, PVOID* InfoBuffer, PSIZE_T InfoSize) 6 | { 7 | PVOID info = NULL; 8 | NTSTATUS status; 9 | ULONG size = 0, written = 0; 10 | 11 | 12 | status = ZwQuerySystemInformation(Class, 0, 0, &size); 13 | if (status != STATUS_INFO_LENGTH_MISMATCH) 14 | return status; 15 | 16 | while (status == STATUS_INFO_LENGTH_MISMATCH) 17 | { 18 | size += written; 19 | 20 | if (info) 21 | ExFreePoolWithTag(info, HELPER_ALLOC_TAG); 22 | 23 | info = ExAllocatePoolWithTag(NonPagedPool, size, HELPER_ALLOC_TAG); 24 | if (!info) 25 | break; 26 | 27 | status = ZwQuerySystemInformation(Class, info, size, &written); 28 | } 29 | 30 | if (!info) 31 | return STATUS_ACCESS_DENIED; 32 | 33 | if (!NT_SUCCESS(status)) 34 | { 35 | ExFreePoolWithTag(info, HELPER_ALLOC_TAG); 36 | return status; 37 | } 38 | 39 | *InfoBuffer = info; 40 | *InfoSize = size; 41 | 42 | return status; 43 | } 44 | 45 | NTSTATUS QueryProcessInformation(PROCESSINFOCLASS Class, HANDLE Process, PVOID* InfoBuffer, PSIZE_T InfoSize) 46 | { 47 | PVOID info = NULL; 48 | NTSTATUS status; 49 | ULONG size = 0, written = 0; 50 | 51 | // Query required size 52 | status = ZwQueryInformationProcess(Process, Class, 0, 0, &size); 53 | if (status != STATUS_INFO_LENGTH_MISMATCH) 54 | return status; 55 | 56 | while (status == STATUS_INFO_LENGTH_MISMATCH) 57 | { 58 | size += written; 59 | 60 | if (info) 61 | ExFreePoolWithTag(info, HELPER_ALLOC_TAG); 62 | 63 | info = ExAllocatePoolWithTag(NonPagedPool, size, HELPER_ALLOC_TAG); 64 | if (!info) 65 | break; 66 | 67 | status = ZwQueryInformationProcess(Process, Class, info, size, &written); 68 | } 69 | 70 | if (!info) 71 | return STATUS_ACCESS_DENIED; 72 | 73 | if (!NT_SUCCESS(status)) 74 | { 75 | ExFreePoolWithTag(info, HELPER_ALLOC_TAG); 76 | return status; 77 | } 78 | 79 | *InfoBuffer = info; 80 | *InfoSize = size; 81 | 82 | return status; 83 | } 84 | 85 | VOID FreeInformation(PVOID Buffer) 86 | { 87 | ExFreePoolWithTag(Buffer, HELPER_ALLOC_TAG); 88 | } 89 | 90 | NTSTATUS ResolveSymbolicLink(PUNICODE_STRING Link, PUNICODE_STRING Resolved) 91 | { 92 | OBJECT_ATTRIBUTES attribs; 93 | HANDLE hsymLink; 94 | ULONG written; 95 | NTSTATUS status = STATUS_SUCCESS; 96 | 97 | 98 | 99 | InitializeObjectAttributes(&attribs, Link, OBJ_KERNEL_HANDLE, NULL, NULL); 100 | 101 | status = ZwOpenSymbolicLinkObject(&hsymLink, GENERIC_READ, &attribs); 102 | if (!NT_SUCCESS(status)) 103 | return status; 104 | 105 | 106 | status = ZwQuerySymbolicLinkObject(hsymLink, Resolved, &written); 107 | ZwClose(hsymLink); 108 | if (!NT_SUCCESS(status)) 109 | return status; 110 | 111 | return status; 112 | } 113 | 114 | 115 | NTSTATUS NormalizeDevicePath(PCUNICODE_STRING Path, PUNICODE_STRING Normalized) 116 | { 117 | UNICODE_STRING globalPrefix, dvcPrefix, sysrootPrefix; 118 | NTSTATUS status; 119 | 120 | RtlInitUnicodeString(&globalPrefix, L"\\??\\"); 121 | RtlInitUnicodeString(&dvcPrefix, L"\\Device\\"); 122 | RtlInitUnicodeString(&sysrootPrefix, L"\\SystemRoot\\"); 123 | 124 | if (RtlPrefixUnicodeString(&globalPrefix, Path, TRUE)) 125 | { 126 | OBJECT_ATTRIBUTES attribs; 127 | UNICODE_STRING subPath; 128 | HANDLE hsymLink; 129 | ULONG i, written, size; 130 | 131 | subPath.Buffer = (PWCH)((PUCHAR)Path->Buffer + globalPrefix.Length); 132 | subPath.Length = Path->Length - globalPrefix.Length; 133 | 134 | for (i = 0; i < subPath.Length; i++) 135 | { 136 | if (subPath.Buffer[i] == L'\\') 137 | { 138 | subPath.Length = (USHORT)(i * sizeof(WCHAR)); 139 | break; 140 | } 141 | } 142 | 143 | if (subPath.Length == 0) 144 | return STATUS_INVALID_PARAMETER_1; 145 | 146 | subPath.Buffer = Path->Buffer; 147 | subPath.Length += globalPrefix.Length; 148 | subPath.MaximumLength = subPath.Length; 149 | 150 | 151 | 152 | InitializeObjectAttributes(&attribs, &subPath, OBJ_KERNEL_HANDLE, NULL, NULL); 153 | 154 | status = ZwOpenSymbolicLinkObject(&hsymLink, GENERIC_READ, &attribs); 155 | if (!NT_SUCCESS(status)) 156 | return status; 157 | 158 | 159 | 160 | status = ZwQuerySymbolicLinkObject(hsymLink, Normalized, &written); 161 | ZwClose(hsymLink); 162 | if (!NT_SUCCESS(status)) 163 | return status; 164 | 165 | 166 | 167 | size = Path->Length - subPath.Length + Normalized->Length; 168 | if (size > Normalized->MaximumLength) 169 | return STATUS_BUFFER_OVERFLOW; 170 | 171 | subPath.Buffer = (PWCH)((PUCHAR)Path->Buffer + subPath.Length); 172 | subPath.Length = Path->Length - subPath.Length; 173 | subPath.MaximumLength = subPath.Length; 174 | 175 | status = RtlAppendUnicodeStringToString(Normalized, &subPath); 176 | if (!NT_SUCCESS(status)) 177 | return status; 178 | } 179 | else if (RtlPrefixUnicodeString(&dvcPrefix, Path, TRUE)) 180 | { 181 | Normalized->Length = 0; 182 | status = RtlAppendUnicodeStringToString(Normalized, Path); 183 | if (!NT_SUCCESS(status)) 184 | return status; 185 | } 186 | else if (RtlPrefixUnicodeString(&sysrootPrefix, Path, TRUE)) 187 | { 188 | UNICODE_STRING subPath, resolvedLink, winDir; 189 | WCHAR buffer[64]; 190 | SHORT i; 191 | 192 | 193 | 194 | subPath.Buffer = sysrootPrefix.Buffer; 195 | subPath.MaximumLength = subPath.Length = sysrootPrefix.Length - sizeof(WCHAR); 196 | 197 | resolvedLink.Buffer = buffer; 198 | resolvedLink.Length = 0; 199 | resolvedLink.MaximumLength = sizeof(buffer); 200 | 201 | status = ResolveSymbolicLink(&subPath, &resolvedLink); 202 | if (!NT_SUCCESS(status)) 203 | return status; 204 | 205 | 206 | 207 | winDir.Length = 0; 208 | for (i = (resolvedLink.Length - sizeof(WCHAR)) / sizeof(WCHAR); i >= 0; i--) 209 | { 210 | if (resolvedLink.Buffer[i] == L'\\') 211 | { 212 | winDir.Buffer = resolvedLink.Buffer + i; 213 | winDir.Length = resolvedLink.Length - (i * sizeof(WCHAR)); 214 | winDir.MaximumLength = winDir.Length; 215 | resolvedLink.Length = (i * sizeof(WCHAR)); 216 | break; 217 | } 218 | } 219 | 220 | 221 | status = ResolveSymbolicLink(&resolvedLink, Normalized); 222 | if (!NT_SUCCESS(status)) 223 | return status; 224 | 225 | 226 | 227 | subPath.Buffer = (PWCHAR)((PCHAR)Path->Buffer + sysrootPrefix.Length - sizeof(WCHAR)); 228 | subPath.MaximumLength = subPath.Length = Path->Length - sysrootPrefix.Length + sizeof(WCHAR); 229 | 230 | status = RtlAppendUnicodeStringToString(Normalized, &winDir); 231 | if (!NT_SUCCESS(status)) 232 | return status; 233 | 234 | status = RtlAppendUnicodeStringToString(Normalized, &subPath); 235 | if (!NT_SUCCESS(status)) 236 | return status; 237 | } 238 | else 239 | { 240 | return STATUS_INVALID_PARAMETER; 241 | } 242 | 243 | return STATUS_SUCCESS; 244 | } 245 | -------------------------------------------------------------------------------- /hidden/Hidden/Helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef enum _SYSTEM_INFORMATION_CLASS { 6 | SystemBasicInformation = 0, 7 | SystemPerformanceInformation = 2, 8 | SystemTimeOfDayInformation = 3, 9 | SystemProcessInformation = 5, 10 | SystemProcessorPerformanceInformation = 8, 11 | SystemInterruptInformation = 23, 12 | SystemExceptionInformation = 33, 13 | SystemRegistryQuotaInformation = 37, 14 | SystemLookasideInformation = 45, 15 | SystemPolicyInformation = 134, 16 | } SYSTEM_INFORMATION_CLASS; 17 | 18 | typedef struct _SYSTEM_PROCESS_INFORMATION { 19 | ULONG NextEntryOffset; 20 | ULONG NumberOfThreads; 21 | LARGE_INTEGER Reserved[3]; 22 | LARGE_INTEGER CreateTime; 23 | LARGE_INTEGER UserTime; 24 | LARGE_INTEGER KernelTime; 25 | UNICODE_STRING ImageName; 26 | KPRIORITY BasePriority; 27 | HANDLE ProcessId; 28 | HANDLE InheritedFromProcessId; 29 | ULONG HandleCount; 30 | UCHAR Reserved4[4]; 31 | PVOID Reserved5[11]; 32 | SIZE_T PeakPagefileUsage; 33 | SIZE_T PrivatePageCount; 34 | LARGE_INTEGER Reserved6[6]; 35 | } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 36 | 37 | typedef struct _LDR_DATA_TABLE_ENTRY { 38 | LIST_ENTRY LoadOrder; 39 | LIST_ENTRY MemoryOrder; 40 | LIST_ENTRY InitializationOrder; 41 | PVOID ModuleBaseAddress; 42 | PVOID EntryPoint; 43 | ULONG ModuleSize; 44 | UNICODE_STRING FullModuleName; 45 | UNICODE_STRING ModuleName; 46 | ULONG Flags; 47 | USHORT LoadCount; 48 | USHORT TlsIndex; 49 | union { 50 | LIST_ENTRY Hash; 51 | struct { 52 | PVOID SectionPointer; 53 | ULONG CheckSum; 54 | } s; 55 | } u; 56 | ULONG TimeStamp; 57 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; 58 | 59 | NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation( 60 | _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, 61 | _Inout_ PVOID SystemInformation, 62 | _In_ ULONG SystemInformationLength, 63 | _Out_opt_ PULONG ReturnLength 64 | ); 65 | 66 | NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess( 67 | _In_ HANDLE ProcessHandle, 68 | _In_ PROCESSINFOCLASS ProcessInformationClass, 69 | _Out_ PVOID ProcessInformation, 70 | _In_ ULONG ProcessInformationLength, 71 | _Out_opt_ PULONG ReturnLength 72 | ); 73 | 74 | NTSTATUS QuerySystemInformation(SYSTEM_INFORMATION_CLASS Class, PVOID* InfoBuffer, PSIZE_T InfoSize); 75 | NTSTATUS QueryProcessInformation(PROCESSINFOCLASS Class, HANDLE ProcessId, PVOID* InfoBuffer, PSIZE_T InfoSize); 76 | VOID FreeInformation(PVOID Buffer); 77 | 78 | #define NORMALIZE_INCREAMENT (USHORT)128 79 | 80 | NTSTATUS NormalizeDevicePath(PCUNICODE_STRING Path, PUNICODE_STRING Normalized); 81 | -------------------------------------------------------------------------------- /hidden/Hidden/PsMonitor.c: -------------------------------------------------------------------------------- 1 | #include "PsMonitor.h" 2 | #include "ExcludeList.h" 3 | #include "Helper.h" 4 | #include "PsTable.h" 5 | #include "PsRules.h" 6 | #include "Driver.h" 7 | #include "Configs.h" 8 | 9 | 10 | #define PSMON_ALLOC_TAG 'nMsP' 11 | 12 | #define PROCESS_QUERY_LIMITED_INFORMATION 0x1000 13 | #define SYSTEM_PROCESS_ID (HANDLE)4 14 | 15 | BOOLEAN g_psMonitorInited = FALSE; 16 | PVOID g_obRegCallback = NULL; 17 | 18 | OB_OPERATION_REGISTRATION g_regOperation[2]; 19 | OB_CALLBACK_REGISTRATION g_regCallback; 20 | 21 | PsRulesContext g_excludeProcessRules; 22 | PsRulesContext g_protectProcessRules; 23 | 24 | FAST_MUTEX g_processTableLock; 25 | 26 | typedef struct _ProcessListEntry { 27 | LPCWSTR path; 28 | ULONG inherit; 29 | } ProcessListEntry, *PProcessListEntry; 30 | 31 | CONST ProcessListEntry g_excludeProcesses[] = { 32 | { NULL, PsRuleTypeWithoutInherit } 33 | }; 34 | 35 | 36 | CONST ProcessListEntry g_protectProcesses[] = { 37 | { NULL, PsRuleTypeWithoutInherit } 38 | }; 39 | 40 | #define CSRSS_PAHT_BUFFER_SIZE 256 41 | 42 | UNICODE_STRING g_csrssPath; 43 | WCHAR g_csrssPathBuffer[CSRSS_PAHT_BUFFER_SIZE]; 44 | 45 | BOOLEAN CheckProtectedOperation(HANDLE Source, HANDLE Destination) 46 | { 47 | ProcessTableEntry srcInfo, destInfo; 48 | BOOLEAN result; 49 | 50 | if (Source == Destination) 51 | return FALSE; 52 | 53 | srcInfo.processId = Source; 54 | 55 | ExAcquireFastMutex(&g_processTableLock); 56 | result = GetProcessInProcessTable(&srcInfo); 57 | ExReleaseFastMutex(&g_processTableLock); 58 | 59 | if (!result) 60 | return FALSE; 61 | 62 | destInfo.processId = Destination; 63 | 64 | ExAcquireFastMutex(&g_processTableLock); 65 | 66 | if (!GetProcessInProcessTable(&destInfo)) 67 | { 68 | ExReleaseFastMutex(&g_processTableLock); 69 | return FALSE; 70 | } 71 | 72 | 73 | if (!destInfo.inited) 74 | { 75 | result = TRUE; 76 | 77 | 78 | if (srcInfo.subsystem) 79 | { 80 | destInfo.inited = TRUE; 81 | if (!UpdateProcessInProcessTable(&destInfo)) 82 | result = FALSE; 83 | } 84 | 85 | ExReleaseFastMutex(&g_processTableLock); 86 | 87 | if (!result) 88 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %p\n", destInfo.processId); 89 | 90 | return FALSE; 91 | } 92 | 93 | ExReleaseFastMutex(&g_processTableLock); 94 | 95 | if (!destInfo.protected) 96 | return FALSE; 97 | 98 | if (srcInfo.protected) 99 | return FALSE; 100 | 101 | if (srcInfo.subsystem) 102 | return FALSE; 103 | 104 | return TRUE; 105 | } 106 | 107 | OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) 108 | { 109 | 110 | return OB_PREOP_SUCCESS; 111 | } 112 | 113 | OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation) 114 | { 115 | UNREFERENCED_PARAMETER(RegistrationContext); 116 | 117 | if (!IsDriverEnabled()) 118 | return OB_PREOP_SUCCESS; 119 | 120 | if (OperationInformation->KernelHandle) 121 | return OB_PREOP_SUCCESS; 122 | 123 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %p(%p:%p), Oper: %s, Space: %s\n", 124 | PsGetThreadId(OperationInformation->Object), PsGetCurrentProcessId(), PsGetCurrentThreadId(), 125 | (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE ? "create" : "dup"), 126 | (OperationInformation->KernelHandle ? "kernel" : "user") 127 | ); 128 | 129 | if (!CheckProtectedOperation(PsGetCurrentProcessId(), PsGetProcessId(OperationInformation->Object))) 130 | { 131 | return OB_PREOP_SUCCESS; 132 | } 133 | 134 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata %p\n", PsGetCurrentProcessId()); 135 | 136 | if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) 137 | OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION); 138 | else 139 | OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION); 140 | 141 | return OB_PREOP_SUCCESS; 142 | } 143 | 144 | VOID CheckProcessFlags(PProcessTableEntry Entry, PCUNICODE_STRING ImgPath, HANDLE ParentId) 145 | { 146 | ProcessTableEntry lookup; 147 | ULONG inheritType; 148 | BOOLEAN result; 149 | 150 | RtlZeroMemory(&lookup, sizeof(lookup)); 151 | 152 | Entry->inited = (!g_psMonitorInited ? TRUE : FALSE); 153 | if (Entry->processId == (HANDLE)4) 154 | Entry->subsystem = TRUE; 155 | else 156 | Entry->subsystem = RtlEqualUnicodeString(&g_csrssPath, ImgPath, TRUE); 157 | 158 | 159 | Entry->excluded = FALSE; 160 | Entry->inheritExclusion = PsRuleTypeWithoutInherit; 161 | 162 | if (FindInheritanceInPsRuleList(g_excludeProcessRules, ImgPath, &inheritType)) 163 | { 164 | Entry->excluded = TRUE; 165 | Entry->inheritExclusion = inheritType; 166 | } 167 | else if (ParentId != 0) 168 | { 169 | lookup.processId = ParentId; 170 | 171 | ExAcquireFastMutex(&g_processTableLock); 172 | result = GetProcessInProcessTable(&lookup); 173 | ExReleaseFastMutex(&g_processTableLock); 174 | 175 | if (result) 176 | { 177 | if (lookup.inheritExclusion == PsRuleTypeInherit) 178 | { 179 | Entry->excluded = TRUE; 180 | Entry->inheritExclusion = PsRuleTypeInherit; 181 | } 182 | else if (lookup.inheritExclusion == PsRuleTypeInheritOnce) 183 | { 184 | Entry->excluded = TRUE; 185 | Entry->inheritExclusion = PsRuleTypeWithoutInherit; 186 | } 187 | } 188 | } 189 | 190 | 191 | 192 | Entry->protected = FALSE; 193 | Entry->inheritProtection = PsRuleTypeWithoutInherit; 194 | 195 | if (FindInheritanceInPsRuleList(g_protectProcessRules, ImgPath, &inheritType)) 196 | { 197 | Entry->protected = TRUE; 198 | Entry->inheritProtection = inheritType; 199 | } 200 | else if (ParentId != 0) 201 | { 202 | lookup.processId = ParentId; 203 | 204 | ExAcquireFastMutex(&g_processTableLock); 205 | result = GetProcessInProcessTable(&lookup); 206 | ExReleaseFastMutex(&g_processTableLock); 207 | 208 | if (result) 209 | { 210 | if (lookup.inheritProtection == PsRuleTypeInherit) 211 | { 212 | Entry->protected = TRUE; 213 | Entry->inheritProtection = PsRuleTypeInherit; 214 | } 215 | else if (lookup.inheritProtection == PsRuleTypeInheritOnce) 216 | { 217 | Entry->protected = TRUE; 218 | Entry->inheritProtection = PsRuleTypeWithoutInherit; 219 | } 220 | } 221 | } 222 | } 223 | 224 | VOID CreateProcessNotifyCallback(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo) 225 | { 226 | ProcessTableEntry entry; 227 | BOOLEAN result; 228 | 229 | UNREFERENCED_PARAMETER(Process); 230 | 231 | if (CreateInfo) 232 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %p (%p:%p), %wZ\n", ProcessId, PsGetCurrentProcessId(), PsGetCurrentThreadId(), CreateInfo->ImageFileName); 233 | else 234 | DbgPrint("FsFilter1!" __FUNCTION__ ":hata: %p (%p:%p)\n", ProcessId, PsGetCurrentProcessId(), PsGetCurrentThreadId()); 235 | 236 | RtlZeroMemory(&entry, sizeof(entry)); 237 | entry.processId = ProcessId; 238 | 239 | if (CreateInfo) 240 | { 241 | const USHORT maxBufSize = CreateInfo->ImageFileName->Length + NORMALIZE_INCREAMENT; 242 | UNICODE_STRING normalized; 243 | NTSTATUS status; 244 | 245 | normalized.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, maxBufSize, PSMON_ALLOC_TAG); 246 | normalized.Length = 0; 247 | normalized.MaximumLength = maxBufSize; 248 | 249 | if (!normalized.Buffer) 250 | { 251 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 252 | return; 253 | } 254 | 255 | status = NormalizeDevicePath(CreateInfo->ImageFileName, &normalized); 256 | if (!NT_SUCCESS(status)) 257 | { 258 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x, path:%wZ\n", status, CreateInfo->ImageFileName); 259 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 260 | return; 261 | } 262 | 263 | CheckProcessFlags(&entry, &normalized, PsGetCurrentProcessId()/*CreateInfo->ParentProcessId*/); 264 | 265 | if (entry.excluded) 266 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%p\n", ProcessId); 267 | 268 | if (entry.protected) 269 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%p\n", ProcessId); 270 | 271 | ExAcquireFastMutex(&g_processTableLock); 272 | result = AddProcessToProcessTable(&entry); 273 | ExReleaseFastMutex(&g_processTableLock); 274 | 275 | if (!result) 276 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n", ProcessId); 277 | 278 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 279 | } 280 | else 281 | { 282 | ExAcquireFastMutex(&g_processTableLock); 283 | result = RemoveProcessFromProcessTable(&entry); 284 | ExReleaseFastMutex(&g_processTableLock); 285 | 286 | if (!result) 287 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n", ProcessId); 288 | } 289 | 290 | } 291 | 292 | BOOLEAN IsProcessExcluded(HANDLE ProcessId) 293 | { 294 | ProcessTableEntry entry; 295 | BOOLEAN result; 296 | 297 | 298 | if (ProcessId == (HANDLE)4) 299 | return TRUE; 300 | 301 | entry.processId = ProcessId; 302 | 303 | ExAcquireFastMutex(&g_processTableLock); 304 | result = GetProcessInProcessTable(&entry); 305 | ExReleaseFastMutex(&g_processTableLock); 306 | 307 | if (!result) 308 | return FALSE; 309 | 310 | 311 | return ((entry.excluded || ProcessId == (HANDLE)4) ? TRUE : FALSE); 312 | } 313 | 314 | BOOLEAN IsProcessProtected(HANDLE ProcessId) 315 | { 316 | ProcessTableEntry entry; 317 | BOOLEAN result; 318 | 319 | entry.processId = ProcessId; 320 | 321 | ExAcquireFastMutex(&g_processTableLock); 322 | result = GetProcessInProcessTable(&entry); 323 | ExReleaseFastMutex(&g_processTableLock); 324 | 325 | if (!result) 326 | return FALSE; 327 | 328 | return entry.protected; 329 | } 330 | 331 | NTSTATUS ParsePsConfigEntry(PUNICODE_STRING Entry, PUNICODE_STRING Path, PULONG Inherit) 332 | { 333 | USHORT inx, length = Entry->Length / sizeof(WCHAR); 334 | LPWSTR str = Entry->Buffer; 335 | UNICODE_STRING command, template; 336 | 337 | RtlZeroMemory(&command, sizeof(command)); 338 | 339 | for (inx = 0; inx < length; inx++) 340 | { 341 | if (str[inx] == L';') 342 | { 343 | command.Buffer = str + inx + 1; 344 | command.Length = (length - inx - 1) * sizeof(WCHAR); 345 | command.MaximumLength = command.Length; 346 | break; 347 | } 348 | } 349 | 350 | if (inx == 0) 351 | return STATUS_NO_DATA_DETECTED; 352 | 353 | Path->Buffer = Entry->Buffer; 354 | Path->Length = inx * sizeof(WCHAR); 355 | Path->MaximumLength = Path->Length; 356 | 357 | RtlInitUnicodeString(&template, L"none"); 358 | if (RtlCompareUnicodeString(&command, &template, TRUE) == 0) 359 | { 360 | *Inherit = PsRuleTypeWithoutInherit; 361 | return STATUS_SUCCESS; 362 | } 363 | 364 | RtlInitUnicodeString(&template, L"always"); 365 | if (RtlCompareUnicodeString(&command, &template, TRUE) == 0) 366 | { 367 | *Inherit = PsRuleTypeInherit; 368 | return STATUS_SUCCESS; 369 | } 370 | 371 | RtlInitUnicodeString(&template, L"once"); 372 | if (RtlCompareUnicodeString(&command, &template, TRUE) == 0) 373 | { 374 | *Inherit = PsRuleTypeInheritOnce; 375 | return STATUS_SUCCESS; 376 | } 377 | 378 | return STATUS_NOT_FOUND; 379 | } 380 | 381 | VOID LoadProtectedRulesCallback(PUNICODE_STRING Str, PVOID Params) 382 | { 383 | UNICODE_STRING path; 384 | ULONG inherit; 385 | PsRuleEntryId ruleId; 386 | 387 | UNREFERENCED_PARAMETER(Params); 388 | 389 | if (NT_SUCCESS(ParsePsConfigEntry(Str, &path, &inherit))) 390 | AddProtectedImage(&path, inherit, FALSE, &ruleId); 391 | } 392 | 393 | VOID LoadIgnoredRulesCallback(PUNICODE_STRING Str, PVOID Params) 394 | { 395 | UNICODE_STRING path; 396 | ULONG inherit; 397 | PsRuleEntryId ruleId; 398 | 399 | UNREFERENCED_PARAMETER(Params); 400 | 401 | if (NT_SUCCESS(ParsePsConfigEntry(Str, &path, &inherit))) 402 | AddExcludedImage(&path, inherit, FALSE, &ruleId); 403 | } 404 | 405 | NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject) 406 | { 407 | const USHORT maxBufSize = 512; 408 | NTSTATUS status; 409 | UNICODE_STRING str, normalized, csrss; 410 | UINT32 i; 411 | PsRuleEntryId ruleId; 412 | 413 | UNREFERENCED_PARAMETER(DriverObject); 414 | 415 | 416 | 417 | RtlZeroMemory(g_csrssPathBuffer, sizeof(g_csrssPathBuffer)); 418 | g_csrssPath.Buffer = g_csrssPathBuffer; 419 | g_csrssPath.Length = 0; 420 | g_csrssPath.MaximumLength = sizeof(g_csrssPathBuffer); 421 | 422 | RtlInitUnicodeString(&csrss, L"\\SystemRoot\\System32\\csrss.exe"); 423 | status = NormalizeDevicePath(&csrss, &g_csrssPath); 424 | if (!NT_SUCCESS(status)) 425 | { 426 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 427 | return status; 428 | } 429 | 430 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\n", &g_csrssPath); 431 | 432 | 433 | 434 | normalized.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, maxBufSize, PSMON_ALLOC_TAG); 435 | normalized.Length = 0; 436 | normalized.MaximumLength = maxBufSize; 437 | if (!normalized.Buffer) 438 | { 439 | DbgPrint("FsFilter1!" __FUNCTION__ ": hatad\n"); 440 | return STATUS_ACCESS_DENIED; 441 | } 442 | 443 | 444 | 445 | status = InitializePsRuleListContext(&g_excludeProcessRules); 446 | if (!NT_SUCCESS(status)) 447 | { 448 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 449 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 450 | return status; 451 | } 452 | 453 | for (i = 0; g_excludeProcesses[i].path; i++) 454 | { 455 | RtlInitUnicodeString(&str, g_excludeProcesses[i].path); 456 | 457 | status = NormalizeDevicePath(&str, &normalized); 458 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata %wZ\n", &normalized); 459 | if (!NT_SUCCESS(status)) 460 | { 461 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x, path:%wZ\n", status, &str); 462 | continue; 463 | } 464 | 465 | AddRuleToPsRuleList(g_excludeProcessRules, &normalized, g_excludeProcesses[i].inherit, &ruleId); 466 | } 467 | 468 | // Load entries from the config 469 | CfgEnumConfigsTable(IgnoreImagesTable, &LoadIgnoredRulesCallback, NULL); 470 | 471 | // protected 472 | 473 | status = InitializePsRuleListContext(&g_protectProcessRules); 474 | if (!NT_SUCCESS(status)) 475 | { 476 | DbgPrint("FsFilter1!" __FUNCTION__ ":hata:%08x\n", status); 477 | DestroyPsRuleListContext(g_excludeProcessRules); 478 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 479 | return status; 480 | } 481 | 482 | for (i = 0; g_protectProcesses[i].path; i++) 483 | { 484 | RtlInitUnicodeString(&str, g_protectProcesses[i].path); 485 | 486 | status = NormalizeDevicePath(&str, &normalized); 487 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata%wZ\n", &normalized); 488 | if (!NT_SUCCESS(status)) 489 | { 490 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata%wZ\n", status, &str); 491 | continue; 492 | } 493 | 494 | AddRuleToPsRuleList(g_protectProcessRules, &normalized, g_protectProcesses[i].inherit, &ruleId); 495 | } 496 | 497 | // Load entries from the config 498 | CfgEnumConfigsTable(ProtectImagesTable, &LoadProtectedRulesCallback, NULL); 499 | 500 | // Process table 501 | 502 | ExInitializeFastMutex(&g_processTableLock); 503 | 504 | status = InitializeProcessTable(CheckProcessFlags); 505 | if (!NT_SUCCESS(status)) 506 | { 507 | DestroyPsRuleListContext(g_excludeProcessRules); 508 | DestroyPsRuleListContext(g_protectProcessRules); 509 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 510 | return status; 511 | } 512 | 513 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 514 | 515 | g_psMonitorInited = TRUE; 516 | 517 | 518 | 519 | g_regOperation[0].ObjectType = PsProcessType; 520 | g_regOperation[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; 521 | g_regOperation[0].PreOperation = ProcessPreCallback; 522 | g_regOperation[0].PostOperation = NULL; 523 | 524 | g_regOperation[1].ObjectType = PsThreadType; 525 | g_regOperation[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; 526 | g_regOperation[1].PreOperation = ThreadPreCallback; 527 | g_regOperation[1].PostOperation = NULL; 528 | 529 | g_regCallback.Version = OB_FLT_REGISTRATION_VERSION; 530 | g_regCallback.OperationRegistrationCount = 2; 531 | g_regCallback.RegistrationContext = NULL; 532 | g_regCallback.OperationRegistration = g_regOperation; 533 | RtlInitUnicodeString(&g_regCallback.Altitude, L"1000"); 534 | 535 | status = ObRegisterCallbacks(&g_regCallback, &g_obRegCallback); 536 | if (!NT_SUCCESS(status)) 537 | { 538 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 539 | DestroyPsMonitor(); 540 | return status; 541 | } 542 | 543 | // Register rocess create\destroy callback 544 | 545 | status = PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyCallback, FALSE); 546 | if (!NT_SUCCESS(status)) 547 | { 548 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 549 | DestroyPsMonitor(); 550 | return status; 551 | } 552 | 553 | return status; 554 | } 555 | 556 | NTSTATUS DestroyPsMonitor() 557 | { 558 | if (!g_psMonitorInited) 559 | return STATUS_ALREADY_DISCONNECTED; 560 | 561 | if (g_obRegCallback) 562 | { 563 | ObUnRegisterCallbacks(g_obRegCallback); 564 | g_obRegCallback = NULL; 565 | } 566 | 567 | PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyCallback, TRUE); 568 | 569 | DestroyPsRuleListContext(g_excludeProcessRules); 570 | DestroyPsRuleListContext(g_protectProcessRules); 571 | 572 | ExAcquireFastMutex(&g_processTableLock); 573 | DestroyProcessTable(); 574 | ExReleaseFastMutex(&g_processTableLock); 575 | 576 | g_psMonitorInited = FALSE; 577 | 578 | return STATUS_SUCCESS; 579 | } 580 | 581 | NTSTATUS SetStateForProcessesByImage(PCUNICODE_STRING ImagePath, BOOLEAN Excluded, BOOLEAN Protected) 582 | { 583 | PSYSTEM_PROCESS_INFORMATION processInfo = NULL, first; 584 | SIZE_T size = 0, offset; 585 | NTSTATUS status; 586 | 587 | status = QuerySystemInformation(SystemProcessInformation, &processInfo, &size); 588 | if (!NT_SUCCESS(status)) 589 | { 590 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", status); 591 | return status; 592 | } 593 | 594 | offset = 0; 595 | first = processInfo; 596 | do 597 | { 598 | HANDLE hProcess; 599 | CLIENT_ID clientId; 600 | OBJECT_ATTRIBUTES attribs; 601 | PUNICODE_STRING procName; 602 | ProcessTableEntry entry; 603 | 604 | processInfo = (PSYSTEM_PROCESS_INFORMATION)((SIZE_T)processInfo + offset); 605 | 606 | if (processInfo->ProcessId == 0) 607 | { 608 | offset = processInfo->NextEntryOffset; 609 | continue; 610 | } 611 | 612 | InitializeObjectAttributes(&attribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); 613 | clientId.UniqueProcess = processInfo->ProcessId; 614 | clientId.UniqueThread = 0; 615 | 616 | status = ZwOpenProcess(&hProcess, 0x1000/*PROCESS_QUERY_LIMITED_INFORMATION*/, &attribs, &clientId); 617 | if (!NT_SUCCESS(status)) 618 | { 619 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", processInfo->ProcessId, status); 620 | offset = processInfo->NextEntryOffset; 621 | continue; 622 | } 623 | 624 | status = QueryProcessInformation(ProcessImageFileName, hProcess, &procName, &size); 625 | ZwClose(hProcess); 626 | 627 | if (!NT_SUCCESS(status)) 628 | { 629 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", processInfo->ProcessId, status); 630 | offset = processInfo->NextEntryOffset; 631 | continue; 632 | } 633 | 634 | entry.processId = processInfo->ProcessId; 635 | if (RtlCompareUnicodeString(procName, ImagePath, TRUE) == 0) 636 | { 637 | BOOLEAN result = TRUE; 638 | 639 | 640 | ExAcquireFastMutex(&g_processTableLock); 641 | 642 | if (GetProcessInProcessTable(&entry)) 643 | { 644 | if (Excluded) 645 | { 646 | entry.excluded = TRUE; 647 | entry.inheritExclusion = PsRuleTypeWithoutInherit; 648 | } 649 | 650 | if (Protected) 651 | { 652 | entry.protected = TRUE; 653 | entry.inheritProtection = PsRuleTypeWithoutInherit; 654 | } 655 | 656 | if (!UpdateProcessInProcessTable(&entry)) 657 | result = FALSE; 658 | } 659 | 660 | ExReleaseFastMutex(&g_processTableLock); 661 | 662 | if (!result) 663 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata %p\n", processInfo->ProcessId); 664 | } 665 | 666 | FreeInformation(procName); 667 | offset = processInfo->NextEntryOffset; 668 | } while (offset); 669 | 670 | FreeInformation(first); 671 | return STATUS_SUCCESS; 672 | } 673 | 674 | NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId) 675 | { 676 | const USHORT maxBufSize = ImagePath->Length + NORMALIZE_INCREAMENT; 677 | UNICODE_STRING normalized; 678 | NTSTATUS status; 679 | 680 | normalized.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, maxBufSize, PSMON_ALLOC_TAG); 681 | normalized.Length = 0; 682 | normalized.MaximumLength = maxBufSize; 683 | 684 | if (!normalized.Buffer) 685 | { 686 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 687 | return STATUS_MEMORY_NOT_ALLOCATED; 688 | } 689 | 690 | status = NormalizeDevicePath(ImagePath, &normalized); 691 | if (!NT_SUCCESS(status)) 692 | { 693 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x, path:%wZ\n", status, ImagePath); 694 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 695 | return status; 696 | } 697 | 698 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\n", &normalized); 699 | status = AddRuleToPsRuleList(g_protectProcessRules, &normalized, InheritType, ObjId); 700 | 701 | if (ApplyForProcesses) 702 | SetStateForProcessesByImage(&normalized, FALSE, TRUE); 703 | 704 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 705 | 706 | return status; 707 | } 708 | 709 | NTSTATUS GetProtectedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable) 710 | { 711 | ProcessTableEntry entry; 712 | BOOLEAN result; 713 | 714 | entry.processId = ProcessId; 715 | 716 | ExAcquireFastMutex(&g_processTableLock); 717 | result = GetProcessInProcessTable(&entry); 718 | ExReleaseFastMutex(&g_processTableLock); 719 | 720 | if (!result) 721 | return STATUS_NOT_FOUND; 722 | 723 | *Enable = entry.protected; 724 | *InheritType = entry.inheritProtection; 725 | 726 | return STATUS_SUCCESS; 727 | } 728 | 729 | NTSTATUS SetProtectedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN Enable) 730 | { 731 | NTSTATUS status = STATUS_SUCCESS; 732 | ProcessTableEntry entry; 733 | BOOLEAN result; 734 | 735 | entry.processId = ProcessId; 736 | 737 | ExAcquireFastMutex(&g_processTableLock); 738 | result = GetProcessInProcessTable(&entry); 739 | ExReleaseFastMutex(&g_processTableLock); 740 | 741 | if (!result) 742 | return STATUS_NOT_FOUND; 743 | 744 | if (Enable) 745 | { 746 | entry.protected = TRUE; 747 | entry.inheritProtection = InheritType; 748 | } 749 | else 750 | { 751 | entry.protected = FALSE; 752 | } 753 | 754 | ExAcquireFastMutex(&g_processTableLock); 755 | result = UpdateProcessInProcessTable(&entry); 756 | ExReleaseFastMutex(&g_processTableLock); 757 | 758 | if (!result) 759 | return STATUS_NOT_FOUND; 760 | 761 | return status; 762 | } 763 | 764 | NTSTATUS RemoveProtectedImage(ULONGLONG ObjId) 765 | { 766 | return RemoveRuleFromPsRuleList(g_protectProcessRules, ObjId); 767 | } 768 | 769 | NTSTATUS RemoveAllProtectedImages() 770 | { 771 | return RemoveAllRulesFromPsRuleList(g_protectProcessRules); 772 | } 773 | 774 | NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId) 775 | { 776 | const USHORT maxBufSize = ImagePath->Length + NORMALIZE_INCREAMENT; 777 | UNICODE_STRING normalized; 778 | NTSTATUS status; 779 | 780 | normalized.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, maxBufSize, PSMON_ALLOC_TAG); 781 | normalized.Length = 0; 782 | normalized.MaximumLength = maxBufSize; 783 | 784 | if (!normalized.Buffer) 785 | { 786 | DbgPrint("FsFilter1!" __FUNCTION__ ":hata\n"); 787 | return STATUS_MEMORY_NOT_ALLOCATED; 788 | } 789 | 790 | status = NormalizeDevicePath(ImagePath, &normalized); 791 | if (!NT_SUCCESS(status)) 792 | { 793 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x, path:%wZ\n", status, ImagePath); 794 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 795 | return status; 796 | } 797 | 798 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %wZ\n", &normalized); 799 | status = AddRuleToPsRuleList(g_excludeProcessRules, &normalized, InheritType, ObjId); 800 | 801 | if (ApplyForProcesses) 802 | SetStateForProcessesByImage(&normalized, TRUE, FALSE); 803 | 804 | ExFreePoolWithTag(normalized.Buffer, PSMON_ALLOC_TAG); 805 | 806 | return status; 807 | } 808 | 809 | NTSTATUS GetExcludedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable) 810 | { 811 | ProcessTableEntry entry; 812 | BOOLEAN result; 813 | 814 | entry.processId = ProcessId; 815 | 816 | ExAcquireFastMutex(&g_processTableLock); 817 | result = GetProcessInProcessTable(&entry); 818 | ExReleaseFastMutex(&g_processTableLock); 819 | 820 | if (!result) 821 | return STATUS_NOT_FOUND; 822 | 823 | *Enable = entry.excluded; 824 | *InheritType = entry.inheritExclusion; 825 | 826 | return STATUS_SUCCESS; 827 | } 828 | 829 | NTSTATUS SetExcludedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN Enable) 830 | { 831 | NTSTATUS status = STATUS_SUCCESS; 832 | ProcessTableEntry entry; 833 | BOOLEAN result; 834 | 835 | entry.processId = ProcessId; 836 | 837 | ExAcquireFastMutex(&g_processTableLock); 838 | result = GetProcessInProcessTable(&entry); 839 | ExReleaseFastMutex(&g_processTableLock); 840 | 841 | if (!result) 842 | return STATUS_NOT_FOUND; 843 | 844 | if (Enable) 845 | { 846 | entry.excluded = TRUE; 847 | entry.inheritExclusion = InheritType; 848 | } 849 | else 850 | { 851 | entry.excluded = FALSE; 852 | } 853 | 854 | ExAcquireFastMutex(&g_processTableLock); 855 | result = UpdateProcessInProcessTable(&entry); 856 | ExReleaseFastMutex(&g_processTableLock); 857 | 858 | if (!result) 859 | return STATUS_NOT_FOUND; 860 | 861 | return status; 862 | } 863 | 864 | NTSTATUS RemoveExcludedImage(ULONGLONG ObjId) 865 | { 866 | return RemoveRuleFromPsRuleList(g_excludeProcessRules, ObjId); 867 | } 868 | 869 | NTSTATUS RemoveAllExcludedImages() 870 | { 871 | return RemoveAllRulesFromPsRuleList(g_excludeProcessRules); 872 | } 873 | -------------------------------------------------------------------------------- /hidden/Hidden/PsMonitor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct _ProcessId { 6 | HANDLE id; 7 | LARGE_INTEGER creationTime; 8 | } ProcessId, *PProcessId; 9 | 10 | NTSTATUS InitializePsMonitor(PDRIVER_OBJECT DriverObject); 11 | NTSTATUS DestroyPsMonitor(); 12 | 13 | BOOLEAN IsProcessExcluded(HANDLE ProcessId); 14 | BOOLEAN IsProcessProtected(HANDLE ProcessId); 15 | 16 | NTSTATUS AddProtectedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId); 17 | NTSTATUS GetProtectedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable); 18 | NTSTATUS SetProtectedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN Enable); 19 | NTSTATUS RemoveProtectedImage(ULONGLONG ObjId); 20 | NTSTATUS RemoveAllProtectedImages(); 21 | 22 | NTSTATUS AddExcludedImage(PUNICODE_STRING ImagePath, ULONG InheritType, BOOLEAN ApplyForProcesses, PULONGLONG ObjId); 23 | NTSTATUS GetExcludedProcessState(HANDLE ProcessId, PULONG InheritType, PBOOLEAN Enable); 24 | NTSTATUS SetExcludedProcessState(HANDLE ProcessId, ULONG InheritType, BOOLEAN Enable); 25 | NTSTATUS RemoveExcludedImage(ULONGLONG ObjId); 26 | NTSTATUS RemoveAllExcludedImages(); 27 | -------------------------------------------------------------------------------- /hidden/Hidden/PsRules.c: -------------------------------------------------------------------------------- 1 | #include "PsRules.h" 2 | 3 | #define PSRULE_ALLOC_TAG 'lRsP' 4 | 5 | typedef struct _PsRulesInternalContext { 6 | RTL_AVL_TABLE table; 7 | ULONGLONG idCounter; 8 | FAST_MUTEX tableLock; 9 | } PsRulesInternalContext, *PPsRulesInternalContext; 10 | 11 | _Function_class_(RTL_AVL_COMPARE_ROUTINE) 12 | RTL_GENERIC_COMPARE_RESULTS ComparePsRuleEntry(struct _RTL_AVL_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct) 13 | { 14 | PPsRuleEntry first = *(PPsRuleEntry*)FirstStruct; 15 | PPsRuleEntry second = *(PPsRuleEntry*)SecondStruct; 16 | INT res; 17 | 18 | UNREFERENCED_PARAMETER(Table); 19 | 20 | res = RtlCompareUnicodeString(&first->imagePath, &second->imagePath, TRUE); 21 | 22 | if (res > 0) 23 | return GenericGreaterThan; 24 | 25 | if (res < 0) 26 | return GenericLessThan; 27 | 28 | return GenericEqual; 29 | } 30 | 31 | _Function_class_(RTL_AVL_ALLOCATE_ROUTINE) 32 | PVOID AllocatePsRuleEntry(struct _RTL_AVL_TABLE *Table, CLONG ByteSize) 33 | { 34 | UNREFERENCED_PARAMETER(Table); 35 | return ExAllocatePoolWithTag(NonPagedPool, ByteSize, PSRULE_ALLOC_TAG); 36 | } 37 | 38 | _Function_class_(RTL_AVL_FREE_ROUTINE) 39 | VOID FreePsRuleEntry(struct _RTL_AVL_TABLE *Table, PVOID Buffer) 40 | { 41 | UNREFERENCED_PARAMETER(Table); 42 | ExFreePoolWithTag(Buffer, PSRULE_ALLOC_TAG); 43 | } 44 | 45 | NTSTATUS InitializePsRuleListContext(PPsRulesContext pRuleContext) 46 | { 47 | NTSTATUS status = STATUS_SUCCESS; 48 | PPsRulesInternalContext context; 49 | 50 | context = (PPsRulesInternalContext)ExAllocatePoolWithTag(NonPagedPool, sizeof(PsRulesInternalContext), PSRULE_ALLOC_TAG); 51 | if (!context) 52 | { 53 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 54 | return STATUS_MEMORY_NOT_ALLOCATED; 55 | } 56 | 57 | context->idCounter = 1; 58 | ExInitializeFastMutex(&context->tableLock); 59 | RtlInitializeGenericTableAvl(&context->table, ComparePsRuleEntry, AllocatePsRuleEntry, FreePsRuleEntry, NULL); 60 | 61 | *pRuleContext = context; 62 | return status; 63 | } 64 | 65 | VOID DestroyPsRuleListContext(PsRulesContext RuleContext) 66 | { 67 | RemoveAllRulesFromPsRuleList(RuleContext); 68 | ExFreePoolWithTag(RuleContext, PSRULE_ALLOC_TAG); 69 | } 70 | 71 | NTSTATUS AddRuleToPsRuleList(PsRulesContext RuleContext, PUNICODE_STRING ImgPath, ULONG InheritType, PPsRuleEntryId EntryId) 72 | { 73 | PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext; 74 | NTSTATUS status = STATUS_SUCCESS; 75 | ULONGLONG guid; 76 | PPsRuleEntry entry; 77 | ULONG entryLen; 78 | BOOLEAN newElem; 79 | PVOID buf; 80 | 81 | if (InheritType > PsRuleTypeMax) 82 | { 83 | DbgPrint("FsFilter1!" __FUNCTION__ ":hata: %d\n", InheritType); 84 | return STATUS_INVALID_PARAMETER_3; 85 | } 86 | 87 | entryLen = sizeof(PsRuleEntry) + ImgPath->Length; 88 | entry = (PPsRuleEntry)ExAllocatePoolWithTag(NonPagedPool, entryLen, PSRULE_ALLOC_TAG); 89 | if (!entry) 90 | { 91 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 92 | return STATUS_MEMORY_NOT_ALLOCATED; 93 | } 94 | 95 | entry->inheritType = InheritType; 96 | entry->len = entryLen; 97 | entry->imagePath.Buffer = (PWCH)(entry + 1); 98 | entry->imagePath.Length = 0; 99 | entry->imagePath.MaximumLength = ImgPath->Length; 100 | RtlCopyUnicodeString(&entry->imagePath, ImgPath); 101 | 102 | ExAcquireFastMutex(&context->tableLock); 103 | guid = context->idCounter++; 104 | entry->guid = guid; 105 | buf = RtlInsertElementGenericTableAvl(&context->table, &entry, sizeof(&entry)/*entryLen*/, &newElem); 106 | ExReleaseFastMutex(&context->tableLock); 107 | 108 | if (!buf) 109 | { 110 | ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG); 111 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 112 | return STATUS_MEMORY_NOT_ALLOCATED; 113 | } 114 | 115 | if (!newElem) 116 | { 117 | ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG); 118 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 119 | return STATUS_DUPLICATE_NAME; 120 | } 121 | 122 | *EntryId = guid; 123 | return status; 124 | } 125 | 126 | NTSTATUS RemoveRuleFromPsRuleList(PsRulesContext RuleContext, PsRuleEntryId EntryId) 127 | { 128 | PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext; 129 | NTSTATUS status = STATUS_NOT_FOUND; 130 | PPsRuleEntry entry, *pentry; 131 | PVOID restartKey = NULL; 132 | 133 | ExAcquireFastMutex(&context->tableLock); 134 | 135 | for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey); 136 | pentry != NULL; 137 | pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey)) 138 | { 139 | entry = *pentry; 140 | if (entry->guid == EntryId) 141 | { 142 | if (!RtlDeleteElementGenericTableAvl(&context->table, pentry)) 143 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 144 | else 145 | ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG); 146 | 147 | status = STATUS_SUCCESS; 148 | break; 149 | } 150 | } 151 | 152 | ExReleaseFastMutex(&context->tableLock); 153 | 154 | return status; 155 | } 156 | 157 | NTSTATUS RemoveAllRulesFromPsRuleList(PsRulesContext RuleContext) 158 | { 159 | PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext; 160 | NTSTATUS status = STATUS_SUCCESS; 161 | PPsRuleEntry entry, *pentry; 162 | PVOID restartKey = NULL; 163 | 164 | ExAcquireFastMutex(&context->tableLock); 165 | 166 | for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey); 167 | pentry != NULL; 168 | pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey)) 169 | { 170 | entry = *pentry; 171 | if (!RtlDeleteElementGenericTableAvl(&context->table, pentry)) 172 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 173 | else 174 | ExFreePoolWithTag(entry, PSRULE_ALLOC_TAG); 175 | 176 | restartKey = NULL; // reset enum 177 | } 178 | 179 | ExReleaseFastMutex(&context->tableLock); 180 | 181 | return status; 182 | } 183 | 184 | NTSTATUS CheckInPsRuleList(PsRulesContext RuleContext, PCUNICODE_STRING ImgPath, PPsRuleEntry Rule, ULONG RuleSize, PULONG OutSize) 185 | { 186 | PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext; 187 | NTSTATUS status = STATUS_NOT_FOUND; 188 | PPsRuleEntry entry, *pentry; 189 | PVOID restartKey = NULL; 190 | 191 | ExAcquireFastMutex(&context->tableLock); 192 | 193 | for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey); 194 | pentry != NULL; 195 | pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey)) 196 | { 197 | entry = *pentry; 198 | if (RtlCompareUnicodeString(&entry->imagePath, ImgPath, TRUE) == 0) 199 | { 200 | *OutSize = entry->len; 201 | 202 | if (RuleSize < entry->len) 203 | { 204 | status = STATUS_BUFFER_TOO_SMALL; 205 | break; 206 | } 207 | 208 | RtlCopyMemory(Rule, entry, entry->len); 209 | status = STATUS_SUCCESS; 210 | break; 211 | } 212 | } 213 | 214 | ExReleaseFastMutex(&context->tableLock); 215 | 216 | return status; 217 | } 218 | 219 | BOOLEAN FindInheritanceInPsRuleList(PsRulesContext RuleContext, PCUNICODE_STRING ImgPath, PULONG pInheritance) 220 | { 221 | PPsRulesInternalContext context = (PPsRulesInternalContext)RuleContext; 222 | PPsRuleEntry entry, *pentry; 223 | PVOID restartKey = NULL; 224 | BOOLEAN result = FALSE; 225 | 226 | ExAcquireFastMutex(&context->tableLock); 227 | 228 | for (pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey); 229 | pentry != NULL; 230 | pentry = RtlEnumerateGenericTableWithoutSplayingAvl(&context->table, &restartKey)) 231 | { 232 | entry = *pentry; 233 | if (RtlCompareUnicodeString(&entry->imagePath, ImgPath, TRUE) == 0) 234 | { 235 | *pInheritance = entry->inheritType; 236 | result = TRUE; 237 | break; 238 | } 239 | } 240 | 241 | ExReleaseFastMutex(&context->tableLock); 242 | 243 | return result; 244 | } 245 | -------------------------------------------------------------------------------- /hidden/Hidden/PsRules.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef PVOID PsRulesContext; 6 | typedef PsRulesContext* PPsRulesContext; 7 | 8 | typedef ULONGLONG PsRuleEntryId; 9 | typedef PsRuleEntryId* PPsRuleEntryId; 10 | 11 | enum PsRuleInheritTypes { 12 | PsRuleTypeWithoutInherit = 0, 13 | PsRuleTypeInherit, 14 | PsRuleTypeInheritOnce, 15 | PsRuleTypeMax 16 | }; 17 | 18 | typedef struct _PsRuleEntry { 19 | ULONGLONG guid; 20 | UNICODE_STRING imagePath; 21 | ULONG inheritType; 22 | ULONG len; 23 | } PsRuleEntry, *PPsRuleEntry; 24 | 25 | NTSTATUS InitializePsRuleListContext(PPsRulesContext pRuleContext); 26 | VOID DestroyPsRuleListContext(PsRulesContext RuleContext); 27 | 28 | NTSTATUS AddRuleToPsRuleList(PsRulesContext RuleContext, PUNICODE_STRING ImgPath, ULONG InheritType, PPsRuleEntryId EntryId); 29 | 30 | NTSTATUS RemoveRuleFromPsRuleList(PsRulesContext RuleContext, PsRuleEntryId EntryId); 31 | NTSTATUS RemoveAllRulesFromPsRuleList(PsRulesContext RuleContext); 32 | 33 | NTSTATUS CheckInPsRuleList(PsRulesContext RuleContext, PCUNICODE_STRING ImgPath, PPsRuleEntry Rule, ULONG RuleSize, PULONG OutSize); 34 | BOOLEAN FindInheritanceInPsRuleList(PsRulesContext RuleContext, PCUNICODE_STRING ImgPath, PULONG pInheritance); 35 | -------------------------------------------------------------------------------- /hidden/Hidden/PsTable.c: -------------------------------------------------------------------------------- 1 | #include "PsTable.h" 2 | #include "Helper.h" 3 | 4 | #define PSTREE_ALLOC_TAG 'rTsP' 5 | 6 | RTL_AVL_TABLE g_processTable; 7 | 8 | _Function_class_(RTL_AVL_COMPARE_ROUTINE) 9 | RTL_GENERIC_COMPARE_RESULTS CompareProcessTableEntry(struct _RTL_AVL_TABLE *Table, PVOID FirstStruct, PVOID SecondStruct) 10 | { 11 | PProcessTableEntry first = (PProcessTableEntry)FirstStruct; 12 | PProcessTableEntry second = (PProcessTableEntry)SecondStruct; 13 | 14 | UNREFERENCED_PARAMETER(Table); 15 | 16 | if (first->processId > second->processId) 17 | return GenericGreaterThan; 18 | 19 | if (first->processId < second->processId) 20 | return GenericLessThan; 21 | 22 | return GenericEqual; 23 | } 24 | 25 | _Function_class_(RTL_AVL_ALLOCATE_ROUTINE) 26 | PVOID AllocateProcessTableEntry(struct _RTL_AVL_TABLE *Table, CLONG ByteSize) 27 | { 28 | UNREFERENCED_PARAMETER(Table); 29 | return ExAllocatePoolWithTag(NonPagedPool, ByteSize, PSTREE_ALLOC_TAG); 30 | } 31 | 32 | _Function_class_(RTL_AVL_FREE_ROUTINE) 33 | VOID FreeProcessTableEntry(struct _RTL_AVL_TABLE *Table, PVOID Buffer) 34 | { 35 | UNREFERENCED_PARAMETER(Table); 36 | ExFreePoolWithTag(Buffer, PSTREE_ALLOC_TAG); 37 | } 38 | 39 | 40 | BOOLEAN AddProcessToProcessTable(PProcessTableEntry entry) 41 | { 42 | BOOLEAN result = FALSE; 43 | 44 | if (RtlInsertElementGenericTableAvl(&g_processTable, entry, sizeof(ProcessTableEntry), &result) == NULL) 45 | return FALSE; 46 | 47 | return result; 48 | } 49 | 50 | BOOLEAN RemoveProcessFromProcessTable(PProcessTableEntry entry) 51 | { 52 | return RtlDeleteElementGenericTableAvl(&g_processTable, entry); 53 | } 54 | 55 | BOOLEAN GetProcessInProcessTable(PProcessTableEntry entry) 56 | { 57 | PProcessTableEntry entry2; 58 | 59 | entry2 = (PProcessTableEntry)RtlLookupElementGenericTableAvl(&g_processTable, entry); 60 | if (entry2) 61 | RtlCopyMemory(entry, entry2, sizeof(ProcessTableEntry)); 62 | 63 | return (entry2 ? TRUE : FALSE); 64 | } 65 | 66 | BOOLEAN UpdateProcessInProcessTable(PProcessTableEntry entry) 67 | { 68 | PProcessTableEntry entry2; 69 | 70 | entry2 = (PProcessTableEntry)RtlLookupElementGenericTableAvl(&g_processTable, entry); 71 | 72 | if (entry2) 73 | RtlCopyMemory(entry2, entry, sizeof(ProcessTableEntry)); 74 | 75 | return (entry2 ? TRUE : FALSE); 76 | } 77 | 78 | 79 | NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEntry, PCUNICODE_STRING, HANDLE)) 80 | { 81 | PSYSTEM_PROCESS_INFORMATION processInfo = NULL, first; 82 | NTSTATUS status; 83 | SIZE_T size = 0, offset; 84 | 85 | 86 | 87 | RtlInitializeGenericTableAvl(&g_processTable, CompareProcessTableEntry, AllocateProcessTableEntry, FreeProcessTableEntry, NULL); 88 | 89 | 90 | 91 | status = QuerySystemInformation(SystemProcessInformation, &processInfo, &size); 92 | if (!NT_SUCCESS(status)) 93 | { 94 | DbgPrint("FsFilter1!" __FUNCTION__ ": query system information(pslist) failed with code:%08x\n", status); 95 | return status; 96 | } 97 | 98 | offset = 0; 99 | first = processInfo; 100 | do 101 | { 102 | ProcessTableEntry entry; 103 | PUNICODE_STRING procName; 104 | CLIENT_ID clientId; 105 | OBJECT_ATTRIBUTES attribs; 106 | HANDLE hProcess; 107 | 108 | 109 | 110 | processInfo = (PSYSTEM_PROCESS_INFORMATION)((SIZE_T)processInfo + offset); 111 | 112 | if (processInfo->ProcessId == 0) 113 | { 114 | offset = processInfo->NextEntryOffset; 115 | continue; 116 | } 117 | 118 | InitializeObjectAttributes(&attribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); 119 | clientId.UniqueProcess = processInfo->ProcessId; 120 | clientId.UniqueThread = 0; 121 | 122 | status = ZwOpenProcess(&hProcess, 0x1000, &attribs, &clientId); 123 | if (!NT_SUCCESS(status)) 124 | { 125 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", processInfo->ProcessId, status); 126 | offset = processInfo->NextEntryOffset; 127 | continue; 128 | } 129 | 130 | status = QueryProcessInformation(ProcessImageFileName, hProcess, &procName, &size); 131 | ZwClose(hProcess); 132 | 133 | if (!NT_SUCCESS(status)) 134 | { 135 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%08x\n", processInfo->ProcessId, status); 136 | offset = processInfo->NextEntryOffset; 137 | continue; 138 | } 139 | 140 | 141 | 142 | RtlZeroMemory(&entry, sizeof(entry)); 143 | entry.processId = processInfo->ProcessId; 144 | 145 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata: %p, %wZ\n", processInfo->ProcessId, procName); 146 | 147 | InitProcessEntryCallback(&entry, procName, processInfo->InheritedFromProcessId); 148 | if (!AddProcessToProcessTable(&entry)) 149 | DbgPrint("FsFilter1!" __FUNCTION__ ": hatae\n", processInfo->ProcessId); 150 | 151 | if (entry.excluded) 152 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%p\n", entry.processId); 153 | 154 | if (entry.protected) 155 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%p\n", entry.processId); 156 | 157 | if (entry.subsystem) 158 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata:%p\n", entry.processId); 159 | 160 | 161 | 162 | FreeInformation(procName); 163 | offset = processInfo->NextEntryOffset; 164 | } 165 | while (offset); 166 | 167 | FreeInformation(first); 168 | return status; 169 | } 170 | 171 | VOID DestroyProcessTable() 172 | { 173 | PProcessTableEntry entry; 174 | PVOID restartKey = NULL; 175 | 176 | for (entry = RtlEnumerateGenericTableWithoutSplayingAvl(&g_processTable, &restartKey); 177 | entry != NULL; 178 | entry = RtlEnumerateGenericTableWithoutSplayingAvl(&g_processTable, &restartKey)) 179 | { 180 | if (!RtlDeleteElementGenericTableAvl(&g_processTable, entry)) 181 | DbgPrint("FsFilter1!" __FUNCTION__ ": hata\n"); 182 | 183 | restartKey = NULL; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /hidden/Hidden/PsTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct _ProcessTableEntry { 6 | HANDLE processId; 7 | 8 | BOOLEAN excluded; 9 | ULONG inheritExclusion; 10 | 11 | BOOLEAN protected; 12 | ULONG inheritProtection; 13 | 14 | BOOLEAN subsystem; 15 | BOOLEAN inited; 16 | 17 | } ProcessTableEntry, *PProcessTableEntry; 18 | 19 | NTSTATUS InitializeProcessTable(VOID(*InitProcessEntryCallback)(PProcessTableEntry, PCUNICODE_STRING, HANDLE)); 20 | VOID DestroyProcessTable(); 21 | 22 | BOOLEAN AddProcessToProcessTable(PProcessTableEntry entry); 23 | BOOLEAN RemoveProcessFromProcessTable(PProcessTableEntry entry); 24 | BOOLEAN GetProcessInProcessTable(PProcessTableEntry entry); 25 | BOOLEAN UpdateProcessInProcessTable(PProcessTableEntry entry); 26 | 27 | -------------------------------------------------------------------------------- /hidden/Hidden/RegFilter.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x1-1/Battleye-VAC-EAC-Kernel-Bypass/0d8c1b80de27dcbbe232d7a3120bc3d13aafdc4d/hidden/Hidden/RegFilter.c -------------------------------------------------------------------------------- /hidden/Hidden/RegFilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | NTSTATUS InitializeRegistryFilter(PDRIVER_OBJECT DriverObject); 6 | NTSTATUS DestroyRegistryFilter(); 7 | 8 | NTSTATUS AddHiddenRegKey(PUNICODE_STRING KeyPath, PULONGLONG ObjId); 9 | NTSTATUS RemoveHiddenRegKey(ULONGLONG ObjId); 10 | NTSTATUS RemoveAllHiddenRegKeys(); 11 | 12 | NTSTATUS AddHiddenRegValue(PUNICODE_STRING ValuePath, PULONGLONG ObjId); 13 | NTSTATUS RemoveHiddenRegValue(ULONGLONG ObjId); 14 | NTSTATUS RemoveAllHiddenRegValues(); 15 | 16 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Commands.cpp: -------------------------------------------------------------------------------- 1 | #include "Commands.h" 2 | #include "Hide.h" 3 | #include "Ignore.h" 4 | #include "Protect.h" 5 | #include "Query.h" 6 | #include "State.h" 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | // ================= 14 | 15 | void LoadCommandsStack(vector& stack) 16 | { 17 | stack.push_back(CommandPtr(new CommandHide())); 18 | stack.push_back(CommandPtr(new CommandUnhide())); 19 | stack.push_back(CommandPtr(new CommandIgnore())); 20 | stack.push_back(CommandPtr(new CommandUnignore())); 21 | stack.push_back(CommandPtr(new CommandProtect())); 22 | stack.push_back(CommandPtr(new CommandUnprotect())); 23 | stack.push_back(CommandPtr(new CommandQuery())); 24 | stack.push_back(CommandPtr(new CommandState())); 25 | } 26 | 27 | // ================= 28 | 29 | void ICommand::InstallCommand(RegistryKey& configKey) 30 | { 31 | throw WException(ERROR_UNSUPPORTED_TYPE, L"Error, install mode is not supported"); 32 | } 33 | 34 | void ICommand::UninstallCommand(RegistryKey& configKey) 35 | { 36 | } 37 | 38 | // ================= 39 | 40 | CommandMode::CommandMode(Arguments& args) : m_type(CommandModeType::Execute) 41 | { 42 | wstring mode, all; 43 | 44 | if (!args.Probe(mode)) 45 | throw WException(ERROR_INVALID_PARAMETER, L"Error, no command, please use 'hiddencli /help'"); 46 | 47 | if (mode == L"/install") 48 | { 49 | args.SwitchToNext(); 50 | m_type = CommandModeType::Install; 51 | LoadConfigPath(args); 52 | } 53 | else if (mode == L"/uninstall") 54 | { 55 | args.SwitchToNext(); 56 | m_type = CommandModeType::Uninstall; 57 | LoadConfigPath(args); 58 | } 59 | 60 | if (m_type == CommandModeType::Uninstall) 61 | { 62 | if (!args.Probe(all) || all != L"all") 63 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid '/unistall' format"); 64 | 65 | args.SwitchToNext(); 66 | } 67 | } 68 | 69 | void CommandMode::LoadConfigPath(Arguments& args) 70 | { 71 | wstring path; 72 | 73 | if (!args.Probe(path) || path.compare(0, 1, L"/") == 0 || path == L"all") 74 | { 75 | m_regConfigPath = L"System\\CurrentControlSet\\Services\\Hidden"; 76 | return; 77 | } 78 | 79 | args.SwitchToNext(); 80 | 81 | m_regConfigPath = L"System\\CurrentControlSet\\Services\\"; 82 | m_regConfigPath += path; 83 | } 84 | 85 | CommandModeType CommandMode::GetModeType() 86 | { 87 | return m_type; 88 | } 89 | 90 | const wstring& CommandMode::GetConfigRegistryKeyPath() 91 | { 92 | return m_regConfigPath; 93 | } 94 | 95 | // ================= 96 | 97 | SingleCommand::SingleCommand(Arguments& args, CommandModeType mode) 98 | { 99 | wstring arg; 100 | bool found = false; 101 | 102 | if (mode == CommandModeType::Uninstall) 103 | { 104 | if (args.SwitchToNext()) 105 | throw WException(ERROR_INVALID_PARAMETER, L"Error, too many arguments"); 106 | 107 | LoadCommandsStack(m_commandsStack); 108 | return; 109 | } 110 | 111 | if (!args.GetNext(arg)) 112 | throw WException(ERROR_INVALID_PARAMETER, L"Error, no command, please use 'hiddencli /help'"); 113 | 114 | LoadCommandsStack(m_commandsStack); 115 | 116 | for (auto it = m_commandsStack.begin(); it != m_commandsStack.end(); it++) 117 | { 118 | if ((*it)->CompareCommand(arg)) 119 | { 120 | (*it)->LoadArgs(args, mode); 121 | m_current = *it; 122 | found = true; 123 | break; 124 | } 125 | } 126 | 127 | if (!found) 128 | throw WException(ERROR_INVALID_PARAMETER, L"Error, unknown command, please use 'hiddencli /help'"); 129 | 130 | if (args.SwitchToNext()) 131 | throw WException(ERROR_INVALID_PARAMETER, L"Error, too many arguments"); 132 | } 133 | 134 | SingleCommand::~SingleCommand() 135 | { 136 | } 137 | 138 | void SingleCommand::Perform(Connection& connection) 139 | { 140 | m_current->PerformCommand(connection); 141 | } 142 | 143 | void SingleCommand::Install(RegistryKey& configKey) 144 | { 145 | m_current->InstallCommand(configKey); 146 | } 147 | 148 | void SingleCommand::Uninstall(RegistryKey& configKey) 149 | { 150 | for (auto it = m_commandsStack.begin(); it != m_commandsStack.end(); it++) 151 | { 152 | try 153 | { 154 | (*it)->UninstallCommand(configKey); 155 | } 156 | catch (WException&) 157 | { 158 | // Skip exceptions because we don't wan't break uninstall on registry deletion fails 159 | } 160 | } 161 | } 162 | 163 | // ================= 164 | 165 | MultipleCommands::MultipleCommands(Arguments& args, CommandModeType mode) 166 | { 167 | wstring arg; 168 | 169 | if (mode == CommandModeType::Uninstall) 170 | throw WException(ERROR_INVALID_PARAMETER, L"Error, /uninstall can't be combined with /multi"); 171 | 172 | if (!args.GetNext(arg)) 173 | throw WException(ERROR_INVALID_PARAMETER, L"Error, no command, please use 'hiddencli /help'"); 174 | 175 | LoadCommandsStack(m_commandsStack); 176 | 177 | do 178 | { 179 | bool found = false; 180 | 181 | for (auto it = m_commandsStack.begin(); it != m_commandsStack.end(); it++) 182 | { 183 | if ((*it)->CompareCommand(arg)) 184 | { 185 | CommandPtr command = (*it)->CreateInstance(); 186 | command->LoadArgs(args, mode); 187 | m_currentStack.push_back(command); 188 | found = true; 189 | break; 190 | } 191 | } 192 | 193 | if (!found) 194 | throw WException(ERROR_INVALID_PARAMETER, L"Error, unknown command, please use 'hiddencli /help'"); 195 | } 196 | while (args.GetNext(arg)); 197 | } 198 | 199 | MultipleCommands::~MultipleCommands() 200 | { 201 | } 202 | 203 | void MultipleCommands::Perform(Connection& connection) 204 | { 205 | for (auto it = m_currentStack.begin(); it != m_currentStack.end(); it++) 206 | (*it)->PerformCommand(connection); 207 | } 208 | 209 | void MultipleCommands::Install(RegistryKey& configKey) 210 | { 211 | for (auto it = m_currentStack.begin(); it != m_currentStack.end(); it++) 212 | (*it)->InstallCommand(configKey); 213 | } 214 | 215 | void MultipleCommands::Uninstall(RegistryKey& configKey) 216 | { 217 | throw WException(ERROR_UNSUPPORTED_TYPE, L"Error, uninstall mode is not supported"); 218 | } 219 | 220 | // ================= 221 | 222 | class ArgsParser 223 | { 224 | private: 225 | 226 | shared_ptr m_args; 227 | bool m_haveArgs; 228 | 229 | public: 230 | 231 | ArgsParser(wstring& line) : m_haveArgs(false) 232 | { 233 | int argc; 234 | LPWSTR* argv; 235 | 236 | if (line.compare(0, 1, L";") == 0) // comment 237 | return; 238 | 239 | if (all_of(line.begin(), line.end(), isspace)) // whitespace only string 240 | return; 241 | 242 | argv = CommandLineToArgvW(line.c_str(), &argc); 243 | if (!argv) 244 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid command format"); 245 | 246 | try 247 | { 248 | m_args.reset(new Arguments(argc, argv, 0)); 249 | } 250 | catch (WException& e) 251 | { 252 | LocalFree(argv); 253 | throw e; 254 | } 255 | 256 | LocalFree(argv); 257 | m_haveArgs = true; 258 | } 259 | 260 | bool HaveArgs() 261 | { 262 | return m_haveArgs; 263 | } 264 | 265 | Arguments& GetArgs() 266 | { 267 | return *m_args.get(); 268 | } 269 | 270 | }; 271 | 272 | MultipleCommandsFromFile::MultipleCommandsFromFile(Arguments& args, CommandModeType mode) 273 | { 274 | wstring configFile; 275 | 276 | if (mode == CommandModeType::Uninstall) 277 | throw WException(ERROR_INVALID_PARAMETER, L"Error, /uninstall can't be combined with /config"); 278 | 279 | if (!args.GetNext(configFile)) 280 | throw WException(ERROR_INVALID_PARAMETER, L"Error, no command, please use 'hiddencli /help'"); 281 | 282 | if (args.SwitchToNext()) 283 | throw WException(ERROR_INVALID_PARAMETER, L"Error, too many arguments"); 284 | 285 | wifstream fconfig(configFile); 286 | wstring line; 287 | 288 | LoadCommandsStack(m_commandsStack); 289 | 290 | while (getline(fconfig, line)) 291 | { 292 | ArgsParser parser(line); 293 | wstring arg; 294 | 295 | if (parser.HaveArgs()) 296 | { 297 | Arguments lineArgs = parser.GetArgs(); 298 | 299 | if (!lineArgs.GetNext(arg)) 300 | throw WException(ERROR_INVALID_PARAMETER, L"Error, no command, please use 'hiddencli /help'"); 301 | 302 | do 303 | { 304 | bool found = false; 305 | 306 | for (auto it = m_commandsStack.begin(); it != m_commandsStack.end(); it++) 307 | { 308 | if ((*it)->CompareCommand(arg)) 309 | { 310 | CommandPtr command = (*it)->CreateInstance(); 311 | command->LoadArgs(lineArgs, mode); 312 | m_currentStack.push_back(command); 313 | found = true; 314 | break; 315 | } 316 | } 317 | 318 | if (!found) 319 | throw WException(ERROR_INVALID_PARAMETER, L"Error, unknown command, please use 'hiddencli /help'"); 320 | } 321 | while (lineArgs.GetNext(arg)); 322 | } 323 | } 324 | } 325 | 326 | MultipleCommandsFromFile::~MultipleCommandsFromFile() 327 | { 328 | } 329 | 330 | void MultipleCommandsFromFile::Perform(Connection& connection) 331 | { 332 | for (auto it = m_currentStack.begin(); it != m_currentStack.end(); it++) 333 | (*it)->PerformCommand(connection); 334 | } 335 | 336 | void MultipleCommandsFromFile::Install(RegistryKey& configKey) 337 | { 338 | for (auto it = m_currentStack.begin(); it != m_currentStack.end(); it++) 339 | (*it)->InstallCommand(configKey); 340 | } 341 | 342 | void MultipleCommandsFromFile::Uninstall(RegistryKey& configKey) 343 | { 344 | throw WException(ERROR_UNSUPPORTED_TYPE, L"Error, uninstall mode is not supported"); 345 | } 346 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Commands.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Helper.h" 4 | #include "Connection.h" 5 | #include 6 | 7 | enum CommandModeType { 8 | Execute, 9 | Install, 10 | Uninstall 11 | }; 12 | 13 | class ICommand 14 | { 15 | public: 16 | typedef std::shared_ptr CommandPtrInternal; 17 | 18 | virtual ~ICommand() {}; 19 | 20 | virtual bool CompareCommand(std::wstring& command) = 0; 21 | virtual void LoadArgs(Arguments& args, CommandModeType mode) = 0; 22 | virtual void PerformCommand(Connection& connection) = 0; 23 | virtual void InstallCommand(RegistryKey& configKey); 24 | virtual void UninstallCommand(RegistryKey& configKey); 25 | 26 | virtual CommandPtrInternal CreateInstance() = 0; 27 | }; 28 | 29 | typedef ICommand::CommandPtrInternal CommandPtr; 30 | 31 | class CommandMode 32 | { 33 | std::wstring m_regConfigPath; 34 | CommandModeType m_type; 35 | 36 | void LoadConfigPath(Arguments& args); 37 | 38 | public: 39 | CommandMode(Arguments& args); 40 | 41 | CommandModeType GetModeType(); 42 | const std::wstring& GetConfigRegistryKeyPath(); 43 | }; 44 | 45 | class ICommandTemplate 46 | { 47 | public: 48 | virtual ~ICommandTemplate() {} 49 | virtual void Perform(Connection& connection) = 0; 50 | virtual void Install(RegistryKey& configKey) = 0; 51 | virtual void Uninstall(RegistryKey& configKey) = 0; 52 | }; 53 | 54 | typedef std::shared_ptr CommandTemplatePtr; 55 | 56 | class SingleCommand : public ICommandTemplate 57 | { 58 | std::vector m_commandsStack; 59 | CommandPtr m_current; 60 | 61 | public: 62 | 63 | SingleCommand(Arguments& args, CommandModeType mode); 64 | virtual ~SingleCommand(); 65 | 66 | virtual void Perform(Connection& connection); 67 | virtual void Install(RegistryKey& configKey); 68 | virtual void Uninstall(RegistryKey& configKey); 69 | }; 70 | 71 | class MultipleCommands : public ICommandTemplate 72 | { 73 | std::vector m_commandsStack; 74 | std::vector m_currentStack; 75 | 76 | public: 77 | 78 | MultipleCommands(Arguments& args, CommandModeType mode); 79 | virtual ~MultipleCommands(); 80 | 81 | virtual void Perform(Connection& connection); 82 | virtual void Install(RegistryKey& configKey); 83 | virtual void Uninstall(RegistryKey& configKey); 84 | }; 85 | 86 | class MultipleCommandsFromFile : public ICommandTemplate 87 | { 88 | std::vector m_commandsStack; 89 | std::vector m_currentStack; 90 | 91 | public: 92 | 93 | MultipleCommandsFromFile(Arguments& args, CommandModeType mode); 94 | virtual ~MultipleCommandsFromFile(); 95 | 96 | virtual void Perform(Connection& connection); 97 | virtual void Install(RegistryKey& configKey); 98 | virtual void Uninstall(RegistryKey& configKey); 99 | }; 100 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Connection.cpp: -------------------------------------------------------------------------------- 1 | #include "Connection.h" 2 | 3 | using namespace std; 4 | 5 | Connection::Connection(Arguments& args) : 6 | m_context(nullptr) 7 | { 8 | wstring arg; 9 | 10 | if (!args.Probe(arg)) 11 | return; 12 | 13 | do 14 | { 15 | if (arg == L"/gate") 16 | { 17 | args.SwitchToNext(); 18 | if (!args.GetNext(m_deviceName)) 19 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument for command 'gate'"); 20 | 21 | if (m_deviceName.compare(0, 1, L"\\") != 0) 22 | m_deviceName.insert(0, L"\\\\.\\"); 23 | } 24 | else 25 | { 26 | break; 27 | } 28 | } 29 | while (args.Probe(arg)); 30 | } 31 | 32 | Connection::~Connection() 33 | { 34 | if (m_context) 35 | Hid_Destroy(m_context); 36 | } 37 | 38 | void Connection::Open() 39 | { 40 | HidStatus status; 41 | const wchar_t* deviceName = nullptr; 42 | 43 | if (m_deviceName.size()) 44 | deviceName = m_deviceName.c_str(); 45 | 46 | status = Hid_Initialize(&m_context, deviceName); 47 | if (!HID_STATUS_SUCCESSFUL(status)) 48 | throw WException(HID_STATUS_CODE(status), L"Error, can't connect to gate"); 49 | } 50 | 51 | HidContext Connection::GetContext() 52 | { 53 | return m_context; 54 | } 55 | 56 | LibInitializator::LibInitializator() 57 | { 58 | HidStatus status = Hid_InitializeWithNoConnection(); 59 | if (!HID_STATUS_SUCCESSFUL(status)) 60 | throw WException(HID_STATUS_CODE(status), L"Error, init hidden lib"); 61 | } 62 | 63 | LibInitializator::~LibInitializator() 64 | { 65 | // We don't need release lib resources because in case of the 66 | // Hid_InitializeWithNoConnection() there aren't any dynamic data 67 | } 68 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Connection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Helper.h" 4 | #include "../HiddenLib/HiddenLib.h" 5 | 6 | class Connection 7 | { 8 | private: 9 | 10 | HidContext m_context; 11 | 12 | std::wstring m_deviceName; 13 | 14 | public: 15 | 16 | Connection(Arguments& args); 17 | ~Connection(); 18 | 19 | void Open(); 20 | 21 | HidContext GetContext(); 22 | }; 23 | 24 | class LibInitializator 25 | { 26 | public: 27 | LibInitializator(); 28 | ~LibInitializator(); 29 | }; 30 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Helper.cpp: -------------------------------------------------------------------------------- 1 | #include "helper.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | // ================= 7 | 8 | std::wstringstream g_stdout; 9 | std::wstringstream g_stderr; 10 | 11 | // ================= 12 | 13 | WException::WException(unsigned int Code, wchar_t* Format, ...) : 14 | m_errorCode(Code) 15 | { 16 | wchar_t buffer[256]; 17 | 18 | va_list args; 19 | va_start(args, Format); 20 | _vsnwprintf_s(buffer, _countof(buffer), _TRUNCATE, Format, args); 21 | va_end(args); 22 | 23 | m_errorMessage = buffer; 24 | } 25 | 26 | const wchar_t* WException::What() 27 | { 28 | return m_errorMessage.c_str(); 29 | } 30 | 31 | unsigned int WException::Code() 32 | { 33 | return m_errorCode; 34 | } 35 | 36 | // ================= 37 | 38 | Arguments::Arguments(int argc, wchar_t* argv[], int start) : 39 | m_argPointer(0) 40 | { 41 | for (int i = start; i < argc; i++) 42 | m_arguments.push_back(argv[i]); 43 | } 44 | 45 | size_t Arguments::ArgsCount() 46 | { 47 | return m_arguments.size(); 48 | } 49 | 50 | bool Arguments::Probe(std::wstring& arg) 51 | { 52 | if (m_argPointer >= m_arguments.size()) 53 | return false; 54 | 55 | arg = m_arguments[m_argPointer]; 56 | return true; 57 | } 58 | 59 | bool Arguments::SwitchToNext() 60 | { 61 | if (m_argPointer >= m_arguments.size()) 62 | return false; 63 | 64 | m_argPointer++; 65 | return true; 66 | } 67 | 68 | bool Arguments::GetNext(wstring& arg) 69 | { 70 | if (m_argPointer >= m_arguments.size()) 71 | return false; 72 | 73 | arg = m_arguments[m_argPointer++]; 74 | return true; 75 | } 76 | 77 | // ================= 78 | 79 | Handle::Handle(HANDLE handle) : 80 | m_handle(handle), 81 | m_error(::GetLastError()) 82 | { 83 | } 84 | 85 | Handle::~Handle() 86 | { 87 | if (m_handle != INVALID_HANDLE_VALUE) 88 | ::CloseHandle(m_handle); 89 | } 90 | 91 | HANDLE Handle::Get() 92 | { 93 | return m_handle; 94 | } 95 | 96 | DWORD Handle::Error() 97 | { 98 | return m_error; 99 | } 100 | 101 | // ================= 102 | 103 | RegistryKey::RegistryKey(std::wstring regKey, HKEY root, REGSAM access, bool newKey) : m_hkey(NULL) 104 | { 105 | if (newKey) 106 | { 107 | LONG status = RegCreateKeyExW(root, regKey.c_str(), 0, NULL, 0, access, NULL, &m_hkey, NULL); 108 | if (status != ERROR_SUCCESS) 109 | throw WException(status, L"Error, can't create registry key"); 110 | } 111 | else 112 | { 113 | LONG status = RegOpenKeyExW(root, regKey.c_str(), 0, access, &m_hkey); 114 | if (status != ERROR_SUCCESS) 115 | throw WException(status, L"Error, can't open registry key"); 116 | } 117 | } 118 | 119 | RegistryKey::~RegistryKey() 120 | { 121 | RegCloseKey(m_hkey); 122 | } 123 | 124 | void RegistryKey::CopyTreeFrom(RegistryKey& src) 125 | { 126 | LONG status; 127 | 128 | status = RegCopyTree(src.m_hkey, NULL, m_hkey); 129 | if (status != ERROR_SUCCESS) 130 | throw WException(status, L"Error, can't copy registry tree"); 131 | } 132 | 133 | void RegistryKey::DeleteKey(std::wstring regKey, HKEY root) 134 | { 135 | LONG status; 136 | 137 | status = RegDeleteTreeW(root, regKey.c_str()); 138 | if (status != ERROR_SUCCESS) 139 | throw WException(status, L"Error, can't copy registry tree"); 140 | } 141 | 142 | void RegistryKey::SetDwordValue(const wchar_t* name, DWORD value) 143 | { 144 | LONG status; 145 | 146 | status = RegSetValueExW(m_hkey, name, NULL, REG_DWORD, (LPBYTE)&value, sizeof(value)); 147 | if (status != ERROR_SUCCESS) 148 | throw WException(status, L"Error, can't set registry value"); 149 | } 150 | 151 | DWORD RegistryKey::GetDwordValue(const wchar_t* name, DWORD defValue) 152 | { 153 | DWORD value, size = sizeof(value), type = REG_DWORD; 154 | LONG status; 155 | 156 | status = RegQueryValueEx(m_hkey, name, NULL, &type, (LPBYTE)&value, &size); 157 | if (status != ERROR_SUCCESS) 158 | { 159 | if (status != ERROR_FILE_NOT_FOUND) 160 | throw WException(status, L"Error, can't query registry value"); 161 | 162 | return defValue; 163 | } 164 | 165 | return value; 166 | } 167 | 168 | void RegistryKey::SetStrValue(const wchar_t* name, std::wstring& value, bool expanded) 169 | { 170 | LONG status; 171 | 172 | status = RegSetValueExW(m_hkey, name, NULL, (expanded ? REG_EXPAND_SZ : REG_SZ), (LPBYTE)value.c_str(), (DWORD)(value.size() + 1) * sizeof(wchar_t)); 173 | if (status != ERROR_SUCCESS) 174 | throw WException(status, L"Error, can't set registry value"); 175 | } 176 | 177 | void RegistryKey::GetStrValue(const wchar_t* name, std::wstring& value, const wchar_t* defValue) 178 | { 179 | DWORD size = 0, type = REG_SZ; 180 | LONG status; 181 | 182 | status = RegQueryValueExW(m_hkey, name, NULL, &type, NULL, &size); 183 | if (status != ERROR_SUCCESS) 184 | { 185 | if (status != ERROR_FILE_NOT_FOUND) 186 | throw WException(status, L"Error, can't query registry value"); 187 | 188 | value = defValue; 189 | return; 190 | } 191 | 192 | if (type != REG_SZ && type != REG_EXPAND_SZ) 193 | throw WException(status, L"Error, invalid registry key type"); 194 | 195 | if (size == 0) 196 | return; 197 | 198 | value.clear(); 199 | value.insert(0, size / sizeof(wchar_t), L'\0'); 200 | 201 | status = RegQueryValueExW(m_hkey, name, NULL, &type, (LPBYTE)value.c_str(), &size); 202 | if (status != ERROR_SUCCESS) 203 | throw WException(status, L"Error, can't query registry value"); 204 | 205 | while (value.size() > 0 && value[value.size() - 1] == L'\0') 206 | value.pop_back(); 207 | } 208 | 209 | void RegistryKey::SetMultiStrValue(const wchar_t* name, const std::vector& strs) 210 | { 211 | DWORD size = 0, offset = 0; 212 | shared_ptr buffer; 213 | LONG status; 214 | 215 | for (auto it = strs.begin(); it != strs.end(); it++) 216 | { 217 | if (it->size() > 0) 218 | size += (DWORD)(it->size() + 1) * sizeof(wchar_t); 219 | } 220 | 221 | if (size == 0) 222 | { 223 | WCHAR value = 0; 224 | status = RegSetValueExW(m_hkey, name, NULL, REG_MULTI_SZ, (LPBYTE)&value, 2); 225 | if (status != ERROR_SUCCESS) 226 | throw WException(status, L"Error, can't set registry value"); 227 | 228 | return; 229 | } 230 | 231 | buffer.reset(new BYTE[size]); 232 | memset(buffer.get(), 0, size); 233 | 234 | for (auto it = strs.begin(); it != strs.end(); it++) 235 | { 236 | if (it->size() == 0) 237 | continue; 238 | 239 | DWORD strSize = (DWORD)(it->size() + 1) * sizeof(wchar_t); 240 | memcpy(buffer.get() + offset, it->c_str(), strSize); 241 | offset += strSize; 242 | } 243 | 244 | status = RegSetValueExW(m_hkey, name, NULL, REG_MULTI_SZ, buffer.get(), size); 245 | if (status != ERROR_SUCCESS) 246 | throw WException(status, L"Error, can't set registry value"); 247 | } 248 | 249 | void RegistryKey::GetMultiStrValue(const wchar_t* name, std::vector& strs) 250 | { 251 | DWORD size = 0, type = REG_MULTI_SZ; 252 | shared_ptr buffer; 253 | LPWSTR bufferPtr; 254 | LONG status; 255 | 256 | strs.clear(); 257 | 258 | status = RegQueryValueExW(m_hkey, name, NULL, &type, NULL, &size); 259 | if (status != ERROR_SUCCESS) 260 | { 261 | if (status != ERROR_FILE_NOT_FOUND) 262 | throw WException(status, L"Error, can't query registry value"); 263 | 264 | return; 265 | } 266 | 267 | if (type != REG_MULTI_SZ) 268 | throw WException(status, L"Error, invalid registry key type"); 269 | 270 | if (size == 0) 271 | return; 272 | 273 | buffer.reset(new BYTE[size + sizeof(WCHAR)]); 274 | memset(buffer.get(), 0, size + sizeof(WCHAR)); 275 | 276 | status = RegQueryValueExW(m_hkey, name, NULL, &type, buffer.get(), &size); 277 | if (status != ERROR_SUCCESS) 278 | throw WException(status, L"Error, can't query registry value"); 279 | 280 | bufferPtr = (LPWSTR)buffer.get(); 281 | while (size > 1) 282 | { 283 | ULONG inx, delta = 0; 284 | ULONG len = size / sizeof(WCHAR); 285 | 286 | for (inx = 0; inx < len; inx++) 287 | { 288 | if (bufferPtr[inx] == L'\0') 289 | { 290 | delta = 1; 291 | break; 292 | } 293 | } 294 | 295 | if (inx > 0) 296 | strs.push_back(bufferPtr); 297 | 298 | size -= (inx + delta) * sizeof(WCHAR); 299 | bufferPtr += (inx + delta); 300 | } 301 | } 302 | 303 | void RegistryKey::RemoveValue(const wchar_t* name) 304 | { 305 | LONG status = RegDeleteKeyValueW(m_hkey, NULL, name); 306 | if (status != ERROR_SUCCESS) 307 | throw WException(status, L"Error, can't delete registry value"); 308 | } 309 | 310 | // ================= 311 | 312 | HidRegRootTypes GetRegType(wstring& path) 313 | { 314 | static wchar_t regHKLM[] = L"HKLM\\"; 315 | static wchar_t regHKCU[] = L"HKCU\\"; 316 | static wchar_t regHKU[] = L"HKU\\"; 317 | 318 | if (path.compare(0, _countof(regHKLM) - 1, regHKLM) == 0) 319 | return HidRegRootTypes::RegHKLM; 320 | else if (path.compare(0, _countof(regHKCU) - 1, regHKCU) == 0) 321 | return HidRegRootTypes::RegHKCU; 322 | else if (path.compare(0, _countof(regHKU) - 1, regHKU) == 0) 323 | return HidRegRootTypes::RegHKU; 324 | else 325 | throw WException(ERROR_INVALID_DATA, L"Error, invalid registry prefix"); 326 | } 327 | 328 | HidPsInheritTypes LoadInheritOption(Arguments& args, HidPsInheritTypes default) 329 | { 330 | wstring arg; 331 | 332 | if (!args.Probe(arg)) 333 | return default; 334 | 335 | if (arg == L"inherit:none") 336 | { 337 | args.SwitchToNext(); 338 | return HidPsInheritTypes::WithoutInherit; 339 | } 340 | else if (arg == L"inherit:always") 341 | { 342 | args.SwitchToNext(); 343 | return HidPsInheritTypes::InheritAlways; 344 | } 345 | else if (arg == L"inherit:once") 346 | { 347 | args.SwitchToNext(); 348 | return HidPsInheritTypes::InheritOnce; 349 | } 350 | 351 | return default; 352 | } 353 | 354 | bool LoadApplyOption(Arguments& args, bool applyByDefault) 355 | { 356 | wstring arg; 357 | 358 | if (!args.Probe(arg)) 359 | return applyByDefault; 360 | 361 | if (arg == L"apply:fornew") 362 | { 363 | args.SwitchToNext(); 364 | return false; 365 | } 366 | else if (arg == L"apply:forall") 367 | { 368 | args.SwitchToNext(); 369 | return true; 370 | } 371 | 372 | return applyByDefault; 373 | } 374 | 375 | const wchar_t* ConvertInheritTypeToUnicode(HidPsInheritTypes type) 376 | { 377 | switch (type) 378 | { 379 | case HidPsInheritTypes::WithoutInherit: 380 | return L"none"; 381 | break; 382 | case HidPsInheritTypes::InheritOnce: 383 | return L"once"; 384 | break; 385 | case HidPsInheritTypes::InheritAlways: 386 | return L"always"; 387 | break; 388 | } 389 | return L"unknown"; 390 | } 391 | 392 | const wchar_t* ConvertRegRootTypeToUnicode(HidRegRootTypes type) 393 | { 394 | switch (type) 395 | { 396 | case HidRegRootTypes::RegHKCU: 397 | return L"HKCU"; 398 | break; 399 | case HidRegRootTypes::RegHKLM: 400 | return L"HKLM"; 401 | break; 402 | case HidRegRootTypes::RegHKU: 403 | return L"HKU"; 404 | break; 405 | } 406 | return L"unknown"; 407 | } 408 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../HiddenLib/HiddenLib.h" 11 | 12 | extern std::wstringstream g_stdout; 13 | extern std::wstringstream g_stderr; 14 | 15 | class WException 16 | { 17 | std::wstring m_errorMessage; 18 | unsigned int m_errorCode; 19 | 20 | public: 21 | 22 | WException(unsigned int Code, wchar_t* Format, ...); 23 | 24 | const wchar_t* What(); 25 | unsigned int Code(); 26 | }; 27 | 28 | class Arguments 29 | { 30 | std::vector m_arguments; 31 | unsigned int m_argPointer; 32 | 33 | public: 34 | 35 | Arguments(int argc, wchar_t* argv[], int start = 1); 36 | 37 | size_t ArgsCount(); 38 | 39 | bool Probe(std::wstring& arg); 40 | bool SwitchToNext(); 41 | bool GetNext(std::wstring& arg); 42 | }; 43 | 44 | class Handle 45 | { 46 | private: 47 | DWORD m_error; 48 | HANDLE m_handle; 49 | 50 | public: 51 | 52 | Handle(HANDLE handle); 53 | ~Handle(); 54 | 55 | HANDLE Get(); 56 | DWORD Error(); 57 | 58 | }; 59 | 60 | class RegistryKey 61 | { 62 | private: 63 | 64 | HKEY m_hkey; 65 | 66 | public: 67 | 68 | RegistryKey(std::wstring regKey, HKEY root = HKEY_LOCAL_MACHINE, REGSAM access = KEY_ALL_ACCESS | KEY_WOW64_64KEY, bool newKey = false); 69 | ~RegistryKey(); 70 | 71 | void CopyTreeFrom(RegistryKey& src); 72 | 73 | void SetDwordValue(const wchar_t* name, DWORD value); 74 | DWORD GetDwordValue(const wchar_t* name, DWORD defValue); 75 | 76 | void SetStrValue(const wchar_t* name, std::wstring& value, bool expanded = false); 77 | void GetStrValue(const wchar_t* name, std::wstring& value, const wchar_t* defValue); 78 | 79 | void SetMultiStrValue(const wchar_t* name, const std::vector& strs); 80 | void GetMultiStrValue(const wchar_t* name, std::vector& strs); 81 | 82 | void RemoveValue(const wchar_t* name); 83 | 84 | static void DeleteKey(std::wstring regKey, HKEY root = HKEY_LOCAL_MACHINE); 85 | }; 86 | 87 | enum EObjTypes { 88 | TypeFile, 89 | TypeDir, 90 | TypeRegKey, 91 | TypeRegVal, 92 | }; 93 | 94 | enum EProcTypes { 95 | TypeProcessId, 96 | TypeImage, 97 | }; 98 | 99 | HidRegRootTypes GetRegType(std::wstring& path); 100 | 101 | HidPsInheritTypes LoadInheritOption(Arguments& args, HidPsInheritTypes default); 102 | bool LoadApplyOption(Arguments& args, bool applyByDefault); 103 | 104 | const wchar_t* ConvertInheritTypeToUnicode(HidPsInheritTypes type); 105 | const wchar_t* ConvertRegRootTypeToUnicode(HidRegRootTypes type); 106 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/HiddenCLI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "Helper.h" 6 | #include "Connection.h" 7 | #include "Commands.h" 8 | 9 | using namespace std; 10 | 11 | bool PrintUsage(Arguments& args) 12 | { 13 | wstring command; 14 | 15 | if (!args.Probe(command)) 16 | return false; 17 | 18 | if (command != L"/help" && command != L"/?") 19 | return false; 20 | 21 | wchar_t message[] = 22 | L"hiddencli [mode] [connection] [perform] \n" 23 | L"hiddencli /help\n" 24 | L"\n" 25 | L"mode:\n" 26 | L"\n" 27 | L" By default perform current commands\n" 28 | L"\n" 29 | L" /install [%driver%]\n" 30 | L" Install commands to registry without execution, driver will load them on\n" 31 | L" start. If this flag is set connection parameters shouldn't be set. Optional\n" 32 | L" parameter is used for set valid registry path if driver name is changed, by\n" 33 | L" default \"hidden\"\n" 34 | L"\n" 35 | L" /uninstall [%driver%] all\n" 36 | L" Uninstall all configs from registry. This flag is all-sufficient therefore\n" 37 | L" if this flag is set no other parameters and commands should be set after\n" 38 | L"\n" 39 | L"connection:\n" 40 | L"\n" 41 | L" /gate <%name%>\n" 42 | L" Set specific connection gate name. By default \"HiddenGate\" is used\n" 43 | L"\n" 44 | L"perform:\n" 45 | L"\n" 46 | L" By default perform one command by one execution\n" 47 | L"\n" 48 | L" /multi\n" 49 | L" Enable multiple commands per execution, just type commands one by one\n" 50 | L" without any separator\n" 51 | L"\n" 52 | L" /config <%path%>\n" 53 | L" Loads multiple commands from file, each command should be on separate line\n" 54 | L"\n" 55 | L"commands:\n" 56 | L"\n" 57 | L" /state \n" 58 | L" Enable or disable hidden\n" 59 | L"\n" 60 | L" /query state\n" 61 | L" Get enforcement state\n" 62 | L"\n" 63 | L" /hide <%path%>\n" 64 | L" Hide filesystem or registry object by path\n" 65 | L"\n" 66 | L" /unhide all\n" 67 | L" Unhide all filesystem or registry object by selected type\n" 68 | L"\n" 69 | L" /unhide <%ruleid%>\n" 70 | L" Unhide all filesystem or registry object by selected type and rule ID\n" 71 | L"\n" 72 | L" /ignore image [inherit:] [apply:] <%path%>\n" 73 | L" Set rule that allows to see hidden filesystem and registry objects for\n" 74 | L" processes with specific image path\n" 75 | L"\n" 76 | L" /unignore <%ruleid%>\n" 77 | L" Remove rule that allows to see hidden filesystem and registry objects by\n" 78 | L" rule ID\n" 79 | L"\n" 80 | L" /unignore all\n" 81 | L" Remove all rules that allow to see hidden filesystem and registry objects\n" 82 | L"\n" 83 | L" /ignore pid [inherit:] <%pid%>\n" 84 | L" Turn on abillity to see hidden filesystem and registry objects for\n" 85 | L" specific process by PID\n" 86 | L"\n" 87 | L" /unignore pid <%pid%>\n" 88 | L" Turn off abillity to see hidden filesystem and registry objects for\n" 89 | L" specific process by PID\n" 90 | L"\n" 91 | L" /protect image [inherit:] [apply:] <%path%>\n" 92 | L" Set rule that allows to enable process protection for processes with\n" 93 | L" specific image path\n" 94 | L"\n" 95 | L" /unprotect <%ruleid%>\n" 96 | L" Remove rule that enables process protection by rule ID\n" 97 | L"\n" 98 | L" /unprotect all\n" 99 | L" Remove all rules that enable process protection\n" 100 | L"\n" 101 | L" /protect pid [inherit:] <%pid%>\n" 102 | L" Turn on protection for specific process by PID\n" 103 | L"\n" 104 | L" /unprotect pid <%pid%>\n" 105 | L" Turn off protection for specific process by PID\n" 106 | L"\n" 107 | L" /query process <%pid%>\n" 108 | L" Query information about state of the process by PID\n" 109 | L"\n" 110 | L"options:\n" 111 | L"\n" 112 | L" inherit:none\n" 113 | L" Disable inheritance of the protected or ignored state\n" 114 | L"\n" 115 | L" inherit:once\n" 116 | L" Child process will inherit the same state but its children no\n" 117 | L"\n" 118 | L" inherit:always\n" 119 | L" Child process will inherit the same state and its children too\n" 120 | L"\n" 121 | L" apply:forall\n" 122 | L" Apply policy for existing processes and for all new processes\n" 123 | L"\n" 124 | L" apply:fornew\n" 125 | L" Don't apply policy for existing processes only for new\n"; 126 | 127 | wcout << message << endl; 128 | return true; 129 | } 130 | 131 | CommandTemplatePtr LoadCommandsTemplate(Arguments& args, CommandMode& mode) 132 | { 133 | wstring templateType; 134 | 135 | if (mode.GetModeType() == CommandModeType::Uninstall) 136 | return CommandTemplatePtr(new SingleCommand(args, mode.GetModeType())); 137 | 138 | if (!args.Probe(templateType)) 139 | throw WException(ERROR_INVALID_PARAMETER, L"Error, unknown perform mode, please use 'hiddencli /help'"); 140 | 141 | if (templateType == L"/multi") 142 | { 143 | args.SwitchToNext(); 144 | return CommandTemplatePtr(new MultipleCommands(args, mode.GetModeType())); 145 | } 146 | else if (templateType == L"/config") 147 | { 148 | args.SwitchToNext(); 149 | return CommandTemplatePtr(new MultipleCommandsFromFile(args, mode.GetModeType())); 150 | } 151 | 152 | return CommandTemplatePtr(new SingleCommand(args, mode.GetModeType())); 153 | } 154 | 155 | int wmain(int argc, wchar_t* argv[]) 156 | { 157 | try 158 | { 159 | Arguments arguments(argc , argv); 160 | 161 | if (!arguments.ArgsCount()) 162 | throw WException( 163 | ERROR_INVALID_PARAMETER, 164 | L"Welcome to HiddenCLI, please use 'hiddencli /help'" 165 | ); 166 | 167 | if (PrintUsage(arguments)) 168 | return 0; 169 | 170 | 171 | CommandMode mode(arguments); 172 | 173 | if (mode.GetModeType() == CommandModeType::Execute) 174 | { 175 | Connection connection(arguments); 176 | { 177 | CommandTemplatePtr commands = LoadCommandsTemplate(arguments, mode); 178 | connection.Open(); 179 | commands->Perform(connection); 180 | } 181 | } 182 | else if (mode.GetModeType() == CommandModeType::Install) 183 | { 184 | LibInitializator lib; 185 | { 186 | CommandTemplatePtr commands = LoadCommandsTemplate(arguments, mode); 187 | RegistryKey key(mode.GetConfigRegistryKeyPath()); 188 | commands->Install(key); 189 | } 190 | } 191 | else if (mode.GetModeType() == CommandModeType::Uninstall) 192 | { 193 | LibInitializator lib; 194 | { 195 | CommandTemplatePtr commands = LoadCommandsTemplate(arguments, mode); 196 | RegistryKey key(mode.GetConfigRegistryKeyPath()); 197 | commands->Uninstall(key); 198 | } 199 | } 200 | 201 | const wstring output = g_stdout.str(); 202 | 203 | wcerr << g_stderr.str(); 204 | 205 | if (output.empty()) 206 | wcout << L"status:ok" << endl; 207 | else 208 | wcout << L"status:ok;" << output << endl; 209 | } 210 | catch (WException& exception) 211 | { 212 | wcerr << exception.What() << endl; 213 | wcout << L"status:failed" << endl; 214 | return exception.Code(); 215 | } 216 | catch (exception& exception) 217 | { 218 | cerr << exception.what() << endl; 219 | wcout << L"status:failed" << endl; 220 | return -1; 221 | } 222 | 223 | return 0; 224 | } 225 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Hide.cpp: -------------------------------------------------------------------------------- 1 | #include "Hide.h" 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | // ================= 8 | 9 | CommandHide::CommandHide() : m_command(L"/hide") 10 | { 11 | } 12 | 13 | CommandHide::~CommandHide() 14 | { 15 | } 16 | 17 | bool CommandHide::CompareCommand(std::wstring& command) 18 | { 19 | return (command == m_command); 20 | } 21 | 22 | HidRegRootTypes CommandHide::GetTypeAndNormalizeRegPath(std::wstring& regPath) 23 | { 24 | HidRegRootTypes type = GetRegType(regPath); 25 | size_t pos = regPath.find(L"\\"); 26 | if (pos == wstring::npos) 27 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid registry path"); 28 | 29 | regPath = std::move(wstring(regPath.c_str() + pos + 1)); 30 | return type; 31 | } 32 | 33 | void CommandHide::LoadArgs(Arguments& args, CommandModeType mode) 34 | { 35 | wstring object; 36 | 37 | if (!args.GetNext(object)) 38 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'hide'"); 39 | 40 | if (!args.GetNext(m_path)) 41 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'hide'"); 42 | 43 | if (object == L"file") 44 | { 45 | m_hideType = EObjTypes::TypeFile; 46 | } 47 | else if (object == L"dir") 48 | { 49 | m_hideType = EObjTypes::TypeDir; 50 | } 51 | else if (object == L"regkey") 52 | { 53 | m_hideType = EObjTypes::TypeRegKey; 54 | m_regRootType = GetTypeAndNormalizeRegPath(m_path); 55 | } 56 | else if (object == L"regval") 57 | { 58 | m_hideType = EObjTypes::TypeRegVal; 59 | m_regRootType = GetTypeAndNormalizeRegPath(m_path); 60 | } 61 | else 62 | { 63 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid argument for command 'hide'"); 64 | } 65 | } 66 | 67 | void CommandHide::PerformCommand(Connection& connection) 68 | { 69 | HidStatus status; 70 | HidObjId objId; 71 | 72 | switch (m_hideType) 73 | { 74 | case EObjTypes::TypeFile: 75 | status = Hid_AddHiddenFile(connection.GetContext(), m_path.c_str(), &objId); 76 | break; 77 | case EObjTypes::TypeDir: 78 | status = Hid_AddHiddenDir(connection.GetContext(), m_path.c_str(), &objId); 79 | break; 80 | case EObjTypes::TypeRegKey: 81 | status = Hid_AddHiddenRegKey(connection.GetContext(), m_regRootType, m_path.c_str(), &objId); 82 | break; 83 | case EObjTypes::TypeRegVal: 84 | status = Hid_AddHiddenRegValue(connection.GetContext(), m_regRootType, m_path.c_str(), &objId); 85 | break; 86 | default: 87 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error, invalid type for command 'hide'"); 88 | } 89 | 90 | if (!HID_STATUS_SUCCESSFUL(status)) 91 | throw WException(HID_STATUS_CODE(status), L"Error, command 'hide' rejected"); 92 | 93 | g_stderr << L"Command 'hide' successful" << endl; 94 | g_stdout << L"ruleid:" << objId << endl; 95 | } 96 | 97 | void CommandHide::InstallCommand(RegistryKey& configKey) 98 | { 99 | vector commands; 100 | const wchar_t* valueName; 101 | HidStatus status; 102 | wstring entry; 103 | 104 | entry.insert(0, m_path.size() + HID_NORMALIZATION_OVERHEAD, L'\0'); 105 | 106 | switch (m_hideType) 107 | { 108 | case EObjTypes::TypeFile: 109 | valueName = L"Hid_HideFsFiles"; 110 | status = Hid_NormalizeFilePath(m_path.c_str(), const_cast(entry.c_str()), entry.size()); 111 | break; 112 | case EObjTypes::TypeDir: 113 | valueName = L"Hid_HideFsDirs"; 114 | status = Hid_NormalizeFilePath(m_path.c_str(), const_cast(entry.c_str()), entry.size()); 115 | break; 116 | case EObjTypes::TypeRegKey: 117 | valueName = L"Hid_HideRegKeys"; 118 | status = Hid_NormalizeRegistryPath(m_regRootType, m_path.c_str(), const_cast(entry.c_str()), entry.size()); 119 | break; 120 | case EObjTypes::TypeRegVal: 121 | valueName = L"Hid_HideRegValues"; 122 | status = Hid_NormalizeRegistryPath(m_regRootType, m_path.c_str(), const_cast(entry.c_str()), entry.size()); 123 | break; 124 | default: 125 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error, invalid type for command 'hide'"); 126 | } 127 | 128 | configKey.GetMultiStrValue(valueName, commands); 129 | commands.push_back(entry); 130 | configKey.SetMultiStrValue(valueName, commands); 131 | 132 | g_stderr << L"Install 'hide' successful" << endl; 133 | } 134 | 135 | void CommandHide::UninstallCommand(RegistryKey& configKey) 136 | { 137 | int errors = 0; 138 | 139 | try { configKey.RemoveValue(L"Hid_HideFsFiles"); } catch (...) { errors++; } 140 | try { configKey.RemoveValue(L"Hid_HideFsDirs"); } catch (...) { errors++; } 141 | try { configKey.RemoveValue(L"Hid_HideRegKeys"); } catch (...) { errors++; } 142 | try { configKey.RemoveValue(L"Hid_HideRegValues"); } catch (...) { errors++; } 143 | 144 | if (errors < 4) 145 | g_stderr << L"Uninstall 'hide' successful" << endl; 146 | } 147 | 148 | CommandPtr CommandHide::CreateInstance() 149 | { 150 | return CommandPtr(new CommandHide()); 151 | } 152 | 153 | // ================= 154 | 155 | CommandUnhide::CommandUnhide() : m_command(L"/unhide") 156 | { 157 | m_targetId = 0; 158 | } 159 | 160 | CommandUnhide::~CommandUnhide() 161 | { 162 | } 163 | 164 | bool CommandUnhide::CompareCommand(std::wstring& command) 165 | { 166 | return (command == m_command); 167 | } 168 | 169 | void CommandUnhide::LoadArgs(Arguments& args, CommandModeType mode) 170 | { 171 | wstring object, target; 172 | 173 | if (!args.GetNext(object)) 174 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'unhide'"); 175 | 176 | if (!args.GetNext(target)) 177 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'unhide'"); 178 | 179 | if (object == L"file") 180 | { 181 | m_hideType = EObjTypes::TypeFile; 182 | } 183 | else if (object == L"dir") 184 | { 185 | m_hideType = EObjTypes::TypeDir; 186 | } 187 | else if (object == L"regkey") 188 | { 189 | m_hideType = EObjTypes::TypeRegKey; 190 | } 191 | else if (object == L"regval") 192 | { 193 | m_hideType = EObjTypes::TypeRegVal; 194 | } 195 | else 196 | { 197 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid argument for command 'unhide'"); 198 | } 199 | 200 | m_targetAll = (target == L"all"); 201 | if (!m_targetAll) 202 | { 203 | m_targetId = _wtoll(target.c_str()); 204 | if (!m_targetId) 205 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target objid for command 'unhide'"); 206 | } 207 | } 208 | 209 | void CommandUnhide::PerformCommand(Connection& connection) 210 | { 211 | HidStatus status; 212 | 213 | if (m_targetAll) 214 | { 215 | switch (m_hideType) 216 | { 217 | case EObjTypes::TypeFile: 218 | status = Hid_RemoveAllHiddenFiles(connection.GetContext()); 219 | break; 220 | case EObjTypes::TypeDir: 221 | status = Hid_RemoveAllHiddenDirs(connection.GetContext()); 222 | break; 223 | case EObjTypes::TypeRegKey: 224 | status = Hid_RemoveAllHiddenRegKeys(connection.GetContext()); 225 | break; 226 | case EObjTypes::TypeRegVal: 227 | status = Hid_RemoveAllHiddenRegValues(connection.GetContext()); 228 | break; 229 | default: 230 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error #1, invalid type for command 'unhide'"); 231 | } 232 | } 233 | else 234 | { 235 | switch (m_hideType) 236 | { 237 | case EObjTypes::TypeFile: 238 | status = Hid_RemoveHiddenFile(connection.GetContext(), m_targetId); 239 | break; 240 | case EObjTypes::TypeDir: 241 | status = Hid_RemoveHiddenDir(connection.GetContext(), m_targetId); 242 | break; 243 | case EObjTypes::TypeRegKey: 244 | status = Hid_RemoveHiddenRegKey(connection.GetContext(), m_targetId); 245 | break; 246 | case EObjTypes::TypeRegVal: 247 | status = Hid_RemoveHiddenRegValue(connection.GetContext(), m_targetId); 248 | break; 249 | default: 250 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error #2, invalid type for command 'unhide'"); 251 | } 252 | } 253 | 254 | if (!HID_STATUS_SUCCESSFUL(status)) 255 | throw WException(HID_STATUS_CODE(status), L"Error, command 'unhide' rejected"); 256 | 257 | g_stderr << L"Command 'unhide' successful" << endl; 258 | } 259 | 260 | CommandPtr CommandUnhide::CreateInstance() 261 | { 262 | return CommandPtr(new CommandUnhide()); 263 | } 264 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Hide.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Commands.h" 4 | 5 | class CommandHide : public ICommand 6 | { 7 | const wchar_t* m_command = nullptr; 8 | 9 | EObjTypes m_hideType; 10 | HidRegRootTypes m_regRootType; 11 | std::wstring m_path; 12 | 13 | HidRegRootTypes GetTypeAndNormalizeRegPath(std::wstring& regPath); 14 | 15 | public: 16 | 17 | CommandHide(); 18 | virtual ~CommandHide(); 19 | 20 | virtual bool CompareCommand(std::wstring& command); 21 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 22 | virtual void PerformCommand(Connection& connection); 23 | virtual void InstallCommand(RegistryKey& configKey); 24 | virtual void UninstallCommand(RegistryKey& configKey); 25 | 26 | virtual CommandPtr CreateInstance(); 27 | }; 28 | 29 | class CommandUnhide : public ICommand 30 | { 31 | const wchar_t* m_command = nullptr; 32 | 33 | EObjTypes m_hideType; 34 | HidObjId m_targetId; 35 | bool m_targetAll; 36 | 37 | public: 38 | 39 | CommandUnhide(); 40 | virtual ~CommandUnhide(); 41 | 42 | virtual bool CompareCommand(std::wstring& command); 43 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 44 | virtual void PerformCommand(Connection& connection); 45 | 46 | virtual CommandPtr CreateInstance(); 47 | }; 48 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Ignore.cpp: -------------------------------------------------------------------------------- 1 | #include "Ignore.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | // ================= 7 | 8 | CommandIgnore::CommandIgnore() : m_command(L"/ignore") 9 | { 10 | } 11 | 12 | CommandIgnore::~CommandIgnore() 13 | { 14 | } 15 | 16 | bool CommandIgnore::CompareCommand(std::wstring& command) 17 | { 18 | return (command == m_command); 19 | } 20 | 21 | void CommandIgnore::LoadArgs(Arguments& args, CommandModeType mode) 22 | { 23 | wstring object, target; 24 | 25 | if (!args.GetNext(object)) 26 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'ignore'"); 27 | 28 | if (object == L"image") 29 | { 30 | m_procType = EProcTypes::TypeImage; 31 | } 32 | else if (object == L"pid") 33 | { 34 | if (!CommandModeType::Execute) 35 | throw WException(ERROR_INVALID_PARAMETER, L"Error, target 'pid' isn't allowed"); 36 | 37 | m_procType = EProcTypes::TypeProcessId; 38 | } 39 | else 40 | { 41 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid object type in command 'ignore'"); 42 | } 43 | 44 | m_inheritType = LoadInheritOption(args, HidPsInheritTypes::WithoutInherit); 45 | 46 | m_applyByDefault = false; 47 | if (m_procType == EProcTypes::TypeImage && mode == CommandModeType::Execute) 48 | m_applyByDefault = LoadApplyOption(args, m_applyByDefault); 49 | 50 | if (!args.GetNext(target)) 51 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'ignore'"); 52 | 53 | if (m_procType == EProcTypes::TypeImage) 54 | { 55 | m_targetImage = target; 56 | } 57 | else 58 | { 59 | m_targetProcId = _wtol(target.c_str()); 60 | if (!m_targetProcId) 61 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target pid for command 'ignore'"); 62 | } 63 | } 64 | 65 | void CommandIgnore::PerformCommand(Connection& connection) 66 | { 67 | HidStatus status; 68 | HidObjId objId = 0; 69 | 70 | switch (m_procType) 71 | { 72 | case EProcTypes::TypeProcessId: 73 | status = Hid_AttachExcludedState(connection.GetContext(), m_targetProcId, m_inheritType); 74 | break; 75 | case EProcTypes::TypeImage: 76 | status = Hid_AddExcludedImage(connection.GetContext(), m_targetImage.c_str(), m_inheritType, m_applyByDefault, &objId); 77 | break; 78 | default: 79 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error, invalid type for command 'ignore'"); 80 | } 81 | 82 | if (!HID_STATUS_SUCCESSFUL(status)) 83 | throw WException(HID_STATUS_CODE(status), L"Error, command 'ignore' rejected"); 84 | 85 | g_stderr << L"Command 'ignore' successful" << endl; 86 | if (m_procType == EProcTypes::TypeImage) 87 | g_stdout << L"ruleid:" << objId << endl; 88 | } 89 | 90 | void CommandIgnore::InstallCommand(RegistryKey& configKey) 91 | { 92 | vector commands; 93 | wstring temp, entry; 94 | HidStatus status; 95 | 96 | temp.insert(0, m_targetImage.size() + HID_NORMALIZATION_OVERHEAD, L'\0'); 97 | 98 | status = Hid_NormalizeFilePath(m_targetImage.c_str(), const_cast(temp.c_str()), temp.size()); 99 | if (!HID_STATUS_SUCCESSFUL(status)) 100 | throw WException(HID_STATUS_CODE(status), L"Error, can't normalize path, 'ignore' rejected"); 101 | 102 | entry += temp.c_str(); 103 | entry += L";"; 104 | entry += ConvertInheritTypeToUnicode(m_inheritType); 105 | 106 | configKey.GetMultiStrValue(L"Hid_IgnoredImages", commands); 107 | commands.push_back(entry); 108 | configKey.SetMultiStrValue(L"Hid_IgnoredImages", commands); 109 | 110 | g_stderr << L"Install 'ignore' successful" << endl; 111 | } 112 | 113 | void CommandIgnore::UninstallCommand(RegistryKey& configKey) 114 | { 115 | configKey.RemoveValue(L"Hid_IgnoredImages"); 116 | 117 | g_stderr << L"Uninstall 'ignore' successful" << endl; 118 | } 119 | 120 | CommandPtr CommandIgnore::CreateInstance() 121 | { 122 | return CommandPtr(new CommandIgnore()); 123 | } 124 | 125 | // ================= 126 | 127 | CommandUnignore::CommandUnignore() : m_command(L"/unignore") 128 | { 129 | } 130 | 131 | CommandUnignore::~CommandUnignore() 132 | { 133 | } 134 | 135 | bool CommandUnignore::CompareCommand(std::wstring& command) 136 | { 137 | return (command == m_command); 138 | } 139 | 140 | void CommandUnignore::LoadArgs(Arguments& args, CommandModeType mode) 141 | { 142 | wstring object, target; 143 | 144 | if (mode != CommandModeType::Execute) 145 | throw WException(ERROR_INVALID_PARAMETER, L"Error, install/uninstall mode isn't supported for this command"); 146 | 147 | if (!args.GetNext(object)) 148 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'unignore'"); 149 | 150 | if (object == L"pid") 151 | { 152 | m_targetType = ETargetIdType::ProcId; 153 | 154 | if (!args.GetNext(target)) 155 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'unignore'"); 156 | 157 | m_targetProcId = _wtol(target.c_str()); 158 | if (!m_targetProcId) 159 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target ruleid for command 'unignore'"); 160 | } 161 | else if (object == L"all") 162 | { 163 | m_targetType = ETargetIdType::All; 164 | } 165 | else 166 | { 167 | m_targetType = ETargetIdType::RuleId; 168 | 169 | m_targetId = _wtoll(object.c_str()); 170 | if (!m_targetId) 171 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target ruleid for command 'unignore'"); 172 | } 173 | } 174 | 175 | void CommandUnignore::PerformCommand(Connection& connection) 176 | { 177 | HidStatus status; 178 | 179 | switch (m_targetType) 180 | { 181 | case ETargetIdType::All: 182 | status = Hid_RemoveAllExcludedImages(connection.GetContext()); 183 | break; 184 | case ETargetIdType::ProcId: 185 | status = Hid_RemoveExcludedState(connection.GetContext(), m_targetProcId); 186 | break; 187 | case ETargetIdType::RuleId: 188 | status = Hid_RemoveExcludedImage(connection.GetContext(), m_targetId); 189 | break; 190 | default: 191 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error, invalid type for command 'unignore'"); 192 | } 193 | 194 | if (!HID_STATUS_SUCCESSFUL(status)) 195 | throw WException(HID_STATUS_CODE(status), L"Error, command 'unignore' rejected"); 196 | 197 | g_stderr << L"Command 'unignore' successful" << endl; 198 | } 199 | 200 | CommandPtr CommandUnignore::CreateInstance() 201 | { 202 | return CommandPtr(new CommandUnignore()); 203 | } 204 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Ignore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Commands.h" 4 | 5 | class CommandIgnore : public ICommand 6 | { 7 | const wchar_t* m_command = nullptr; 8 | 9 | EProcTypes m_procType; 10 | std::wstring m_targetImage; 11 | HidProcId m_targetProcId; 12 | HidPsInheritTypes m_inheritType; 13 | bool m_applyByDefault; 14 | 15 | public: 16 | 17 | CommandIgnore(); 18 | virtual ~CommandIgnore(); 19 | 20 | virtual bool CompareCommand(std::wstring& command); 21 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 22 | virtual void PerformCommand(Connection& connection); 23 | virtual void InstallCommand(RegistryKey& configKey); 24 | virtual void UninstallCommand(RegistryKey& configKey); 25 | 26 | virtual CommandPtr CreateInstance(); 27 | }; 28 | 29 | class CommandUnignore : public ICommand 30 | { 31 | const wchar_t* m_command = nullptr; 32 | 33 | enum ETargetIdType { 34 | RuleId, 35 | ProcId, 36 | All 37 | }; 38 | 39 | ETargetIdType m_targetType; 40 | HidProcId m_targetProcId; 41 | HidObjId m_targetId; 42 | 43 | public: 44 | 45 | CommandUnignore(); 46 | virtual ~CommandUnignore(); 47 | 48 | virtual bool CompareCommand(std::wstring& command); 49 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 50 | virtual void PerformCommand(Connection& connection); 51 | 52 | virtual CommandPtr CreateInstance(); 53 | }; 54 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Protect.cpp: -------------------------------------------------------------------------------- 1 | #include "Protect.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | // ================= 7 | 8 | CommandProtect::CommandProtect() : m_command(L"/protect") 9 | { 10 | } 11 | 12 | CommandProtect::~CommandProtect() 13 | { 14 | } 15 | 16 | bool CommandProtect::CompareCommand(std::wstring& command) 17 | { 18 | return (command == m_command); 19 | } 20 | 21 | void CommandProtect::LoadArgs(Arguments& args, CommandModeType mode) 22 | { 23 | wstring object, target; 24 | 25 | if (!args.GetNext(object)) 26 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'protect'"); 27 | 28 | if (object == L"image") 29 | { 30 | m_procType = EProcTypes::TypeImage; 31 | } 32 | else if (object == L"pid") 33 | { 34 | if (!CommandModeType::Execute) 35 | throw WException(ERROR_INVALID_PARAMETER, L"Error, target 'pid' isn't allowed"); 36 | 37 | m_procType = EProcTypes::TypeProcessId; 38 | } 39 | else 40 | { 41 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid object type in command 'protect'"); 42 | } 43 | 44 | m_inheritType = LoadInheritOption(args, HidPsInheritTypes::WithoutInherit); 45 | 46 | m_applyByDefault = false; 47 | if (m_procType == EProcTypes::TypeImage && mode == CommandModeType::Execute) 48 | m_applyByDefault = LoadApplyOption(args, m_applyByDefault); 49 | 50 | if (!args.GetNext(target)) 51 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'protect'"); 52 | 53 | if (m_procType == EProcTypes::TypeImage) 54 | { 55 | m_targetImage = target; 56 | } 57 | else 58 | { 59 | m_targetProcId = _wtol(target.c_str()); 60 | if (!m_targetProcId) 61 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target pid for command 'protect'"); 62 | } 63 | } 64 | 65 | void CommandProtect::PerformCommand(Connection& connection) 66 | { 67 | HidStatus status; 68 | HidObjId objId; 69 | 70 | switch (m_procType) 71 | { 72 | case EProcTypes::TypeProcessId: 73 | status = Hid_AttachProtectedState(connection.GetContext(), m_targetProcId, m_inheritType); 74 | break; 75 | case EProcTypes::TypeImage: 76 | status = Hid_AddProtectedImage(connection.GetContext(), m_targetImage.c_str(), m_inheritType, m_applyByDefault, &objId); 77 | break; 78 | default: 79 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error, invalid type for command 'protect'"); 80 | } 81 | 82 | if (!HID_STATUS_SUCCESSFUL(status)) 83 | throw WException(HID_STATUS_CODE(status), L"Error, command 'protect' rejected"); 84 | 85 | g_stderr << L"Command 'protect' successful" << endl; 86 | if (m_procType == EProcTypes::TypeImage) 87 | g_stdout << L"status:ok;ruleid:" << objId << endl; 88 | } 89 | 90 | void CommandProtect::InstallCommand(RegistryKey& configKey) 91 | { 92 | vector commands; 93 | wstring temp, entry; 94 | HidStatus status; 95 | 96 | temp.insert(0, m_targetImage.size() + HID_NORMALIZATION_OVERHEAD, L'\0'); 97 | 98 | status = Hid_NormalizeFilePath(m_targetImage.c_str(), const_cast(temp.c_str()), temp.size()); 99 | if (!HID_STATUS_SUCCESSFUL(status)) 100 | throw WException(HID_STATUS_CODE(status), L"Error, can't normalize path, 'protect' rejected"); 101 | 102 | entry += temp.c_str(); 103 | entry += L";"; 104 | entry += ConvertInheritTypeToUnicode(m_inheritType); 105 | 106 | configKey.GetMultiStrValue(L"Hid_ProtectedImages", commands); 107 | commands.push_back(entry); 108 | configKey.SetMultiStrValue(L"Hid_ProtectedImages", commands); 109 | 110 | g_stderr << L"Install 'protect' successful" << endl; 111 | } 112 | 113 | void CommandProtect::UninstallCommand(RegistryKey& configKey) 114 | { 115 | configKey.RemoveValue(L"Hid_ProtectedImages"); 116 | 117 | g_stderr << L"Uninstall 'protect' successful" << endl; 118 | } 119 | 120 | CommandPtr CommandProtect::CreateInstance() 121 | { 122 | return CommandPtr(new CommandProtect()); 123 | } 124 | 125 | // ================= 126 | 127 | CommandUnprotect::CommandUnprotect() : m_command(L"/unprotect") 128 | { 129 | } 130 | 131 | CommandUnprotect::~CommandUnprotect() 132 | { 133 | } 134 | 135 | bool CommandUnprotect::CompareCommand(std::wstring& command) 136 | { 137 | return (command == m_command); 138 | } 139 | 140 | void CommandUnprotect::LoadArgs(Arguments& args, CommandModeType mode) 141 | { 142 | wstring object, target; 143 | 144 | if (mode != CommandModeType::Execute) 145 | throw WException(ERROR_INVALID_PARAMETER, L"Error, install/uninstall mode isn't supported for this command"); 146 | 147 | if (!args.GetNext(object)) 148 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'unprotect'"); 149 | 150 | if (object == L"pid") 151 | { 152 | m_targetType = ETargetIdType::ProcId; 153 | 154 | if (!args.GetNext(target)) 155 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'unprotect'"); 156 | 157 | m_targetProcId = _wtol(target.c_str()); 158 | if (!m_targetProcId) 159 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target ruleid for command 'unprotect'"); 160 | } 161 | else if (object == L"all") 162 | { 163 | m_targetType = ETargetIdType::All; 164 | } 165 | else 166 | { 167 | m_targetType = ETargetIdType::RuleId; 168 | 169 | m_targetId = _wtoll(object.c_str()); 170 | if (!m_targetId) 171 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target ruleid for command 'unprotect'"); 172 | } 173 | } 174 | 175 | void CommandUnprotect::PerformCommand(Connection& connection) 176 | { 177 | HidStatus status; 178 | 179 | switch (m_targetType) 180 | { 181 | case ETargetIdType::All: 182 | status = Hid_RemoveAllProtectedImages(connection.GetContext()); 183 | break; 184 | case ETargetIdType::ProcId: 185 | status = Hid_RemoveProtectedState(connection.GetContext(), m_targetProcId); 186 | break; 187 | case ETargetIdType::RuleId: 188 | status = Hid_RemoveProtectedImage(connection.GetContext(), m_targetId); 189 | break; 190 | default: 191 | throw WException(ERROR_UNKNOWN_COMPONENT, L"Internal error, invalid type for command 'unprotect'"); 192 | } 193 | 194 | if (!HID_STATUS_SUCCESSFUL(status)) 195 | throw WException(HID_STATUS_CODE(status), L"Error, command 'unprotect' rejected"); 196 | 197 | g_stderr << L"Command 'unprotect' successful" << endl; 198 | } 199 | 200 | CommandPtr CommandUnprotect::CreateInstance() 201 | { 202 | return CommandPtr(new CommandUnprotect()); 203 | } 204 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Protect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Commands.h" 4 | 5 | class CommandProtect : public ICommand 6 | { 7 | const wchar_t* m_command = nullptr; 8 | 9 | EProcTypes m_procType; 10 | std::wstring m_targetImage; 11 | HidProcId m_targetProcId; 12 | HidPsInheritTypes m_inheritType; 13 | bool m_applyByDefault; 14 | 15 | public: 16 | 17 | CommandProtect(); 18 | virtual ~CommandProtect(); 19 | 20 | virtual bool CompareCommand(std::wstring& command); 21 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 22 | virtual void PerformCommand(Connection& connection); 23 | virtual void InstallCommand(RegistryKey& configKey); 24 | virtual void UninstallCommand(RegistryKey& configKey); 25 | 26 | virtual CommandPtr CreateInstance(); 27 | }; 28 | 29 | class CommandUnprotect : public ICommand 30 | { 31 | const wchar_t* m_command = nullptr; 32 | 33 | enum ETargetIdType { 34 | RuleId, 35 | ProcId, 36 | All 37 | }; 38 | 39 | ETargetIdType m_targetType; 40 | HidProcId m_targetProcId; 41 | HidObjId m_targetId; 42 | 43 | public: 44 | 45 | CommandUnprotect(); 46 | virtual ~CommandUnprotect(); 47 | 48 | virtual bool CompareCommand(std::wstring& command); 49 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 50 | virtual void PerformCommand(Connection& connection); 51 | 52 | virtual CommandPtr CreateInstance(); 53 | }; 54 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Query.cpp: -------------------------------------------------------------------------------- 1 | #include "Query.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | CommandQuery::CommandQuery() : m_command(L"/query") 7 | { 8 | } 9 | 10 | CommandQuery::~CommandQuery() 11 | { 12 | } 13 | 14 | bool CommandQuery::CompareCommand(std::wstring& command) 15 | { 16 | return (command == m_command); 17 | } 18 | 19 | void CommandQuery::LoadArgs(Arguments& args, CommandModeType mode) 20 | { 21 | wstring object, target; 22 | 23 | if (!args.GetNext(object)) 24 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'query'"); 25 | 26 | if (object == L"process") 27 | { 28 | m_queryType = EQueryType::QueryProcess; 29 | 30 | if (!args.GetNext(target)) 31 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'query'"); 32 | 33 | m_targetProcId = _wtol(target.c_str()); 34 | if (!m_targetProcId) 35 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid target pid for command 'query'"); 36 | } 37 | else if (object == L"state") 38 | { 39 | m_queryType = EQueryType::QueryState; 40 | } 41 | else 42 | { 43 | 44 | throw WException(ERROR_INVALID_PARAMETER, L"Error, invalid object type for command 'query'"); 45 | } 46 | } 47 | 48 | void CommandQuery::PerformCommand(Connection& connection) 49 | { 50 | HidStatus status; 51 | 52 | if (m_queryType == EQueryType::QueryState) 53 | { 54 | HidActiveState state; 55 | 56 | status = Hid_GetState(connection.GetContext(), &state); 57 | if (!HID_STATUS_SUCCESSFUL(status)) 58 | throw WException(HID_STATUS_CODE(status), L"Error, query state rejected"); 59 | 60 | g_stderr << L"Driver state:" << (state == HidActiveState::StateEnabled ? L"enabled" : L"disabled") << endl; 61 | g_stdout << L"state:" << (state == HidActiveState::StateEnabled ? 1 : 0) << endl; 62 | } 63 | else if (m_queryType == EQueryType::QueryProcess) 64 | { 65 | HidActiveState excludeState, protectedState; 66 | HidPsInheritTypes excludedInherit, protectedInherit; 67 | 68 | status = Hid_GetExcludedState(connection.GetContext(), m_targetProcId, &excludeState, &excludedInherit); 69 | if (!HID_STATUS_SUCCESSFUL(status)) 70 | throw WException(HID_STATUS_CODE(status), L"Error, query ignored state rejected"); 71 | 72 | status = Hid_GetProtectedState(connection.GetContext(), m_targetProcId, &protectedState, &protectedInherit); 73 | if (!HID_STATUS_SUCCESSFUL(status)) 74 | throw WException(HID_STATUS_CODE(status), L"Error, query protected state rejected"); 75 | 76 | g_stderr << L"Ignored state:" << (excludeState == HidActiveState::StateEnabled ? L"true" : L"false") 77 | << L", inherit:" << ConvertInheritTypeToUnicode(excludedInherit) << endl; 78 | g_stderr << L"Protected state:" << (protectedState == HidActiveState::StateEnabled ? L"true" : L"false") 79 | << L", inherit:" << ConvertInheritTypeToUnicode(protectedInherit) << endl; 80 | 81 | g_stdout << L"ignored:" << excludeState << L"," << excludedInherit 82 | << L";protected:" << protectedState << L"," << protectedInherit << endl; 83 | } 84 | } 85 | 86 | CommandPtr CommandQuery::CreateInstance() 87 | { 88 | return CommandPtr(new CommandQuery()); 89 | } 90 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/Query.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Commands.h" 4 | 5 | class CommandQuery : public ICommand 6 | { 7 | enum EQueryType { 8 | QueryProcess, 9 | QueryState, 10 | }; 11 | 12 | const wchar_t* m_command = nullptr; 13 | 14 | EQueryType m_queryType; 15 | HidProcId m_targetProcId; 16 | 17 | public: 18 | 19 | CommandQuery(); 20 | virtual ~CommandQuery(); 21 | 22 | virtual bool CompareCommand(std::wstring& command); 23 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 24 | virtual void PerformCommand(Connection& connection); 25 | 26 | virtual CommandPtr CreateInstance(); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/State.cpp: -------------------------------------------------------------------------------- 1 | #include "State.h" 2 | #include 3 | 4 | using namespace std; 5 | 6 | CommandState::CommandState() : m_command(L"/state") 7 | { 8 | } 9 | 10 | CommandState::~CommandState() 11 | { 12 | } 13 | 14 | bool CommandState::CompareCommand(std::wstring& command) 15 | { 16 | return (command == m_command); 17 | } 18 | 19 | void CommandState::LoadArgs(Arguments& args, CommandModeType mode) 20 | { 21 | wstring state, enable; 22 | 23 | if (!args.GetNext(state)) 24 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #1 for command 'state'"); 25 | 26 | if (state == L"on") 27 | m_state = true; 28 | else if (state == L"off") 29 | m_state = false; 30 | else 31 | throw WException(ERROR_INVALID_PARAMETER, L"Error, mismatched argument #2 for command 'state'"); 32 | } 33 | 34 | void CommandState::PerformCommand(Connection& connection) 35 | { 36 | HidStatus status; 37 | 38 | status = Hid_SetState(connection.GetContext(), (m_state ? HidActiveState::StateEnabled : HidActiveState::StateDisabled)); 39 | if (!HID_STATUS_SUCCESSFUL(status)) 40 | throw WException(HID_STATUS_CODE(status), L"Error, command 'state' rejected"); 41 | 42 | g_stderr << L"Command 'state' successful" << endl; 43 | } 44 | 45 | void CommandState::InstallCommand(RegistryKey& configKey) 46 | { 47 | configKey.SetDwordValue(L"Hid_State", (m_state ? 1 : 0)); 48 | 49 | g_stderr << L"Install 'state' successful" << endl; 50 | } 51 | 52 | void CommandState::UninstallCommand(RegistryKey& configKey) 53 | { 54 | configKey.RemoveValue(L"Hid_State"); 55 | 56 | g_stderr << L"Uninstall 'state' successful" << endl; 57 | } 58 | 59 | CommandPtr CommandState::CreateInstance() 60 | { 61 | return CommandPtr(new CommandState()); 62 | } 63 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/State.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Commands.h" 4 | 5 | class CommandState : public ICommand 6 | { 7 | const wchar_t* m_command = nullptr; 8 | 9 | bool m_state; 10 | 11 | public: 12 | 13 | CommandState(); 14 | virtual ~CommandState(); 15 | 16 | virtual bool CompareCommand(std::wstring& command); 17 | virtual void LoadArgs(Arguments& args, CommandModeType mode); 18 | virtual void PerformCommand(Connection& connection); 19 | virtual void InstallCommand(RegistryKey& configKey); 20 | virtual void UninstallCommand(RegistryKey& configKey); 21 | 22 | virtual CommandPtr CreateInstance(); 23 | }; 24 | -------------------------------------------------------------------------------- /hidden/HiddenCLI/cli.txt: -------------------------------------------------------------------------------- 1 | 2 | hiddencli [mode] [connection] [perform] 3 | hiddencli /help 4 | 5 | mode: 6 | 7 | By default perform current commands 8 | 9 | /install [%driver%] 10 | Install commands to registry without execution, driver will load them on start. If this flag is set 11 | connection parameters shouldn't be set. Optional parameter is used for set valid registry path if 12 | driver name is changed, by default "hidden" 13 | 14 | /uninstall [%driver%] 15 | Uninstall all configs from registry. This flag is all-sufficient therefore if this flag is set 16 | no other parameters and commands should be set after 17 | 18 | connection: 19 | 20 | /gate <%name%> 21 | Set specific connection gate name (driver device name) 22 | 23 | perform: 24 | 25 | By default perform one command by one execution 26 | 27 | /multi 28 | Enable multiple commands per execution, just type commands one by one without any separator 29 | 30 | /config <%path%> 31 | Loads multiple commands from file, each command should be on separate line 32 | 33 | commands: 34 | 35 | /state 36 | Enable or disable enforcement (hiding, protecting, ignoring etc) 37 | 38 | /query state 39 | Get enforcement state 40 | 41 | /hide <%path%> 42 | Hide filesystem or registry object by path 43 | 44 | /unhide all 45 | Unhide all filesystem or registry object by selected type 46 | 47 | /unhide <%ruleid%> 48 | Unhide all filesystem or registry object by selected type and rule ID 49 | 50 | /ignore image [inherit:] [apply:] <%path%> 51 | Set rule that allows to see hidden filesystem and registry objects for processes with specific image path 52 | 53 | /unignore <%ruleid%> 54 | Remove rule that allows to see hidden filesystem and registry objects by rule ID 55 | 56 | /unignore all 57 | Remove all rules that allow to see hidden filesystem and registry objects 58 | 59 | /ignore pid [inherit:] <%pid%> 60 | Turn on abillity to see hidden filesystem and registry objects for specific process by PID 61 | 62 | /unignore pid <%pid%> 63 | Turn off abillity to see hidden filesystem and registry objects for specific process by PID 64 | 65 | /protect image [inherit:] [apply:] <%path%> 66 | Set rule that allows to enable process protection for processes with specific image path 67 | 68 | /unprotect <%ruleid%> 69 | Remove rule that enables process protection by rule ID 70 | 71 | /unprotect all 72 | Remove all rules that enable process protection 73 | 74 | /protect pid [inherit:] <%pid%> 75 | Turn on protection for specific process by PID 76 | 77 | /unprotect pid <%pid%> 78 | Turn off protection for specific process by PID 79 | 80 | /query process <%pid%> 81 | Query information about state of the process by PID 82 | 83 | options: 84 | 85 | inherit:none 86 | Disable inheritance of the protected or ignored state 87 | 88 | inherit:once 89 | Child process will inherit the same state but its children no 90 | 91 | inherit:always 92 | Child process will inherit the same state and its children too 93 | 94 | apply:forall 95 | Apply policy for existing processes and for all new processes 96 | 97 | apply:fornew 98 | Don't apply policy for existing processes only for new 99 | --------------------------------------------------------------------------------