这两天由于修改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()生成的临时文件究竟放在哪里了?的更多相关文章

  1. Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试

    摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...

  2. DRF之解析器源码解析

    解析器 RESTful一种API的命名风格,主要因为前后端分离开发出现前后端分离: 用户访问静态文件的服务器,数据全部由ajax请求给到 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己 ...

  3. Django 之 restframework 解析器源码分析

    解析器分类: 1. JSONPaser ----> 解析 JSON-serialized data (解析JSON序列化的数据) 2.FormParser ---->解析form 表单中 ...

  4. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  5. jquery2源码分析系列

    学习jquery的源码对于提高前端的能力很有帮助,下面的系列是我在网上看到的对jquery2的源码的分析.等有时间了好好研究下.我们知道jquery2开始就不支持IE6-8了,从jquery2的源码中 ...

  6. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  7. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

  8. SpringBoot源码学习系列之异常处理自动配置

    SpringBoot源码学习系列之异常处理自动配置 1.源码学习 先给个SpringBoot中的异常例子,假如访问一个错误链接,让其返回404页面 在浏览器访问: 而在其它的客户端软件,比如postm ...

  9. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

随机推荐

  1. javascript对象模型和function对象

    javascript中,函数就是对象 <html> <head> <script type="text/javascript"> functio ...

  2. select_tag in rails about selected not change and onchange()

    make it more easy after http://www.cnblogs.com/juandx/p/4058399.html 1  if you want the selected is ...

  3. docker-4 Dockerfile的使用

    Dockerfile FROM      基础镜像 MAINTAINER  维护这信息 RUN       运行什么命令,在命令前面加上RUN ADD       往里面加点文件,copy文件,会自动 ...

  4. PHP笔试题(转载)

    整理了一份PHP高级工程师的笔试题,问题很全面.嗯,基本上这些题都答得不错,那么你应该可以胜任大部分互联网企业的PHP职位了.下面直接上题. 1. 基本知识点 HTTP协议中几个状态码的含义:503, ...

  5. Github学习进阶-初露锋芒,通过命令行将本地git仓库推送到Github上面的仓库

    前提: 1. 需要安装git 客户端.  能打开 git  bash 命令行窗口. 2. 生成了ssh 秘钥,并添加到了Github上面. 一.在Github上面建立一个git仓库. 点击 + 号,在 ...

  6. Android Studio运行程序出现Session ‘app’: Error Launching activity 解决办法

    session "app":error launching activity 一下两种方法,可以轻松解决: 1. 2.把复选框去除:  

  7. NGUI:HUD Text(头顶伤害漂浮文字)

    HUD Text 很早之前就有闻于NGUI中的HUD Text插件,今天得以尝试,看了会儿官方的文档,楞是没给看明白,官方的ReadMe.txt写的使用方法如下: 官网Usage 1. Attach ...

  8. java 为啥变量名前要加个m?

    用m_开头表示类的成员变量,member的意思如果是全局变量,则由g_开头还有常量c_开头 静态变量s_开头

  9. JMeter学习(十九)JMeter测试MongoDB

    JMeter测试MongoDB性能有两种方式,一种是利用JMeter直接进行测试MongoDB,还有一种是写Java代码方式测试MongoDB性能. 第一种方法 1.编写Java代码,内容如下: pa ...

  10. Genymotion出现unknown generic error和This may occur if you are using a proxy错误的解决方案

    今天在实验室希望在Genymotion上多下载几个模拟器,需要重新登录帐号,却发现一个错误,叫做unknown generic error.前几天还出现过一个很诡异的问题.截图如下: . (1)unk ...