Python解析器源码加密系列之(一):标准c的tmpfile()、tmpfile_s()生成的临时文件究竟放在哪里了?
这两天由于修改python解释器的需求,需要用到tmpfile()来生成临时文件的FILE*,但是又担心这个临时文件是否存在于磁盘的某个地方,终究会被人找到,所以就简单做了以下几点实验,看看是否可以找到tmpfile临时文件的路径。
实验环境:Win7 + VS2010
一、实验一:跟踪调试
写了一小段简单的tmpfile调用,然后跟踪调试,在tmpfile_s内部也没能发现这个临时文件的路径,当然,通过stream->_tmpfname,可以看到一个临时文件的名称,但是看不到路径;根据这个名称到WINDOWS\TEMP(或者C:\Users\xxx\AppData\Local\Temp)路径下去查找,也没有找到类似名称的文件。
void TesttempfileFunc()
{
FILE *stream;
char tempstring[] = "String to be written";
// Create temporary files.
for(int i = ; i <= ; i++ )
{
errno_t err = tmpfile_s(&stream);
fwrite(tempstring, , strlen(tempstring), stream);
if( err )
perror( "Could not open new temporary file\n" );
else
printf( "Temporary file %d was created\n", i );
}
// Remove temporary files.
printf( "%d temporary files deleted\n", _rmtmp() );
}
二、实验二,通过api提取FILE*的路径
是否可以通过FILE*,然后通过某种API的调用,找到对应的文件名称,bing搜了一把,有一篇类似的文章(通过文件句柄获得文件路径http://www.bkjia.com/cjjc/498250.html),但是这里是通过HANDLE来获取文件路径,而我需要的是从FILE*获取文件路径,想到下午了解到有一个函数(_get_osfhandle)可以将FILE*转换为文件句柄,所以写了如下代码来验证:
1)首先来尝试针对普通文件的FILE*来提取他的路径,提取成功,代码如下:
BOOL GetFileNameFromHandle(HANDLE hFile)
{
TCHAR pszFileName[MAX_PATH];
HANDLE hFileMap;
PVOID pMem; //获取文件大小
DWORD dwFileSizeHigh = ;
DWORD dwFileSizeLow = ;//GetFileSize(hFile, &dwFileSizeHigh);
if (dwFileSizeLow == && dwFileSizeHigh == )
{
printf("不能map文件大小为0的文件.\n");
return FALSE;
} //创建Mapping对象
hFileMap = CreateFileMapping(hFile,
NULL,
PAGE_READONLY,
,
,
NULL);
if (!hFileMap)
{
printf("CreateFileMapping error: %d", GetLastError());
return FALSE;
} pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, , , );
if (!pMem)
{
printf("MapViewOfFile error: %d", GetLastError());
return FALSE;
} //从Mapping对象获得文件名
if ( == GetMappedFileName(GetCurrentProcess(),
pMem,
pszFileName, //以设备名的形式获得文件路径,运行时设个断点查看即可
MAX_PATH))
{
printf("GetMappedFileName error: %d", GetLastError());
return FALSE;
} TCHAR szTemp[MAX_PATH] = {};
//获取电脑上的所有驱动器,如"C:\" "D:\"等,连续放置的
if ( == GetLogicalDriveStrings(BUFSIZE-, szTemp))
{
printf("GetLogicalDriveStrings error: %d", GetLastError());
return FALSE;
} TCHAR szName[MAX_PATH];
TCHAR szDrive[] = {};
BOOL bFound = FALSE;
//通过指针p的移动来顺序访问所有的驱动器目录
TCHAR* p = szTemp;
do
{
CopyMemory(szDrive, p, *sizeof(TCHAR));
//通过路径查找设备名,如"C:"
if (!QueryDosDevice(szDrive, szName, BUFSIZE))
{
printf("QueryDosDrive error: %d", GetLastError());
return FALSE;
}
UINT uNameLen = lstrlen(szName);
if (uNameLen < MAX_PATH)
{
//比较驱动器的设备名文件名与文件设备名是否匹配
bFound = _tcsnccmp(pszFileName, szName, uNameLen) == ;
if (bFound)
{
//如果匹配,说明已找到,构造路径
TCHAR szTempFile[MAX_PATH];
wsprintf(szTempFile,
TEXT("%s%s"),
szDrive,
pszFileName+uNameLen);
lstrcpy(pszFileName, szTempFile);
}
}
//这里不理解的话可以去看看GetLogicalDriveStrings
while (*p++);
}while (!bFound && *p); UnmapViewOfFile(pMem);
CloseHandle(hFileMap);
std::wcout<<_T("File Path is: ")<<pszFileName<<std::endl;
//printf("File Path is %s\n", pszFileName);
return TRUE;
} void GetFileNameFromFILEPtr(FILE* pFile)
{
HANDLE hFile = (HANDLE)_get_osfhandle(fileno(pFile));
GetFileNameFromHandle(hFile);
} void TestGetFilePathFromNormalFILEPtr()
{
FILE* fd = fopen("D:\\TestMemMapFile.txt", "r");
char c = fgetc(fd);
GetFileNameFromFILEPtr(fd);
}
2)然后尝试对tmpfile生成的FILE* 提取文件路径,提取失败,因为这种临时文件在获取文件长度(GetFileSize)时就会失败,无法转换为内存映射文件,我怀疑可能是因为这个临时文件本来就不在磁盘上,所以去做映射的时候就失败了,相关代码如下:
void TestGettempfilePath()
{
FILE *stream;
char tempstring[] = "String to be written";
errno_t err = tmpfile_s(&stream);
if( err )
{
perror( "Could not open new temporary file\n" );
return;
}
else
printf( "Temporary file was created\n"); fwrite(tempstring, , strlen(tempstring), stream);
GetFileNameFromFILEPtr(stream);
fclose(stream);
}
三、结论
综上,tmpfile()、tmpfile_s()生成的临时文件没有放在磁盘上,或者是没有出现在文件系统中,或者至少是在一个非常隐蔽的地方,我暂时没有办法找到。
有了这层保障,后续使用tmpfile的时候,就不用太担心泄密的问题了。
Python解析器源码加密系列之(一):标准c的tmpfile()、tmpfile_s()生成的临时文件究竟放在哪里了?的更多相关文章
- Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试
摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...
- DRF之解析器源码解析
解析器 RESTful一种API的命名风格,主要因为前后端分离开发出现前后端分离: 用户访问静态文件的服务器,数据全部由ajax请求给到 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己 ...
- Django 之 restframework 解析器源码分析
解析器分类: 1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据) 2.FormParser ---->解析form 表单中 ...
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- jquery2源码分析系列
学习jquery的源码对于提高前端的能力很有帮助,下面的系列是我在网上看到的对jquery2的源码的分析.等有时间了好好研究下.我们知道jquery2开始就不支持IE6-8了,从jquery2的源码中 ...
- [转]jQuery源码分析系列
文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...
- jQuery源码分析系列(转载来源Aaron.)
声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...
- SpringBoot源码学习系列之异常处理自动配置
SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...
- jQuery源码分析系列——来自Aaron
jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...
随机推荐
- java获取时间戳的方法
JAVA 获取当前月的初始时间的时间戳 public static long getMonthFirstDay() { Calendar calendar = Calendar.getInstance ...
- System占用端口80
可尝试如下结束System进程: 开始——设置——控制面板——管理工具——服务结束系统服务项:World Wide Web Publishing Service
- HTTPAnalyzer截获SoapUI发送的接口报文
一.截获过程 1. 开启HTTPAnalyzer报文截获工具. 2. 通过SoapUI工具发送报文. 3. HTTPAnalyzer报文截获工具自动截获. 二.SoapUI报文准备 准备工作是:打 ...
- Effective Java 43 Return empty arrays or collections, not nulls
Feature Return empty arrays or collection Return nulls Avoids the expense of allocating the array N ...
- 关于Redis中的数据类型
一. Redis常用数据类型 Redis最为常用的数据类型主要有以下: String Hash List Set Sorted set 一张图说明问题的本质 图一: 图二: 代码: /* Object ...
- centos7安装python-pip
在使用centos7的软件包管理程序yum安装python-pip的时候会报一下错误: No package python-pip available. Error: Nothing to do 说没 ...
- Gradle系列教程之依赖管理(转)
转自Lippi-浮生志 :http://ezlippi.com/blog/2015/05/gradle-dependency-management.html 这一章我将介绍Gradle对依赖管理的强大 ...
- 关于mac环境下删除cocos2d-x环境变量配置的方法
yangchaodeMacBook-Air:downloads yangchao$ vim ~/.bash_profile
- jQuery Validate 表单验证插件----Validate简介,官方文档,官方下载地址
一. jQuery Validate 插件的介绍 jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆 ...
- 设计模式C#实现(六)——单例模式
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 构成: 1.私有的构造函数 2.私有静态的实例 3.返回实例的静态方法 public class Singleton { privat ...