Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Newsgroups | ger.ct |
| Subject | Re: Onleihe |
| Date | 2022-05-18 08:30 +0200 |
| Organization | A noiseless patient Spider |
| Message-ID | <t623pc$45g$1@dont-email.me> (permalink) |
| References | <t3qqfg$2lh$1@dont-email.me> |
Auf jeden Fall habe ich mal angenommen, dass Adobe Digital Editions
das PDF im Prozess-Adressraum liegen hat und ich es aus diesem aus-
lesen könnte. Da hab ich mir mal ein kleines Windows-Programm in
C++20 geschrieben das den Prozess-Adressraum nach einem Speicherblock
durchsucht der einen PDF-Header ("%PDF-*.*" - * steht für Versions-
nummer-Anteile) sowie einen PDF-Tailer ("%%EOF") enthält. Eigentlich
ganz einfach und hier ist der Code:
#include <Windows.h>
#include <iostream>
#include <vector>
#include <charconv>
#include <cstring>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <cctype>
#include <fstream>
using namespace std;
template<typename FilterFn>
requires requires( FilterFn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn(
mbi ) } -> std::convertible_to<bool>; }
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess,
FilterFn filterFn );
void savePdf( char const *header, size_t nBytes );
using XHANDLE = unique_ptr<void, decltype([]( HANDLE h ) { h && h !=
INVALID_HANDLE_VALUE && CloseHandle( h ); })>;
int main( int argc, char **argv )
{
if( argc < 2 )
return EXIT_FAILURE;
try
{
DWORD dwProcessId = [&]() -> DWORD
{
DWORD dwRet;
if( from_chars_result fcr = from_chars( argv[1], argv[1] + strlen(
argv[1] ), dwRet ); fcr.ec != errc() || *fcr.ptr )
throw invalid_argument( "process-id unparseable" );
return dwRet;
}();
XHANDLE hProcess( [&]() -> HANDLE
{
HANDLE hRet = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, FALSE, dwProcessId );
if( !hRet )
throw system_error( (int)GetLastError(), system_category(), "can't
open process" );
return hRet;
}() );
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbi = pageTree(
hProcess.get(), []( MEMORY_BASIC_INFORMATION &mbi ) -> bool
{
return mbi.State == MEM_COMMIT;
} );
vector<char> processRegion;
for( vector<MEMORY_BASIC_INFORMATION> const &vmbi : vvmbi )
for( MEMORY_BASIC_INFORMATION const &vmbi : vmbi )
{
processRegion.resize( vmbi.RegionSize );
if( !ReadProcessMemory( hProcess.get(), vmbi.BaseAddress,
to_address( processRegion.begin() ), vmbi.RegionSize, nullptr ) )
continue;
char const *end;
auto detectBegin = [&]( char const *p ) -> char const *
{
if( end - p < 8 )
return nullptr;
if( memcmp( p, "%PDF-", 5 ) != 0 )
return p;
if( !isdigit( p[5] ) || p[6] != '.' || !isdigit( p[7] ) )
return p;
return p + 8;
};
auto detectEnd = [&]( char const *p ) -> char const *
{
if( end - p < 5 )
return nullptr;
if( memcmp( p, "%%EOF", 5 ) != 0 )
return p;
return p + 5;
};
char const
*scn = to_address( processRegion.begin() ),
*next, *header;
end = scn + processRegion.size();
while( scn != end )
{
next = detectBegin( scn );
if( !next )
goto nextRegion;
if( next == scn )
{
++scn;
continue;
}
header = scn;
for( scn = next; scn != end; ++scn )
{
next = detectEnd( scn );
if( !next )
goto nextRegion;
if( next != scn )
{
savePdf( header, next - header );
scn = next;
break;
}
}
}
nextRegion:;
}
}
catch( exception const &exc )
{
cout << exc.what() << endl;
}
}
void savePdf( char const *header, size_t nBytes )
{
string strFileName;
for( unsigned iFileNo = 0; ; )
{
strFileName = (ostringstream() << iFileNo << ".pdf").str();
using FIND_HANDLE = unique_ptr<void, decltype([]( HANDLE h ) { h && h
!= INVALID_HANDLE_VALUE && FindClose( h ); })>;
WIN32_FIND_DATAA fd;
FIND_HANDLE fh( FindFirstFileA( strFileName.c_str(), &fd ) );
if( fh.get() == INVALID_HANDLE_VALUE )
if( DWORD dwErr = GetLastError(); dwErr == ERROR_FILE_NOT_FOUND )
break;
else
throw system_error( (int)dwErr, system_category(), "error
enumerating files to write" );
if( !++iFileNo )
return;
}
ofstream ofs;
ofs.exceptions( ofstream::failbit | ofstream::badbit );
ofs.open( strFileName.c_str(), ofstream::out | ofstream::trunc |
ofstream::binary );
ofs.write( header, nBytes );
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi )
} -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn );
template<typename FilterFn>
requires requires( FilterFn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn(
mbi ) } -> std::convertible_to<bool>; }
vector<vector<MEMORY_BASIC_INFORMATION>> pageTree( HANDLE hProcess,
FilterFn filterFn )
{
vector<vector<MEMORY_BASIC_INFORMATION>> vvmbis;
enumProcessMemory( hProcess, [&]( MEMORY_BASIC_INFORMATION &mbi ) -> bool
{
if( !filterFn( mbi ) )
return true;
if( !vvmbis.size() || vvmbis.back().back().BaseAddress !=
mbi.BaseAddress )
vvmbis.emplace_back( vector<MEMORY_BASIC_INFORMATION>() );
vvmbis.back().emplace_back( mbi );
return true;
} );
return vvmbis;
}
template<typename Fn>
requires requires( Fn fn, MEMORY_BASIC_INFORMATION &mbi ) { { fn( mbi )
} -> std::convertible_to<bool>; }
void enumProcessMemory( HANDLE hProcess, Fn fn )
{
MEMORY_BASIC_INFORMATION mbi;
for( char *last = nullptr; ; last = (char *)mbi.BaseAddress +
mbi.RegionSize )
{
size_t nBytes = VirtualQueryEx( hProcess, last, &mbi, sizeof mbi );
if( nBytes != sizeof mbi )
if( DWORD dwErr = GetLastError(); dwErr == ERROR_INVALID_PARAMETER )
break;
else
throw system_error( (int)dwErr, system_category(), "can't query
process pages" );
if( !fn( mbi ) )
break;
}
}
Mit verschiedenen PDF-Readern funktioniert das auch einwandfrei und
der Code speichert alle in dem Prozess-Adressraum gefundenen PDF ab
0.pdf durchnummeriert und überschreibt dabei keine exisitierenden
Dateien.
Dummerweise funktoniert das nicht mit Adobe Digital Editions bzw.
ich vermute, dass die das PDF verschlüsselt im RAM halten und on
the fly entschlüsseln.
Back to ger.ct | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Onleihe Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-21 07:36 +0200
Re: Onleihe Lothar Kimmeringer <news201705@kimmeringer.de> - 2022-04-21 18:59 +0200
Re: Onleihe Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-22 05:13 +0200
Re: Onleihe "Wendelin Uez" <wuez@online.de> - 2022-04-24 13:03 +0200
Re: Onleihe Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-24 17:24 +0200
Re: Onleihe Dietz Proepper <dietz-usenet@rotfl.franken.de> - 2022-04-24 18:14 +0200
Re: Onleihe Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-24 19:01 +0200
Re: Onleihe "Wendelin Uez" <wuez@online.de> - 2022-04-25 15:43 +0200
Re: Onleihe Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-26 05:02 +0200
Re: Onleihe "Wendelin Uez" <wuez@online.de> - 2022-04-21 15:02 +0200
Re: Onleihe Bonita Montero <Bonita.Montero@gmail.com> - 2022-05-18 08:30 +0200
Es wird noch verrückter ... Bonita Montero <Bonita.Montero@gmail.com> - 2022-05-23 13:07 +0200
Und noch einen oben drauf Bonita Montero <Bonita.Montero@gmail.com> - 2022-05-27 10:11 +0200
Re: Und noch einen oben drauf "Wendelin Uez" <wuez@online.de> - 2022-05-27 12:11 +0200
Re: Und noch einen oben drauf Bonita Montero <Bonita.Montero@gmail.com> - 2022-05-27 19:39 +0200
csiph-web