170113

来源:互联网 发布:excel数据被保护 编辑:程序博客网 时间:2024/06/05 15:29

1625-5    王子昂    总结《2016年1月13日》  【连续第105天总结】

A. 逆向作业 100%

python一章 100%

B. 自己编程实现URLDownloadToFile函数的功能,然后实现自启动功能

一脸懵逼,乖乖去百度

基本想法是打开URL然后将数据写入一个文件中

刚开始找到CInternetSession相关的方法,但是看了一下需要使用MFC,CodeBlocks里似乎没这东西,在VC里才行

于是放弃,找到wininet.h的函数。

主要是通过InternetOpen和InternetReadFile来读取,fwrite来写入

看起来很麻烦,参数非常多,不过大多数都保持默认或者NULL就行了所以写起来还是挺简单的

完成下载以后准备实现自启动功能

一共有五种方法:system/WinExec/ShellExecute/CreateProcess/exec和execv

system:

以前只用过system("cls");命令清屏,这次又看到它才知道实际上就相当于使用cmd的命令

那么打开文件只需要直接输入路径即可

如system("E:\\test.jpg");

WinExec:

WinExec('C:\WINDOWS\NOTEPAD.EXE', SW_SHOWNORMAL);

第二个参数是控制程序主窗口的显示方式。

用WinExec只能执行exe文件,并且打开以后就无法管它的死活了。

//WinExec是Windows的老函数了,现在的CreateProcess几乎可以替代WinExe的所有功能。

ShellExecute:

函数原型:

  1. HINSTANCE ShellExecute(  
  2. HWND hwnd,           //运行的窗口句拼   
  3. LPCTSTR lpOperation, //运行方式         
  4. LPCTSTR lpFile,     //文件及路径         
  5. LPCTSTR lpParameters,//参数(一般程序没有)         
  6. LPCTSTR lpDirectory, //默认搜索路径         
  7. INT nShowCmd         //当程序运行后的显示方式  
  8. )

CreateProcess:

最大的区别是它创建了新的进程。不过它创建的进程必须自己来关闭。

  1. BOOL CreateProcess  
  2. (  
  3. LPCTSTR lpApplicationName,//可执行模块  
  4. LPTSTR lpCommandLine,//要执行的命令行  
  5. LPSECURITY_ATTRIBUTES lpProcessAttributes,//是否返回的句柄可以被子进程继承  
  6. LPSECURITY_ATTRIBUTES lpThreadAttributes,//线程是否被继承  
  7. BOOL bInheritHandles,//指示新进程是否从调用进程处继承了句柄  
  8. DWORD dwCreationFlags,//...  
  9. LPVOID lpEnvironment,  
  10. LPCTSTR lpCurrentDirectory,//指定子进程的工作路径  
  11. LPSTARTUPINFO lpStartupInfo,  
  12. LPPROCESS_INFORMATIONlpProcessInformation  
  13. ); 

大部分保持默认或空即可,最后一个结构体保存新进程的ID,用来使用TerminateProcess函数来结束该进程。

exec和execv:

这是exec函数族里面的两个函数,在UNIX环境下用的比较多。

exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容。

也就是说在调用进程内部执行一个可执行文件,这里的可执行文件既可以是二进制文件,也可以是任何Linux下的可执行的脚本文件。

与一般情况不同,exec函数族的函数执行成功后不会返回,只有调用失败了才会返回一个-1,从原程序的调用点接着往下执行。它也是不能控制程序窗口是否显示。


我使用了system和CreateProcess两种方法。

写的时候查了很久CreateProcess前两个参数的作用和区别。

前两个参数分别指向新进程要使用的可执行文件的名称,以及要传给新进程的命令行字符串,lpCommandLine的类型为LPTSTR。

这是因为在内部,CreateProcess实际上会修改我们传给他的命令行字符串,当然在它返回前,它会把这个字符串还原,

所以这样的代码是错误的:py

      1. STARTUPINFO si = {sizeof(si)} ;  
      2. PROCESS_INFORMATION pi ;  
      3. CreateProcess(NULL,TEXT("NOTEPAD"),NULL,NULL,  
      4.     FALSE,0,NULL,NULL,&si,&pi) ;  

解决这个BUG的方法是把常量字符串复制到一个临时缓冲区中,如下所示:

      1. STARTUPINFO si = {sizeof(si)} ;  
      2.     PROCESS_INFORMATION pi ;  
      3.     TCHAR szCommandLine[] = TEXT("NOTEPAD") ;  
      4.     CreateProcess(NULL,szCommandLine,NULL,NULL,  
      5.         FALSE,0,NULL,NULL,&si,&pi) ;  

    1:lpApplicationName为NULL,(99%都设为NULL)
