├── .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 |
--------------------------------------------------------------------------------