设为首页 收藏本站
查看: 880|回复: 0

[经验分享] Python解析器源码加密系列之(一):标准c的tmpfile()、tmpfile_s()生成的临时文件究竟放在哪里了?

[复制链接]

尚未签到

发表于 2015-11-29 13:12:27 | 显示全部楼层 |阅读模式
  这两天由于修改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 = 1; i <= 3; i++ )
{
errno_t err = tmpfile_s(&stream);
fwrite(tempstring, 1, 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 = 0;  
DWORD  dwFileSizeLow = 5;//GetFileSize(hFile, &dwFileSizeHigh);  
if (dwFileSizeLow == 0 && dwFileSizeHigh == 0)  
{  
printf("不能map文件大小为0的文件.\n");  
return FALSE;  
}  
//创建Mapping对象  
hFileMap = CreateFileMapping(hFile,  
NULL,  
PAGE_READONLY,  
0,  
1,  
NULL);  
if (!hFileMap)  
{  
printf("CreateFileMapping error: %d", GetLastError());  
return FALSE;  
}  
pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);  
if (!pMem)  
{  
printf("MapViewOfFile error: %d", GetLastError());  
return FALSE;  
}  
//从Mapping对象获得文件名  
if (0 == GetMappedFileName(GetCurrentProcess(),  
pMem,  
pszFileName,  //以设备名的形式获得文件路径,运行时设个断点查看即可  
        MAX_PATH))  
{  
printf("GetMappedFileName error: %d", GetLastError());  
return FALSE;  
}  
TCHAR szTemp[MAX_PATH] = {0};  
//获取电脑上的所有驱动器,如"C:\"  "D:\"等,连续放置的  
if (0 == GetLogicalDriveStrings(BUFSIZE-1, szTemp))  
{  
printf("GetLogicalDriveStrings error: %d", GetLastError());  
return FALSE;  
}  
TCHAR  szName[MAX_PATH];  
TCHAR  szDrive[3] = {0};  
BOOL   bFound = FALSE;  
//通过指针p的移动来顺序访问所有的驱动器目录  
TCHAR* p = szTemp;  
do  
{  
CopyMemory(szDrive, p, 2*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) == 0;  
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, 1, strlen(tempstring), stream);
GetFileNameFromFILEPtr(stream);
fclose(stream);
}
  三、结论
  综上,tmpfile()、tmpfile_s()生成的临时文件没有放在磁盘上,或者是没有出现在文件系统中,或者至少是在一个非常隐蔽的地方,我暂时没有办法找到。
  有了这层保障,后续使用tmpfile的时候,就不用太担心泄密的问题了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-144938-1-1.html 上篇帖子: python进程池:multiprocessing.pool 下篇帖子: APScheduler —— Python化的Cron
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表