├── .gitignore
├── LICENSE
├── README.md
├── screenshots
├── mainmenu.png
└── scanpattern.png
└── src
├── Agent
├── AboutDlg.cpp
├── AboutDlg.h
├── Agent.cpp
├── Agent.h
├── Agent.rc
├── Agent.vcxproj
├── Agent.vcxproj.filters
├── AgentDlg.cpp
├── AgentDlg.h
├── Communication.cpp
├── Communication.h
├── LoadDriver.cpp
├── LoadDriver.h
├── ScanDlg.cpp
├── ScanDlg.h
├── framework.h
├── pch.cpp
├── pch.h
├── res
│ ├── About.bmp
│ ├── Agent.rc2
│ └── KernelV.ico
├── resource.h
└── targetver.h
├── Driver
├── Driver.vcxproj
├── Driver.vcxproj.filters
├── define.h
├── engine.c
├── engine.h
├── hidedriver.c
├── hidedriver.h
├── listentry.c
├── listentry.h
├── main.c
├── main.h
├── undocumented.h
├── util.c
└── util.h
└── KernelV.sln
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | *.nupkg
187 | # NuGet Symbol Packages
188 | *.snupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 | *.appxbundle
214 | *.appxupload
215 |
216 | # Visual Studio cache files
217 | # files ending in .cache can be ignored
218 | *.[Cc]ache
219 | # but keep track of directories ending in .cache
220 | !?*.[Cc]ache/
221 |
222 | # Others
223 | ClientBin/
224 | ~$*
225 | *~
226 | *.dbmdl
227 | *.dbproj.schemaview
228 | *.jfm
229 | *.pfx
230 | *.publishsettings
231 | orleans.codegen.cs
232 |
233 | # Including strong name files can present a security risk
234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
235 | #*.snk
236 |
237 | # Since there are multiple workflows, uncomment next line to ignore bower_components
238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
239 | #bower_components/
240 |
241 | # RIA/Silverlight projects
242 | Generated_Code/
243 |
244 | # Backup & report files from converting an old project file
245 | # to a newer Visual Studio version. Backup files are not needed,
246 | # because we have git ;-)
247 | _UpgradeReport_Files/
248 | Backup*/
249 | UpgradeLog*.XML
250 | UpgradeLog*.htm
251 | ServiceFabricBackup/
252 | *.rptproj.bak
253 |
254 | # SQL Server files
255 | *.mdf
256 | *.ldf
257 | *.ndf
258 |
259 | # Business Intelligence projects
260 | *.rdl.data
261 | *.bim.layout
262 | *.bim_*.settings
263 | *.rptproj.rsuser
264 | *- [Bb]ackup.rdl
265 | *- [Bb]ackup ([0-9]).rdl
266 | *- [Bb]ackup ([0-9][0-9]).rdl
267 |
268 | # Microsoft Fakes
269 | FakesAssemblies/
270 |
271 | # GhostDoc plugin setting file
272 | *.GhostDoc.xml
273 |
274 | # Node.js Tools for Visual Studio
275 | .ntvs_analysis.dat
276 | node_modules/
277 |
278 | # Visual Studio 6 build log
279 | *.plg
280 |
281 | # Visual Studio 6 workspace options file
282 | *.opt
283 |
284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
285 | *.vbw
286 |
287 | # Visual Studio LightSwitch build output
288 | **/*.HTMLClient/GeneratedArtifacts
289 | **/*.DesktopClient/GeneratedArtifacts
290 | **/*.DesktopClient/ModelManifest.xml
291 | **/*.Server/GeneratedArtifacts
292 | **/*.Server/ModelManifest.xml
293 | _Pvt_Extensions
294 |
295 | # Paket dependency manager
296 | .paket/paket.exe
297 | paket-files/
298 |
299 | # FAKE - F# Make
300 | .fake/
301 |
302 | # CodeRush personal settings
303 | .cr/personal
304 |
305 | # Python Tools for Visual Studio (PTVS)
306 | __pycache__/
307 | *.pyc
308 |
309 | # Cake - Uncomment if you are using it
310 | # tools/**
311 | # !tools/packages.config
312 |
313 | # Tabs Studio
314 | *.tss
315 |
316 | # Telerik's JustMock configuration file
317 | *.jmconfig
318 |
319 | # BizTalk build output
320 | *.btp.cs
321 | *.btm.cs
322 | *.odx.cs
323 | *.xsd.cs
324 |
325 | # OpenCover UI analysis results
326 | OpenCover/
327 |
328 | # Azure Stream Analytics local run output
329 | ASALocalRun/
330 |
331 | # MSBuild Binary and Structured Log
332 | *.binlog
333 |
334 | # NVidia Nsight GPU debugger configuration file
335 | *.nvuser
336 |
337 | # MFractors (Xamarin productivity tool) working folder
338 | .mfractor/
339 |
340 | # Local History for Visual Studio
341 | .localhistory/
342 |
343 | # BeatPulse healthcheck temp database
344 | healthchecksdb
345 |
346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
347 | MigrationBackup/
348 |
349 | # Ionide (cross platform F# VS Code tools) working folder
350 | .ionide/
351 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 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 Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KernelV
2 | 
3 |
4 | Rootkit & Anti-Rootkit (Windows 10/11 x64 only)
5 |
6 | Download : https://github.com/codetronik/KernelV/releases
7 |
8 |
9 |
10 | Built in Visual Studio 2019 + wdk 10.0.19041.0
11 |
12 | Tested on Windows 10 Build 19041 64-bit version.
13 |
14 | It still works on Windows 11 Build 22000
15 |
16 | ## Features
17 | - Scan binary patterns in kernel drivers
18 | - Hide the driver
19 | + Breaking the chain of LDR_DATA_TABLE_ENTRY(PsLoadedModuleList)
20 | + Breaking the chain of OBJECT_DIRECTORY_ENTRY
21 | - Detect hidden drivers
22 | + Enumerating Object Name
23 | + Scanning "MmLd"(LDR_DATA_TABLE_ENTRY) in Kernel-memory
24 |
25 | ## Pattern Scan
26 | 
27 |
28 | Enter one binary pattern per line. Patterns cannot be entered in more than two lines.
29 |
30 | The delimiter("\r\n") of the pattern is the Enter key.
31 |
32 | ## Precautions
33 | If you hide ntoskrnl.exe or myself, the next run may fail.
34 |
35 | Hiding a driver can cause BSOD. (19 : Loaded module list modification)
36 |
37 |
38 | ## Codesign
39 | The built driver I provide is signed with the "HT Srl" certificate. It is highly likely to be detected in the anti-virus.
40 |
41 | As of January 2024, the certificate has been blocked and cannot be executed.
42 |
--------------------------------------------------------------------------------
/screenshots/mainmenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codetronik/KernelV/aa5e9cad341662da4b274e39428b97f7e3e9cb2a/screenshots/mainmenu.png
--------------------------------------------------------------------------------
/screenshots/scanpattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codetronik/KernelV/aa5e9cad341662da4b274e39428b97f7e3e9cb2a/screenshots/scanpattern.png
--------------------------------------------------------------------------------
/src/Agent/AboutDlg.cpp:
--------------------------------------------------------------------------------
1 | // About.cpp: 구현 파일
2 | //
3 |
4 | #include "pch.h"
5 | #include "Agent.h"
6 | #include "AboutDlg.h"
7 | #include "afxdialogex.h"
8 |
9 |
10 | // About 대화 상자
11 |
12 | IMPLEMENT_DYNAMIC(CAboutDlg, CDialogEx)
13 |
14 | CAboutDlg::CAboutDlg(CWnd* pParent /*=nullptr*/)
15 | : CDialogEx(IDD_ABOUT_DIALOG, pParent)
16 | {
17 |
18 | }
19 |
20 | CAboutDlg::~CAboutDlg()
21 | {
22 | }
23 |
24 | void CAboutDlg::DoDataExchange(CDataExchange* pDX)
25 | {
26 | CDialogEx::DoDataExchange(pDX);
27 | DDX_Control(pDX, IDC_PICTURE, m_cPicture);
28 | }
29 |
30 |
31 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
32 | END_MESSAGE_MAP()
33 |
34 |
35 | // About 메시지 처리기
36 |
37 | BOOL CAboutDlg::OnInitDialog()
38 | {
39 | CDialogEx::OnInitDialog();
40 | // 이미지 띄우기
41 | m_cPicture.ModifyStyle(0xF, SS_BITMAP | SS_CENTERIMAGE);
42 | HBITMAP hBmp = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
43 | m_cPicture.SetBitmap(hBmp);
44 | BITMAP size;
45 | ::GetObject(hBmp, sizeof(BITMAP), &size);
46 | m_cPicture.MoveWindow(0, 0, size.bmWidth, size.bmHeight);
47 |
48 | // dialog 크기 조절
49 | ::SetWindowPos(GetSafeHwnd(), NULL, 0, 0, size.bmWidth+15, size.bmHeight+40, SWP_NOMOVE | SWP_NOZORDER);
50 | return TRUE;
51 | }
52 |
--------------------------------------------------------------------------------
/src/Agent/AboutDlg.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 |
4 | // About 대화 상자
5 |
6 | class CAboutDlg : public CDialogEx
7 | {
8 | DECLARE_DYNAMIC(CAboutDlg)
9 |
10 | public:
11 | CAboutDlg(CWnd* pParent = nullptr); // 표준 생성자입니다.
12 | virtual ~CAboutDlg();
13 |
14 | // 대화 상자 데이터입니다.
15 | #ifdef AFX_DESIGN_TIME
16 | enum { IDD = IDD_ABOUT_DIALOG };
17 | #endif
18 |
19 | protected:
20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
21 | virtual BOOL OnInitDialog();
22 |
23 | DECLARE_MESSAGE_MAP()
24 |
25 | public:
26 | CStatic m_cPicture;
27 | };
28 |
--------------------------------------------------------------------------------
/src/Agent/Agent.cpp:
--------------------------------------------------------------------------------
1 |
2 | // Agent.cpp: 애플리케이션에 대한 클래스 동작을 정의합니다.
3 | //
4 |
5 | #include "pch.h"
6 | #include "framework.h"
7 | #include "Agent.h"
8 | #include "AgentDlg.h"
9 |
10 | #ifdef _DEBUG
11 | #define new DEBUG_NEW
12 | #endif
13 |
14 |
15 | // CAgentApp
16 |
17 | BEGIN_MESSAGE_MAP(CAgentApp, CWinApp)
18 | ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
19 |
20 | END_MESSAGE_MAP()
21 |
22 |
23 | // CAgentApp 생성
24 |
25 | CAgentApp::CAgentApp()
26 | {
27 | // TODO: 여기에 생성 코드를 추가합니다.
28 | // InitInstance에 모든 중요한 초기화 작업을 배치합니다.
29 |
30 | }
31 | CAgentApp::~CAgentApp()
32 | {
33 | }
34 |
35 |
36 | // 유일한 CAgentApp 개체입니다.
37 |
38 | CAgentApp theApp;
39 |
40 |
41 | // CAgentApp 초기화
42 |
43 | BOOL CAgentApp::InitInstance()
44 | {
45 | // 애플리케이션 매니페스트가 ComCtl32.dll 버전 6 이상을 사용하여 비주얼 스타일을
46 | // 사용하도록 지정하는 경우, Windows XP 상에서 반드시 InitCommonControlsEx()가 필요합니다.
47 | // InitCommonControlsEx()를 사용하지 않으면 창을 만들 수 없습니다.
48 | INITCOMMONCONTROLSEX InitCtrls;
49 | InitCtrls.dwSize = sizeof(InitCtrls);
50 | // 응용 프로그램에서 사용할 모든 공용 컨트롤 클래스를 포함하도록
51 | // 이 항목을 설정하십시오.
52 | InitCtrls.dwICC = ICC_WIN95_CLASSES;
53 | InitCommonControlsEx(&InitCtrls);
54 |
55 | CWinApp::InitInstance();
56 | CAgentDlg dlg;
57 |
58 | // 대화 상자에 셸 트리 뷰 또는
59 | // 셸 목록 뷰 컨트롤이 포함되어 있는 경우 셸 관리자를 만듭니다.
60 | CShellManager *pShellManager = new CShellManager;
61 |
62 | // MFC 컨트롤의 테마를 사용하기 위해 "Windows 원형" 비주얼 관리자 활성화
63 | CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
64 |
65 | // 표준 초기화
66 | // 이들 기능을 사용하지 않고 최종 실행 파일의 크기를 줄이려면
67 | // 아래에서 필요 없는 특정 초기화
68 | // 루틴을 제거해야 합니다.
69 | // 해당 설정이 저장된 레지스트리 키를 변경하십시오.
70 | // TODO: 이 문자열을 회사 또는 조직의 이름과 같은
71 | // 적절한 내용으로 수정해야 합니다.
72 | SetRegistryKey(_T("KernelV"));
73 |
74 | m_pMainWnd = &dlg;
75 | INT_PTR nResponse = dlg.DoModal();
76 |
77 | if (nResponse == IDOK)
78 | {
79 | // TODO: 여기에 [확인]을 클릭하여 대화 상자가 없어질 때 처리할
80 | // 코드를 배치합니다.
81 | }
82 | else if (nResponse == IDCANCEL)
83 | {
84 | // TODO: 여기에 [취소]를 클릭하여 대화 상자가 없어질 때 처리할
85 | // 코드를 배치합니다.
86 | }
87 | else if (nResponse == -1)
88 | {
89 | TRACE(traceAppMsg, 0, "경고: 대화 상자를 만들지 못했으므로 애플리케이션이 예기치 않게 종료됩니다.\n");
90 | TRACE(traceAppMsg, 0, "경고: 대화 상자에서 MFC 컨트롤을 사용하는 경우 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS를 수행할 수 없습니다.\n");
91 | }
92 |
93 | //EXIT:
94 | // 위에서 만든 셸 관리자를 삭제합니다.
95 | if (pShellManager != nullptr)
96 | {
97 | delete pShellManager;
98 | }
99 |
100 | #if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
101 | ControlBarCleanUp();
102 | #endif
103 |
104 | // 대화 상자가 닫혔으므로 응용 프로그램의 메시지 펌프를 시작하지 않고 응용 프로그램을 끝낼 수 있도록 FALSE를
105 | // 반환합니다.
106 | return FALSE;
107 | }
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/src/Agent/Agent.h:
--------------------------------------------------------------------------------
1 |
2 | // Agent.h: PROJECT_NAME 애플리케이션에 대한 주 헤더 파일입니다.
3 | //
4 |
5 | #pragma once
6 |
7 | #ifndef __AFXWIN_H__
8 | #error "PCH에 대해 이 파일을 포함하기 전에 'pch.h'를 포함합니다."
9 | #endif
10 |
11 | #include "resource.h" // 주 기호입니다.
12 |
13 |
14 | // CAgentApp:
15 | // 이 클래스의 구현에 대해서는 Agent.cpp을(를) 참조하세요.
16 | //
17 |
18 | class CAgentApp : public CWinApp
19 | {
20 | public:
21 | CAgentApp();
22 | ~CAgentApp();
23 | // 재정의입니다.
24 | public:
25 | virtual BOOL InitInstance();
26 |
27 | // 구현입니다.
28 |
29 | DECLARE_MESSAGE_MAP()
30 |
31 | };
32 |
33 | extern CAgentApp theApp;
34 |
35 |
--------------------------------------------------------------------------------
/src/Agent/Agent.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codetronik/KernelV/aa5e9cad341662da4b274e39428b97f7e3e9cb2a/src/Agent/Agent.rc
--------------------------------------------------------------------------------
/src/Agent/Agent.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 16.0
23 | {83A69940-6517-49EC-8AA0-19896305574E}
24 | MFCProj
25 | Agent
26 | 10.0
27 |
28 |
29 |
30 | Application
31 | true
32 | v142
33 | Unicode
34 | Dynamic
35 |
36 |
37 | Application
38 | false
39 | v142
40 | true
41 | Unicode
42 | Dynamic
43 |
44 |
45 | Application
46 | true
47 | v142
48 | Unicode
49 | Dynamic
50 |
51 |
52 | Application
53 | false
54 | v142
55 | true
56 | Unicode
57 | Dynamic
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | true
79 |
80 |
81 | true
82 | ..\..\build\x64Debug\
83 | ..\..\build\x64Debug\obj\$(ProjectName)\
84 | KernelV
85 |
86 |
87 | false
88 |
89 |
90 | false
91 | ..\..\build\x64Release\
92 | ..\..\build\x64Release\obj\$(ProjectName)\
93 | KernelV
94 |
95 |
96 |
97 | Use
98 | Level3
99 | true
100 | WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
101 | pch.h
102 |
103 |
104 | Windows
105 |
106 |
107 | false
108 | true
109 | _DEBUG;%(PreprocessorDefinitions)
110 |
111 |
112 | 0x0412
113 | _DEBUG;%(PreprocessorDefinitions)
114 | $(IntDir);%(AdditionalIncludeDirectories)
115 |
116 |
117 |
118 |
119 | Use
120 | Level3
121 | true
122 | _WINDOWS;_DEBUG;%(PreprocessorDefinitions)
123 | pch.h
124 |
125 |
126 | Windows
127 | $(OutDir)KernelV.exe
128 | RequireAdministrator
129 |
130 |
131 | false
132 | true
133 | _DEBUG;%(PreprocessorDefinitions)
134 |
135 |
136 | 0x0412
137 | _DEBUG;%(PreprocessorDefinitions)
138 | $(IntDir);%(AdditionalIncludeDirectories)
139 |
140 |
141 |
142 |
143 | Use
144 | Level3
145 | true
146 | true
147 | true
148 | WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
149 | pch.h
150 |
151 |
152 | Windows
153 | true
154 | true
155 |
156 |
157 | false
158 | true
159 | NDEBUG;%(PreprocessorDefinitions)
160 |
161 |
162 | 0x0412
163 | NDEBUG;%(PreprocessorDefinitions)
164 | $(IntDir);%(AdditionalIncludeDirectories)
165 |
166 |
167 |
168 |
169 | Use
170 | Level4
171 | true
172 | true
173 | true
174 | _WINDOWS;NDEBUG;%(PreprocessorDefinitions)
175 | pch.h
176 | false
177 |
178 |
179 | Windows
180 | true
181 | true
182 | $(OutDir)KernelV.exe
183 |
184 |
185 | false
186 | true
187 | NDEBUG;%(PreprocessorDefinitions)
188 |
189 |
190 | 0x0412
191 | NDEBUG;%(PreprocessorDefinitions)
192 | $(IntDir);%(AdditionalIncludeDirectories)
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 | Create
215 | Create
216 | Create
217 | Create
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
--------------------------------------------------------------------------------
/src/Agent/Agent.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | 헤더 파일
20 |
21 |
22 | 헤더 파일
23 |
24 |
25 | 헤더 파일
26 |
27 |
28 | 헤더 파일
29 |
30 |
31 | 헤더 파일
32 |
33 |
34 | 헤더 파일
35 |
36 |
37 | 헤더 파일
38 |
39 |
40 | 헤더 파일
41 |
42 |
43 | 헤더 파일
44 |
45 |
46 | 헤더 파일
47 |
48 |
49 |
50 |
51 | 소스 파일
52 |
53 |
54 | 소스 파일
55 |
56 |
57 | 소스 파일
58 |
59 |
60 | 소스 파일
61 |
62 |
63 | 소스 파일
64 |
65 |
66 | 소스 파일
67 |
68 |
69 | 소스 파일
70 |
71 |
72 |
73 |
74 | 리소스 파일
75 |
76 |
77 |
78 |
79 | 리소스 파일
80 |
81 |
82 |
83 |
84 | 리소스 파일
85 |
86 |
87 | 리소스 파일
88 |
89 |
90 |
--------------------------------------------------------------------------------
/src/Agent/AgentDlg.cpp:
--------------------------------------------------------------------------------
1 |
2 | // AgentDlg.cpp: 구현 파일
3 | //
4 |
5 | #include "pch.h"
6 | #include "framework.h"
7 | #include "Agent.h"
8 | #include "AgentDlg.h"
9 | #include "afxdialogex.h"
10 | #include "LoadDriver.h"
11 | #include "AboutDlg.h"
12 | #include "ScanDlg.h"
13 | #ifdef _DEBUG
14 | #define new DEBUG_NEW
15 | #endif
16 |
17 |
18 | // CAgentDlg 대화 상자
19 |
20 |
21 |
22 | CAgentDlg::CAgentDlg(CWnd* pParent /*=nullptr*/)
23 | : CDialogEx(IDD_AGENT_DIALOG, pParent)
24 | {
25 | m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
26 | m_bInit = FALSE;
27 | }
28 |
29 | void CAgentDlg::DoDataExchange(CDataExchange* pDX)
30 | {
31 | CDialogEx::DoDataExchange(pDX);
32 | DDX_Control(pDX, IDC_LIST, m_cList);
33 | }
34 |
35 | BEGIN_MESSAGE_MAP(CAgentDlg, CDialogEx)
36 | ON_WM_PAINT()
37 | ON_WM_QUERYDRAGICON()
38 | ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST, OnNMCustomdraw)
39 |
40 | ON_WM_CLOSE()
41 | ON_WM_SIZE()
42 | ON_COMMAND(ID_DRIVER_REFRESH, &CAgentDlg::OnDriverRefreshList)
43 | ON_COMMAND(ID_DRIVER_HIDEMYSELF, &CAgentDlg::OnDriverHideMyself)
44 | ON_COMMAND(ID_ABOUT, &CAgentDlg::OnAbout)
45 | ON_COMMAND(ID_PATTERNSCAN, &CAgentDlg::OnPatternscan)
46 |
47 | ON_WM_CONTEXTMENU()
48 | ON_COMMAND(ID_POPUP_REFRESH, &CAgentDlg::OnDriverRefreshList)
49 | ON_COMMAND(ID_POPUP_HIDESELECTEDDRIVER, &CAgentDlg::OnPopupHideSelectedDriver)
50 |
51 | END_MESSAGE_MAP()
52 |
53 | // 리스트컨트롤 row 색상 바꾸기
54 | void CAgentDlg::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
55 | {
56 | NMLVCUSTOMDRAW* pLVCD = reinterpret_cast(pNMHDR);
57 |
58 | *pResult = 0;
59 |
60 | // 숨김인 경우만
61 | CString hidden = m_cList.GetItemText((int)pLVCD->nmcd.dwItemSpec, 6);
62 |
63 | if (CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
64 | {
65 | *pResult = CDRF_NOTIFYITEMDRAW;
66 | }
67 | else if (CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
68 | {
69 | COLORREF crText;
70 |
71 | // 숨김인 경우만
72 | if (hidden == "YES")
73 | crText = RGB(255, 0, 0);
74 | else
75 | crText = RGB(0, 0, 0);
76 |
77 | pLVCD->clrText = crText;
78 | *pResult = CDRF_DODEFAULT;
79 | }
80 |
81 | }
82 |
83 | // CAgentDlg 메시지 처리기
84 |
85 | BOOL CAgentDlg::OnInitDialog()
86 | {
87 | CDialogEx::OnInitDialog();
88 |
89 | // 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
90 | // 프레임워크가 이 작업을 자동으로 수행합니다.
91 | SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
92 | SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.
93 |
94 | /*
95 | if (AllocConsole())
96 | {
97 | FILE* stream = NULL;
98 | freopen_s(&stream, "CONOUT$", "w", stdout);
99 | SetConsoleTitle(L"Console");
100 | SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
101 | _wsetlocale(0, L"korean");
102 | }
103 | */
104 |
105 | m_cList.InsertColumn(0, L"No", LVCFMT_LEFT, 30);
106 | m_cList.InsertColumn(1, L"Base", LVCFMT_LEFT, 120);
107 | m_cList.InsertColumn(2, L"Size", LVCFMT_LEFT, 65);
108 | m_cList.InsertColumn(3, L"DriverObject", LVCFMT_LEFT, 125);
109 | m_cList.InsertColumn(4, L"Path", LVCFMT_LEFT, 400);
110 | m_cList.InsertColumn(5, L"Service", LVCFMT_LEFT, 120);
111 | m_cList.InsertColumn(6, L"Hidden", LVCFMT_LEFT, 50);
112 |
113 | m_cList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
114 |
115 | // 드라이버 시작
116 | CLoadDriver cLoadDriver;
117 | BOOL bSuccess = cLoadDriver.Load();
118 | if (FALSE == bSuccess)
119 | {
120 | goto EXIT_ERROR;
121 | }
122 |
123 | m_bInit = TRUE;
124 |
125 | bSuccess = m_cComm.Initialize();
126 | if (FALSE == bSuccess)
127 | {
128 | goto EXIT_ERROR;
129 | }
130 | OnDriverRefreshList();
131 |
132 | EXIT_ERROR:
133 | return TRUE;
134 | }
135 |
136 | void CAgentDlg::OnPaint()
137 | {
138 | if (IsIconic())
139 | {
140 | CPaintDC dc(this);
141 |
142 | SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
143 |
144 | int cxIcon = GetSystemMetrics(SM_CXICON);
145 | int cyIcon = GetSystemMetrics(SM_CYICON);
146 | CRect rect;
147 | GetClientRect(&rect);
148 | int x = (rect.Width() - cxIcon + 1) / 2;
149 | int y = (rect.Height() - cyIcon + 1) / 2;
150 |
151 | dc.DrawIcon(x, y, m_hIcon);
152 | }
153 | else
154 | {
155 | CDialogEx::OnPaint();
156 | }
157 | }
158 |
159 | // 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
160 | // 이 함수를 호출합니다.
161 | HCURSOR CAgentDlg::OnQueryDragIcon()
162 | {
163 | return static_cast(m_hIcon);
164 | }
165 |
166 |
167 | BOOL CAgentDlg::PreTranslateMessage(MSG* pMsg)
168 | {
169 | if (pMsg->message == WM_KEYDOWN)
170 | {
171 | if (pMsg->wParam == VK_RETURN)
172 | return TRUE;
173 | else if (pMsg->wParam == VK_ESCAPE)
174 | return TRUE;
175 | }
176 | return CDialogEx::PreTranslateMessage(pMsg);
177 | }
178 |
179 |
180 | void CAgentDlg::OnClose()
181 | {
182 | m_cComm.Finalize();
183 | CLoadDriver cLoadDriver;
184 |
185 | cLoadDriver.Unload();
186 |
187 | CDialogEx::OnClose();
188 | }
189 |
190 |
191 | void CAgentDlg::OnSize(UINT nType, int cx, int cy)
192 | {
193 | CDialogEx::OnSize(nType, cx, cy);
194 |
195 | // dialog 크기가 변하면 리스트컨트롤 크기도 조절함
196 | if (m_bInit)
197 | {
198 | CWnd* pCtl = GetDlgItem(IDC_LIST);
199 | CRect rectCtl;
200 | pCtl->GetWindowRect(&rectCtl);
201 | ScreenToClient(&rectCtl);
202 | pCtl->MoveWindow(rectCtl.left, rectCtl.top, cx - 2 * rectCtl.left, cy - rectCtl.top - rectCtl.left, TRUE);
203 | }
204 |
205 | }
206 |
207 |
208 | void CAgentDlg::OnContextMenu(CWnd* /*pWnd*/, CPoint point)
209 | {
210 | CMenu popup;
211 | CMenu* pMenu;
212 |
213 | popup.LoadMenuW(IDR_POPUP_MENU);
214 | pMenu = popup.GetSubMenu(0);
215 |
216 | pMenu->TrackPopupMenu(TPM_LEFTALIGN || TPM_RIGHTBUTTON, point.x, point.y, this);
217 | }
218 |
219 | /*
220 | * 이하 메뉴 클릭 이벤트 처리
221 | */
222 |
223 | // 팝업 메뉴와 함께 사용
224 | void CAgentDlg::OnDriverRefreshList()
225 | {
226 |
227 | BOOL bSuccess = m_cComm.GetDrivers();
228 | if (FALSE == bSuccess)
229 | {
230 | AfxMessageBox(L"failed to communicate with driver.");
231 | return;
232 | }
233 | m_cList.DeleteAllItems();
234 | for (int i = 0; i < m_cComm.m_DriverListEntry.size(); i++)
235 | {
236 | int nIndex = m_cList.InsertItem(m_cList.GetItemCount(), L"");
237 | CString str;
238 | str.Format(L"%d", nIndex);
239 | m_cList.SetItem(nIndex, 0, LVIF_TEXT, str, NULL, NULL, NULL, NULL);
240 |
241 | str.Format(L"%llx", m_cComm.m_DriverListEntry[i].modBaseAddress);
242 | str.MakeUpper();
243 | m_cList.SetItem(nIndex, 1, LVIF_TEXT, str, NULL, NULL, NULL, NULL);
244 |
245 | str.Format(L"%x", m_cComm.m_DriverListEntry[i].modSize);
246 | str.MakeUpper();
247 | m_cList.SetItem(nIndex, 2, LVIF_TEXT, str, NULL, NULL, NULL, NULL);
248 | if (m_cComm.m_DriverListEntry[i].DriverObject != 0)
249 | {
250 | str.Format(L"%llx", m_cComm.m_DriverListEntry[i].DriverObject);
251 | str.MakeUpper();
252 | m_cList.SetItem(nIndex, 3, LVIF_TEXT, str, NULL, NULL, NULL, NULL);
253 | }
254 | m_cList.SetItem(nIndex, 4, LVIF_TEXT, m_cComm.m_DriverListEntry[i].FilePath, NULL, NULL, NULL, NULL);
255 | m_cList.SetItem(nIndex, 5, LVIF_TEXT, m_cComm.m_DriverListEntry[i].ServiceName, NULL, NULL, NULL, NULL);
256 | if (TRUE == m_cComm.m_DriverListEntry[i].isHidden)
257 | {
258 | m_cList.SetItem(nIndex, 6, LVIF_TEXT, L"YES", NULL, NULL, NULL, NULL);
259 | }
260 | else
261 | {
262 | m_cList.SetItem(nIndex, 6, LVIF_TEXT, L"NO", NULL, NULL, NULL, NULL);
263 | }
264 | }
265 | }
266 |
267 | void CAgentDlg::OnDriverHideMyself()
268 | {
269 | BOOL bSuccess = m_cComm.HideMyself();
270 | if (FALSE == bSuccess)
271 | {
272 | AfxMessageBox(L"failed to communicate with driver.");
273 | return;
274 | }
275 | AfxMessageBox(L"succeeded in hiding the driver.");
276 | OnDriverRefreshList();
277 | }
278 |
279 | void CAgentDlg::OnPopupHideSelectedDriver()
280 | {
281 | int nPosition = m_cList.GetSelectionMark();
282 | CString strFilePath = m_cList.GetItemText(nPosition, 4);
283 | LPCWSTR pFilePath = strFilePath.GetBuffer();
284 | CString strServiceName = m_cList.GetItemText(nPosition, 5);
285 | LPCWSTR pServiceName = strServiceName.GetBuffer();
286 |
287 | BOOL bHide = FALSE;
288 | BOOL bSuccess = m_cComm.HideDriver(pFilePath, pServiceName, &bHide);
289 | if (FALSE == bSuccess)
290 | {
291 | AfxMessageBox(L"failed to communicate with driver.");
292 | goto EXIT;
293 | }
294 | if (bHide)
295 | {
296 | AfxMessageBox(L"succeeded in hiding the driver.");
297 | }
298 | else
299 | {
300 | AfxMessageBox(L"failed to hide the driver.");
301 | }
302 | EXIT:
303 | strFilePath.ReleaseBuffer();
304 | OnDriverRefreshList();
305 | }
306 |
307 | void CAgentDlg::OnAbout()
308 | {
309 | CAboutDlg about;
310 | about.DoModal();
311 | }
312 |
313 | void CAgentDlg::OnPatternscan()
314 | {
315 | CScan scan;
316 | scan.SetClass(m_cComm);
317 | scan.DoModal();
318 | }
319 |
--------------------------------------------------------------------------------
/src/Agent/AgentDlg.h:
--------------------------------------------------------------------------------
1 |
2 | // AgentDlg.h: 헤더 파일
3 | //
4 |
5 | #pragma once
6 | #include "Communication.h"
7 |
8 | // CAgentDlg 대화 상자
9 | class CAgentDlg : public CDialogEx
10 | {
11 | // 생성입니다.
12 | public:
13 | CAgentDlg(CWnd* pParent = nullptr); // 표준 생성자입니다.
14 |
15 | // 대화 상자 데이터입니다.
16 | #ifdef AFX_DESIGN_TIME
17 | enum { IDD = IDD_AGENT_DIALOG };
18 | #endif
19 |
20 | protected:
21 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
22 |
23 |
24 | // 구현입니다.
25 | protected:
26 | HICON m_hIcon;
27 |
28 | // 생성된 메시지 맵 함수
29 | virtual BOOL OnInitDialog();
30 | afx_msg void OnPaint();
31 | afx_msg HCURSOR OnQueryDragIcon();
32 | afx_msg void OnNMCustomdraw(NMHDR*, LRESULT*);
33 | DECLARE_MESSAGE_MAP()
34 |
35 | public:
36 |
37 | CListCtrl m_cList;
38 | virtual BOOL PreTranslateMessage(MSG* pMsg);
39 | afx_msg void OnClose();
40 |
41 | private:
42 | CCommunication m_cComm;
43 | BOOL m_bInit;
44 | public:
45 | afx_msg void OnSize(UINT nType, int cx, int cy);
46 | afx_msg void OnDriverRefreshList();
47 | afx_msg void OnDriverHideMyself();
48 |
49 | afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
50 |
51 | afx_msg void OnPopupHideSelectedDriver();
52 | afx_msg void OnAbout();
53 | afx_msg void OnPatternscan();
54 | };
55 |
--------------------------------------------------------------------------------
/src/Agent/Communication.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "Communication.h"
3 | #include "LoadDriver.h"
4 | #include
5 |
6 | #define IOCTL_KERNELV_LOAD_DRIVER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
7 | #define IOCTL_KERNELV_HIDE_MYSELF CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
8 | #define IOCTL_KERNELV_HIDE_DRIVER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
9 | #define IOCTL_KERNELV_SCAN_PATTERN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
10 |
11 |
12 | CCommunication::CCommunication()
13 | {
14 | m_hDevice = NULL;
15 | }
16 | CCommunication::~CCommunication()
17 | {
18 |
19 | }
20 |
21 | BOOL CCommunication::Initialize()
22 | {
23 | TCHAR szPath[MAX_PATH] = { 0, };
24 | TCHAR szCurrentDir[MAX_PATH] = { 0, };
25 | CString strErrorMsg;
26 |
27 | GetCurrentDirectory(MAX_PATH, szCurrentDir);
28 | swprintf_s(szPath, MAX_PATH, _T("%s\\%s"), szCurrentDir, DRIVER_NAME);
29 |
30 | TCHAR* szDeviceLink = _T("\\\\.\\KernelV");
31 |
32 | m_hDevice = CreateFile(szDeviceLink, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
33 | if (INVALID_HANDLE_VALUE == m_hDevice)
34 | {
35 | strErrorMsg.Format(L"[I/O driver] CreateFile Error : %d", GetLastError());
36 | AfxMessageBox(strErrorMsg);
37 | return FALSE;
38 | }
39 | return TRUE;
40 |
41 | }
42 | void CCommunication::Finalize()
43 | {
44 | if (m_hDevice)
45 | {
46 | CloseHandle(m_hDevice);
47 | m_hDevice = NULL;
48 | }
49 | }
50 | BOOL CCommunication::HideMyself()
51 | {
52 | DWORD dwRetBytes = 0;
53 |
54 | BOOL bSuccess = DeviceIoControl(m_hDevice, IOCTL_KERNELV_HIDE_MYSELF, NULL, 0, NULL, 0, &dwRetBytes, NULL);
55 | if (FALSE == bSuccess)
56 | {
57 | return FALSE;
58 | }
59 |
60 | return TRUE;
61 | }
62 | BOOL CCommunication::HideDriver(LPCWSTR pDriverPath, LPCWSTR pServiceName, PBOOL pbHide)
63 | {
64 | DWORD dwRetBytes = 0;
65 | WCHAR szYes[4] = { 0, };
66 | // null스트링 포함
67 | CString SendData;
68 | SendData.Format(L"%s::%s", pDriverPath, pServiceName);
69 | BOOL bSuccess = DeviceIoControl(m_hDevice, IOCTL_KERNELV_HIDE_DRIVER, (LPVOID)SendData.GetBuffer(), (DWORD)(wcslen(SendData.GetBuffer())*2 + 2), szYes, (DWORD)sizeof(szYes), &dwRetBytes, NULL);
70 | if (FALSE == bSuccess)
71 | {
72 | return FALSE;
73 | }
74 | if (wcscmp(L"YES", szYes) == 0)
75 | {
76 | *pbHide = TRUE;
77 | }
78 | else
79 | {
80 | *pbHide = FALSE;
81 | }
82 | return TRUE;
83 | }
84 |
85 | BOOL CCommunication::GetDrivers()
86 | {
87 | m_DriverListEntry.clear();
88 |
89 | DWORD dwRetBytes = 0;
90 | // 필요한 버퍼 사이즈를 묻는다.
91 | BOOL bSuccess = DeviceIoControl(m_hDevice, IOCTL_KERNELV_LOAD_DRIVER, NULL, 0, NULL, 0, &dwRetBytes, NULL);
92 | printf("1. dwret : %d\n", dwRetBytes);
93 |
94 | // 정확한 사이즈를 가지고 도전
95 | m_DriverListEntry.resize(dwRetBytes / sizeof(DRIVER_LIST_ENTRY));
96 | bSuccess = DeviceIoControl(m_hDevice, IOCTL_KERNELV_LOAD_DRIVER, NULL, 0, &m_DriverListEntry.front(), dwRetBytes, &dwRetBytes, NULL);
97 | if (FALSE == bSuccess || dwRetBytes == 0)
98 | {
99 | return FALSE;
100 | }
101 | printf("2. dwret : %d\n", dwRetBytes);
102 | return TRUE;
103 | }
104 |
105 | BOOL CCommunication::ScanPattern(PBYTE pPattern, size_t nPatternSize)
106 | {
107 | m_DetectListEntry.clear();
108 |
109 | DWORD dwRetBytes = 0;
110 |
111 | // 필요한 버퍼 사이즈를 묻는다.
112 | BOOL bSuccess = DeviceIoControl(m_hDevice, IOCTL_KERNELV_SCAN_PATTERN, pPattern, (DWORD)nPatternSize, NULL, 0, &dwRetBytes, NULL);
113 | printf("1. dwret : %d\n", dwRetBytes);
114 | if (FALSE == bSuccess)
115 | {
116 | return FALSE;
117 | }
118 | if (dwRetBytes == 0)
119 | {
120 | return TRUE;
121 | }
122 |
123 | // 정확한 사이즈를 가지고 도전
124 | m_DetectListEntry.resize(dwRetBytes / sizeof(DETECT_LIST_ENTRY));
125 |
126 | bSuccess = DeviceIoControl(m_hDevice, IOCTL_KERNELV_SCAN_PATTERN, NULL, 0, &m_DetectListEntry.front(), dwRetBytes, &dwRetBytes, NULL);
127 | if (FALSE == bSuccess)
128 | {
129 | return FALSE;
130 | }
131 | printf("2. dwret : %d\n", dwRetBytes);
132 |
133 |
134 | return TRUE;
135 | }
--------------------------------------------------------------------------------
/src/Agent/Communication.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | using namespace std;
4 |
5 | typedef struct _DRIVER_LIST_ENTRY {
6 | uintptr_t modBaseAddress;
7 | ULONG modSize;
8 | WCHAR FilePath[MAX_PATH];
9 | WCHAR ServiceName[MAX_PATH];
10 | uintptr_t DriverObject;
11 | BOOLEAN isHidden;
12 | LIST_ENTRY Entry; // list chain
13 | } DRIVER_LIST_ENTRY, * PDRIVER_LIST_ENTRY;
14 |
15 | typedef struct _DETECT_LIST_ENTRY {
16 | LIST_ENTRY Entry; // list chain
17 | UINT PatternNo;
18 | uintptr_t BaseAddress;
19 | UINT Offset;
20 | } DETECT_LIST_ENTRY, * PDETECT_LIST_ENTRY;
21 |
22 |
23 | class CCommunication
24 | {
25 | public:
26 | CCommunication();
27 | ~CCommunication();
28 | public:
29 | BOOL Initialize();
30 | void Finalize();
31 | BOOL GetDrivers();
32 | BOOL HideMyself();
33 | BOOL ScanPattern(PBYTE pPattern, size_t nPatternSize);
34 | BOOL HideDriver(LPCWSTR pDriverPath, LPCWSTR pServiceName, PBOOL pbHide);
35 | vector m_DriverListEntry;
36 | vector m_DetectListEntry;
37 |
38 | private:
39 | HANDLE m_hDevice;
40 | };
41 |
--------------------------------------------------------------------------------
/src/Agent/LoadDriver.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "LoadDriver.h"
3 | #include
4 |
5 | CLoadDriver::CLoadDriver()
6 | {
7 |
8 | }
9 |
10 | CLoadDriver::~CLoadDriver(void)
11 | {
12 |
13 | }
14 |
15 | BOOL CLoadDriver::Load()
16 | {
17 | BOOL bRet = FALSE;
18 | SC_HANDLE hSCManager = NULL;
19 | SC_HANDLE hService = NULL;
20 | SC_HANDLE hCService = NULL;
21 | TCHAR szCurrentDirectory[MAX_PATH] = { 0, };
22 | TCHAR szDriverPath[MAX_PATH] = { 0, };
23 |
24 | DWORD dwError = 0;
25 | CString str;
26 |
27 | GetCurrentDirectory(MAX_PATH, szCurrentDirectory);
28 | swprintf_s(szDriverPath, MAX_PATH, _T("%s\\%s.sys"), szCurrentDirectory, DRIVER_NAME);
29 |
30 | hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
31 | if (NULL == hSCManager)
32 | {
33 | dwError = GetLastError();
34 | str.Format(L"[Load driver] OpenSCManager() Error : %d", dwError);
35 | AfxMessageBox(str);
36 | goto EXIT_ERROR;
37 | }
38 |
39 | hCService = CreateService(
40 | hSCManager,
41 | DRIVER_NAME,
42 | DRIVER_NAME,
43 | SERVICE_ALL_ACCESS,
44 | SERVICE_KERNEL_DRIVER,
45 | SERVICE_DEMAND_START,
46 | SERVICE_ERROR_NORMAL,
47 | szDriverPath,
48 | NULL,
49 | NULL,
50 | NULL,
51 | NULL,
52 | NULL);
53 | if (NULL == hCService)
54 | {
55 | dwError = GetLastError();
56 | if (ERROR_SERVICE_EXISTS == dwError)
57 | {
58 | str.Format(L"[Load driver] CreateService() Error : %d", dwError);
59 | bRet = TRUE;
60 | goto EXIT;
61 | }
62 | str.Format(L"[Load driver] CreateService() Error : %d", dwError);
63 | AfxMessageBox(str);
64 | goto EXIT_ERROR;
65 | }
66 |
67 | hService = OpenService(hSCManager, DRIVER_NAME, SERVICE_ALL_ACCESS);
68 | if (NULL == hService)
69 | {
70 | dwError = GetLastError();
71 | str.Format(L"[Load driver] OpenService() Error : %d", dwError);
72 | AfxMessageBox(str);
73 | goto EXIT_ERROR;
74 | }
75 |
76 | if (FALSE == StartService(hService, 0, NULL))
77 | {
78 | dwError = GetLastError();
79 | str.Format(L"[Load driver] StartService() Error : %d", dwError);
80 | AfxMessageBox(str);
81 | goto EXIT_ERROR;
82 | }
83 |
84 | bRet = TRUE;
85 | goto EXIT;
86 |
87 | EXIT_ERROR:
88 | bRet = FALSE;
89 |
90 | EXIT:
91 | if (hCService)
92 | {
93 | CloseServiceHandle(hCService);
94 | }
95 | if (hService)
96 | {
97 | CloseServiceHandle(hService);
98 | }
99 | if (hSCManager)
100 | {
101 | CloseServiceHandle(hSCManager);
102 | }
103 | return bRet;
104 | }
105 |
106 |
107 |
108 | BOOL CLoadDriver::Unload()
109 | {
110 | BOOL bRet = FALSE;
111 | SC_HANDLE hSCManager = NULL;
112 | SC_HANDLE hService = NULL;
113 | SERVICE_STATUS ss;
114 | DWORD dwError = 0;
115 | CString str;
116 |
117 | _tprintf(_T("Stoping and unloading Driver.."));
118 | hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
119 | if (NULL == hSCManager)
120 | {
121 | dwError = GetLastError();
122 | str.Format(L"[Unload driver] OpenSCManager() Error : %d", dwError);
123 | AfxMessageBox(str);
124 | goto EXIT_ERROR;
125 | }
126 |
127 | hService = OpenService(hSCManager, DRIVER_NAME, SERVICE_ALL_ACCESS);
128 | if (NULL == hService)
129 | {
130 | dwError = GetLastError();
131 | str.Format(L"[Unload driver] OpenService() Error : %d", dwError);
132 | AfxMessageBox(str);
133 | goto EXIT_ERROR;
134 | }
135 |
136 | if (!ControlService(hService, SERVICE_CONTROL_STOP, &ss))
137 | {
138 | dwError = GetLastError();
139 | str.Format(L"[Unload driver] ControlService() Error : %d", dwError);
140 | AfxMessageBox(str);
141 | // goto EXIT_ERROR;
142 | }
143 |
144 | if (!DeleteService(hService))
145 | {
146 | dwError = GetLastError();
147 | str.Format(L"[Unload driver] DeleteService() Error : %d", dwError);
148 | AfxMessageBox(str);
149 | goto EXIT_ERROR;
150 | }
151 |
152 | bRet = TRUE;
153 | goto EXIT;
154 |
155 | EXIT_ERROR:
156 | bRet = FALSE;
157 |
158 | EXIT:
159 | if (hService)
160 | {
161 | CloseServiceHandle(hService);
162 | }
163 | if (hSCManager)
164 | {
165 | CloseServiceHandle(hSCManager);
166 | }
167 | return bRet;
168 | }
--------------------------------------------------------------------------------
/src/Agent/LoadDriver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define DRIVER_NAME L"KernelV"
4 |
5 | class CLoadDriver
6 | {
7 | public:
8 | CLoadDriver();
9 | ~CLoadDriver();
10 | BOOL Load();
11 | BOOL Unload();
12 | };
13 |
14 |
--------------------------------------------------------------------------------
/src/Agent/ScanDlg.cpp:
--------------------------------------------------------------------------------
1 | // ScanDlg.cpp: 구현 파일
2 | //
3 |
4 | #include "pch.h"
5 | #include "Agent.h"
6 | #include "ScanDlg.h"
7 | #include "afxdialogex.h"
8 | #include
9 |
10 | using namespace std;
11 |
12 | // CScan 대화 상자
13 |
14 | IMPLEMENT_DYNAMIC(CScan, CDialogEx)
15 |
16 | CScan::CScan(CWnd* pParent /*=nullptr*/)
17 | : CDialogEx(IDD_SCAN_DIALOG, pParent)
18 | {
19 |
20 | }
21 |
22 | CScan::~CScan()
23 | {
24 | }
25 |
26 | void CScan::DoDataExchange(CDataExchange* pDX)
27 | {
28 | CDialogEx::DoDataExchange(pDX);
29 | DDX_Control(pDX, IDC_EDIT_PATTERN, m_cPattern);
30 | DDX_Control(pDX, IDC_STATIC_NUM_PATTERN, m_cStaticNumPattern);
31 | DDX_Control(pDX, IDC_EDIT_RESULT, m_cResult);
32 | }
33 |
34 |
35 | BEGIN_MESSAGE_MAP(CScan, CDialogEx)
36 | ON_BN_CLICKED(IDC_BUTTON_SCAN, &CScan::OnBnClickedButtonScan)
37 | END_MESSAGE_MAP()
38 |
39 |
40 | // CScan 메시지 처리기
41 |
42 | BOOL CScan::OnInitDialog()
43 | {
44 | CDialogEx::OnInitDialog();
45 | return TRUE;
46 | }
47 |
48 | BOOL CScan::PreTranslateMessage(MSG* pMsg)
49 | {
50 | CEdit* edit;
51 | // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
52 | if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
53 | {
54 | if (GetDlgItem(IDC_EDIT_PATTERN) == GetFocus())
55 | {
56 | edit = (CEdit*)GetDlgItem(IDC_EDIT_PATTERN);
57 | edit->ReplaceSel(_T("\r\n"));
58 | }
59 |
60 | }
61 |
62 | return CDialogEx::PreTranslateMessage(pMsg);
63 | }
64 |
65 | void CScan::SetClass(CCommunication cComm)
66 | {
67 | m_cComm = cComm;
68 | }
69 |
70 | void CScan::OnBnClickedButtonScan()
71 | {
72 | CString strMsg;
73 | CString result;
74 |
75 | vector Pattern;
76 |
77 | CString strEdit; // 에디트 컨트롤에서 가져온 문자열
78 | GetDlgItemTextW(IDC_EDIT_PATTERN, strEdit);
79 |
80 | // 입력 데이터가 너무 크면 뱉음
81 | if (strEdit.GetLength() > 4096)
82 | {
83 | AfxMessageBox(L"The maximum input string length is 4096 bytes.");
84 | goto EXIT_ERROR;
85 | }
86 | strEdit.Replace(L" ", NULL); // 공백 제거
87 |
88 | // 문자열 유효성 검사
89 | if (strEdit.SpanIncluding(L"0123456789abcdefABCDEF\r\n") != strEdit)
90 | {
91 | AfxMessageBox(L"It contains non-HEX strings.\r\nYou can only enter hex.");
92 | goto EXIT_ERROR;
93 | }
94 |
95 | int nPatternCount = 0;
96 |
97 | while (!strEdit.IsEmpty())
98 | {
99 | CString strLine = strEdit.SpanExcluding(L"\r\n");
100 | strEdit = strEdit.Right(strEdit.GetLength() - strLine.GetLength()).TrimLeft(L"\r\n");
101 | if (strLine.IsEmpty())
102 | {
103 | continue;
104 | }
105 |
106 | int nLineLen = strLine.GetLength();
107 | if (nLineLen < 8)
108 | {
109 | strMsg.Format(L"The pattern(No. %d) size is too short. Input at least 4 bytes.", nPatternCount + 1);
110 | AfxMessageBox(strMsg);
111 | goto EXIT_ERROR;
112 | }
113 | if (nLineLen % 2 != 0)
114 | {
115 | strMsg.Format(L"The pattern(No. %d) size is not even.\r\nEX) BFF(WRONG) 0BFF(TRUE)", nPatternCount + 1);
116 | AfxMessageBox(strMsg);
117 | goto EXIT_ERROR;
118 | }
119 | // 시작 패턴을 알리는 signature
120 | Pattern.push_back('S');
121 | Pattern.push_back('T');
122 | Pattern.push_back('a');
123 | Pattern.push_back('r');
124 | Pattern.push_back('t');
125 |
126 | // 한줄읽은거에서 바이트 형식으로 변환
127 | for (int j = 0; j < nLineLen; j = j + 2)
128 | {
129 | WCHAR temp[5] = { 0, };
130 | wcsncpy_s(temp, 5, strLine.GetBuffer() + j, 2);
131 | Pattern.push_back((BYTE)wcstoul(temp, NULL, 16));
132 | }
133 |
134 | // 끝 패턴을 알리는 signature
135 | Pattern.push_back('e');
136 | Pattern.push_back('n');
137 | Pattern.push_back('D');
138 |
139 | nPatternCount++;
140 | }
141 |
142 | strMsg.Format(L"Input Pattern count : %d", nPatternCount);
143 | m_cStaticNumPattern.SetWindowTextW(strMsg);
144 |
145 | // 잘 들어갔는지 로깅
146 | char* szBuffer = (char*)malloc(5000);
147 | memset(szBuffer, 0, 5000);
148 | printf("pattern size : %zd\n", Pattern.size());
149 | for (int i = 0; i < Pattern.size(); i++)
150 | {
151 | if (i % 16 == 0)
152 | {
153 | strcat_s(szBuffer, 5000, "\r\n");
154 | }
155 | char temp[5] = { 0, };
156 | sprintf_s(temp, 5, "%02x ", Pattern[i]);
157 | strcat_s(szBuffer, 5000, temp);
158 | }
159 | printf("%s\r\n", szBuffer);
160 | free(szBuffer);
161 |
162 | BOOL bSuccess = m_cComm.ScanPattern(&Pattern.front(), Pattern.size());
163 | if (FALSE == bSuccess)
164 | {
165 | AfxMessageBox(L"failed to communicate with driver.");
166 | goto EXIT_ERROR;
167 | }
168 |
169 | // 0개 검출시 1바이트가 리턴옴
170 | if (m_cComm.m_DetectListEntry.size() == 0)
171 | {
172 | m_cResult.SetWindowText(L"No pattern detected.");
173 | goto EXIT;
174 | }
175 |
176 |
177 | for (int i = 0; i < m_cComm.m_DetectListEntry.size(); i++)
178 | {
179 | for (int j = 0; j < m_cComm.m_DriverListEntry.size(); j++)
180 | {
181 | if (m_cComm.m_DriverListEntry[j].modBaseAddress == m_cComm.m_DetectListEntry[i].BaseAddress)
182 | {
183 | strMsg.Format(L"Pattern No (%d) Base : %llX Offset : %X %s\r\n",
184 | m_cComm.m_DetectListEntry[i].PatternNo,
185 | m_cComm.m_DetectListEntry[i].BaseAddress,
186 | m_cComm.m_DetectListEntry[i].Offset,
187 | m_cComm.m_DriverListEntry[j].FilePath);
188 | result = result + strMsg;
189 | }
190 | }
191 | }
192 | m_cComm.m_DetectListEntry.clear();
193 | m_cResult.SetWindowText(result);
194 | EXIT:
195 | EXIT_ERROR:
196 | return;
197 | }
198 |
--------------------------------------------------------------------------------
/src/Agent/ScanDlg.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "Communication.h"
3 |
4 | // CScan 대화 상자
5 |
6 | class CScan : public CDialogEx
7 | {
8 | DECLARE_DYNAMIC(CScan)
9 |
10 | public:
11 | CScan(CWnd* pParent = nullptr); // 표준 생성자입니다.
12 | virtual ~CScan();
13 |
14 | // 대화 상자 데이터입니다.
15 | #ifdef AFX_DESIGN_TIME
16 | enum { IDD = IDD_SCAN_DIALOG };
17 | #endif
18 |
19 | protected:
20 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
21 | virtual BOOL OnInitDialog();
22 | DECLARE_MESSAGE_MAP()
23 | public:
24 | virtual BOOL PreTranslateMessage(MSG* pMsg);
25 | afx_msg void OnBnClickedButtonScan();;
26 | void SetClass(CCommunication cComm);
27 |
28 | private:
29 | CCommunication m_cComm;
30 | public:
31 | CStatic m_cStaticNumPattern;
32 | CEdit m_cResult;
33 | CEdit m_cPattern;
34 | };
35 |
--------------------------------------------------------------------------------
/src/Agent/framework.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef VC_EXTRALEAN
4 | #define VC_EXTRALEAN // 거의 사용되지 않는 내용은 Windows 헤더에서 제외합니다.
5 | #endif
6 |
7 | #include "targetver.h"
8 |
9 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 일부 CString 생성자는 명시적으로 선언됩니다.
10 |
11 | // MFC의 공통 부분과 무시 가능한 경고 메시지에 대한 숨기기를 해제합니다.
12 | #define _AFX_ALL_WARNINGS
13 |
14 | #include // MFC 핵심 및 표준 구성 요소입니다.
15 | #include // MFC 확장입니다.
16 |
17 |
18 |
19 |
20 |
21 | #ifndef _AFX_NO_OLE_SUPPORT
22 | #include // Internet Explorer 4 공용 컨트롤에 대한 MFC 지원입니다.
23 | #endif
24 | #ifndef _AFX_NO_AFXCMN_SUPPORT
25 | #include // Windows 공용 컨트롤에 대한 MFC 지원입니다.
26 | #endif // _AFX_NO_AFXCMN_SUPPORT
27 |
28 | #include // MFC의 리본 및 컨트롤 막대 지원
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/Agent/pch.cpp:
--------------------------------------------------------------------------------
1 | // pch.cpp: 미리 컴파일된 헤더에 해당하는 소스 파일
2 |
3 | #include "pch.h"
4 |
5 | // 미리 컴파일된 헤더를 사용하는 경우 컴파일이 성공하려면 이 소스 파일이 필요합니다.
6 |
--------------------------------------------------------------------------------
/src/Agent/pch.h:
--------------------------------------------------------------------------------
1 | // pch.h: 미리 컴파일된 헤더 파일입니다.
2 | // 아래 나열된 파일은 한 번만 컴파일되었으며, 향후 빌드에 대한 빌드 성능을 향상합니다.
3 | // 코드 컴파일 및 여러 코드 검색 기능을 포함하여 IntelliSense 성능에도 영향을 미칩니다.
4 | // 그러나 여기에 나열된 파일은 빌드 간 업데이트되는 경우 모두 다시 컴파일됩니다.
5 | // 여기에 자주 업데이트할 파일을 추가하지 마세요. 그러면 성능이 저하됩니다.
6 |
7 | #ifndef PCH_H
8 | #define PCH_H
9 |
10 | // 여기에 미리 컴파일하려는 헤더 추가
11 | #include "framework.h"
12 |
13 | #endif //PCH_H
14 |
--------------------------------------------------------------------------------
/src/Agent/res/About.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codetronik/KernelV/aa5e9cad341662da4b274e39428b97f7e3e9cb2a/src/Agent/res/About.bmp
--------------------------------------------------------------------------------
/src/Agent/res/Agent.rc2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codetronik/KernelV/aa5e9cad341662da4b274e39428b97f7e3e9cb2a/src/Agent/res/Agent.rc2
--------------------------------------------------------------------------------
/src/Agent/res/KernelV.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codetronik/KernelV/aa5e9cad341662da4b274e39428b97f7e3e9cb2a/src/Agent/res/KernelV.ico
--------------------------------------------------------------------------------
/src/Agent/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++에서 생성한 포함 파일입니다.
3 | // Agent.rc에서 사용되고 있습니다.
4 | //
5 | #define IDD_AGENT_DIALOG 102
6 | #define IDD_ABOUT_DIALOG 103
7 | #define IDD_SCAN_DIALOG 104
8 | #define IDR_MAINFRAME 128
9 | #define IDR_MENU 130
10 | #define IDR_POPUP_MENU 131
11 | #define IDB_BITMAP1 134
12 | #define IDC_LIST 1000
13 | #define IDC_PICTURE 1001
14 | #define IDC_EDIT_RESULT 1002
15 | #define IDC_BUTTON_SCAN 1003
16 | #define IDC_STATIC_PATTERN 1004
17 | #define IDC_STATIC_RESULT 1005
18 | #define IDC_EDIT_PATTERN 1006
19 | #define IDC_STATIC_NUM_PATTERN 1008
20 | #define ID_DRIVER_REFRESH 32771
21 | #define ID_DRIVER_HIDEMYSELF 32772
22 | #define ID_POPUP_REFRESH 32775
23 | #define ID_POPUP_HIDESELECTEDDRIVER 32778
24 | #define ID_ABOUT 32779
25 | #define ID_PATTERNSCAN 32780
26 |
27 | // Next default values for new objects
28 | //
29 | #ifdef APSTUDIO_INVOKED
30 | #ifndef APSTUDIO_READONLY_SYMBOLS
31 | #define _APS_NEXT_RESOURCE_VALUE 136
32 | #define _APS_NEXT_COMMAND_VALUE 32781
33 | #define _APS_NEXT_CONTROL_VALUE 1010
34 | #define _APS_NEXT_SYMED_VALUE 105
35 | #endif
36 | #endif
37 |
--------------------------------------------------------------------------------
/src/Agent/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // SDKDDKVer.h를 포함하면 최고 수준의 가용성을 가진 Windows 플랫폼이 정의됩니다.
4 |
5 | // 이전 Windows 플랫폼에 대해 애플리케이션을 빌드하려는 경우에는 SDKDDKVer.h를 포함하기 전에
6 | // WinSDKVer.h를 포함하고 _WIN32_WINNT 매크로를 지원하려는 플랫폼으로 설정하십시오.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------
/src/Driver/Driver.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 | Debug
22 | ARM
23 |
24 |
25 | Release
26 | ARM
27 |
28 |
29 | Debug
30 | ARM64
31 |
32 |
33 | Release
34 | ARM64
35 |
36 |
37 |
38 | {AF42A289-FB31-44C7-9254-E7B5BC50708F}
39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d}
40 | v4.5
41 | 12.0
42 | Debug
43 | Win32
44 | Driver
45 | $(LatestTargetPlatformVersion)
46 |
47 |
48 |
49 | Windows10
50 | true
51 | WindowsKernelModeDriver10.0
52 | Driver
53 | WDM
54 |
55 |
56 | Windows10
57 | false
58 | WindowsKernelModeDriver10.0
59 | Driver
60 | WDM
61 |
62 |
63 | Windows10
64 | true
65 | WindowsKernelModeDriver10.0
66 | Driver
67 | WDM
68 |
69 |
70 | Windows10
71 | false
72 | WindowsKernelModeDriver10.0
73 | Driver
74 | WDM
75 |
76 |
77 | Windows10
78 | true
79 | WindowsKernelModeDriver10.0
80 | Driver
81 | WDM
82 |
83 |
84 | Windows10
85 | false
86 | WindowsKernelModeDriver10.0
87 | Driver
88 | WDM
89 |
90 |
91 | Windows10
92 | true
93 | WindowsKernelModeDriver10.0
94 | Driver
95 | WDM
96 |
97 |
98 | Windows10
99 | false
100 | WindowsKernelModeDriver10.0
101 | Driver
102 | WDM
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | DbgengKernelDebugger
114 |
115 |
116 | DbgengKernelDebugger
117 |
118 |
119 | DbgengKernelDebugger
120 | ..\..\build\x64Debug\
121 | ..\..\build\x64Debug\obj\$(ProjectName)\
122 | KernelV
123 |
124 |
125 | DbgengKernelDebugger
126 | ..\..\build\x64Release\
127 | ..\..\build\x64Release\obj\$(ProjectName)\
128 | KernelV
129 |
130 |
131 | DbgengKernelDebugger
132 |
133 |
134 | DbgengKernelDebugger
135 |
136 |
137 | DbgengKernelDebugger
138 |
139 |
140 | DbgengKernelDebugger
141 |
142 |
143 |
144 | Level4
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/src/Driver/Driver.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {8E41214B-6785-4CFE-B992-037D68949A14}
18 | inf;inv;inx;mof;mc;
19 |
20 |
21 |
22 |
23 | Header Files
24 |
25 |
26 | Header Files
27 |
28 |
29 | Header Files
30 |
31 |
32 | Header Files
33 |
34 |
35 | Header Files
36 |
37 |
38 | Header Files
39 |
40 |
41 | Header Files
42 |
43 |
44 |
45 |
46 | Source Files
47 |
48 |
49 | Source Files
50 |
51 |
52 | Source Files
53 |
54 |
55 | Source Files
56 |
57 |
58 | Source Files
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/Driver/define.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define kprintf(...) KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, __VA_ARGS__)) // DbgPrint()를 사용한 경우 로딩이 되지 않았던 문제 발생
4 | #define POOL_TAG 'coTr'
5 |
6 |
--------------------------------------------------------------------------------
/src/Driver/engine.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "engine.h"
8 | #include "define.h"
9 | #include "undocumented.h"
10 | #include "listentry.h"
11 |
12 | // Build 19041
13 | #define EPROCESS_ACTIVE_PROCESS_LINKS 0x448
14 | // Build 18362
15 | //#define EPROCESS_ACTIVE_PROCESS_LINKS 0x2F0
16 |
17 | #define EPROCESS_IMAGE_FILE_NAME 0x5A8
18 | #define EPROCESS_UNIQUE_PROCESS_ID 0x440 // PVOID64
19 |
20 |
21 | extern PDRIVER_OBJECT g_pDriverObject;
22 | extern POBJECT_TYPE* IoDriverObjectType;
23 | PLDR_DATA_TABLE_ENTRY PsLoadedModuleList;
24 |
25 | VOID EnumerateEPROCESS(PUCHAR pTargetFileName)
26 | {
27 | // system(pid:4)의 EPROCESS 를 반환함
28 | PEPROCESS pCurrentProcess = PsInitialSystemProcess; /* PsGetCurrentProcess() 와 같음 */
29 | PLIST_ENTRY pCurrentListEntry = NULL;
30 |
31 | while (TRUE)
32 | {
33 | // next EPROCESS
34 | pCurrentListEntry = (PLIST_ENTRY)((uintptr_t)pCurrentProcess + EPROCESS_ACTIVE_PROCESS_LINKS);
35 | PEPROCESS pNextProcess = (PEPROCESS)((uintptr_t)pCurrentListEntry->Flink - EPROCESS_ACTIVE_PROCESS_LINKS);
36 |
37 | /* 구조체에서 구하기
38 | size_t dwPid = *((uintptr_t*)((uintptr_t)pCurrentProcess + EPROCESS_UNIQUE_PROCESS_ID));
39 | char* pImageFileName = (char*)((uintptr_t)pCurrentProcess + EPROCESS_IMAGE_FILE_NAME);
40 | */
41 |
42 | // build 버전마다 오프셋이 다르기때문에 가급적 api를 사용
43 | size_t dwPid = (size_t)PsGetProcessId(pCurrentProcess);
44 | dwPid = 0;
45 | UCHAR* pImageFileName = PsGetProcessImageFileName(pCurrentProcess); // 제대로 못가져옴.
46 |
47 | kprintf("%p %s %lld", pCurrentProcess, PsGetProcessImageFileName(pCurrentProcess), dwPid);
48 |
49 | // process 숨기기
50 | // 수 분 이내로 patch guard에 의한 BSOD 발생 (CRITICAL STRUCTURE CORRUPTION)
51 | // 참조 : https://www.sysnet.pe.kr/2/0/12110
52 | if (0 == strcmp((char*)pTargetFileName, (char*)pImageFileName))
53 | {
54 | kprintf("hide process\n");
55 | PLIST_ENTRY pPrevListEntry = pCurrentListEntry->Blink;
56 | PLIST_ENTRY pNextListEntry = pCurrentListEntry->Flink;
57 | pPrevListEntry->Flink = pCurrentListEntry->Flink; // 이전 노드의 다음을 내 다음으로 바꿈
58 | pNextListEntry->Blink = pCurrentListEntry->Blink; // 다음 노드의 이전을 내 이전로 바꿈
59 |
60 | pCurrentListEntry->Flink = pCurrentListEntry;
61 | pCurrentListEntry->Blink = pCurrentListEntry;
62 | }
63 |
64 | /* ring3 프로세스인지 검사하는 루틴 필요
65 | if (PsGetProcessPeb(pCurrentProcess))
66 | {
67 | PPEB ppp = PsGetProcessPeb(pCurrentProcess);
68 |
69 | kprintf("have peb\n");
70 | }
71 | */
72 |
73 | // 원형 구조라 break하지 않으면 무한으로 돌아감
74 | if (pNextProcess == PsInitialSystemProcess)
75 | {
76 | break;
77 | }
78 | pCurrentProcess = pNextProcess;
79 | }
80 |
81 | }
82 |
83 | VOID ScanMemory(UINT PatternNo, uintptr_t StartAddr, uintptr_t EndAddr, PBYTE Pattern, UINT PatternSize)
84 | {
85 |
86 | // kprintf("pattern size : %d %llx %llx", PatternSize, StartAddr , EndAddr);
87 |
88 | if (Pattern == NULL || PatternSize < 4)
89 | {
90 | kprintf("pattern is null or size is too small.");
91 | return;
92 | }
93 | __try
94 | {
95 | // page 사이즈 단위로 검색
96 | for (uintptr_t Addr = StartAddr; Addr < EndAddr; Addr = Addr + PAGE_SIZE)
97 | {
98 | // 특정 section은 메모리 접근이 불가능하기 때문에 skip함
99 | BOOLEAN bValid = MmIsAddressValid((PVOID)Addr);
100 | if (bValid == FALSE)
101 | {
102 | // kprintf("skipAddr %p \n", Addr);
103 | continue;
104 | }
105 |
106 | for (int i = 0; i <= PAGE_SIZE - (int)PatternSize; i++)
107 | {
108 | size_t j = 0;
109 |
110 | for (j = 0; j < PatternSize; j++)
111 | {
112 | PUCHAR pAddr = (PUCHAR)Addr;
113 | if (pAddr[i + j] != Pattern[j])
114 | {
115 | // 일치하지 않으면 j의 증가를 멈춤
116 | break;
117 | }
118 | }
119 | // 패턴 검출
120 | if (j == PatternSize)
121 | {
122 | DETECT_LIST_ENTRY DetectListEntry = { 0, };
123 | DetectListEntry.BaseAddress = StartAddr;
124 | uintptr_t Offset = Addr + i - StartAddr;
125 | DetectListEntry.Offset = (UINT)Offset;
126 | DetectListEntry.PatternNo = PatternNo;
127 | AddDetectListEntry(&DetectListEntry);
128 | kprintf("byte pattern detect : %llx %llx\n", Addr + i, Offset);
129 | }
130 | }
131 | }
132 | }
133 | __except (EXCEPTION_EXECUTE_HANDLER)
134 | {
135 | kprintf("Exception caught in ScanMemory()");
136 | }
137 | }
138 |
139 |
140 | VOID EnumerateDriversViaPsLoadedModuleList(int type, uintptr_t* OutStartAddr, uintptr_t* OutEndAddr)
141 | {
142 | kprintf("===EnumerateDriversViaPsLoadedModuleList (%d)===", type);
143 | if (!MmIsAddressValid(PsLoadedModuleList))
144 | {
145 | return;
146 | }
147 | PLDR_DATA_TABLE_ENTRY Entry = (PLDR_DATA_TABLE_ENTRY)PsLoadedModuleList->InLoadOrderLinks.Flink;
148 |
149 | int modCount = 0;
150 | uintptr_t EntryArray[500] = { 0, };
151 |
152 | while (Entry != PsLoadedModuleList)
153 | {
154 | kprintf("[%d] %p %ws %p %llx ", modCount, Entry, Entry->FullDllName.Buffer, Entry->DllBase, Entry->SizeOfImage);
155 | EntryArray[modCount] = (uintptr_t)Entry;
156 | DRIVER_LIST_ENTRY DriverListEntry = { 0, };
157 | DriverListEntry.DriverObject = 0;
158 | DriverListEntry.modBaseAddress = (uintptr_t)Entry->DllBase;
159 | DriverListEntry.modSize = (ULONG)Entry->SizeOfImage;
160 | RtlStringCchCopyW(DriverListEntry.ServiceName, MAX_PATH, L"");
161 | RtlStringCchCopyW(DriverListEntry.FilePath, MAX_PATH, (WCHAR*)Entry->FullDllName.Buffer);
162 | DriverListEntry.isHidden = FALSE;
163 | AddDriverListEntry(type, &DriverListEntry);
164 |
165 | Entry = (PLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink;
166 | modCount++;
167 | }
168 | // 정렬
169 | uintptr_t temp = 0;
170 | for (int i = 0; i < modCount - 1; i++)
171 | {
172 | for (int j = i + 1; j < modCount; j++)
173 | {
174 | if (EntryArray[i] < EntryArray[j])
175 | {
176 | temp = EntryArray[j];
177 | EntryArray[j] = EntryArray[i];
178 | EntryArray[i] = temp;
179 | }
180 | }
181 | }
182 | kprintf("min max %p %p", EntryArray[modCount - 1], EntryArray[0]);
183 |
184 | // PAGE_SIZE 단위로 재조정
185 | // 숨겨진 entry를 찾기 위해 범위를 늘린다.
186 | // 만약 시작 위치가 0xFFFFDC8A51E50C40라면
187 | // 0x1000000을 align해서 0xffffdc8a51000000로 만든다.
188 | *OutStartAddr = (EntryArray[modCount-1] & ~(0x1000000 - 1));
189 | *OutEndAddr = (EntryArray[0] & ~(0x1000000 - 1))+ 0x1000000;
190 | kprintf("min max %p %p", *OutStartAddr, *OutEndAddr);
191 |
192 | }
193 |
194 | /* 약점 : 메모리 풀스캔이 아니라 LDR 엔트리의 가장 작은 주소 ~ 가장 큰 주소 사이를 검색하기 때문에
195 | 가장 작은 주소나 가장 큰 주소를 숨기면 찾을 수 없게 된다.
196 |
197 | 숨겨진 모듈만 찾는다.
198 | */
199 | VOID EnumerateDriversViaMmLd(int type, uintptr_t StartAddr, uintptr_t EndAddr)
200 | {
201 | kprintf("===EnumerateDriversViaMmLd (%d)===", type);
202 | InitDetectListEntry();
203 |
204 | // "MmLd"
205 | BYTE Pattern[4] = { 0x4d, 0x6d, 0x4c, 0x64 };
206 | ScanMemory(0x1938, StartAddr, EndAddr, Pattern, 4); // 0x1938은 로깅을 위해서.. 0x0으로 해도 무방
207 |
208 | UINT nIndex = 0;
209 | // int entryCnt = 0;
210 |
211 | while (TRUE)
212 | {
213 | PDETECT_LIST_ENTRY pDetectListEntry;
214 | GetDetectListEntry(nIndex, &pDetectListEntry);
215 | if (NULL == pDetectListEntry)
216 | {
217 | break;
218 | }
219 |
220 | PLDR_DATA_TABLE_ENTRY pEntry = (PLDR_DATA_TABLE_ENTRY)((uintptr_t)pDetectListEntry->BaseAddress + pDetectListEntry->Offset + 0xC);
221 | // kprintf("PLDR_DATA_TABLE_ENTRY %p", pEntry);
222 | __try
223 | {
224 | /*
225 | 숨겨진 모듈만 찾는다.
226 | */
227 | if (pEntry->InLoadOrderLinks.Blink == (PLIST_ENTRY)pEntry // chain이 끊어진 경우
228 | && pEntry->InLoadOrderLinks.Flink == (PLIST_ENTRY)pEntry // chain이 끊어진 경우
229 | && pEntry->InInitializationOrderLinks.Flink == NULL // 유효한 모듈은 Blink는 값이 일부 있지만 Flink는 죄다 null임
230 | && pEntry->ObsoleteLoadCount != 0) // 언로드된 모듈은 ObsoleteLoadCount가 0
231 | {
232 | DRIVER_LIST_ENTRY DriverListEntry = { 0, };
233 | DriverListEntry.DriverObject = 0;
234 | DriverListEntry.modBaseAddress = (uintptr_t)pEntry->DllBase;
235 | DriverListEntry.modSize = (ULONG)pEntry->SizeOfImage;
236 | RtlStringCchCopyW(DriverListEntry.ServiceName, MAX_PATH, L"");
237 | RtlStringCchCopyW(DriverListEntry.FilePath, MAX_PATH, (WCHAR*)pEntry->FullDllName.Buffer);
238 | DriverListEntry.isHidden = FALSE;
239 | AddDriverListEntry(type, &DriverListEntry);
240 | // kprintf("[%d] %ws", entryCnt++, DriverListEntry.FilePath);
241 | }
242 | }
243 | __except (EXCEPTION_EXECUTE_HANDLER)
244 | {
245 | kprintf("Exception caught in EnumerateDriversViaMmLd()");
246 | }
247 | // NEXT:
248 | nIndex++;
249 | }
250 |
251 | FreeDetectListEntry();
252 | }
253 |
254 | BOOLEAN ScanKernelDriver(UINT PatternNo, PBYTE Pattern, UINT PatternSize)
255 | {
256 | kprintf("----- ScanKernelDriver() %d-----", PatternSize);
257 |
258 | int modCount = 0;
259 |
260 | PDRIVER_LIST_ENTRY pDriverListEntry = NULL;
261 |
262 | __try
263 | {
264 | while (TRUE)
265 | {
266 | GetDriverListEntry(0, modCount, &pDriverListEntry);
267 | if (NULL == pDriverListEntry)
268 | {
269 | break;
270 | }
271 | // kprintf("[%d] %p %ws %llx %x ", modCount, pDriverListEntry, pDriverListEntry->FilePath, pDriverListEntry->modBaseAddress, pDriverListEntry->modSize);
272 | BOOLEAN bSuccess = MmIsAddressValid((PVOID)pDriverListEntry->modBaseAddress);
273 | if (bSuccess == FALSE)
274 | {
275 | kprintf("cannot access memory\n");
276 | goto NEXT;
277 | }
278 | ScanMemory(PatternNo, pDriverListEntry->modBaseAddress, pDriverListEntry->modBaseAddress + pDriverListEntry->modSize, Pattern, PatternSize);
279 | NEXT:
280 | modCount++;
281 | }
282 | }
283 | __except (EXCEPTION_EXECUTE_HANDLER)
284 | {
285 | kprintf("Exception caught in ScanKernelDriver()");
286 | }
287 | if (0 >= modCount)
288 | {
289 | kprintf("first init");
290 | goto EXIT_ERROR;
291 | }
292 |
293 |
294 | UINT nIndex = 0;
295 |
296 | while (TRUE)
297 | {
298 | PDETECT_LIST_ENTRY pDetectListEntry;
299 | GetDetectListEntry(nIndex, &pDetectListEntry);
300 | if (NULL == pDetectListEntry)
301 | {
302 | break;
303 | }
304 | kprintf("[%d] %llx %llx ", nIndex, pDetectListEntry->Offset , pDetectListEntry->BaseAddress);
305 |
306 | nIndex++;
307 | }
308 |
309 | EXIT_ERROR:
310 |
311 | return TRUE;
312 | }
313 |
314 | BOOLEAN ScanKernelDriverViaAPI()
315 | {
316 | NTSTATUS ntSuccess = STATUS_SUCCESS;
317 | BOOLEAN bSuccess = FALSE;
318 |
319 | // 정확한 사이즈를 얻기 위해 사용
320 | ULONG neededSize = 0;
321 | ZwQuerySystemInformation(SystemModuleInformation, &neededSize, 0, &neededSize);
322 |
323 | PSYSTEM_MODULE_INFORMATION pModuleList = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(PagedPool, neededSize, POOL_TAG);
324 | if (!pModuleList)
325 | {
326 | kprintf("error.1\n");
327 | goto EXIT_ERROR;
328 | }
329 | // 커널 드라이버 리스트 버퍼 획득
330 | ntSuccess = ZwQuerySystemInformation(SystemModuleInformation, pModuleList, neededSize, 0);
331 | if (!NT_SUCCESS(ntSuccess))
332 | {
333 | kprintf("error.2\n");
334 | goto EXIT_ERROR;
335 | }
336 |
337 | uintptr_t modBaseAddress = 0;
338 | ULONG modSize = 0;
339 | kprintf("mod Count : %d", (int)pModuleList->ulModuleCount);
340 | // 커널 드라이버 열거
341 | for (int i = 0; i < (int)pModuleList->ulModuleCount; i++)
342 | {
343 | SYSTEM_MODULE mod = pModuleList->Modules[i];
344 |
345 | modBaseAddress = (uintptr_t)(pModuleList->Modules[i].Base);
346 | modSize = (ULONG)(pModuleList->Modules[i].Size);
347 | kprintf("Path : %s Base : %llx Size : %x\n", mod.ImageName, modBaseAddress, modSize);
348 |
349 | // system32\drivers\volmgrx.sys 같은 아예 접근이 불가능한 모듈은 걸러냄
350 | bSuccess = MmIsAddressValid((PVOID)modBaseAddress);
351 | if (bSuccess == FALSE)
352 | {
353 | // kprintf("Skip.1\n");
354 | continue;
355 | }
356 |
357 | PIMAGE_NT_HEADERS pHdr = (PIMAGE_NT_HEADERS)RtlImageNtHeader((PVOID)mod.Base);
358 | if (!pHdr)
359 | {
360 | kprintf("Skip.2\n");
361 | continue;
362 | }
363 |
364 | // 섹션 체크 (스캔에는 필요하지는 않으나 확인용도)
365 | PIMAGE_SECTION_HEADER pFirstSection = (PIMAGE_SECTION_HEADER)((uintptr_t)&pHdr->FileHeader + pHdr->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER));
366 | for (PIMAGE_SECTION_HEADER pSection = pFirstSection; pSection < pFirstSection + pHdr->FileHeader.NumberOfSections; pSection++)
367 | {
368 | kprintf("%-10s\t%-8x\t%-6x\n", pSection->Name, pSection->VirtualAddress, pSection->SizeOfRawData);
369 | }
370 |
371 |
372 | // ScanMemory(modBaseAddress, modBaseAddress + modSize);
373 |
374 | }
375 | EXIT_ERROR:
376 | if (pModuleList) ExFreePoolWithTag(pModuleList, POOL_TAG);
377 |
378 | return TRUE;
379 | }
380 |
381 |
382 | VOID GetPsLoadedModuleList()
383 | {
384 | UNICODE_STRING name = RTL_CONSTANT_STRING(L"PsLoadedModuleList");
385 | PsLoadedModuleList = MmGetSystemRoutineAddress(&name);
386 |
387 | }
388 |
389 | /*
390 | * 오브젝트 이름을 enumerate하고 해당 이름으로 DriverObject를 구한다.
391 | *
392 | * 참조 사이트
393 | * https://github.com/swatkat/arkitlib/blob/master/ARKitDrv/Drv.c
394 | * https://github.com/ApexLegendsUC/anti-cheat-emulator/blob/master/Source.cpp
395 | *
396 | */
397 | VOID EnumerateDriversViaObjectNameInside(int type, IN PUNICODE_STRING pObjectName)
398 | {
399 | kprintf("===EnumerateDriversViaObjectNameInside (%wZ)===", pObjectName);
400 | NTSTATUS status = STATUS_UNSUCCESSFUL;
401 | OBJECT_ATTRIBUTES objectAttributes;
402 | HANDLE hDirectoryHandle = NULL;
403 | ULONG Context = 0;
404 | ULONG ReturnedLength;
405 | POBJECT_DIRECTORY_INFORMATION pObjectDirectoryInformation = NULL;
406 |
407 | InitializeObjectAttributes(&objectAttributes, pObjectName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
408 | status = ZwOpenDirectoryObject(&hDirectoryHandle, DIRECTORY_QUERY /*GENERIC_READ | SYNCHRONIZE*/, &objectAttributes);
409 | if (!NT_SUCCESS(status))
410 | {
411 | kprintf("ZwOpenDirectoryObject occurs an error. %x\n", status);
412 | return;
413 | }
414 |
415 | // 정확한 구조체 사이즈를 모르니까 넉넉하게 페이지 크기만큼 할당한다.
416 | pObjectDirectoryInformation = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, POOL_TAG);
417 |
418 | RtlZeroMemory(pObjectDirectoryInformation, PAGE_SIZE);
419 | //int count = 0;
420 | while(TRUE)
421 | {
422 | status = ZwQueryDirectoryObject(hDirectoryHandle, pObjectDirectoryInformation, PAGE_SIZE, TRUE, FALSE, &Context, &ReturnedLength);
423 | if (status == STATUS_NO_MORE_ENTRIES)
424 | {
425 | // success
426 | break;
427 | }
428 | else if (status != STATUS_SUCCESS)
429 | {
430 | kprintf("ZwQueryDirectoryObject occurs an error. %x", status);
431 | break;
432 | }
433 |
434 | // kprintf("[%d] %wZ %wZ ", count++, pObjectDirectoryInformation->Name, pObjectDirectoryInformation->TypeName);
435 |
436 | // Driver 유형만 구함. 나머지는 skip.
437 | UNICODE_STRING Driver = RTL_CONSTANT_STRING(L"Driver");
438 | if (!RtlEqualUnicodeString(&Driver, &pObjectDirectoryInformation->TypeName, TRUE))
439 | {
440 | // kprintf("non driver skip");
441 | continue;
442 | }
443 |
444 | UNICODE_STRING FullName;
445 | FullName.MaximumLength = MAX_PATH * 2; // 문자열 버퍼 최대 사이즈
446 | WCHAR szFullName[MAX_PATH] = { 0, };
447 | FullName.Buffer = szFullName;
448 |
449 | RtlCopyUnicodeString(&FullName, pObjectName);
450 | RtlAppendUnicodeToString(&FullName, L"\\");
451 | RtlAppendUnicodeStringToString(&FullName, &pObjectDirectoryInformation->Name);
452 |
453 | // kprintf("Name %wZ\n", &FullName);
454 |
455 | //PVOID pObject = NULL;
456 | PDRIVER_OBJECT pDriverObject = NULL;
457 |
458 | // 이름으로 DriverObject 구하기
459 | NTSTATUS retVal = ObReferenceObjectByName(&FullName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &pDriverObject);
460 | if (STATUS_SUCCESS != retVal)
461 | {
462 | kprintf("ObReferenceObjectByName occurs an error. %x", retVal);
463 | continue;
464 |
465 | }
466 | // kprintf("pDriverObject : %p", pDriverObject);
467 |
468 | if (MmIsAddressValid(pDriverObject))
469 | {
470 | PLDR_DATA_TABLE_ENTRY pModEntry = (PLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
471 | // kprintf("DriverSection %p", pModEntry);
472 | if (MmIsAddressValid(pModEntry))
473 | {
474 | DRIVER_LIST_ENTRY DriverListEntry = { 0, };
475 | DriverListEntry.DriverObject = (uintptr_t)pDriverObject;
476 | DriverListEntry.modBaseAddress = (uintptr_t)pModEntry->DllBase;
477 | DriverListEntry.modSize = (ULONG)pModEntry->SizeOfImage;
478 | RtlStringCchCopyW(DriverListEntry.ServiceName, MAX_PATH, pObjectDirectoryInformation->Name.Buffer);
479 | RtlStringCchCopyW(DriverListEntry.FilePath, MAX_PATH, (WCHAR*)pModEntry->FullDllName.Buffer);
480 | DriverListEntry.isHidden = FALSE;
481 | AddDriverListEntry(type, &DriverListEntry);
482 |
483 | // kprintf("final get : %ws %p", pModEntry->BaseDllName.Buffer, pModEntry->DllBase);
484 | }
485 | else
486 | {
487 | // kprintf("DriverSection is not valid.");
488 | }
489 | }
490 | else
491 | {
492 | // kprintf("pDriverObject is not vaild.");
493 | }
494 |
495 | ObDereferenceObject(pDriverObject);
496 | }
497 |
498 | if (pObjectDirectoryInformation)
499 | {
500 | ExFreePoolWithTag(pObjectDirectoryInformation, POOL_TAG);
501 | }
502 |
503 | if (hDirectoryHandle) ZwClose(hDirectoryHandle);
504 |
505 | }
506 |
507 |
508 | VOID EnumerateDriversViaObjectName(int type)
509 | {
510 | UNICODE_STRING directory = RTL_CONSTANT_STRING(L"\\Driver");
511 | UNICODE_STRING FileSystem = RTL_CONSTANT_STRING(L"\\FileSystem");
512 |
513 | EnumerateDriversViaObjectNameInside(type, &directory);
514 | EnumerateDriversViaObjectNameInside(type, &FileSystem);
515 | }
516 |
517 |
518 | void EnumerateDrivers()
519 | {
520 | UINT nIndex0 = 0;
521 | UINT nIndex1 = 0;
522 | UINT nIndex2 = 0;
523 | InitDriverListEntry(0);
524 | InitDriverListEntry(1);
525 | InitDriverListEntry(2);
526 | uintptr_t ldrEntryStartAddr = 0;
527 | uintptr_t ldrEntryEndAddr = 0;
528 | EnumerateDriversViaPsLoadedModuleList(0, &ldrEntryStartAddr, &ldrEntryEndAddr);
529 | EnumerateDriversViaObjectName(1);
530 | EnumerateDriversViaMmLd(2, ldrEntryStartAddr, ldrEntryEndAddr);
531 |
532 | PDRIVER_LIST_ENTRY pDriverListEntryObjectName = NULL;
533 | PDRIVER_LIST_ENTRY pDriverListEntry = NULL;
534 | PDRIVER_LIST_ENTRY pDriverListEntryMmLd = NULL;
535 |
536 | BOOLEAN isHidden = FALSE;
537 |
538 |
539 | pDriverListEntry = NULL;
540 | nIndex0 = 0;
541 | while (TRUE)
542 | {
543 | GetDriverListEntry(2, nIndex2, &pDriverListEntryMmLd);
544 | if (NULL == pDriverListEntryMmLd)
545 | {
546 | break;
547 | }
548 |
549 | pDriverListEntryMmLd->isHidden = TRUE;
550 | AddDriverListEntry(0, pDriverListEntryMmLd);
551 |
552 |
553 | nIndex2++;
554 | }
555 |
556 | pDriverListEntry = NULL;
557 | nIndex0 = 0;
558 | while (TRUE)
559 | {
560 | GetDriverListEntry(1, nIndex1, &pDriverListEntryObjectName);
561 | if (NULL == pDriverListEntryObjectName)
562 | {
563 | break;
564 | }
565 |
566 | nIndex0 = 0;
567 | pDriverListEntry = NULL;
568 | isHidden = TRUE;
569 | while (TRUE)
570 | {
571 |
572 | GetDriverListEntry(0, nIndex0, &pDriverListEntry);
573 | if (NULL == pDriverListEntry)
574 | {
575 | break;
576 | }
577 | if (0 == wcscmp(pDriverListEntryObjectName->FilePath, pDriverListEntry->FilePath))
578 | {
579 | isHidden = FALSE;
580 | // 서비스 이름 채워넣기
581 | RtlStringCchCopyW(pDriverListEntry->ServiceName, MAX_PATH, pDriverListEntryObjectName->ServiceName);
582 | // 드라이버 오브젝트 채워넣기
583 | pDriverListEntry->DriverObject = pDriverListEntryObjectName->DriverObject;
584 | }
585 |
586 | nIndex0++;
587 | }
588 |
589 | if (isHidden == TRUE)
590 | {
591 | // kprintf("Hidden Driver:");
592 | pDriverListEntryObjectName->isHidden = TRUE;
593 | AddDriverListEntry(0, pDriverListEntryObjectName);
594 | }
595 |
596 | nIndex1++;
597 | }
598 |
599 |
600 | /*
601 |
602 | pDriverListEntry = NULL;
603 | nIndex0 = 0;
604 | while (TRUE)
605 | {
606 | GetDriverListEntry(0, nIndex0, &pDriverListEntry);
607 | if (NULL == pDriverListEntry)
608 | {
609 | break;
610 | }
611 | // kprintf("[%d] %ws Base Address : %llx", nIndex0, pDriverListEntry->FilePath, pDriverListEntry->modBaseAddress);
612 | // kprintf("Size : %x Service : %ws DriverObject : %llx", pDriverListEntry->modSize, pDriverListEntry->ServiceName, pDriverListEntry->DriverObject);
613 | // kprintf("hidden : %x", pDriverListEntry->isHidden);
614 | nIndex0++;
615 | }
616 | */
617 |
618 | FreeDriverListEntry(1);
619 | FreeDriverListEntry(2);
620 | }
--------------------------------------------------------------------------------
/src/Driver/engine.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "listentry.h"
3 |
4 | VOID GetPsLoadedModuleList();
5 | BOOLEAN ScanKernelDriver(UINT PatternNo, PBYTE Pattern, UINT PatternSize);
6 | //BOOLEAN ScanKernelDriverViaAPI();
7 | VOID EnumerateDriversViaPsLoadedModuleList(int type, uintptr_t* OutStartAddr, uintptr_t* OutEndAddr);
8 | VOID EnumerateDriversViaObjectName(int type);
9 | VOID EnumerateDriversViaMmLd(int type, uintptr_t StartAddr, uintptr_t EndAddr);
10 | void EnumerateDrivers();
11 | VOID ScanMemory(UINT PatternNo, uintptr_t StartAddr, uintptr_t EndAddr, PBYTE Pattern, UINT PatternSize);
12 |
--------------------------------------------------------------------------------
/src/Driver/hidedriver.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "hidedriver.h"
8 | #include "define.h"
9 | #include "undocumented.h"
10 | #include "listentry.h"
11 |
12 | extern PDRIVER_OBJECT g_pDriverObject;
13 | PLDR_DATA_TABLE_ENTRY PsLoadedModuleList;
14 |
15 | BOOLEAN HideDriverViaPsLoadedModuleList(PCWSTR szFileName)
16 | {
17 | BOOLEAN Hide = FALSE;
18 | kprintf("===hide driver (PsLoadedModuleList traversing)===");
19 | PLDR_DATA_TABLE_ENTRY prevEntry, nextEntry, Entry;
20 | Entry = (PLDR_DATA_TABLE_ENTRY)PsLoadedModuleList->InLoadOrderLinks.Flink;
21 |
22 | // int count = 0;
23 |
24 | while (Entry != PsLoadedModuleList)
25 | {
26 | // kprintf("[%d] %p %ws %p", count++, Entry, Entry->FullDllName.Buffer, &Entry);
27 | if (0 == wcscmp((PCWSTR)Entry->FullDllName.Buffer, szFileName))
28 | {
29 | kprintf("found");
30 | prevEntry = (PLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Blink; // 이전 노드
31 | nextEntry = (PLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink; // 다음 노드
32 | prevEntry->InLoadOrderLinks.Flink = Entry->InLoadOrderLinks.Flink; // 이전 노드의 다음을 내 다음으로 바꿈
33 | nextEntry->InLoadOrderLinks.Blink = Entry->InLoadOrderLinks.Blink; // 다음 노드의 이전을 내 이전로 바꿈
34 | // 내 노드의 앞, 뒤를 나 자신으로 바꿈
35 | // 바꾸지 않는다면 드라이버 서비스를 stop할때 BSOD발생 (KERNEL SECURITY CHECK FAILURE)
36 | Entry->InLoadOrderLinks.Flink = (PLIST_ENTRY)Entry;
37 | Entry->InLoadOrderLinks.Blink = (PLIST_ENTRY)Entry;
38 | Hide = TRUE;
39 | break;
40 | }
41 |
42 | Entry = (PLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink;
43 | }
44 | return Hide;
45 | }
46 |
47 |
48 | /* hide DRIVER_OBJECT
49 | * service 이름과 DRIVER_OBJECT가 목록에서 날라감
50 | * "\\Driver" 으로 오브젝트 목록 구하는것과 완전히 동일함
51 | */
52 | BOOLEAN HideDriverFromObjectDirectory(PUNICODE_STRING pDriverName)
53 | {
54 | kprintf("===hide driver (Object Directory Entry traversing)===");
55 |
56 | POBJECT_HEADER_NAME_INFO pObjectHeaderNameInfo;
57 | POBJECT_DIRECTORY pObjectDirectory;
58 |
59 | BOOLEAN bRet = FALSE;
60 |
61 | pObjectHeaderNameInfo = ObQueryNameInfo(g_pDriverObject);
62 | if (!MmIsAddressValid(pObjectHeaderNameInfo))
63 | {
64 | kprintf("ObQueryNameInfo occurs an error.\n");
65 | return FALSE;
66 | }
67 | // kprintf("name : %wZ\n", &pObjectHeaderNameInfo->Name);
68 |
69 | pObjectDirectory = pObjectHeaderNameInfo->Directory;
70 |
71 | int count;
72 | count = 0;
73 | for (int p = 0; p < 37; p++)
74 | {
75 | POBJECT_DIRECTORY_ENTRY pBlinkObjectDirectoryEntry = NULL;
76 | POBJECT_DIRECTORY_ENTRY pObjectDirectoryEntry = pObjectDirectory->HashBuckets[p];
77 |
78 | // HashBuckets 가 NULL 인 경우도 많음 (대표적으로 \FileSystem)
79 | if (!MmIsAddressValid(pObjectDirectoryEntry))
80 | {
81 | continue;
82 | }
83 | while (pObjectDirectoryEntry)
84 | {
85 |
86 | if (!MmIsAddressValid(pObjectDirectoryEntry) ||
87 | !MmIsAddressValid(pObjectDirectoryEntry->Object))
88 | {
89 | bRet = FALSE;
90 | break;
91 | }
92 |
93 | pObjectHeaderNameInfo = ObQueryNameInfo(pObjectDirectoryEntry->Object);
94 |
95 |
96 | if (RtlEqualUnicodeString(pDriverName, &pObjectHeaderNameInfo->Name, TRUE))
97 | {
98 | kprintf("pObjectDirectoryEntry : %p", pObjectDirectoryEntry);
99 | kprintf("[%d %d] >>> %wZ", p, count++, pObjectHeaderNameInfo->Name);
100 | // 체인의 0번째(=헤드)가 자신의 Entry일때
101 | if (pObjectDirectory->HashBuckets[p] == pObjectDirectoryEntry)
102 | {
103 | kprintf("[Found] head node\n");
104 | pObjectDirectory->HashBuckets[p] = pObjectDirectoryEntry->ChainLink; // 자신Entry의 다음 Entry를 헤드로 만든다.
105 | pObjectDirectoryEntry->ChainLink = NULL;
106 | }
107 | else // 1번째부터
108 | {
109 | kprintf("[Found] no head node\n");
110 | pBlinkObjectDirectoryEntry->ChainLink = pObjectDirectoryEntry->ChainLink; // 이전 Entry의 다음 Entry를 내 다음 Entry로 가리킨다.
111 | pObjectDirectoryEntry->ChainLink = NULL;
112 | }
113 | bRet = TRUE;
114 | goto EXIT;
115 | }
116 |
117 | pBlinkObjectDirectoryEntry = pObjectDirectoryEntry; // 0이 아닌 n번째 Entry에서 체인이 끊어질때를 대비
118 | pObjectDirectoryEntry = pObjectDirectoryEntry->ChainLink;
119 |
120 | }
121 | }
122 | kprintf("NOT FOUND!!!!!!!!!!!!!!!!!");
123 | EXIT:
124 | return bRet;
125 | }
126 |
127 | VOID HideMyself()
128 | {
129 | //KIRQL irql = KeRaiseIrqlToDpcLevel(); // 동작이 잘 안되면 IRQL 상승
130 | PLDR_DATA_TABLE_ENTRY currentEntry = (PLDR_DATA_TABLE_ENTRY)g_pDriverObject->DriverSection;
131 | PLDR_DATA_TABLE_ENTRY prevEntry, nextEntry;
132 |
133 | prevEntry = (PLDR_DATA_TABLE_ENTRY)currentEntry->InLoadOrderLinks.Blink; // 이전 노드
134 | nextEntry = (PLDR_DATA_TABLE_ENTRY)currentEntry->InLoadOrderLinks.Flink; // 다음 노드
135 | prevEntry->InLoadOrderLinks.Flink = currentEntry->InLoadOrderLinks.Flink; // 이전 노드의 다음을 내 다음으로 바꿈
136 | nextEntry->InLoadOrderLinks.Blink = currentEntry->InLoadOrderLinks.Blink; // 다음 노드의 이전을 내 이전로 바꿈
137 |
138 | // 내 노드의 앞, 뒤를 나 자신으로 바꿈
139 | // 바꾸지 않는다면 드라이버 서비스를 stop할때 BSOD발생 (KERNEL SECURITY CHECK FAILURE)
140 | currentEntry->InLoadOrderLinks.Flink = (PLIST_ENTRY)currentEntry;
141 | currentEntry->InLoadOrderLinks.Blink = (PLIST_ENTRY)currentEntry;
142 |
143 | // KeLowerIrql(irql);
144 | }
145 |
146 | BOOLEAN HideDriver(LPCWSTR pDriverPath, LPCWSTR pServiceName)
147 | {
148 | UNICODE_STRING ServiceName;
149 | RtlInitUnicodeString(&ServiceName, pServiceName);
150 | UNICODE_STRING Empty = RTL_CONSTANT_STRING(L"");
151 | BOOLEAN bHide = FALSE;
152 | BOOLEAN bHide2 = FALSE;
153 | BOOLEAN bRet = FALSE;
154 | if (0 != wcscmp(pDriverPath, L""))
155 | {
156 | bHide = HideDriverViaPsLoadedModuleList(pDriverPath);
157 | }
158 | if (!RtlEqualUnicodeString(&Empty, &ServiceName, TRUE))
159 | {
160 | bHide2 = HideDriverFromObjectDirectory(&ServiceName);
161 | }
162 |
163 | if (TRUE == bHide || TRUE == bHide2)
164 | {
165 | bRet = TRUE;
166 | }
167 | else if (FALSE == bHide && FALSE == bHide2)
168 | {
169 | bRet = FALSE;
170 | }
171 |
172 | return bRet;
173 | }
--------------------------------------------------------------------------------
/src/Driver/hidedriver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | BOOLEAN HideDriver(LPCWSTR pDriverPath, LPCWSTR pServiceName);
4 | VOID HideMyself();
5 |
--------------------------------------------------------------------------------
/src/Driver/listentry.c:
--------------------------------------------------------------------------------
1 | // https://github.com/swatkat/arkitlib/tree/master/ARKitDrv 참조해서 만듦
2 |
3 | #include "listentry.h"
4 | #include "define.h"
5 | #include
6 | #include
7 | #include
8 |
9 | PLIST_ENTRY pListDriverEntry[4];
10 | PLIST_ENTRY pListDetectEntry;
11 |
12 |
13 | void FreeDriverListEntry(int type)
14 | {
15 | if (!MmIsAddressValid(pListDriverEntry[type]))
16 | {
17 | return;
18 | }
19 |
20 | while (!IsListEmpty(pListDriverEntry[type]))
21 | {
22 | // 리스트에서 하나 꺼냄
23 | PLIST_ENTRY pEntry = RemoveHeadList(pListDriverEntry[type]);
24 | PDRIVER_LIST_ENTRY pDriverEntry = CONTAINING_RECORD(pEntry, DRIVER_LIST_ENTRY, Entry);
25 | if (MmIsAddressValid(pDriverEntry))
26 | {
27 | RtlZeroMemory(pDriverEntry, sizeof(DRIVER_LIST_ENTRY)); // wipe
28 | // kprintf("free: %p", pDriverEntry);
29 | ExFreePool(pDriverEntry);
30 | }
31 |
32 | }
33 | kprintf("free : %p (type : %d)", pListDriverEntry[type], type);
34 | ExFreePool(pListDriverEntry[type]);
35 | pListDriverEntry[type] = NULL;
36 | }
37 |
38 |
39 | void InitDriverListEntry(int type)
40 | {
41 | // 이미 존재하면 지우고 만듦 : IOCTL_KERNELV_SCAN_PATTERN 요청시 기존 pListDriverEntry가 필요하므로 free를 수행하면 안됨. 그래서 reinit이 존재함.
42 | if (MmIsAddressValid(pListDriverEntry[type]))
43 | {
44 | kprintf("reinit (type : %d)", type);
45 | FreeDriverListEntry(type);
46 |
47 | }
48 | pListDriverEntry[type] = ExAllocatePoolWithTag(NonPagedPool, sizeof(LIST_ENTRY), POOL_TAG);
49 | if (NULL == pListDriverEntry[type])
50 | {
51 | kprintf("AllocatePool error!");
52 | return;
53 | }
54 | RtlZeroMemory(pListDriverEntry[type], sizeof(LIST_ENTRY));
55 | InitializeListHead(pListDriverEntry[type]);
56 | kprintf("init : %p (type : %d)", pListDriverEntry[type], type);
57 | }
58 |
59 | void AddDriverListEntry(int type, PDRIVER_LIST_ENTRY pDriverEntry)
60 | {
61 | // 새롭게 붙이는 entry 생성
62 | PDRIVER_LIST_ENTRY pNewEntry = NULL;
63 | pNewEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof(DRIVER_LIST_ENTRY), POOL_TAG);
64 | if (NULL == pNewEntry)
65 | {
66 | kprintf("AllocatePool error!");
67 | return;
68 | }
69 | RtlZeroMemory(pNewEntry, sizeof(DRIVER_LIST_ENTRY));
70 |
71 | pNewEntry->DriverObject = pDriverEntry->DriverObject;
72 | pNewEntry->modBaseAddress = pDriverEntry->modBaseAddress;
73 | pNewEntry->modSize = pDriverEntry->modSize;
74 | RtlStringCchCopyW(pNewEntry->ServiceName, MAX_PATH, pDriverEntry->ServiceName);
75 | RtlStringCchCopyW(pNewEntry->FilePath, MAX_PATH, pDriverEntry->FilePath);
76 | pNewEntry->isHidden = pDriverEntry->isHidden;
77 | // kprintf("alloc : %p", pNewEntry);
78 | InsertHeadList(pListDriverEntry[type], &(pNewEntry->Entry));
79 | }
80 |
81 | UINT GetDriverListEntryCount(int type)
82 | {
83 | int nIndex = 0;
84 | while (TRUE)
85 | {
86 | PDRIVER_LIST_ENTRY pDriverListEntry = NULL;
87 | GetDriverListEntry(type, nIndex, &pDriverListEntry);
88 | if (NULL == pDriverListEntry)
89 | {
90 | break;
91 | }
92 | nIndex++;
93 | }
94 | return nIndex;
95 | }
96 |
97 |
98 | void GetDriverListEntry(int type, UINT nPosition, DRIVER_LIST_ENTRY** ppDriverListEntry)
99 | {
100 | if (!MmIsAddressValid(pListDriverEntry[type]))
101 | {
102 | kprintf("pListDriverEntry is not valid. %p", pListDriverEntry[type]);
103 | return;
104 | }
105 | *ppDriverListEntry = NULL;
106 | PLIST_ENTRY pEntry = pListDriverEntry[type]->Blink;
107 |
108 | UINT nIndex = 0;
109 | while (TRUE)
110 | {
111 | if (!MmIsAddressValid(pEntry))
112 | {
113 | kprintf("not valid");
114 | break;
115 | }
116 |
117 | // 한바퀴 다 돌면 멈춤
118 | if (pEntry == pListDriverEntry[type])
119 | {
120 | break;
121 | }
122 |
123 | if (nIndex == nPosition)
124 | {
125 | *ppDriverListEntry = CONTAINING_RECORD(pEntry, DRIVER_LIST_ENTRY, Entry);
126 | }
127 | nIndex++;
128 | pEntry = pEntry->Blink;
129 | }
130 | }
131 |
132 |
133 |
134 |
135 |
136 | void InitDetectListEntry()
137 | {
138 | // pListDetectEntry는 계속 메모리에 남길 필요가 없으므로 reinit이 존재할 필요가 없음
139 | if (MmIsAddressValid(pListDetectEntry))
140 | {
141 | kprintf("reinit pListDetectEntry");
142 | FreeDetectListEntry();
143 |
144 | }
145 |
146 | pListDetectEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof(LIST_ENTRY), POOL_TAG);
147 | if (NULL == pListDetectEntry)
148 | {
149 | kprintf("AllocatePool error!");
150 | return;
151 | }
152 | RtlZeroMemory(pListDetectEntry, sizeof(LIST_ENTRY));
153 | InitializeListHead(pListDetectEntry);
154 | kprintf("init : %p", pListDetectEntry);
155 | }
156 |
157 | void FreeDetectListEntry()
158 | {
159 | if (!MmIsAddressValid(pListDetectEntry))
160 | {
161 | return;
162 | }
163 |
164 | while (!IsListEmpty(pListDetectEntry))
165 | {
166 | // 리스트에서 하나 꺼냄
167 | PLIST_ENTRY pEntry = RemoveHeadList(pListDetectEntry);
168 | PDETECT_LIST_ENTRY pDetectEntry = CONTAINING_RECORD(pEntry, DETECT_LIST_ENTRY, Entry);
169 | if (MmIsAddressValid(pDetectEntry))
170 | {
171 | RtlZeroMemory(pDetectEntry, sizeof(DETECT_LIST_ENTRY)); // wipe
172 | // kprintf("free: %p", pDriverEntry);
173 | ExFreePool(pDetectEntry);
174 | }
175 |
176 | }
177 | kprintf("free : %p", pListDetectEntry);
178 | ExFreePool(pListDetectEntry);
179 | pListDetectEntry = NULL;
180 | }
181 | void AddDetectListEntry(PDETECT_LIST_ENTRY pDetectEntry)
182 | {
183 | if (!MmIsAddressValid(pListDetectEntry))
184 | {
185 | kprintf("no pListDetectEntry");
186 | return;
187 | }
188 |
189 | // 새롭게 붙이는 entry 생성
190 | PDETECT_LIST_ENTRY pNewEntry = NULL;
191 | pNewEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof(DETECT_LIST_ENTRY), POOL_TAG);
192 | if (NULL == pNewEntry)
193 | {
194 | kprintf("AllocatePool error!");
195 | return;
196 | }
197 | RtlZeroMemory(pNewEntry, sizeof(DETECT_LIST_ENTRY));
198 | __try
199 | {
200 | pNewEntry->PatternNo = pDetectEntry->PatternNo;
201 | pNewEntry->BaseAddress = pDetectEntry->BaseAddress;
202 | pNewEntry->Offset = pDetectEntry->Offset;
203 |
204 | InsertHeadList(pListDetectEntry, &pNewEntry->Entry);
205 | }
206 | __except (EXCEPTION_EXECUTE_HANDLER)
207 | {
208 | kprintf("Exception caught in AddDetectListEntry()");
209 | }
210 | }
211 | void GetDetectListEntry(UINT nPosition, DETECT_LIST_ENTRY** ppDetectListEntry)
212 | {
213 | *ppDetectListEntry = NULL;
214 | PLIST_ENTRY pEntry = pListDetectEntry->Blink;
215 |
216 | UINT nIndex = 0;
217 | while (TRUE)
218 | {
219 | if (!MmIsAddressValid(pEntry))
220 | {
221 | kprintf("not valid");
222 | break;
223 | }
224 |
225 | // 한바퀴 다 돌면 멈춤
226 | if (pEntry == pListDetectEntry)
227 | {
228 | break;
229 | }
230 |
231 | if (nIndex == nPosition)
232 | {
233 | *ppDetectListEntry = CONTAINING_RECORD(pEntry, DETECT_LIST_ENTRY, Entry);
234 | }
235 | nIndex++;
236 | pEntry = pEntry->Blink;
237 | }
238 | }
239 | UINT GetDetectListEntryCount()
240 | {
241 | int nIndex = 0;
242 | while (TRUE)
243 | {
244 | PDETECT_LIST_ENTRY pDetectListEntry = NULL;
245 | GetDetectListEntry(nIndex, &pDetectListEntry);
246 | if (NULL == pDetectListEntry)
247 | {
248 | break;
249 | }
250 | nIndex++;
251 | }
252 | return nIndex;
253 | }
--------------------------------------------------------------------------------
/src/Driver/listentry.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | typedef struct _DRIVER_LIST_ENTRY {
6 | uintptr_t modBaseAddress;
7 | ULONG modSize;
8 | WCHAR FilePath[MAX_PATH];
9 | WCHAR ServiceName[MAX_PATH];
10 | uintptr_t DriverObject;
11 | BOOLEAN isHidden;
12 | LIST_ENTRY Entry; // list chain
13 | } DRIVER_LIST_ENTRY, *PDRIVER_LIST_ENTRY;
14 |
15 |
16 | typedef struct _DETECT_LIST_ENTRY {
17 | LIST_ENTRY Entry; // list chain
18 | UINT PatternNo;
19 | uintptr_t BaseAddress;
20 | UINT Offset; // detect offset
21 | } DETECT_LIST_ENTRY, *PDETECT_LIST_ENTRY;
22 |
23 | void FreeDriverListEntry(int type);
24 | void InitDriverListEntry(int type);
25 | void AddDriverListEntry(int type, PDRIVER_LIST_ENTRY pDriverEntry);
26 | void GetDriverListEntry(int type, UINT nPosition, DRIVER_LIST_ENTRY** ppDriverListEntry);
27 | UINT GetDriverListEntryCount(int type);
28 |
29 | void FreeDetectListEntry();
30 | void InitDetectListEntry();
31 | void AddDetectListEntry(PDETECT_LIST_ENTRY pDetectEntry);
32 | void GetDetectListEntry(UINT nPosition, DETECT_LIST_ENTRY** ppDetectListEntry);
33 | UINT GetDetectListEntryCount();
--------------------------------------------------------------------------------
/src/Driver/main.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "define.h"
9 | #include "util.h"
10 | #include "undocumented.h"
11 | #include "listentry.h"
12 | #include "engine.h"
13 | #include "hidedriver.h"
14 |
15 |
16 | PDRIVER_OBJECT g_pDriverObject;
17 |
18 |
19 | #define DEVICE_NAME L"\\Device\\KernelV"
20 | #define DEVICE_LINK L"\\DosDevices\\KernelV"
21 |
22 | #define IOCTL_KERNELV_LOAD_DRIVER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
23 | #define IOCTL_KERNELV_HIDE_MYSELF CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
24 | #define IOCTL_KERNELV_HIDE_DRIVER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
25 | #define IOCTL_KERNELV_SCAN_PATTERN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
26 |
27 |
28 |
29 | VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
30 | {
31 | kprintf(("DriverUnload()\n"));
32 | FreeDriverListEntry(0);
33 | FreeDriverListEntry(1);
34 | FreeDriverListEntry(2);
35 | FreeDriverListEntry(3);
36 | FreeDetectListEntry();
37 |
38 | UNICODE_STRING DeviceLink = RTL_CONSTANT_STRING(DEVICE_LINK);
39 | // RtlInitUnicodeString(&DeviceLink, DEVICE_LINK);
40 | IoDeleteSymbolicLink(&DeviceLink);
41 | IoDeleteDevice(pDriverObject->DeviceObject);
42 |
43 | }
44 |
45 |
46 | NTSTATUS CreateCloseDispatch(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
47 | {
48 |
49 | UNREFERENCED_PARAMETER(pDeviceObject);
50 | pIrp->IoStatus.Status = STATUS_SUCCESS;
51 | pIrp->IoStatus.Information = 0;
52 | IoCompleteRequest(pIrp, IO_NO_INCREMENT);
53 |
54 | return STATUS_SUCCESS;
55 | }
56 |
57 | UINT IOCTLScan(PBYTE pUserInput, ULONG InputBufferSize)
58 | {
59 | int nPatternCnt = 0;
60 | BYTE pStart[] = { 0x53, 0x54, 0x61, 0x72, 0x74 };
61 | BYTE pEnd[] = { 0x65, 0x6E, 0x44 };
62 | int nRemainSize = InputBufferSize;
63 |
64 | PBYTE pPattern = pUserInput;
65 |
66 | kprintf("%x %x %x %x %x %x %x %x", pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pPattern[6], pPattern[7]);
67 |
68 | while (TRUE)
69 | {
70 | BYTE Pattern[512] = { 0, };
71 |
72 | PBYTE pPosStart = MemSearch(pPattern, nRemainSize, pStart, 5);
73 | PBYTE pPosEnd = MemSearch(pPattern, nRemainSize, pEnd, 3);
74 | if (pPosStart == NULL || pPosEnd == NULL)
75 | {
76 | kprintf("fuck.."); // 발생하면 안됨
77 | break;
78 | }
79 |
80 | nPatternCnt++;
81 | uintptr_t PatternSize = (uintptr_t)pPosEnd - ((uintptr_t)pPosStart + 5);
82 | RtlCopyMemory(Pattern, pPosStart + 5, PatternSize);
83 | kprintf("%x %x %x %x size : %lld", Pattern[0], Pattern[1], Pattern[2], Pattern[3], PatternSize);
84 | ScanKernelDriver(nPatternCnt, Pattern, (UINT)PatternSize);
85 | uintptr_t gap = (uintptr_t)pPosEnd + 3 - (uintptr_t)pPosStart;
86 | nRemainSize = nRemainSize - (int)gap;
87 | kprintf("nRemainSize : %d", nRemainSize);
88 | if (nRemainSize == 0)
89 | {
90 | kprintf("There are no more buffers left.");
91 | break;
92 | }
93 | pPattern = (PBYTE)pPosEnd + 3;
94 | }
95 |
96 | return nPatternCnt;
97 | }
98 |
99 | NTSTATUS IoControlDispatch(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
100 | {
101 | UNREFERENCED_PARAMETER(pDeviceObject);
102 | PIO_STACK_LOCATION pIoStackIrp;
103 | pIrp->IoStatus.Information = 0;
104 | pIoStackIrp = IoGetCurrentIrpStackLocation(pIrp);
105 | ULONG InputBufferSize = 0;
106 | ULONG OutputBufferSize = 0;
107 |
108 | InputBufferSize = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength; // ring3에서 인자로 가져옴
109 | OutputBufferSize = pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength; // ring3에 리턴할 예정
110 | kprintf("InputBufferSize : %lu / OutputBufferSize: %lu", InputBufferSize, OutputBufferSize);
111 |
112 | if (IOCTL_KERNELV_SCAN_PATTERN == pIoStackIrp->Parameters.DeviceIoControl.IoControlCode)
113 | {
114 | __try
115 | {
116 | kprintf("===IOCTL_KERNELV_SCAN_PATTERN===");
117 | int nPatternCnt = 0;
118 | PBYTE pRecvBuffer = pIrp->AssociatedIrp.SystemBuffer;
119 |
120 | UINT NeedSize = 0;
121 |
122 | // output길이가 궁금한 경우
123 | if (OutputBufferSize == 0)
124 | {
125 | InitDetectListEntry();
126 | nPatternCnt = IOCTLScan(pRecvBuffer, InputBufferSize);
127 | if (nPatternCnt == 0) // 발생하면 안됨
128 | {
129 | kprintf("No pattern was found.");
130 | pIrp->IoStatus.Information = 0;
131 | pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
132 | FreeDetectListEntry();
133 | goto EXIT;
134 | }
135 | NeedSize = sizeof(DETECT_LIST_ENTRY) * GetDetectListEntryCount();
136 | kprintf("OutputBuffer is too small.");
137 | kprintf("need Size : %d", NeedSize);
138 | pIrp->IoStatus.Information = NeedSize; // need size
139 | pIrp->IoStatus.Status = STATUS_SUCCESS; // success로 하지 않으면 NeedSize가 리턴되지 않는다.
140 |
141 | goto EXIT;
142 | }
143 | /*
144 | 2번째 IOCTL_KERNELV_SCAN_PATTERN 요청 처리
145 | */
146 | // 버퍼에 복사
147 | PDETECT_LIST_ENTRY pSendMem = pIrp->AssociatedIrp.SystemBuffer;
148 | // user mode에서 넘어온 포인터
149 | if (!MmIsAddressValid(pSendMem))
150 | {
151 | kprintf("input buffer is wrong");
152 | pIrp->IoStatus.Information = 0;
153 | pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
154 | goto EXIT;
155 | }
156 |
157 | PDETECT_LIST_ENTRY pDetectListEntry = NULL;
158 | int nIndex = 0;
159 |
160 | while (TRUE)
161 | {
162 | GetDetectListEntry(nIndex, &pDetectListEntry);
163 | if (NULL == pDetectListEntry)
164 | {
165 | break;
166 | }
167 | kprintf("detect : %llx", pDetectListEntry->BaseAddress);
168 | RtlCopyMemory(&pSendMem[nIndex], pDetectListEntry, sizeof(DETECT_LIST_ENTRY));
169 | nIndex++;
170 | }
171 | if (nIndex > 0)
172 | {
173 | kprintf("sent %d", sizeof(DETECT_LIST_ENTRY) * nIndex);
174 | pIrp->IoStatus.Information = sizeof(DETECT_LIST_ENTRY) * nIndex;
175 | }
176 |
177 | FreeDetectListEntry();
178 | }
179 | __except (EXCEPTION_EXECUTE_HANDLER)
180 | {
181 | kprintf("Exception caught in IOCTL_KERNELV_SCAN_PATTERN");
182 | }
183 |
184 | }
185 | if (IOCTL_KERNELV_HIDE_DRIVER == pIoStackIrp->Parameters.DeviceIoControl.IoControlCode)
186 | {
187 | kprintf("===IOCTL_KERNELV_HIDE_DRIVER===");
188 | // L"%s::%s" 형태
189 | LPWSTR pReceiveString = pIrp->AssociatedIrp.SystemBuffer;
190 | kprintf("pDriverPath : %ws InputBufferSize : %d", pReceiveString, InputBufferSize);
191 | LPWSTR pPos = wcsstr(pReceiveString, L"::");
192 | LPWSTR pServiceName = pPos + 2;
193 | RtlCopyMemory(pPos, "\x00\x00", 2);
194 | LPWSTR pDriverPath = pReceiveString;
195 | kprintf("parse : %ws %ws", pDriverPath, pServiceName);
196 | BOOLEAN bHide = FALSE;
197 | bHide = HideDriver(pDriverPath, pServiceName);
198 | if (TRUE == bHide)
199 | {
200 | RtlStringCchCopyW(pDriverPath, InputBufferSize, L"YES");
201 | }
202 | else
203 | {
204 | RtlStringCchCopyW(pDriverPath, InputBufferSize, L"NO");
205 | }
206 | pIrp->IoStatus.Information = OutputBufferSize;
207 |
208 | }
209 | if (IOCTL_KERNELV_HIDE_MYSELF == pIoStackIrp->Parameters.DeviceIoControl.IoControlCode)
210 | {
211 | kprintf("===IOCTL_KERNELV_HIDE_MYSELF===");
212 | HideMyself();
213 | pIrp->IoStatus.Information = InputBufferSize;
214 | }
215 | if (IOCTL_KERNELV_LOAD_DRIVER == pIoStackIrp->Parameters.DeviceIoControl.IoControlCode)
216 | {
217 | kprintf("===IOCTL_KERNELV_LOAD_DRIVER===");
218 |
219 | PDRIVER_LIST_ENTRY pSendMem = pIrp->AssociatedIrp.SystemBuffer;
220 |
221 | UINT NeedSize = 0;
222 |
223 | // output길이가 궁금한 경우
224 | if (OutputBufferSize == 0)
225 | {
226 | EnumerateDrivers();
227 | NeedSize = sizeof(DRIVER_LIST_ENTRY) * GetDriverListEntryCount(0);
228 | kprintf("OutputBuffer is too small.");
229 | kprintf("need Size : %d", NeedSize);
230 | pIrp->IoStatus.Information = NeedSize; // need size
231 | pIrp->IoStatus.Status = STATUS_SUCCESS; // success로 하지 않으면 NeedSize가 리턴되지 않는다.
232 |
233 | goto EXIT;
234 | }
235 |
236 | /*
237 | 2번째 IOCTL_KERNELV_LOAD_DRIVER 요청 처리
238 | */
239 |
240 | // user mode에서 넘어온 포인터
241 | if (!MmIsAddressValid(pSendMem))
242 | {
243 | kprintf("input buffer is wrong");
244 | pIrp->IoStatus.Information = 0;
245 | pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
246 | goto EXIT;
247 | }
248 |
249 | // output 버퍼에 복사
250 | PDRIVER_LIST_ENTRY pDriverListEntry = NULL;
251 | int nIndex = 0;
252 | while (TRUE)
253 | {
254 | GetDriverListEntry(0, nIndex, &pDriverListEntry);
255 | if (NULL == pDriverListEntry)
256 | {
257 | break;
258 | }
259 | RtlCopyMemory(&pSendMem[nIndex], pDriverListEntry, sizeof(DRIVER_LIST_ENTRY));
260 | nIndex++;
261 | NeedSize += sizeof(DRIVER_LIST_ENTRY);
262 | }
263 |
264 | if (nIndex >= 0)
265 | {
266 | pIrp->IoStatus.Information = NeedSize;
267 |
268 | }
269 |
270 | }
271 |
272 | pIrp->IoStatus.Status = STATUS_SUCCESS;
273 | EXIT:
274 | IoCompleteRequest(pIrp, IO_NO_INCREMENT);
275 | return STATUS_SUCCESS;
276 | }
277 |
278 | BOOLEAN InitComm(PDRIVER_OBJECT pDriverObject)
279 | {
280 | BOOLEAN bRet = FALSE;
281 | NTSTATUS status = STATUS_UNSUCCESSFUL;
282 | UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
283 | UNICODE_STRING DeviceLink = RTL_CONSTANT_STRING(DEVICE_LINK);
284 | PDEVICE_OBJECT pDeviceObject = NULL;
285 |
286 | __try
287 | {
288 |
289 | status = IoCreateDevice(pDriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
290 |
291 | if (!NT_SUCCESS(status))
292 | {
293 | kprintf("IoCreateDevice occurs an error. %x\n", status);
294 | bRet = FALSE;
295 | goto EXIT;
296 |
297 | }
298 | status = IoCreateSymbolicLink(&DeviceLink, &DeviceName);
299 | if (!NT_SUCCESS(status))
300 | {
301 | kprintf("IoCreateSymbolicLink occurs an error. %x\n", status);
302 | if (pDeviceObject)
303 | {
304 | IoDeleteDevice(pDeviceObject);
305 | pDeviceObject = NULL;
306 | }
307 | bRet = FALSE;
308 | goto EXIT;
309 | }
310 |
311 | pDeviceObject->Flags |= DO_BUFFERED_IO;
312 | pDriverObject->MajorFunction[IRP_MJ_CREATE] = CreateCloseDispatch;
313 | pDriverObject->MajorFunction[IRP_MJ_CLOSE] = CreateCloseDispatch;
314 | pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControlDispatch;
315 | pDriverObject->DriverUnload = DriverUnload;
316 | }
317 | __except (EXCEPTION_EXECUTE_HANDLER)
318 | {
319 | bRet = FALSE;
320 | kprintf("Exception caught in InitComm()");
321 | }
322 | bRet = TRUE;
323 | EXIT:
324 |
325 | return bRet;
326 | }
327 |
328 |
329 | void Test()
330 | {
331 | // ScanKernelDriver();
332 | // EnumerateEPROCESS("notepad.exe");
333 |
334 | }
335 | NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
336 | {
337 | UNREFERENCED_PARAMETER(pRegistryPath);
338 | g_pDriverObject = pDriverObject;
339 | kprintf("===== KernelV start =====");
340 | if (FALSE == InitComm(pDriverObject))
341 | {
342 | return STATUS_SUCCESS;
343 | }
344 | kprintf("pDriverObject %p", pDriverObject);
345 | GetPsLoadedModuleList(); // init;
346 |
347 |
348 | return STATUS_SUCCESS;
349 | }
350 |
--------------------------------------------------------------------------------
/src/Driver/main.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codetronik/KernelV/aa5e9cad341662da4b274e39428b97f7e3e9cb2a/src/Driver/main.h
--------------------------------------------------------------------------------
/src/Driver/undocumented.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | NTSTATUS NTAPI MmCopyVirtualMemory
5 | (
6 | PEPROCESS SourceProcess,
7 | PVOID SourceAddress,
8 | PEPROCESS TargetProcess,
9 | PVOID TargetAddress,
10 | SIZE_T BufferSize,
11 | KPROCESSOR_MODE PreviousMode,
12 | PSIZE_T ReturnSize
13 | );
14 |
15 | PVOID NTAPI ObQueryNameInfo(IN PVOID Object);
16 |
17 | NTSTATUS NTAPI ObReferenceObjectByName(
18 | IN PUNICODE_STRING ObjectPath,
19 | IN ULONG Attributes,
20 | IN PACCESS_STATE PassedAccessState,
21 | IN ACCESS_MASK DesiredAccess,
22 | IN POBJECT_TYPE ObjectType,
23 | IN KPROCESSOR_MODE AccessMode,
24 | IN OUT PVOID ParseContext,
25 | OUT PVOID* ObjectPtr
26 | );
27 |
28 | NTSTATUS WINAPI ZwQueryDirectoryObject(
29 | _In_ HANDLE DirectoryHandle,
30 | _Out_opt_ PVOID Buffer,
31 | _In_ ULONG Length,
32 | _In_ BOOLEAN ReturnSingleEntry,
33 | _In_ BOOLEAN RestartScan,
34 | _Inout_ PULONG Context,
35 | _Out_opt_ PULONG ReturnLength
36 | );
37 |
38 | NTSTATUS NTAPI ZwQuerySystemInformation(
39 | _In_ ULONG InfoClass,
40 | _Inout_ PVOID SystemInformation,
41 | _In_ ULONG SystemInformationLength,
42 | _Out_opt_ PULONG ReturnLength
43 | );
44 |
45 | PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(PVOID BaseOfImage);
46 |
47 | UCHAR* PsGetProcessImageFileName(__in PEPROCESS Process);
48 | PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process);
49 |
50 |
51 | #define SystemModuleInformation 11
52 | #define SystemProcessesAndThreadsInformation 5
53 |
54 | typedef struct _SYSTEM_BASIC_INFORMATION
55 | {
56 | ULONG Reserved;
57 | ULONG TimerResolution;
58 | ULONG PageSize;
59 | ULONG NumberOfPhysicalPages;
60 | ULONG LowestPhysicalPageNumber;
61 | ULONG HighestPhysicalPageNumber;
62 | ULONG AllocationGranularity;
63 | ULONG_PTR MinimumUserModeAddress;
64 | ULONG_PTR MaximumUserModeAddress;
65 | KAFFINITY ActiveProcessorsAffinityMask;
66 | CHAR NumberOfProcessors;
67 | } SYSTEM_BASIC_INFORMATION, * PSYSTEM_BASIC_INFORMATION;
68 |
69 | typedef struct _SYSTEM_MODULE
70 | {
71 | ULONG_PTR Reserved[2];
72 | PVOID Base;
73 | ULONG Size;
74 | ULONG Flags;
75 | USHORT Index;
76 | USHORT Unknown;
77 | USHORT LoadCount;
78 | USHORT ModuleNameOffset;
79 | CHAR ImageName[256];
80 | } SYSTEM_MODULE, * PSYSTEM_MODULE;
81 |
82 | typedef struct _SYSTEM_MODULE_INFORMATION
83 | {
84 | ULONG_PTR ulModuleCount;
85 | SYSTEM_MODULE Modules[1];
86 | } SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
87 |
88 |
89 | typedef struct _LDR_DATA_TABLE_ENTRY
90 | {
91 | LIST_ENTRY InLoadOrderLinks;
92 | LIST_ENTRY InMemoryOrderLinks;
93 | LIST_ENTRY InInitializationOrderLinks;
94 | PVOID64 DllBase;
95 | PVOID64 EntryPoint;
96 | UINT64 SizeOfImage;
97 | UNICODE_STRING64 FullDllName;
98 | UNICODE_STRING64 BaseDllName;
99 | UCHAR FlagGroup[4];
100 | USHORT ObsoleteLoadCount;
101 | /*
102 | 이하 불필요해서 삭제
103 | */
104 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
105 |
106 | typedef struct _OBJECT_DIRECTORY_INFORMATION {
107 | UNICODE_STRING Name;
108 | UNICODE_STRING TypeName;
109 | } OBJECT_DIRECTORY_INFORMATION, * POBJECT_DIRECTORY_INFORMATION;
110 |
111 | typedef struct _OBJECT_DIRECTORY_ENTRY {
112 | PVOID ChainLink;
113 | PVOID Object;
114 | ULONG HashValue;
115 | } OBJECT_DIRECTORY_ENTRY, * POBJECT_DIRECTORY_ENTRY;
116 |
117 | typedef struct _OBJECT_DIRECTORY {
118 | POBJECT_DIRECTORY_ENTRY HashBuckets[37];
119 | // ....
120 | } OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
121 |
122 | typedef struct _OBJECT_HEADER_NAME_INFO {
123 | POBJECT_DIRECTORY Directory;
124 | UNICODE_STRING Name;
125 | // ....
126 | } OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
127 |
128 | typedef struct __OBJECT_HEADER_CREATOR_INFO {
129 | LIST_ENTRY TypeList;
130 | // ....
131 | } OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;
132 |
--------------------------------------------------------------------------------
/src/Driver/util.c:
--------------------------------------------------------------------------------
1 | #include "util.h"
2 |
3 |
4 | PUCHAR MemSearch(PUCHAR pBuffer, int nBufferSize, PUCHAR pPattern, int nPatternSize)
5 | {
6 | for (int i = 0; i <= nBufferSize - nPatternSize; i++)
7 | {
8 | int j = 0;
9 | for (j = 0; j < nPatternSize; j++)
10 | {
11 | if (pBuffer[i + j] != pPattern[j])
12 | {
13 | break;
14 | }
15 |
16 | }
17 | if (j == nPatternSize)
18 | {
19 | return pBuffer + i;
20 | }
21 | }
22 | return NULL;
23 | }
--------------------------------------------------------------------------------
/src/Driver/util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | PUCHAR MemSearch(PUCHAR pBuffer, int nBufferSize, PUCHAR pPattern, int nPatternSize);
--------------------------------------------------------------------------------
/src/KernelV.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30517.126
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Agent", "Agent\Agent.vcxproj", "{83A69940-6517-49EC-8AA0-19896305574E}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Driver", "Driver\Driver.vcxproj", "{AF42A289-FB31-44C7-9254-E7B5BC50708F}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|x64 = Debug|x64
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {83A69940-6517-49EC-8AA0-19896305574E}.Debug|x64.ActiveCfg = Debug|x64
17 | {83A69940-6517-49EC-8AA0-19896305574E}.Debug|x64.Build.0 = Debug|x64
18 | {83A69940-6517-49EC-8AA0-19896305574E}.Release|x64.ActiveCfg = Release|x64
19 | {83A69940-6517-49EC-8AA0-19896305574E}.Release|x64.Build.0 = Release|x64
20 | {AF42A289-FB31-44C7-9254-E7B5BC50708F}.Debug|x64.ActiveCfg = Debug|x64
21 | {AF42A289-FB31-44C7-9254-E7B5BC50708F}.Debug|x64.Build.0 = Debug|x64
22 | {AF42A289-FB31-44C7-9254-E7B5BC50708F}.Debug|x64.Deploy.0 = Debug|x64
23 | {AF42A289-FB31-44C7-9254-E7B5BC50708F}.Release|x64.ActiveCfg = Release|x64
24 | {AF42A289-FB31-44C7-9254-E7B5BC50708F}.Release|x64.Build.0 = Release|x64
25 | {AF42A289-FB31-44C7-9254-E7B5BC50708F}.Release|x64.Deploy.0 = Release|x64
26 | EndGlobalSection
27 | GlobalSection(SolutionProperties) = preSolution
28 | HideSolutionNode = FALSE
29 | EndGlobalSection
30 | GlobalSection(ExtensibilityGlobals) = postSolution
31 | SolutionGuid = {13EBD81A-D5BF-42FF-970A-B0FBE06283A2}
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------