├── .gitattributes
├── .gitignore
├── README.md
├── eof-reader.sln
└── eof-reader
├── eof-reader.vcxproj
├── eof-reader.vcxproj.filters
├── main.cpp
└── termcolor
└── termcolor.hpp
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.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 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Read EOF Data from Portable Executable File (x86 / x64)
2 |
3 | 
4 |
5 | This program detects the presence of suspicious EOF data from any valid PE File.
6 |
7 | Malware often uses append to the end of file :
8 |
9 | * C2 Configurations
10 | * Other malicious applications / plugins
11 | * Payloads
12 |
13 | This program calculates the real expected size for a PE File through the PE Header and compares that size with the size of the file on disk.
14 |
15 | If the size on disk is greater than the size described by the PE Header we are likely facing an infected file.
16 |
17 | After detecting the presence of EOF, it dumps its content in content (Hex Editor Style) then offer you to save it raw content to disk.
18 |
19 | The code is probably not the most optimised and I'm open to any suggestions or fixes. I come from a very long background in Pascal / Delphi for Win programming
20 | I'm not yet as expert in C++ than Pascal / Delphi.
21 |
22 | Coded & Compiled with success on Visual Studio 2019.
23 |
24 | # Special Thanks goes to
25 |
26 | * ikalnytskyi for termcolor lib (https://github.com/ikalnytskyi/termcolor)
27 |
--------------------------------------------------------------------------------
/eof-reader.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29709.97
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eof-reader", "eof-reader\eof-reader.vcxproj", "{1EF0BF22-03EC-4411-B535-4D2273F2979F}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Debug|x64.ActiveCfg = Debug|x64
17 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Debug|x64.Build.0 = Debug|x64
18 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Debug|x86.ActiveCfg = Debug|Win32
19 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Debug|x86.Build.0 = Debug|Win32
20 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Release|x64.ActiveCfg = Release|x64
21 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Release|x64.Build.0 = Release|x64
22 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Release|x86.ActiveCfg = Release|Win32
23 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {C457E17A-2B02-400C-8F70-7F96532EFF22}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/eof-reader/eof-reader.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 | {1EF0BF22-03EC-4411-B535-4D2273F2979F}
24 | eofreader
25 | 10.0
26 |
27 |
28 |
29 | Application
30 | true
31 | v142
32 | Unicode
33 |
34 |
35 | Application
36 | false
37 | v142
38 | true
39 | Unicode
40 |
41 |
42 | Application
43 | true
44 | v142
45 | Unicode
46 |
47 |
48 | Application
49 | false
50 | v142
51 | true
52 | Unicode
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | true
74 |
75 |
76 | true
77 |
78 |
79 | false
80 |
81 |
82 | false
83 |
84 |
85 |
86 | Level3
87 | true
88 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
89 | true
90 |
91 |
92 | Console
93 | true
94 |
95 |
96 |
97 |
98 | Level3
99 | true
100 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
101 | true
102 |
103 |
104 | Console
105 | true
106 |
107 |
108 |
109 |
110 | Level3
111 | true
112 | true
113 | true
114 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
115 | true
116 |
117 |
118 | Console
119 | true
120 | true
121 | true
122 |
123 |
124 |
125 |
126 | Level3
127 | true
128 | true
129 | true
130 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
131 | true
132 |
133 |
134 | Console
135 | true
136 | true
137 | true
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/eof-reader/eof-reader.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;hh;hpp;hxx;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 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/eof-reader/main.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarkCoderSc/eof-reader/42cbf99bdccb820c8ec34141e4996133486c7293/eof-reader/main.cpp
--------------------------------------------------------------------------------
/eof-reader/termcolor/termcolor.hpp:
--------------------------------------------------------------------------------
1 | //!
2 | //! termcolor
3 | //! ~~~~~~~~~
4 | //!
5 | //! termcolor is a header-only c++ library for printing colored messages
6 | //! to the terminal. Written just for fun with a help of the Force.
7 | //!
8 | //! :copyright: (c) 2013 by Ihor Kalnytskyi
9 | //! :license: BSD, see LICENSE for details
10 | //!
11 |
12 | #ifndef TERMCOLOR_HPP_
13 | #define TERMCOLOR_HPP_
14 |
15 | // the following snippet of code detects the current OS and
16 | // defines the appropriate macro that is used to wrap some
17 | // platform specific things
18 | #if defined(_WIN32) || defined(_WIN64)
19 | # define TERMCOLOR_OS_WINDOWS
20 | #elif defined(__APPLE__)
21 | # define TERMCOLOR_OS_MACOS
22 | #elif defined(__unix__) || defined(__unix)
23 | # define TERMCOLOR_OS_LINUX
24 | #else
25 | # error unsupported platform
26 | #endif
27 |
28 |
29 | // This headers provides the `isatty()`/`fileno()` functions,
30 | // which are used for testing whether a standart stream refers
31 | // to the terminal. As for Windows, we also need WinApi funcs
32 | // for changing colors attributes of the terminal.
33 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
34 | # include
35 | #elif defined(TERMCOLOR_OS_WINDOWS)
36 | # include
37 | # include
38 | #endif
39 |
40 |
41 | #include
42 | #include
43 |
44 |
45 |
46 | namespace termcolor
47 | {
48 | // Forward declaration of the `_internal` namespace.
49 | // All comments are below.
50 | namespace _internal
51 | {
52 | // An index to be used to access a private storage of I/O streams. See
53 | // colorize / nocolorize I/O manipulators for details.
54 | static int colorize_index = std::ios_base::xalloc();
55 |
56 | inline FILE* get_standard_stream(const std::ostream& stream);
57 | inline bool is_colorized(std::ostream& stream);
58 | inline bool is_atty(const std::ostream& stream);
59 |
60 | #if defined(TERMCOLOR_OS_WINDOWS)
61 | inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
62 | #endif
63 | }
64 |
65 | inline
66 | std::ostream& colorize(std::ostream& stream)
67 | {
68 | stream.iword(_internal::colorize_index) = 1L;
69 | return stream;
70 | }
71 |
72 | inline
73 | std::ostream& nocolorize(std::ostream& stream)
74 | {
75 | stream.iword(_internal::colorize_index) = 0L;
76 | return stream;
77 | }
78 |
79 | inline
80 | std::ostream& reset(std::ostream& stream)
81 | {
82 | if (_internal::is_colorized(stream))
83 | {
84 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
85 | stream << "\033[00m";
86 | #elif defined(TERMCOLOR_OS_WINDOWS)
87 | _internal::win_change_attributes(stream, -1, -1);
88 | #endif
89 | }
90 | return stream;
91 | }
92 |
93 |
94 | inline
95 | std::ostream& bold(std::ostream& stream)
96 | {
97 | if (_internal::is_colorized(stream))
98 | {
99 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
100 | stream << "\033[1m";
101 | #elif defined(TERMCOLOR_OS_WINDOWS)
102 | #endif
103 | }
104 | return stream;
105 | }
106 |
107 |
108 | inline
109 | std::ostream& dark(std::ostream& stream)
110 | {
111 | if (_internal::is_colorized(stream))
112 | {
113 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
114 | stream << "\033[2m";
115 | #elif defined(TERMCOLOR_OS_WINDOWS)
116 | #endif
117 | }
118 | return stream;
119 | }
120 |
121 |
122 | inline
123 | std::ostream& italic(std::ostream& stream)
124 | {
125 | if (_internal::is_colorized(stream))
126 | {
127 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
128 | stream << "\033[3m";
129 | #elif defined(TERMCOLOR_OS_WINDOWS)
130 | #endif
131 | }
132 | return stream;
133 | }
134 |
135 |
136 | inline
137 | std::ostream& underline(std::ostream& stream)
138 | {
139 | if (_internal::is_colorized(stream))
140 | {
141 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
142 | stream << "\033[4m";
143 | #elif defined(TERMCOLOR_OS_WINDOWS)
144 | #endif
145 | }
146 | return stream;
147 | }
148 |
149 |
150 | inline
151 | std::ostream& blink(std::ostream& stream)
152 | {
153 | if (_internal::is_colorized(stream))
154 | {
155 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
156 | stream << "\033[5m";
157 | #elif defined(TERMCOLOR_OS_WINDOWS)
158 | #endif
159 | }
160 | return stream;
161 | }
162 |
163 |
164 | inline
165 | std::ostream& reverse(std::ostream& stream)
166 | {
167 | if (_internal::is_colorized(stream))
168 | {
169 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
170 | stream << "\033[7m";
171 | #elif defined(TERMCOLOR_OS_WINDOWS)
172 | #endif
173 | }
174 | return stream;
175 | }
176 |
177 |
178 | inline
179 | std::ostream& concealed(std::ostream& stream)
180 | {
181 | if (_internal::is_colorized(stream))
182 | {
183 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
184 | stream << "\033[8m";
185 | #elif defined(TERMCOLOR_OS_WINDOWS)
186 | #endif
187 | }
188 | return stream;
189 | }
190 |
191 |
192 | inline
193 | std::ostream& crossed(std::ostream& stream)
194 | {
195 | if (_internal::is_colorized(stream))
196 | {
197 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
198 | stream << "\033[9m";
199 | #elif defined(TERMCOLOR_OS_WINDOWS)
200 | #endif
201 | }
202 | return stream;
203 | }
204 |
205 |
206 | inline
207 | std::ostream& grey(std::ostream& stream)
208 | {
209 | if (_internal::is_colorized(stream))
210 | {
211 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
212 | stream << "\033[30m";
213 | #elif defined(TERMCOLOR_OS_WINDOWS)
214 | _internal::win_change_attributes(stream,
215 | 0 // grey (black)
216 | );
217 | #endif
218 | }
219 | return stream;
220 | }
221 |
222 | inline
223 | std::ostream& red(std::ostream& stream)
224 | {
225 | if (_internal::is_colorized(stream))
226 | {
227 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
228 | stream << "\033[31m";
229 | #elif defined(TERMCOLOR_OS_WINDOWS)
230 | _internal::win_change_attributes(stream,
231 | FOREGROUND_RED
232 | );
233 | #endif
234 | }
235 | return stream;
236 | }
237 |
238 | inline
239 | std::ostream& bloodred(std::ostream& stream)
240 | {
241 | if (_internal::is_colorized(stream))
242 | {
243 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
244 | stream << "\033[31m";
245 | #elif defined(TERMCOLOR_OS_WINDOWS)
246 | _internal::win_change_attributes(stream,
247 | FOREGROUND_RED | FOREGROUND_INTENSITY
248 | );
249 | #endif
250 | }
251 | return stream;
252 | }
253 |
254 | inline
255 | std::ostream& green(std::ostream& stream)
256 | {
257 | if (_internal::is_colorized(stream))
258 | {
259 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
260 | stream << "\033[32m";
261 | #elif defined(TERMCOLOR_OS_WINDOWS)
262 | _internal::win_change_attributes(stream,
263 | FOREGROUND_GREEN
264 | );
265 | #endif
266 | }
267 | return stream;
268 | }
269 |
270 | inline
271 | std::ostream& lime(std::ostream& stream)
272 | {
273 | if (_internal::is_colorized(stream))
274 | {
275 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
276 | stream << "\033[32m";
277 | #elif defined(TERMCOLOR_OS_WINDOWS)
278 | _internal::win_change_attributes(stream,
279 | FOREGROUND_GREEN | FOREGROUND_INTENSITY
280 | );
281 | #endif
282 | }
283 | return stream;
284 | }
285 |
286 | inline
287 | std::ostream& yellow(std::ostream& stream)
288 | {
289 | if (_internal::is_colorized(stream))
290 | {
291 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
292 | stream << "\033[33m";
293 | #elif defined(TERMCOLOR_OS_WINDOWS)
294 | _internal::win_change_attributes(stream,
295 | FOREGROUND_GREEN | FOREGROUND_RED
296 | );
297 | #endif
298 | }
299 | return stream;
300 | }
301 |
302 | inline
303 | std::ostream& blue(std::ostream& stream)
304 | {
305 | if (_internal::is_colorized(stream))
306 | {
307 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
308 | stream << "\033[34m";
309 | #elif defined(TERMCOLOR_OS_WINDOWS)
310 | _internal::win_change_attributes(stream,
311 | FOREGROUND_BLUE
312 | );
313 | #endif
314 | }
315 | return stream;
316 | }
317 |
318 | inline
319 | std::ostream& magenta(std::ostream& stream)
320 | {
321 | if (_internal::is_colorized(stream))
322 | {
323 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
324 | stream << "\033[35m";
325 | #elif defined(TERMCOLOR_OS_WINDOWS)
326 | _internal::win_change_attributes(stream,
327 | FOREGROUND_BLUE | FOREGROUND_RED
328 | );
329 | #endif
330 | }
331 | return stream;
332 | }
333 |
334 | inline
335 | std::ostream& cyan(std::ostream& stream)
336 | {
337 | if (_internal::is_colorized(stream))
338 | {
339 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
340 | stream << "\033[36m";
341 | #elif defined(TERMCOLOR_OS_WINDOWS)
342 | _internal::win_change_attributes(stream,
343 | FOREGROUND_BLUE | FOREGROUND_GREEN
344 | );
345 | #endif
346 | }
347 | return stream;
348 | }
349 |
350 |
351 | inline
352 | std::ostream& white(std::ostream& stream)
353 | {
354 | if (_internal::is_colorized(stream))
355 | {
356 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
357 | stream << "\033[37m";
358 | #elif defined(TERMCOLOR_OS_WINDOWS)
359 | _internal::win_change_attributes(stream,
360 | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
361 | );
362 | #endif
363 | }
364 | return stream;
365 | }
366 |
367 |
368 |
369 | inline
370 | std::ostream& on_grey(std::ostream& stream)
371 | {
372 | if (_internal::is_colorized(stream))
373 | {
374 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
375 | stream << "\033[40m";
376 | #elif defined(TERMCOLOR_OS_WINDOWS)
377 | _internal::win_change_attributes(stream, -1,
378 | 0 // grey (black)
379 | );
380 | #endif
381 | }
382 | return stream;
383 | }
384 |
385 | inline
386 | std::ostream& on_red(std::ostream& stream)
387 | {
388 | if (_internal::is_colorized(stream))
389 | {
390 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
391 | stream << "\033[41m";
392 | #elif defined(TERMCOLOR_OS_WINDOWS)
393 | _internal::win_change_attributes(stream, -1,
394 | BACKGROUND_RED
395 | );
396 | #endif
397 | }
398 | return stream;
399 | }
400 |
401 | inline
402 | std::ostream& on_green(std::ostream& stream)
403 | {
404 | if (_internal::is_colorized(stream))
405 | {
406 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
407 | stream << "\033[42m";
408 | #elif defined(TERMCOLOR_OS_WINDOWS)
409 | _internal::win_change_attributes(stream, -1,
410 | BACKGROUND_GREEN
411 | );
412 | #endif
413 | }
414 | return stream;
415 | }
416 |
417 | inline
418 | std::ostream& on_yellow(std::ostream& stream)
419 | {
420 | if (_internal::is_colorized(stream))
421 | {
422 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
423 | stream << "\033[43m";
424 | #elif defined(TERMCOLOR_OS_WINDOWS)
425 | _internal::win_change_attributes(stream, -1,
426 | BACKGROUND_GREEN | BACKGROUND_RED
427 | );
428 | #endif
429 | }
430 | return stream;
431 | }
432 |
433 | inline
434 | std::ostream& on_blue(std::ostream& stream)
435 | {
436 | if (_internal::is_colorized(stream))
437 | {
438 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
439 | stream << "\033[44m";
440 | #elif defined(TERMCOLOR_OS_WINDOWS)
441 | _internal::win_change_attributes(stream, -1,
442 | BACKGROUND_BLUE
443 | );
444 | #endif
445 | }
446 | return stream;
447 | }
448 |
449 | inline
450 | std::ostream& on_magenta(std::ostream& stream)
451 | {
452 | if (_internal::is_colorized(stream))
453 | {
454 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
455 | stream << "\033[45m";
456 | #elif defined(TERMCOLOR_OS_WINDOWS)
457 | _internal::win_change_attributes(stream, -1,
458 | BACKGROUND_BLUE | BACKGROUND_RED
459 | );
460 | #endif
461 | }
462 | return stream;
463 | }
464 |
465 | inline
466 | std::ostream& on_cyan(std::ostream& stream)
467 | {
468 | if (_internal::is_colorized(stream))
469 | {
470 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
471 | stream << "\033[46m";
472 | #elif defined(TERMCOLOR_OS_WINDOWS)
473 | _internal::win_change_attributes(stream, -1,
474 | BACKGROUND_GREEN | BACKGROUND_BLUE
475 | );
476 | #endif
477 | }
478 | return stream;
479 | }
480 |
481 | inline
482 | std::ostream& on_white(std::ostream& stream)
483 | {
484 | if (_internal::is_colorized(stream))
485 | {
486 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
487 | stream << "\033[47m";
488 | #elif defined(TERMCOLOR_OS_WINDOWS)
489 | _internal::win_change_attributes(stream, -1,
490 | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
491 | );
492 | #endif
493 | }
494 |
495 | return stream;
496 | }
497 |
498 |
499 |
500 | //! Since C++ hasn't a way to hide something in the header from
501 | //! the outer access, I have to introduce this namespace which
502 | //! is used for internal purpose and should't be access from
503 | //! the user code.
504 | namespace _internal
505 | {
506 | //! Since C++ hasn't a true way to extract stream handler
507 | //! from the a given `std::ostream` object, I have to write
508 | //! this kind of hack.
509 | inline
510 | FILE* get_standard_stream(const std::ostream& stream)
511 | {
512 | if (&stream == &std::cout)
513 | return stdout;
514 | else if ((&stream == &std::cerr) || (&stream == &std::clog))
515 | return stderr;
516 |
517 | return 0;
518 | }
519 |
520 | // Say whether a given stream should be colorized or not. It's always
521 | // true for ATTY streams and may be true for streams marked with
522 | // colorize flag.
523 | inline
524 | bool is_colorized(std::ostream& stream)
525 | {
526 | return is_atty(stream) || static_cast(stream.iword(colorize_index));
527 | }
528 |
529 | //! Test whether a given `std::ostream` object refers to
530 | //! a terminal.
531 | inline
532 | bool is_atty(const std::ostream& stream)
533 | {
534 | FILE* std_stream = get_standard_stream(stream);
535 |
536 | // Unfortunately, fileno() ends with segmentation fault
537 | // if invalid file descriptor is passed. So we need to
538 | // handle this case gracefully and assume it's not a tty
539 | // if standard stream is not detected, and 0 is returned.
540 | if (!std_stream)
541 | return false;
542 |
543 | #if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
544 | return ::isatty(fileno(std_stream));
545 | #elif defined(TERMCOLOR_OS_WINDOWS)
546 | return ::_isatty(_fileno(std_stream));
547 | #endif
548 | }
549 |
550 | #if defined(TERMCOLOR_OS_WINDOWS)
551 | //! Change Windows Terminal colors attribute. If some
552 | //! parameter is `-1` then attribute won't changed.
553 | inline void win_change_attributes(std::ostream& stream, int foreground, int background)
554 | {
555 | // yeah, i know.. it's ugly, it's windows.
556 | static WORD defaultAttributes = 0;
557 |
558 | // Windows doesn't have ANSI escape sequences and so we use special
559 | // API to change Terminal output color. That means we can't
560 | // manipulate colors by means of "std::stringstream" and hence
561 | // should do nothing in this case.
562 | if (!_internal::is_atty(stream))
563 | return;
564 |
565 | // get terminal handle
566 | HANDLE hTerminal = INVALID_HANDLE_VALUE;
567 | if (&stream == &std::cout)
568 | hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
569 | else if (&stream == &std::cerr)
570 | hTerminal = GetStdHandle(STD_ERROR_HANDLE);
571 |
572 | // save default terminal attributes if it unsaved
573 | if (!defaultAttributes)
574 | {
575 | CONSOLE_SCREEN_BUFFER_INFO info;
576 | if (!GetConsoleScreenBufferInfo(hTerminal, &info))
577 | return;
578 | defaultAttributes = info.wAttributes;
579 | }
580 |
581 | // restore all default settings
582 | if (foreground == -1 && background == -1)
583 | {
584 | SetConsoleTextAttribute(hTerminal, defaultAttributes);
585 | return;
586 | }
587 |
588 | // get current settings
589 | CONSOLE_SCREEN_BUFFER_INFO info;
590 | if (!GetConsoleScreenBufferInfo(hTerminal, &info))
591 | return;
592 |
593 | if (foreground != -1)
594 | {
595 | info.wAttributes &= ~(info.wAttributes & 0x0F);
596 | info.wAttributes |= static_cast(foreground);
597 | }
598 |
599 | if (background != -1)
600 | {
601 | info.wAttributes &= ~(info.wAttributes & 0xF0);
602 | info.wAttributes |= static_cast(background);
603 | }
604 |
605 | SetConsoleTextAttribute(hTerminal, info.wAttributes);
606 | }
607 | #endif // TERMCOLOR_OS_WINDOWS
608 |
609 | } // namespace _internal
610 |
611 | } // namespace termcolor
612 |
613 |
614 | #undef TERMCOLOR_OS_WINDOWS
615 | #undef TERMCOLOR_OS_MACOS
616 | #undef TERMCOLOR_OS_LINUX
617 |
618 | #endif // TERMCOLOR_HPP_
619 |
--------------------------------------------------------------------------------