在这种情况下,可执行模块的名字必须处于 lpCommandLine 参数的最前面并由空格符与后面的字符分开。

当CreateProcess解析lpCommandLine 字符串时,它会检查字符串中的第一个标记(token),并假记此标记为我们想运行的可执行文件的名称,

如果可执行文件的名称没有扩展名,默认为.exe,并且如果文件名不包含一个完整的路径,CreateProcess还会按以下顺序来搜索可执行文件:

(1)主调进程.exe文件所在的目录

(2)主调进程的当前目录

(3)windows系统目录,即GetSystemDirectory返回的System32子文件夹

(4)windows目录

(5)PATH环境变量中列出的目录


2:lpApplicationName不为NULL

   在这种情况下,必须指定文件扩展名,系统不会像1那样自动假定扩展名了,

并且如果文件名不包含一个完整的路径,CreateProcess只会在当前目录查找可执行文件,不会在其他任何目录查找了。

一旦系统找到了可执行文件,就创建一个新进程,并将可执行文件的代码和数据映射到新进程的地址空间,然后启动例程,

C/C++会将可执行文件名之后的第一个实参的地址传给(w)WinMain的pszCmdLine参数




使用的时候各种组合搭配都试了,仍然不能成功运行jpg文件,最后想起来这个新建进程只能打开EXE文件

而打开一个JPG文件的本质是 1.打开图像浏览工具

     2.打开图像文件

所以新建进程的第一个参数应该是画图或者图像查看器的exe文件的地址,第二个参数是open *.jpg

这样写了以后运行果然成功了

不过这样子就只能打开图像文件了,解决思路是判断文件名的后缀名是exe、jpg还是txt,并使用相应的exe文件打开即可

不过并没有实现,因为网址和文件名都没有实现自定义输入,所以没有必要修改了╮(╯_╰)╭

代码如下:

#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#include <iostream>
#define MAXBLOCKSIZE 1024
using namespace std;
void download(const char *Url,const char *save_as)/*将Url指向的地址的文件下载到save_as指向的本地文件*/
{
  byte Temp[MAXBLOCKSIZE];  //开辟临时空间
   ULONG Number = 1;


   FILE *stream;            //生成文件对象
   HINTERNET hSession = InternetOpen(  "RookIE/1.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); //建立会话,使用rookie,方式为直接连接,后面两个NULL表示代理连接的相关设置,0是dwFlags的参数
 if (hSession != NULL)                                                                          //成功建立会话
 {
    cout<<"浏览器打开成功"<<endl;
  HINTERNET handle2 = InternetOpenUrl(hSession, Url, NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);     //会话句柄,URL地址,头信息,额外头的大小,dwFlags,dwContext


  if (handle2 != NULL)
  {


    cout<<"连接成功"<<endl;
   if( (stream = fopen( save_as, "wb" )) != NULL )  //以只写二进制文件形式打开文件
   {
    cout<<"文件创建成功,开始从"<<Url<<"下载"<<endl;
    while (Number > 0)
    {
     InternetReadFile(handle2, Temp, MAXBLOCKSIZE - 1, &Number);//从上面建立的网页连接中读取信息,保存在temp变量中,欲读取长度为1023,将读取长度的值保存在number变量中


     fwrite(Temp, sizeof (char), Number , stream);              //写入文件,每个单位为char的一个字节,一共number个单位,文件对象是stream


    }
    cout<<"下载完成,保存为"<<save_as<<endl;
    fclose( stream );
   }


   InternetCloseHandle(handle2);
   handle2 = NULL;
  }
  InternetCloseHandle(hSession);
  hSession = NULL;
 }
}


int main(int argc, char* argv[]){
 //下载   
 //download("http://portrait2.sinaimg.cn/1242047561/blog/180","e:\\test.jpg");
    cout<<"打开程序"<<endl;
 //第一种方法
 //system("e:\\test.jpg");
 
 //第二种方法
    {_PROCESS_INFORMATION pi;
    STARTUPINFO si = {sizeof(si)} ;
    TCHAR commandline[] = "open e:\\test.jpg";
    CreateProcess("C:\\Windows\\System32\\mspaint.exe",commandline,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi) ;  //使用画图打开图片
    Sleep(5000);
    TerminateProcess(pi.hProcess, 0);
    }
 return 0;
}




好久没看python,上次看的四章已经基本全部忘了……

重头复习起_(:з」∠)_

要连续跟着看啊

C. 明日计划

Python一章 

0 0
原创粉丝点击