Skip to content

Instantly share code, notes, and snippets.

@koyzdev
Created June 7, 2024 17:53
Show Gist options
  • Save koyzdev/7aa8abaeb566ddf9aeb65f86d894b978 to your computer and use it in GitHub Desktop.
Save koyzdev/7aa8abaeb566ddf9aeb65f86d894b978 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <vector>
#include <fstream>
#include <cstring>
#include <string>
#include <thread>
#include <windows.h>
int64_t
__fastcall check_window_station()
{
DWORD buffer_length_needed;
const HWINSTA process_window_station = GetProcessWindowStation();
if ( !process_window_station )
return 0xFFFFFFFFi64;
if ( GetUserObjectInformationW( process_window_station, UOI_NAME, NULL, 0, &buffer_length_needed )
|| GetLastError() != ERROR_INSUFFICIENT_BUFFER
|| buffer_length_needed > 512 )
{
return 0xFFFFFFFFi64;
}
buffer_length_needed = ( buffer_length_needed + 1 ) & ~1;
const uint64_t mem_size = ( buffer_length_needed + 17 ) & ~15;
const auto name_buffer = static_cast< wchar_t* >( malloc( mem_size ) );
if ( !GetUserObjectInformationW( process_window_station, UOI_NAME, name_buffer, buffer_length_needed, &buffer_length_needed ) )
return 0xFFFFFFFFi64;
buffer_length_needed = ( buffer_length_needed + 1 ) & ~1;
name_buffer[ buffer_length_needed / sizeof( wchar_t ) ] = L'\0';
return wcsstr( name_buffer, L"Service-0x" ) != nullptr;
}
int
sub_18007F020()
{
int result; // eax
HDC DCW; // r12
HDC compatible_dc; // rsi
int vertical_res; // ebp
HBITMAP compatible_bitmap; // r15
HGDIOBJ v9; // r14
int v13; // ebp
int v14; // ebx
HGDIOBJ v18; // rax
__int64 horizontal_res; // [rsp+50h] [rbp-88h]
void* v28; // [rsp+58h] [rbp-80h]
__int64 pv; // [rsp+60h] [rbp-78h] BYREF
if ( GetVersion() >= 0x80000000 || ( result = check_window_station(), result <= 0 ) )
{
DCW = CreateDCW( L"DISPLAY", 0i64, 0i64, 0i64 );
compatible_dc = CreateCompatibleDC( DCW );
horizontal_res = GetDeviceCaps( DCW, HORZRES );
vertical_res = GetDeviceCaps( DCW, VERTRES );
compatible_bitmap = CreateCompatibleBitmap( DCW, horizontal_res, 16 );
v9 = SelectObject( compatible_dc, compatible_bitmap );
v28 = v9;
GetObjectW( compatible_bitmap, 32, &pv );
v13 = vertical_res - 16;
v14 = 0;
if ( v13 > 0 )
{
int screenshot_id = 0;
do
{
BitBlt( compatible_dc, 0, 0, horizontal_res, 16, DCW, 0, v14, 0xCC0020u );
BITMAP bm;
GetObject( compatible_bitmap, sizeof( bm ), &bm );
BITMAPINFOHEADER bi;
ZeroMemory( &bi, sizeof(bi) );
bi.biSize = sizeof( BITMAPINFOHEADER );
bi.biWidth = bm.bmWidth;
bi.biHeight = -bm.bmHeight; // Use negative height to indicate a top-down DIB
bi.biPlanes = 1;
bi.biBitCount = 24; // Assuming we want a 24-bit bitmap
bi.biCompression = BI_RGB;
int bmp_size = ( ( bm.bmWidth * bi.biBitCount + 31 ) / 32 ) * 4 * bm.bmHeight;
auto bmp_data = new BYTE[ bmp_size ];
GetDIBits( compatible_dc, compatible_bitmap, 0, bm.bmHeight, bmp_data, reinterpret_cast< BITMAPINFO* >( &bi ), DIB_RGB_COLORS );
BITMAPFILEHEADER bf;
bf.bfType = 0x4D42; // 'BM'
bf.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );
bf.bfSize = bf.bfOffBits + bmp_size;
bf.bfReserved1 = 0;
bf.bfReserved2 = 0;
std::ofstream file( "screenshot" + std::to_string( screenshot_id ) + ".bmp", std::ios::out | std::ios::binary );
if ( file )
{
file.write( reinterpret_cast< char* >( &bf ), sizeof( bf ) );
file.write( reinterpret_cast< char* >( &bi ), sizeof( bi ) );
file.write( reinterpret_cast< char* >( bmp_data ), bmp_size );
file.close();
}
screenshot_id++;
v14 += 16;
}
while ( v14 < v13 );
v9 = v28;
}
v18 = SelectObject( compatible_dc, v9 );
DeleteObject( v18 );
DeleteDC( compatible_dc );
return DeleteDC( DCW );
}
return result;
}
int
main()
{
sub_18007F020();
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment