Abstract: Due to the recent intention to modify the Python interpreter to implement the encryption/decryption of the PYc file, the decrypted data can only be placed in memory and cannot be written to the file for confidentiality. However, the subsequent parsing of the code of the PYc file can only accept file* as the entry, so a need to access the memory through the file*, the following is a few aspects of the requirements of the attempt and its conclusions.
The following are the prerequisites: Win7 + VS2010.
In VC, file is actually _iobuf, the definition is as follows:
struct_iobuf {Char*_ptr;//next location for file input int_cnt;//relative position of the current buffer Char*_base;//refers to the base location (which should be the file's starting position) int_flag;//File Flags int_file;//validation of file validity int_charbuf;//Check the buffer condition and do not read if no buffer int_bufsiz;//size of File Char*_tmpfname;//Temporary file name};typedefstruct_iobuf FILE;
This article has tried the following two ways:
First, how to access the memory block through file*, try 1:_open_osfhandle (), fail
The idea is to put the decrypted content into a memory-mapped file (actually a handle), and then convert the memory-mapped file to file*,
There is a post on the Internet (how to manipulate memory files via file*). http://www.cppblog.com/mythma/archive/2005/10/15/681.html. The core of this idea is to convert the Windows handle of a memory-mapped file (HANDLE) to a standard C file*, which has a function (_open_osfhandle) But this method is effective for the HANDLE of ordinary files, The handle of the memory-mapped file is invalid.
Here is the experiment code:
#include"stdafx.h"#include"TestMemFile.h"#include<io.h>#include<fcntl.h>#ifdef _DEBUG#defineNew Debug_new#endif//the only Application objectCWinApp Theapp;using namespacestd; HANDLE Createmmapfilefrommem () {TCHAR* Mf_name = _t ("mf_file_name_test"); intMf_size =4*1024x768; Std::cout<<"Create a mem map file from mem"<<Std::endl; returncreatefilemapping (Invalid_handle_value, NULL, Page_readwrite,0, Mf_size, mf_name);} HANDLE Createmmapfilefromfile () {std::cout<<"Create a normal file"<<Std::endl; //Here I have already created a good file in D disk, and the content is the character AAAHANDLE hfile = CreateFile (L"D:\\testmemmapfile.txt", Generic_read, file_share_read, NULL, open_always, NULL, NULL); returnhfile;}/*a function pointer to create a memory-mapped file*/typedef HANDLE (*create_file_handle) (void);voidtestconverthandletofileptr (Create_file_handle lpcreatefile) {HANDLE hfile=Lpcreatefile (); if(hfile = =nullptr) {Std::cout<<"create file failed."<<Std::endl; return; } intHFD =_open_osfhandle ((intptr_t) hfile, _o_rdonly); if(HFD = =-1) {Std::cout<<"convert File HANDLE to file* failed."<<Std::endl; CloseHandle (hfile); return; } std::cout<<"convert File HANDLE to file* success."<<Std::endl; FILE* fd = _fdopen (HFD,"R"); Charc =getc (FD); Std::cout<<"Use getc (FD) to read a char from converted FD success, the char value is:"<< C <<Std::endl; Fclose (FILE*) (FD);}int_tmain (intARGC, tchar* argv[], tchar*envp[]) { intnRetCode =0; Hmodule hmodule=:: GetModuleHandle (NULL); if(Hmodule! =NULL) { //initializing MFC and displaying errors on Failure if(! AfxWinInit (Hmodule, NULL,:: GetCommandLine (),0)) { //TODO: Change the error code to suit your needs_tprintf (_t ("Error: MFC initialization failed \ n")); nRetCode=1; } Else { //TODO: Write code here for the behavior of the application. testconverthandletofileptr (CREATEMMAPFILEFROMMEM); Testconverthandletofileptr (Createmmapfilefromfile); } } Else { //TODO: Change the error code to suit your needs_tprintf (_t ("error: GetModuleHandle failed \ n")); nRetCode=1; } returnnRetCode;}
The output results are as follows:
Second, how to access the memory block through file*, try 2: Find open source similar to the fopen implementation function
I feel that this need should not be special, there must be other people and I have similar needs.
Since the standard C library does not accept the byte[] parameter as an overloaded version of the incoming parameter, will there be some relevant open source implementations?
Find a post with my similar needs with Bing, found by _iobuf keyword: http://bytes.com/topic/c/answers/217166-typedef-struct-_iobuf-file
The landlord's general needs are also want to use a library, but the library's entry only accept file* as, and he can provide the content is based on memory, do not want to use disk files as a transit. In this post found a person referred to fmemopen,funopen such as the fopen implementation, they can accept byte[] as the entry, and then return a file*. Unfortunately, these are only Linux versions and Windows does not have a corresponding implementation. I have been thinking about whether to package a, considering the complexity of C library, still can't muster this courage.
Third, How to access memory blocks through file*, try 3: Using tmpfile_s ()
The reason why the above want to convert memory to file* to use, because it feels that if the decrypted PYC files temporarily put into memory, people can directly take this file out, and then decompile, then there is a file can not find the path, it can actually achieve the goal. and Tmpfile () may be such a potential method. For a variety of experiments on tmpfile (), please refer to: My other blog post:
Where did the temporary files generated by the Tmpfile () and tmpfile_s () of standard C actually be placed? (http://www.cnblogs.com/strinkbug/p/where_is_the_filepath_which_created_by_tmpfile_of_c.html), the result of the TMPFILE study is , window, the file created with Tmpfile, cannot find the corresponding file on disk (although I do not believe, but did not find), so use tmpfile to create file* can partially achieve the purpose of secrecy.
Four conclusions
To sum up, there is no way to find the inner block directly on windows (such as byte[]), there is a fmemopen and other implementations on Linux. Considering the concealment of the Tmpfile file, the final choice is to use tmpfile to achieve our confidential purpose.
Then I just have to decrypt the Python pyc file first, then write it to the temporary file file* created by Tmpfile, and then pass the file* back.
This series also has:
Python Parser source Encryption series (a): Where is the temporary file generated by standard C tmpfile (), tmpfile_s ()?
Python Parser source Encryption Series (II): an attempt to access a block of memory using standard C file*