当前位置: 首页 > news >正文

【逆向】导入表注入

练手的exe链接

链接:https://pan.baidu.com/s/1_87QNHaZYlfY_5uwIRePUQ?pwd=6gds 
提取码:6gds

原理:

在动态链接库一章提到DllMain,这里再回顾一次

当dll被加载进4GB空间时,会调用一次DllMain(入口方法)

当程序执行完了要把dll从4GB空间被卸载,也会调用一次DllMain

很淦,各种问题频出,这回做了整整六个小时,六个小时啊有木有,总结就是,太自大了,没认真听课,直接上手,吃瘪了。

首先说说创建dll文件吧,我选择的是用.def导出,这样我就可以用Depend查看里边的具体函数名和导出序号。很淦的是,当学到动态链接库的时候尝试过自己用def导出dll文件,当时啥问题都没有,一路畅通,但是很淦的是,昨天却死活导不出,只有dll没有lib文件,导致把dll放到Depend什么东东都没看见。各大资料,博客哥们都要翻烂了,还是没能解决,最后.......家人们,好无语啊,原来我添加def的时候是通过手动改后缀为.def,然后死活不行,机缘巧合,我删了原来的def,采用下图这样添加.def文件,然后导出,涅马,成功导出dll和lib了。(耗费一小时)

 以下是dll具体实现
 


#include "pch.h"
#include "Dll2.h"
#include "framework.h"void Init()
{MessageBox(0, L"INIT", L"INIT", MB_OK);
}void Destroy()
{MessageBox(0, L"Destroy", L"Destroy", MB_OK);
}void ExportFunction()
{MessageBox(0, L"ExportFunction", L"ExportFunction", MB_OK);}BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved
)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:Init();break;case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:Destroy();break;}return TRUE;
}

def文件

LIBRARY "dllmain"EXPORTSInit @14
ExportFunction @15
Destroy @16
导入表和导出表的关系

谈谈我的理解,当exe想要调用dll里的函数的时候,首先去导入表找对应的函数名或者导出序号,如果IAT有现成的已经绑定好的地址,那么就直接调用,如果没有,则需要通过INT IAT表存着的函数名或者导出序号,然后调用GetProcAddress() 函数去导出表找对应的函数真实地址,填在IAT,然后调用函数。(精简的回答)

导入表注入的步骤:

第一步,移动导入表:
首先我们要明白为什么要移动导入表,为什么不能在EXE程序最后一个导入表后面追加一个导入表呢?

就拿我这个程序来说,黑色部分就是导入表了,可以看到,导入表的后门就是一大堆我也不知道啥数据,但是肯定动了就寄了,因此根本没空间让我们新添加东西,所以我们只能扩大节或者新增节,去挪动我们的导入表,这里我选择的是新增节

第二步:修改exe的信息:
改PE头关于节的属性,改exe程序的大小,记住新增节的属性是0XC0000060(反正权限都给就对了),然后讲节表里的导入表的偏移地址修改成挪动后的地址

第三步,新增导入表:
按照这个结构来,注意注意,我在这踩坑了,哎。
就是构造IAT,INT的时候要注意结束符!!要留够一个DWORD大小的0,不然在PEtool甚至不能分析新增dll的,和里面的函数。淦,太淦了,还有导入表的OriginalFirstThunk和FirstThunk要先指向一个IMAGE_THUNK_DATA的结构,这个结构是一个联合体

typedef struct _IMAGE_THUNK_DATA32 {						union {						PBYTE  ForwarderString;						PDWORD Function;						DWORD Ordinal;						 //序号PIMAGE_IMPORT_BY_NAME  AddressOfData;//指向IMAGE_IMPORT_BY_NAME} u1;						
} IMAGE_THUNK_DATA32;						
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;	

其他三个没有用,只用到
PIMAGE_IMPORT_BY_NAME  AddressOfData;
指向一个IMAGE_IMPORT_BY_NAME结构

而不是让导入表的OriginalFirstThunk和FirstThunk直接指向IMAGE_IMPORT_BY_NAME结构。

以下是代码:

VOID PE::Import_Table_Injection(Data& my_data)
{//首先先要挪动导出表//获得dll的大小DWORD real_dll_size = my_data.Import_Directory_num * sizeof(IMAGE_IMPORT_DESCRIPTOR);DWORD dll_size = Section_Align(real_dll_size, my_data);DWORD size_of_rawdata = File_Align(real_dll_size, my_data);//申请一个新的空间DWORD new_data_size = my_data.my_optional->SizeOfImage+dll_size;Data new_data;new_data.Stretch_Data = new char[new_data_size];memset(new_data.Stretch_Data, 0, new_data_size);DWORD SIZE = _msize(new_data.Stretch_Data);memcpy_s(new_data.Stretch_Data, new_data_size, my_data.Stretch_Data, my_data.my_optional->SizeOfImage);//修改节的属性Analyze_PE(new_data, 2);new_data.my_file->NumberOfSections += 1;Analyze_PE(new_data, 2);//必须再分析一次,否则Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]会报错new_data.my_optional->SizeOfImage = new_data_size;new_data.my_section[new_data.my_file->NumberOfSections - 1]->Characteristics = my_data.my_section[0]->Characteristics;new_data.my_section[new_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = real_dll_size;memcpy_s(new_data.my_section[new_data.my_file->NumberOfSections - 1]->Name, 7, "inject", 7);new_data.my_section[new_data.my_file->NumberOfSections - 1]->NumberOfLinenumbers = my_data.my_section[0]->NumberOfLinenumbers;new_data.my_section[new_data.my_file->NumberOfSections - 1]->NumberOfRelocations = my_data.my_section[0]->NumberOfRelocations;new_data.my_section[new_data.my_file->NumberOfSections - 1]->PointerToLinenumbers = my_data.my_section[0]->PointerToLinenumbers;new_data.my_section[new_data.my_file->NumberOfSections - 1]->PointerToRawData = my_data.my_section[my_data.my_file->NumberOfSections - 1]->PointerToRawData + my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;new_data.my_section[new_data.my_file->NumberOfSections - 1]->PointerToRelocations = my_data.my_section[0]->PointerToRelocations;new_data.my_section[new_data.my_file->NumberOfSections - 1]->SizeOfRawData = size_of_rawdata;new_data.my_section[new_data.my_file->NumberOfSections - 1]->VirtualAddress = my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize, my_data);cout<<hex<<Rva_To_Foa(0x10eac, new_data)<<endl;cout << hex << Rva_To_Foa(0x10ea4, new_data) << endl;//挪动导入表DWORD import_table_size = my_data.Import_Directory_num * sizeof(IMAGE_IMPORT_DESCRIPTOR);DWORD* import_table_ptr = (DWORD*)my_data.my_Import_Directory[0];DWORD* new_data_ptr = (DWORD*)((DWORD)new_data.Stretch_Data + (DWORD)new_data.my_section[new_data.my_file->NumberOfSections - 1]->VirtualAddress);DWORD GAP = (DWORD)new_data_ptr - (DWORD)new_data.Stretch_Data;memcpy_s(new_data_ptr, import_table_size, import_table_ptr, import_table_size);//修改导入表的入口地址和大小new_data.my_Data_Directory[1]->VirtualAddress = (DWORD)new_data_ptr-(DWORD)new_data.Stretch_Data;new_data.my_Data_Directory[1]->Size=0x3c;//新增导入表PIMAGE_IMPORT_DESCRIPTOR new_import_ptr2=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)new_data_ptr+ import_table_size);new_import_ptr2->FirstThunk = (DWORD)nullptr;new_import_ptr2->TimeDateStamp = 0;new_import_ptr2->OriginalFirstThunk = (DWORD)nullptr;new_import_ptr2->ForwarderChain = 0;//让FirstThunk指向自己伪造的IAT表,让OriginalFirstThunk指向伪造的INT表PIMAGE_IMPORT_BY_NAME new_data_import_by_name = (PIMAGE_IMPORT_BY_NAME)((DWORD)new_data_ptr+3*0X14+0X10 );//指向新的空间PIMAGE_IMPORT_BY_NAME temp_by_name_ptr = new_data_import_by_name;new_data_import_by_name->Hint = 0;strcpy_s(new_data_import_by_name->Name, 0x5, "Init");new_data_import_by_name = (PIMAGE_IMPORT_BY_NAME)((DWORD)new_data_import_by_name + 0x7);strcpy_s((PCHAR)((DWORD)new_data_import_by_name), 0x9, "Dll2.dll");new_import_ptr2->Name = (DWORD)new_data_import_by_name-(DWORD)new_data.Stretch_Data;new_data_import_by_name = (PIMAGE_IMPORT_BY_NAME)((DWORD)new_data_import_by_name - 0x7);IMAGE_THUNK_DATA32* thunk_ptr = (IMAGE_THUNK_DATA32*)((DWORD)new_data_ptr + 3 * 0x14);thunk_ptr->u1.AddressOfData = (DWORD)new_data_import_by_name - (DWORD)new_data.Stretch_Data;new_import_ptr2->FirstThunk = (DWORD)thunk_ptr - (DWORD)new_data.Stretch_Data;thunk_ptr = (IMAGE_THUNK_DATA32*)((DWORD)thunk_ptr + 0X8);thunk_ptr->u1.AddressOfData = (DWORD)new_data_import_by_name - (DWORD)new_data.Stretch_Data;new_import_ptr2->OriginalFirstThunk = (DWORD)thunk_ptr - (DWORD)new_data.Stretch_Data;//缩小保存FILE* my_dll;Shrink_PE(new_data);Analyze_PE(new_data, 3);DWORD Size = _msize(new_data.Shrink_Data);if (fopen_s(&my_dll, "inject", "wb") == 0){fwrite(new_data.Shrink_Data, 1, Size, my_dll);cout << "写入成功!" << endl;return;}else{cout << "写入失败!" << endl;}
}

完整的代码,可直接运行:
 

#include <windows.h>
#include <iostream>
#include <string>
#include <cstring>
#include <malloc.h>
using namespace std;int MAX(int a, int b)
{return a >= b ? a : b;
}class Data
{
public:PIMAGE_DOS_HEADER my_dos;//dos头结构PIMAGE_FILE_HEADER my_file;//file结构PIMAGE_OPTIONAL_HEADER32 my_optional;//可选PE头结构PIMAGE_SECTION_HEADER* my_section;//节表结构PIMAGE_DATA_DIRECTORY* my_Data_Directory;//数据目录结构//0.导出表	1.导入表	2.资源表	3.异常信息表	4.安全证书表	5.重定位表	6.调试信息表	7.版权所以表	//8.全局指针表	9.TLS表	10.加载配置表	11.绑定导入表	12.IAT表	13.延迟绑定表	14.COM信息表	15.未使用CHAR my_Export_Name[50][30];//导出表的名字PIMAGE_EXPORT_DIRECTORY my_Export_Directory; //指向导出表结构的指针DWORD	Export_AddressOfFunction[50];  //指向导出表中函数的地址PIMAGE_BASE_RELOCATION Relocation_Table[500]; //指向重定位表的数组PIMAGE_IMPORT_DESCRIPTOR* my_Import_Directory; //指向导入表DWORD Import_Directory_num; //导入表的数量void* Before_Stretch_Data; //指向拉伸前的内容void* Stretch_Data; //指向拉伸后的内容void* Shrink_Data; //指向缩小PE结构的内容Data(){my_dos = nullptr;//dos头结构my_file = nullptr;//file结构my_optional = nullptr;//可选PE头结构my_section = nullptr;//节表结构my_Data_Directory = nullptr;my_Import_Directory = nullptr;Before_Stretch_Data = nullptr; //指向拉伸前的内容Stretch_Data = nullptr; //指向拉伸后的内容Shrink_Data = nullptr; //指向缩小PE结构的内容Import_Directory_num = 0;}~Data(){if (Before_Stretch_Data != nullptr){free(Before_Stretch_Data);Before_Stretch_Data = nullptr;}if (Stretch_Data != nullptr){free(Stretch_Data);Stretch_Data = nullptr;}if (Shrink_Data != nullptr){free(Shrink_Data);Shrink_Data = nullptr;}}VOID Copy_Before_Strectch_Data(Data my_data); //只深拷贝Before_Strectch_Data
};VOID Data::Copy_Before_Strectch_Data(Data my_data)
{int size = _msize(my_data.Before_Stretch_Data);memcpy_s(this->Before_Stretch_Data, size, my_data.Before_Stretch_Data, size);
}class PE
{
public:VOID Readfile(char* filename, Data& my_data);  //读取pe文件VOID Analyze_PE(Data& my_data, int num);  //分析pe结构VOID Stretch_PE(Data& my_data);  //拉伸pe结构VOID Shrink_PE(Data& my_data); //缩小pe结构VOID New_Section(char* filename, Data& my_data);//新增节,非扩大节,并写入新的exe文件中VOID Expand_Section(Data& my_data, char* filename);  //扩大节DWORD Section_Align(DWORD temp, Data& my_data); //返回内存对齐后的大小DWORD File_Align(DWORD temp, Data& my_data); //返回文件对齐后的大小VOID Combine_Section(char* filename, Data& my_data); //合并节VOID Copy_Data(Data& my_data);VOID Print_IMAGE_DATA_DIRECTORY(Data& my_data);  //打印目录结构VOID Analyze_Data_Directory(Data& my_data); //分析目录结构 //先分析才能打印DWORD  Rva_To_Foa(DWORD Rva_Offset, Data& my_data); //Rva转FoaVOID Print_ExportTable(Data& my_data);  //打印导出表VOID GetFunctionAddrByName(Data& my_data, char* name);  //通过函数名字输出DLL里函数的偏移VOID GetFunctionAddrByOrdinal(Data& my_data, int ordinal);  //通过序号输出DLL里函数的偏移VOID Print_Relocation(Data& mydata);  //打印重定位表VOID Remove_Export_Table(Data& my_data);  //移动导出表VOID Remove_Relocation(Data& my_data);  //移动重定位表VOID Analyze_Import_Table(Data& my_data);  //分析导入表VOID Print_Import_Table(Data& my_data); //打印导入表VOID Print_IAT(Data& my_data); //打印IAT表VOID Print_INT(Data& my_data);//打印INT表VOID Print_BOUND_IMPORT(Data& my_data);//打印绑定导出表的内容VOID Import_Table_Injection(Data& my_data); //导入表注入
};VOID PE::Import_Table_Injection(Data& my_data)
{//首先先要挪动导出表//获得dll的大小DWORD real_dll_size = my_data.Import_Directory_num * sizeof(IMAGE_IMPORT_DESCRIPTOR);DWORD dll_size = Section_Align(real_dll_size, my_data);DWORD size_of_rawdata = File_Align(real_dll_size, my_data);//申请一个新的空间DWORD new_data_size = my_data.my_optional->SizeOfImage+dll_size;Data new_data;new_data.Stretch_Data = new char[new_data_size];memset(new_data.Stretch_Data, 0, new_data_size);DWORD SIZE = _msize(new_data.Stretch_Data);memcpy_s(new_data.Stretch_Data, new_data_size, my_data.Stretch_Data, my_data.my_optional->SizeOfImage);//修改节的属性Analyze_PE(new_data, 2);new_data.my_file->NumberOfSections += 1;Analyze_PE(new_data, 2);//必须再分析一次,否则Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]会报错new_data.my_optional->SizeOfImage = new_data_size;new_data.my_section[new_data.my_file->NumberOfSections - 1]->Characteristics = my_data.my_section[0]->Characteristics;new_data.my_section[new_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = real_dll_size;memcpy_s(new_data.my_section[new_data.my_file->NumberOfSections - 1]->Name, 7, "inject", 7);new_data.my_section[new_data.my_file->NumberOfSections - 1]->NumberOfLinenumbers = my_data.my_section[0]->NumberOfLinenumbers;new_data.my_section[new_data.my_file->NumberOfSections - 1]->NumberOfRelocations = my_data.my_section[0]->NumberOfRelocations;new_data.my_section[new_data.my_file->NumberOfSections - 1]->PointerToLinenumbers = my_data.my_section[0]->PointerToLinenumbers;new_data.my_section[new_data.my_file->NumberOfSections - 1]->PointerToRawData = my_data.my_section[my_data.my_file->NumberOfSections - 1]->PointerToRawData + my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;new_data.my_section[new_data.my_file->NumberOfSections - 1]->PointerToRelocations = my_data.my_section[0]->PointerToRelocations;new_data.my_section[new_data.my_file->NumberOfSections - 1]->SizeOfRawData = size_of_rawdata;new_data.my_section[new_data.my_file->NumberOfSections - 1]->VirtualAddress = my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize, my_data);cout<<hex<<Rva_To_Foa(0x10eac, new_data)<<endl;cout << hex << Rva_To_Foa(0x10ea4, new_data) << endl;//挪动导入表DWORD import_table_size = my_data.Import_Directory_num * sizeof(IMAGE_IMPORT_DESCRIPTOR);DWORD* import_table_ptr = (DWORD*)my_data.my_Import_Directory[0];DWORD* new_data_ptr = (DWORD*)((DWORD)new_data.Stretch_Data + (DWORD)new_data.my_section[new_data.my_file->NumberOfSections - 1]->VirtualAddress);DWORD GAP = (DWORD)new_data_ptr - (DWORD)new_data.Stretch_Data;memcpy_s(new_data_ptr, import_table_size, import_table_ptr, import_table_size);//修改导入表的入口地址和大小new_data.my_Data_Directory[1]->VirtualAddress = (DWORD)new_data_ptr-(DWORD)new_data.Stretch_Data;new_data.my_Data_Directory[1]->Size=0x3c;//新增导入表PIMAGE_IMPORT_DESCRIPTOR new_import_ptr2=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)new_data_ptr+ import_table_size);new_import_ptr2->FirstThunk = (DWORD)nullptr;new_import_ptr2->TimeDateStamp = 0;new_import_ptr2->OriginalFirstThunk = (DWORD)nullptr;new_import_ptr2->ForwarderChain = 0;//让FirstThunk指向自己伪造的IAT表,让OriginalFirstThunk指向伪造的INT表PIMAGE_IMPORT_BY_NAME new_data_import_by_name = (PIMAGE_IMPORT_BY_NAME)((DWORD)new_data_ptr+3*0X14+0X10 );//指向新的空间PIMAGE_IMPORT_BY_NAME temp_by_name_ptr = new_data_import_by_name;new_data_import_by_name->Hint = 0;strcpy_s(new_data_import_by_name->Name, 0x5, "Init");new_data_import_by_name = (PIMAGE_IMPORT_BY_NAME)((DWORD)new_data_import_by_name + 0x7);strcpy_s((PCHAR)((DWORD)new_data_import_by_name), 0x9, "Dll2.dll");new_import_ptr2->Name = (DWORD)new_data_import_by_name-(DWORD)new_data.Stretch_Data;new_data_import_by_name = (PIMAGE_IMPORT_BY_NAME)((DWORD)new_data_import_by_name - 0x7);IMAGE_THUNK_DATA32* thunk_ptr = (IMAGE_THUNK_DATA32*)((DWORD)new_data_ptr + 3 * 0x14);thunk_ptr->u1.AddressOfData = (DWORD)new_data_import_by_name - (DWORD)new_data.Stretch_Data;new_import_ptr2->FirstThunk = (DWORD)thunk_ptr - (DWORD)new_data.Stretch_Data;thunk_ptr = (IMAGE_THUNK_DATA32*)((DWORD)thunk_ptr + 0X8);thunk_ptr->u1.AddressOfData = (DWORD)new_data_import_by_name - (DWORD)new_data.Stretch_Data;new_import_ptr2->OriginalFirstThunk = (DWORD)thunk_ptr - (DWORD)new_data.Stretch_Data;//缩小保存FILE* my_dll;Shrink_PE(new_data);Analyze_PE(new_data, 3);DWORD Size = _msize(new_data.Shrink_Data);if (fopen_s(&my_dll, "inject", "wb") == 0){fwrite(new_data.Shrink_Data, 1, Size, my_dll);cout << "写入成功!" << endl;return;}else{cout << "写入失败!" << endl;}
}VOID PE::Print_BOUND_IMPORT(Data& my_data)
{for (int i = 0; i < my_data.Import_Directory_num; i++){PIMAGE_IMPORT_DESCRIPTOR temp_import_ptr = my_data.my_Import_Directory[i];if (temp_import_ptr->TimeDateStamp == 0){cout << "导入表:" << (PCHAR)(temp_import_ptr->Name + (DWORD)my_data.Stretch_Data) << "未进行绑定,需要进行由编译器修复IAT" << endl;cout << "-----------------------------------------------------------------------------" << endl;}else{cout << "导入表:" << (PCHAR)(temp_import_ptr->Name+(DWORD)my_data.Stretch_Data) << "已经绑定,不需要由编译器修复IAT" << endl;cout << "-----------------------------------------------------------------------------" << endl;}}PIMAGE_BOUND_IMPORT_DESCRIPTOR temp_bound_import_ptr = nullptr;if (my_data.my_Data_Directory[11]->VirtualAddress != 0){temp_bound_import_ptr = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)my_data.my_Data_Directory[11]->VirtualAddress + (DWORD)my_data.Stretch_Data);}else{cout << "该应用程序没有绑定导入表!" << endl;return;}while (*(DWORD*)temp_bound_import_ptr != 0){if (temp_bound_import_ptr->TimeDateStamp != my_data.my_file->TimeDateStamp){cout << "DLL:"<<(PCHAR)(temp_bound_import_ptr->OffsetModuleName+temp_bound_import_ptr)<<"PE头的时间戳和绑定导出表的时间戳不一致!需要进行IAT重定位" << endl;}else{DWORD* temp_name_ptr = (DWORD*)((DWORD)my_data.Stretch_Data + (DWORD)temp_bound_import_ptr + (DWORD)temp_bound_import_ptr->OffsetModuleName);cout << "从该绑定导出表可知,该dll的名字为:" << (PCHAR)temp_name_ptr << ",它依赖的其他dll的个数为" << temp_bound_import_ptr->NumberOfModuleForwarderRefs << endl << "这些dll的名字是" << endl;for (int i = 0; i < temp_bound_import_ptr->NumberOfModuleForwarderRefs; i++){PIMAGE_BOUND_FORWARDER_REF temp_ref_ptr = (PIMAGE_BOUND_FORWARDER_REF)((DWORD)temp_bound_import_ptr + 0x8) + i * 0x8;cout << (PCHAR)((DWORD)my_data.Stretch_Data + (DWORD)temp_bound_import_ptr + (DWORD)temp_ref_ptr->OffsetModuleName) << endl;}cout << endl;}temp_bound_import_ptr = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)temp_bound_import_ptr + 0x8+(DWORD)temp_bound_import_ptr->NumberOfModuleForwarderRefs * 0x8);}
}VOID PE::Print_INT(Data& my_data)
{for (int i = 0; i < my_data.Import_Directory_num; i++){cout << "这是第" << i << "个导入表" << endl;cout << "此时dll的名字是" << (PCHAR)((DWORD)my_data.my_Import_Directory[i]->Name + (DWORD)my_data.Stretch_Data) << endl;DWORD* Temp_ptr = (DWORD*)((DWORD)my_data.my_Import_Directory[i]->OriginalFirstThunk + (DWORD)my_data.Stretch_Data);int count = 0;while (*Temp_ptr != 0){cout << "第" << ++count << "个INT表的偏移是0x" <<hex<< *Temp_ptr << endl;Temp_ptr++;}}
}VOID PE::Print_IAT(Data& my_data)
{for (int i = 0; i < my_data.Import_Directory_num; i++){cout << "这是第" << i << "个导入表" << endl;cout << "此时dll的名字是" << (PCHAR)((DWORD)my_data.my_Import_Directory[i]->Name + (DWORD)my_data.Stretch_Data) << endl;DWORD* Temp_ptr = (DWORD*)((DWORD)my_data.my_Import_Directory[i]->FirstThunk + (DWORD)my_data.Stretch_Data);int count = 0;while (*Temp_ptr != 0){cout << "第" << ++count << "个IAT表的偏移是0x" <<hex<< *Temp_ptr << endl;Temp_ptr++;}}}VOID PE::Print_Import_Table(Data& my_data)
{for (int i = 0; i < my_data.Import_Directory_num; i++){cout << "第" << i << "个导入表的名字——" << endl<< (PCHAR)(my_data.my_Import_Directory[i]->Name+(DWORD)my_data.Stretch_Data) << endl;PIMAGE_THUNK_DATA32 pimage_thunk_data32 = (PIMAGE_THUNK_DATA32)((my_data.my_Import_Directory[0]->OriginalFirstThunk+ (DWORD)my_data.Stretch_Data));for (int j = 0; j < 100; j++){if ((DWORD)pimage_thunk_data32->u1.AddressOfData >> 31 == 1){cout << "函数对应的序号是" << (pimage_thunk_data32->u1.AddressOfData & 0x7FFF) << endl;}else if ((DWORD)pimage_thunk_data32->u1.AddressOfData != 0){cout << "对应的函数名是: " << (PCHAR)(pimage_thunk_data32->u1.AddressOfData+ (DWORD)my_data.Stretch_Data) << endl;}else if ((DWORD)pimage_thunk_data32->u1.AddressOfData == 0){break;}pimage_thunk_data32++;}}
}VOID PE::Analyze_Import_Table(Data& my_data)
{PIMAGE_IMPORT_DESCRIPTOR Temp_Ptr = (PIMAGE_IMPORT_DESCRIPTOR)my_data.my_Data_Directory[1];my_data.my_Import_Directory = new PIMAGE_IMPORT_DESCRIPTOR[100];Temp_Ptr = (PIMAGE_IMPORT_DESCRIPTOR)(*(DWORD*)Temp_Ptr + (DWORD)my_data.Stretch_Data);int i = 0;for ( i = 0; i < 100; i++){if (Temp_Ptr->Characteristics == 0 && Temp_Ptr->Name == 0 && Temp_Ptr->TimeDateStamp == 0){break;}my_data.my_Import_Directory[i] = Temp_Ptr;Temp_Ptr = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)Temp_Ptr + 5 * sizeof(DWORD));}my_data.Import_Directory_num = i;return;
}VOID PE::Remove_Relocation(Data& my_data)
{Data Remove_Relocation_Data;DWORD Relocation_Data_Size = 0;//重定位表的大小LPVOID Temp_Ptr = (LPVOID)((DWORD)my_data.my_Data_Directory[5]->VirtualAddress + (DWORD)my_data.Stretch_Data);PIMAGE_BASE_RELOCATION relocation_ptr = (PIMAGE_BASE_RELOCATION)Temp_Ptr;while (TRUE){if (relocation_ptr->SizeOfBlock == 0){break;}Relocation_Data_Size += relocation_ptr->SizeOfBlock;relocation_ptr = (PIMAGE_BASE_RELOCATION)((DWORD)relocation_ptr+(DWORD)relocation_ptr->SizeOfBlock);}DWORD Real_Size = Relocation_Data_Size;DWORD SizeOfRawData = File_Align(Relocation_Data_Size, my_data);Relocation_Data_Size = Section_Align(Relocation_Data_Size, my_data);Remove_Relocation_Data.Stretch_Data = new char[Relocation_Data_Size+ my_data.my_optional->SizeOfImage];if (Remove_Relocation_Data.Stretch_Data == nullptr){cout << "Remove_Relocation_Data.Stretch_Data分配空间失败!" << endl;return;}memcpy_s(Remove_Relocation_Data.Stretch_Data, Relocation_Data_Size + my_data.my_optional->SizeOfImage, my_data.Stretch_Data, my_data.my_optional->SizeOfImage);//现在要将新的节设置好//	1. 添加一个新的节//	2. 在新增节后面,填充一个节大小的000//	3. 修改PE头节的数量//	4. 修改sizeOfImage的大小//	5. 再原有的数据的最后,新增一个节的数据(内存对齐的整数倍)//	6. 修正新增节的属性//	7. (被坑了好久)记得在对应节填上数据!!!否则会因为数据为空而不能运行Temp_Ptr = (LPVOID)((DWORD)Remove_Relocation_Data.Stretch_Data + (DWORD)my_data.my_optional->SizeOfImage);memset(Temp_Ptr, 0, Relocation_Data_Size);Analyze_PE(Remove_Relocation_Data, 2);Remove_Relocation_Data.my_file->NumberOfSections += 1;Analyze_PE(Remove_Relocation_Data, 2);//必须再分析一次,否则Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]会报错Remove_Relocation_Data.my_optional->SizeOfImage += Relocation_Data_Size;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->Characteristics = my_data.my_section[0]->Characteristics;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->Misc.VirtualSize =Relocation_Data_Size;memcpy_s(Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->Name, 7, "reloca", 7);Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->NumberOfLinenumbers = my_data.my_section[0]->NumberOfLinenumbers;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->NumberOfRelocations = my_data.my_section[0]->NumberOfRelocations;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->PointerToLinenumbers = my_data.my_section[0]->PointerToLinenumbers;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->PointerToRawData = my_data.my_section[my_data.my_file->NumberOfSections - 1]->PointerToRawData + my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->PointerToRelocations = my_data.my_section[0]->PointerToRelocations;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->SizeOfRawData = SizeOfRawData;Remove_Relocation_Data.my_section[Remove_Relocation_Data.my_file->NumberOfSections - 1]->VirtualAddress = my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize, my_data);memcpy_s(Temp_Ptr, Real_Size, (LPVOID)((DWORD)my_data.my_Data_Directory[5]->VirtualAddress+ (DWORD)my_data.Stretch_Data), Real_Size);Remove_Relocation_Data.my_Data_Directory[5]->VirtualAddress = (DWORD)my_data.my_optional->SizeOfImage;FILE* my_file;Shrink_PE(Remove_Relocation_Data);Analyze_PE(Remove_Relocation_Data, 1);DWORD Size = _msize(Remove_Relocation_Data.Shrink_Data);if (fopen_s(&my_file, "reloca", "wb") == 0){fwrite(Remove_Relocation_Data.Shrink_Data, 1, Size, my_file);cout << "写入成功!" << endl;return;}else{cout << "写入失败!" << endl;}}VOID PE::Remove_Export_Table(Data& my_data)
{DWORD Export_Size = my_data.my_Export_Directory->NumberOfFunctions * sizeof(DWORD) + my_data.my_Export_Directory->NumberOfNames * sizeof(WORD) + my_data.my_Export_Directory->NumberOfNames * sizeof(DWORD);for (int i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++){Export_Size += strlen(my_data.my_Export_Name[i]);}Export_Size = Section_Align(Export_Size, my_data);DWORD Total_Size =Export_Size+ my_data.my_optional->SizeOfImage;Data Remove_Export_Data;Remove_Export_Data.Stretch_Data = new char[Total_Size];if (Remove_Export_Data.Stretch_Data == nullptr){cout << "Remove_Export_Data分配空间失败!!" << endl;}memcpy_s(Remove_Export_Data.Stretch_Data, Total_Size, my_data.Stretch_Data, my_data.my_optional->SizeOfImage);LPVOID Temp_Ptr= (LPVOID)((DWORD)Remove_Export_Data.Stretch_Data + my_data.my_optional->SizeOfImage);//这里是指向新的节//现在要将新的节设置好//	1. 添加一个新的节//	2. 在新增节后面,填充一个节大小的000//	3. 修改PE头节的数量//	4. 修改sizeOfImage的大小//	5. 再原有的数据的最后,新增一个节的数据(内存对齐的整数倍)//	6. 修正新增节的属性//	7. (被坑了好久)记得在对应节填上数据!!!否则会因为数据为空而不能运行memset(Temp_Ptr, 0, Export_Size);Analyze_PE(Remove_Export_Data, 2);Remove_Export_Data.my_file->NumberOfSections++;Remove_Export_Data.my_optional->SizeOfImage += Export_Size;Analyze_PE(Remove_Export_Data, 2); //可以分析到新的节表//开始修改节的属性Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->Characteristics = my_data.my_section[0]->Characteristics;Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->Misc.VirtualSize = Export_Size;memcpy_s(Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->Name, 7, "remove",7);Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->NumberOfLinenumbers = my_data.my_section[0]->NumberOfLinenumbers;Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->NumberOfRelocations = my_data.my_section[0]->NumberOfRelocations;Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->PointerToLinenumbers = my_data.my_section[0]->PointerToLinenumbers;Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->PointerToRawData = my_data.my_section[my_data.my_file->NumberOfSections-1]->PointerToRawData+ my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->PointerToRelocations = my_data.my_section[0]->PointerToRelocations;Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->SizeOfRawData = Export_Size;Remove_Export_Data.my_section[Remove_Export_Data.my_file->NumberOfSections - 1]->VirtualAddress = my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData,my_data);Print_ExportTable(Remove_Export_Data);//开始移动导出表的信息!memcpy_s(Temp_Ptr, sizeof(DWORD) * my_data.my_Export_Directory->NumberOfFunctions, (LPVOID)(my_data.my_Export_Directory->AddressOfFunctions+(DWORD)my_data.Stretch_Data), sizeof(DWORD) * my_data.my_Export_Directory->NumberOfFunctions);Remove_Export_Data.my_Export_Directory->AddressOfFunctions = (DWORD)Temp_Ptr-(DWORD)Remove_Export_Data.Stretch_Data;Temp_Ptr = (LPVOID)((DWORD)Temp_Ptr + sizeof(DWORD) * my_data.my_Export_Directory->NumberOfFunctions);memcpy_s(Temp_Ptr, sizeof(WORD) * my_data.my_Export_Directory->NumberOfNames, (LPVOID)(my_data.my_Export_Directory->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data), sizeof(WORD) * my_data.my_Export_Directory->NumberOfNames);Remove_Export_Data.my_Export_Directory->AddressOfNameOrdinals = (DWORD)Temp_Ptr - (DWORD)Remove_Export_Data.Stretch_Data;Temp_Ptr = (LPVOID)((DWORD)Temp_Ptr + sizeof(WORD) * my_data.my_Export_Directory->NumberOfNames);memcpy_s(Temp_Ptr, sizeof(DWORD) * my_data.my_Export_Directory->AddressOfNames, (LPVOID)(my_data.my_Export_Directory->AddressOfNames + (DWORD)my_data.Stretch_Data), sizeof(DWORD) * my_data.my_Export_Directory->NumberOfNames);Remove_Export_Data.my_Export_Directory->AddressOfNames = (DWORD)Temp_Ptr - (DWORD)Remove_Export_Data.Stretch_Data;Temp_Ptr = (LPVOID)((DWORD)Temp_Ptr + sizeof(DWORD) * my_data.my_Export_Directory->AddressOfNames);FILE* my_file;Shrink_PE(Remove_Export_Data);DWORD Size = _msize(Remove_Export_Data.Shrink_Data);if (fopen_s(&my_file, "remove", "wb") == 0){fwrite(Remove_Export_Data.Shrink_Data, 1, Size, my_file);cout << "写入成功!" << endl;return;}else{cout << "写入失败!" << endl;}}VOID PE::Print_Relocation(Data& my_data)
{DWORD Temp_ptr = (DWORD)my_data.my_Data_Directory[5]->VirtualAddress+(DWORD)my_data.Stretch_Data;int count = 1;//这是需要重定位函数的个数cout << endl << endl;for (int i = 0; i < 500; i++){cout << endl;cout << "第" << i+1 << "个块" << endl;cout << "-----------------------------------------------------" << endl;my_data.Relocation_Table[i] = (PIMAGE_BASE_RELOCATION)Temp_ptr;my_data.Relocation_Table[i]->VirtualAddress = *(DWORD*)Temp_ptr;my_data.Relocation_Table[i]->SizeOfBlock = *(DWORD*)(Temp_ptr + 0x4);Temp_ptr += 0x8;for (int index = 0; index < (my_data.Relocation_Table[i]->SizeOfBlock - 0x8) / 2; index++){PWORD Temp_ptr2 = (PWORD)(Temp_ptr +  2*index);int num = (*Temp_ptr2 >> 12);if (num == 3){cout << count++ << ": 0x" << hex << my_data.Relocation_Table[i]->VirtualAddress + (*(Temp_ptr2) & 0XFFF)<<"  ";}}cout << endl;count = 1;Temp_ptr += my_data.Relocation_Table[i]->SizeOfBlock-0x8;if (*(DWORD*)Temp_ptr == 0&& *(DWORD*)(Temp_ptr+1)==0){break;}}}VOID PE::GetFunctionAddrByOrdinal(Data& my_data, int ordinal)
{DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_data.my_Export_Directory->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data);for (int i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++){if (*(WORD*)AddressOfNames_ptr + my_data.my_Export_Directory->Base == ordinal){cout << "成功通过函数的序号找到函数地址!" << endl;cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;return;}AddressOfNames_ptr = (DWORD)((char*)AddressOfNames_ptr + 2);}cout << "没有匹配上!" << endl;
}VOID PE::GetFunctionAddrByName(Data& my_data, char* name)
{int i = 0;for (i = 0; i < my_data.my_Export_Directory->NumberOfNames; i++){if (!strcmp(name, my_data.my_Export_Name[i])){cout << "成功通过函数名匹配到函数!" << endl;break;}if (i == my_data.my_Export_Directory->NumberOfNames - 1){cout << "没有匹配到函数名!" << endl;return ;}}cout << "0x" << hex << my_data.Export_AddressOfFunction[i] << endl;}void PE::Print_ExportTable(Data& my_data)
{PIMAGE_EXPORT_DIRECTORY my_export_directory_ptr = (PIMAGE_EXPORT_DIRECTORY)((DWORD)my_data.my_Data_Directory[0]->VirtualAddress + (DWORD)my_data.Stretch_Data);my_data.my_Export_Directory = my_export_directory_ptr;DWORD AddressOfFunctions_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfFunctions + (DWORD)my_data.Stretch_Data);DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNames + (DWORD)my_data.Stretch_Data);DWORD AddressOfNameOrdinals_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNameOrdinals + (DWORD)my_data.Stretch_Data);cout << "---------------AddressOfFunctions------------------" << endl;int number = my_export_directory_ptr->NumberOfFunctions;for (int i = 0; i < number; i++){cout << i << ": " << "0x" << hex << *((DWORD*)AddressOfFunctions_ptr) << endl;my_data.Export_AddressOfFunction[i] = *((DWORD*)AddressOfFunctions_ptr);AddressOfFunctions_ptr += 0x4;while (*((DWORD*)AddressOfFunctions_ptr) == 0){AddressOfFunctions_ptr += 0x4;}}cout << "---------------------Names------------------" << endl;number = my_export_directory_ptr->NumberOfNames;for (int i = 0; i < number; i++){strcpy_s(my_data.my_Export_Name[i], (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data));cout << i << ": " << (PCHAR)(*(DWORD*)AddressOfNames_ptr + (DWORD)my_data.Stretch_Data) << endl;AddressOfNames_ptr += 0x4;}cout << "----------------------NameOrdinals---------------" << endl;cout << "base: " << my_export_directory_ptr->Base << endl;for (int i = 0; i < number; i++){cout << i << ": " << *(WORD*)AddressOfNames_ptr << endl;AddressOfNames_ptr += 0x2;}
}DWORD PE::Rva_To_Foa(DWORD Rva_Offset, Data& my_data)
{int index = 0;if (Rva_Offset <= my_data.my_optional->SizeOfHeaders){return Rva_Offset;}else{while (Rva_Offset > my_data.my_section[index]->VirtualAddress){if (index == my_data.my_file->NumberOfSections - 1)break;index++;}//计算在节的偏移DWORD Section_Offset = Rva_Offset - my_data.my_section[index]->VirtualAddress;return my_data.my_section[index]->PointerToRawData + Section_Offset;}
}void PE::Analyze_Data_Directory(Data& my_data)
{my_data.my_Data_Directory = nullptr;my_data.my_Data_Directory = (PIMAGE_DATA_DIRECTORY*)malloc(16 * sizeof(PIMAGE_DATA_DIRECTORY));void* Temp_ptr = my_data.my_optional->DataDirectory;for (int i = 0; i < 16; i++){my_data.my_Data_Directory[i] = (PIMAGE_DATA_DIRECTORY)Temp_ptr;Temp_ptr = (char*)Temp_ptr + 0x8;}
}void PE::Print_IMAGE_DATA_DIRECTORY(Data& my_data)
{char arr[16][40] = {"IMAGE_DIRECTORY_ENTRY_EXPORT","IMAGE_DIRECTORY_ENTRY_IMPORT","IMAGE_DIRECTORY_ENTRY_RESOURCE","IMAGE_DIRECTORY_ENTRY_EXCEPTION","IMAGE_DIRECTORY_ENTRY_SECURITY","IMAGE_DIRECTORY_ENTRY_BASERELOC","IMAGE_DIRECTORY_ENTRY_DEBUG","IMAGE_DIRECTORY_ENTRY_COPYRIGHT","IMAGE_DIRECTORY_ENTRY_GLOBALPTR","IMAGE_DIRECTORY_ENTRY_TLS","IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG","IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT","IMAGE_DIRECTORY_ENTRY_IAT","IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT","IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR","RESERVED"};for (int i = 0; i < 16; i++){cout << arr[i] << " :" << endl;cout << "Size: " << hex << my_data.my_Data_Directory[i]->Size << endl;cout << "Virtual_Address: " << my_data.my_Data_Directory[i]->VirtualAddress << endl;cout << "------------------------------------------------------------------------" << endl;}return;
}void PE::Combine_Section(char* filename, Data& my_data)
{int Max = MAX(my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData, my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize);int Size = my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(Max, my_data) - Section_Align(my_data.my_optional->SizeOfHeaders, my_data) + MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize);Data Comebine_Data;int temp_size = _msize(my_data.Stretch_Data) + Max;Comebine_Data.Stretch_Data = (void*)malloc(temp_size);memset(Comebine_Data.Stretch_Data, 0, Size);temp_size = _msize(my_data.Stretch_Data);memcpy_s(Comebine_Data.Stretch_Data, temp_size, my_data.Stretch_Data, temp_size);Analyze_PE(Comebine_Data, 2);void* temp_ptr = (char*)Comebine_Data.Stretch_Data + Max + my_data.my_section[my_data.my_file->NumberOfSections - 1]->VirtualAddress;memcpy_s(temp_ptr, MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data.my_section[0]->VirtualAddress + (char*)my_data.Stretch_Data, MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize));Comebine_Data.my_optional->SizeOfImage += Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData += File_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = Section_Align(Comebine_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize, my_data) + Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);FILE* my_file;if (fopen_s(&my_file, filename, "wb") != 0){cout << "打开文件失败" << endl;return;}Shrink_PE(Comebine_Data);Analyze_PE(Comebine_Data, 3);fwrite(Comebine_Data.Shrink_Data, 1, _msize(Comebine_Data.Shrink_Data), my_file);cout << "写入成功!" << endl;fclose(my_file);
}void PE::Expand_Section(Data& my_data, char* filename)
{this->Stretch_PE(my_data);unsigned Size = 0;//扩大节后新的文件大小Size = my_data.my_optional->ImageBase + Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);Data Expand_Data;Expand_Data.Stretch_Data = (void*)malloc(Size);memset(Expand_Data.Stretch_Data, 0, Size);memcpy_s(Expand_Data.Stretch_Data, _msize(my_data.Stretch_Data), my_data.Stretch_Data, _msize(my_data.Stretch_Data));Analyze_PE(Expand_Data, 2);Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData = Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data) + Section_Align(MAX(my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData, my_data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize), my_data);Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->Misc.VirtualSize = Expand_Data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;Expand_Data.my_optional->SizeOfImage += Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);void* Temp_Ptr = (char*)Expand_Data.Stretch_Data + Expand_Data.my_section[Expand_Data.my_file->NumberOfSections - 1]->VirtualAddress + Section_Align(MAX(my_data.my_section[Expand_Data.my_file->NumberOfSections - 1]->SizeOfRawData, my_data.my_section[Expand_Data.my_file->NumberOfSections - 1]->Misc.VirtualSize), my_data);int temp_size = Section_Align(MAX(my_data.my_section[0]->SizeOfRawData, my_data.my_section[0]->Misc.VirtualSize), my_data);void* Temp_Ptr2 = (char*)my_data.Stretch_Data + my_data.my_section[0]->VirtualAddress;memcpy_s(Temp_Ptr, temp_size, Temp_Ptr2, temp_size);Shrink_PE(Expand_Data);FILE* my_file;if (fopen_s(&my_file, filename, "wb") != 0){cout << "打开文件失败!" << endl;}else{Size = _msize(Expand_Data.Shrink_Data);fwrite(Expand_Data.Shrink_Data, 1, Size, my_file);cout << "写入成功!" << endl;}fclose(my_file);
}DWORD PE::Section_Align(DWORD temp, Data& my_data)
{int i = 0;while (temp > i * my_data.my_optional->SectionAlignment){i++;}return i * my_data.my_optional->SectionAlignment;}DWORD PE::File_Align(DWORD temp, Data& my_data)
{int i = 0;while (temp > i * my_data.my_optional->FileAlignment){i++;}return i * my_data.my_optional->FileAlignment;
}void PE::New_Section(char* filename, Data& my_data)
{unsigned int Size; //Size是新文件的大小,是原来的文件大小加上.VirtualSize和SizeOfRawData较大的那个Size = my_data.my_optional->SizeOfHeaders;for (int i = 0; i < my_data.my_file->NumberOfSections; i++){Size += my_data.my_section[i]->SizeOfRawData;}Size += my_data.my_section[0]->SizeOfRawData;//这是最终新的文件的大小Data New_Data;New_Data.Before_Stretch_Data = (void*)malloc(Size * 1);memset(New_Data.Before_Stretch_Data, 0, Size);memcpy_s(New_Data.Before_Stretch_Data, Size, my_data.Before_Stretch_Data, Size - my_data.my_section[0]->SizeOfRawData);//将原来的文件复制过来Analyze_PE(New_Data, 1);//让New_Data的dos,file,optional,section有数据//复制新的节表void* Temp_ptr1 = (char*)my_data.Before_Stretch_Data + 0x98 + my_data.my_file->SizeOfOptionalHeader;void* Temp_ptr2 = (char*)New_Data.Before_Stretch_Data + 0x98 + my_data.my_file->SizeOfOptionalHeader + my_data.my_file->NumberOfSections * 0x28;memcpy_s(Temp_ptr2, 0x28, Temp_ptr1, 0x28);//复制新的节Temp_ptr1 = (char*)my_data.Before_Stretch_Data + my_data.my_optional->SizeOfHeaders;//指向.text段Temp_ptr2 = (char*)New_Data.Before_Stretch_Data + Size - my_data.my_section[0]->SizeOfRawData;memcpy_s(Temp_ptr2, my_data.my_section[0]->SizeOfRawData, Temp_ptr1, my_data.my_section[0]->SizeOfRawData);//复制完.text段作为新增节//接下来要改Header的各项数据New_Data.my_file->NumberOfSections++;New_Data.my_optional->SizeOfImage += my_data.my_section[0]->SizeOfRawData;Analyze_PE(New_Data, 1);New_Data.my_section[New_Data.my_file->NumberOfSections - 1]->PointerToRawData = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->PointerToRawData + New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData;int size;if (New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->Misc.VirtualSize >= New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData){size = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->Misc.VirtualSize;}else{size = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->SizeOfRawData;}size = size / my_data.my_optional->SectionAlignment + my_data.my_optional->SectionAlignment;New_Data.my_section[New_Data.my_file->NumberOfSections - 1]->VirtualAddress = New_Data.my_section[New_Data.my_file->NumberOfSections - 2]->VirtualAddress + size;FILE* my_file;if (fopen_s(&my_file, filename, "wb") == 0){fwrite(New_Data.Before_Stretch_Data, 1, Size, my_file);cout << "写入成功!" << endl;return;}else{cout << "打开文件失败" << endl;return;}fclose(my_file);
}void PE::Readfile(char* filename, Data& my_data)
{unsigned int size;FILE* datafile;void* data;//打开文件if (fopen_s(&datafile, filename, "rb") != 0){cout << "打开文件失败" << endl;return;}else{//获取文件的大小cout << "打开文件成功!" << endl;fseek(datafile, 0, SEEK_END);size = ftell(datafile);fseek(datafile, 0, SEEK_SET);if (size == -1L){cout << "文件大小判断失败!" << endl;return;}//申请内存空间把文件内容保存下来my_data.Before_Stretch_Data = (void*)malloc(size * sizeof(char));if (fread_s(my_data.Before_Stretch_Data, size, sizeof(char), size, datafile) == 0){cout << "写入数据失败!" << endl;return;}cout << "写入数据成功,成功获取Data!" << endl;return;}}//分析PE结构
void PE::Analyze_PE(Data& data, int num)
{if (num == 1){if (data.Before_Stretch_Data != nullptr){DWORD* Temp_ptr = (DWORD*)data.Before_Stretch_Data;data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)data.Before_Stretch_Data + data.my_dos->e_lfanew);Temp_ptr++;data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);memset(data.my_section, 0, sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);for (int i = 0; i < data.my_file->NumberOfSections; i++){data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);}Analyze_Data_Directory(data);return;}cout << "分析PE结构失败!" << endl;}if (num == 2){if (data.Stretch_Data != nullptr){DWORD* Temp_ptr = (DWORD*)data.Stretch_Data;data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)data.Stretch_Data + data.my_dos->e_lfanew);Temp_ptr++;data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);data.my_section = nullptr;data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);for (int i = 0; i < data.my_file->NumberOfSections; i++){data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);}Analyze_Data_Directory(data);PIMAGE_EXPORT_DIRECTORY my_export_directory_ptr = (PIMAGE_EXPORT_DIRECTORY)((DWORD)data.my_Data_Directory[0]->VirtualAddress + (DWORD)data.Stretch_Data);data.my_Export_Directory = my_export_directory_ptr;DWORD AddressOfFunctions_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfFunctions + (DWORD)data.Stretch_Data);DWORD AddressOfNames_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNames + (DWORD)data.Stretch_Data);DWORD AddressOfNameOrdinals_ptr = (DWORD)((DWORD)my_export_directory_ptr->AddressOfNameOrdinals + (DWORD)data.Stretch_Data);Analyze_Import_Table(data);return;}cout << "分析PE结构失败!" << endl;}if (num == 3){if (data.Shrink_Data != nullptr){DWORD* Temp_ptr = (DWORD*)data.Shrink_Data;data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)data.Shrink_Data + data.my_dos->e_lfanew);Temp_ptr++;data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)data.my_optional + data.my_file->SizeOfOptionalHeader);data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(PIMAGE_SECTION_HEADER) * data.my_file->NumberOfSections);for (int i = 0; i < data.my_file->NumberOfSections; i++){data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);}Analyze_Data_Directory(data);return;}cout << "分析pe结构失败!" << endl;}}//拉伸PE结构   注意看PIMAGE_XXX_HEADER的定义,它们本就是指向结构体的指针
void PE::Stretch_PE(Data& my_data)
{unsigned Memory_Size = 0;Memory_Size = my_data.my_optional->SizeOfImage;my_data.Stretch_Data = (void*)malloc(sizeof(char) * Memory_Size);memset(my_data.Stretch_Data, 0, Memory_Size);void* temp_before_stretch_data_ptr = my_data.Before_Stretch_Data;int size_of_dos = 0x40;int size_of_junk = 0x40;int size_of_file = 0x18;unsigned Size_Of_Optional = my_data.my_file->SizeOfOptionalHeader;unsigned Size_Of_Section = 0x28;unsigned Size_Of_Header = my_data.my_optional->SizeOfHeaders;//还未对齐memcpy_s(my_data.Stretch_Data, Memory_Size, my_data.Before_Stretch_Data, Size_Of_Header);void* temp_stretch_data = my_data.Stretch_Data;//现在计算head头对齐后的大小int Size = Size_Of_Header % my_data.my_optional->SectionAlignment;Size_Of_Header = my_data.my_optional->SectionAlignment * Size;for (int i = 0; i < my_data.my_file->NumberOfSections; i++){temp_stretch_data = (void*)((char*)my_data.Stretch_Data + my_data.my_section[i]->VirtualAddress);temp_before_stretch_data_ptr = (void*)((char*)my_data.Before_Stretch_Data + my_data.my_section[i]->PointerToRawData);memcpy_s(temp_stretch_data, my_data.my_section[i]->SizeOfRawData, temp_before_stretch_data_ptr, my_data.my_section[i]->SizeOfRawData);}cout << "拉伸成功" << endl;
}void PE::Shrink_PE(Data& my_data)
{unsigned int Size = 0;Size = my_data.my_section[my_data.my_file->NumberOfSections - 1]->PointerToRawData + my_data.my_section[my_data.my_file->NumberOfSections - 1]->SizeOfRawData;my_data.Shrink_Data = (void*)malloc(Size);memset(my_data.Shrink_Data, 0, Size);//从Stretch_Data缩小//复制Headsmemcpy_s(my_data.Shrink_Data, my_data.my_optional->SizeOfHeaders, my_data.Stretch_Data, my_data.my_optional->SizeOfHeaders);//复制节void* temp_shrink_data_ptr = my_data.Shrink_Data;void* temp_stretch_data_ptr = my_data.Stretch_Data;for (int i = 0; i < my_data.my_file->NumberOfSections; i++){temp_shrink_data_ptr = (void*)((char*)my_data.Shrink_Data + my_data.my_section[i]->PointerToRawData);temp_stretch_data_ptr = (void*)((char*)my_data.Stretch_Data + my_data.my_section[i]->VirtualAddress);memcpy_s(temp_shrink_data_ptr, my_data.my_section[i]->SizeOfRawData, temp_stretch_data_ptr, my_data.my_section[i]->SizeOfRawData);}cout << "缩小成功" << endl;return;}int main()
{char filename[100] = "Afkayas.1.Exe";PE my_pe;Data my_data;my_pe.Readfile(filename, my_data);my_pe.Analyze_PE(my_data, 1);   //char*& Data, PIMAGE_DOS_HEADER& dos, PIMAGE_FILE_HEADER& file, PIMAGE_OPTIONAL_HEADER32& optional, PIMAGE_SECTION_HEADER*& sectionmy_pe.Stretch_PE(my_data);my_pe.Analyze_PE(my_data, 2);my_pe.Shrink_PE(my_data);my_pe.Analyze_Data_Directory(my_data);//my_pe.Print_IMAGE_DATA_DIRECTORY(my_data);//my_pe.Print_ExportTable(my_data);//cout << "转化的文件偏移是" << hex << my_pe.Rva_To_Foa(0x3100, my_data) << endl;((void(*)())addr)();//调用//HMODULE hDll = GetModuleHandleA("Dll1.dll");//my_pe.GetFunctionAddrByName(my_data, (char*)"Print");//my_pe.GetFunctionAddrByOrdinal(my_data, 14);//my_pe.Print_ExportTable(my_data);//cout << hex << "0x" << my_pe.Rva_To_Foa(0x6000, my_data) << endl;//my_pe.Print_Relocation(my_data);//cout << hex << my_pe.Rva_To_Foa(0x1b0e0, my_data) << endl;my_pe.Remove_Export_Table(my_data);//my_pe.Remove_Relocation(my_data);//my_pe.Analyze_Import_Table(my_data);//my_pe.Print_Import_Table(my_data);my_pe.Print_INT(my_data);my_pe.Print_IAT(my_data);my_pe.Print_BOUND_IMPORT(my_data);my_pe.Import_Table_Injection(my_data);return 0;
}

有错请师父不吝指出,万分感谢

相关文章:

【逆向】导入表注入

练手的exe链接 链接&#xff1a;https://pan.baidu.com/s/1_87QNHaZYlfY_5uwIRePUQ?pwd6gds 提取码&#xff1a;6gds 原理&#xff1a; 在动态链接库一章提到DllMain&#xff0c;这里再回顾一次 当dll被加载进4GB空间时&#xff0c;会调用一次DllMain&#xff08;入口方法&…...

Unity游戏开发中打造游戏攻击技能架构与设计

一、技能系统的设计 在 MOBA 游戏中&#xff0c;每个英雄角色都会有多个技能&#xff0c;这些技能可以分为普通攻击和技能攻击两种。普通攻击是英雄角色的基本攻击方式&#xff0c;而技能攻击则需要消耗一定的资源&#xff08;如蓝量&#xff09;才能使用。在设计技能系统时&a…...

【微信小程序开发】小程序微信用户授权登录(用户信息手机号)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于小程序的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 授权流程讲解 一.用户信息授权登录 1.w…...

VSCode 自动格式化

1.打开应用商店&#xff0c;搜索 prettier code formatter &#xff0c;选择第一个&#xff0c;点击安装。 2.安装完成后&#xff0c;点击文件&#xff0c;选择首选项&#xff0c;选择设置。 3.在搜索框内输入 save &#xff0c;勾选在保存时格式化文件。 4.随便打开一个文件&a…...

数据库、数据仓库相关

1. 数据库与数据仓库的区别 数据库 Database (Oracle, Mysql, PostgreSQL)主要用于事务处理。数据仓库 Datawarehouse (Amazon Redshift, Hive)主要用于数据分析。 数据库和数据仓库是两种不同的数据存储方式&#xff0c;它们的设计目的和使用场景也有所不同。数据库通常用于…...

【STM32】RCC时钟模块(使用HAL库)

https://gitee.com/linhir-linhir/stm32-f103-c8/blob/master/STM32%E6%9C%80%E6%96%B0%E5%9B%BA%E4%BB%B6%E5%BA%93v3.5/Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h STM32最新固件库v3.5/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c…...

WPF中的绑定知识详解(含案例源码分享)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

【JVM】类的生命周期

【JVM】类的生命周期 文章目录 【JVM】类的生命周期1. 生命周期概述2. 加载阶段3. 连接阶段3.1 验证3.2 准备3.3 解析 4. 初始化阶段4.1 触发初始化的方式4.2 clinit不存在的情况4.3 多个类的初始化 5. 总结 1. 生命周期概述 类的生命周期分为5/7个阶段&#xff1a; 加载(Loa…...

asp.net网上商城系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio协同过滤设计

一、源码特点 asp.net网上商城系统是一套完善的web设计管理系统系统采用协同过滤算法进行商品推荐&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库 为sqlserver2008&#xff0c;使用c#语言开发 ASP…...

APUS入驻百度灵境矩阵,普惠AI大模型插件能力

10月17日&#xff0c;APUS出席百度世界大会2023。会上&#xff0c;百度公布了灵境矩阵业务进展&#xff0c;APUS作为灵境矩阵首批合作伙伴正与百度携手拓展大模型能力边界、构建大模型应用生态。 百度认为&#xff0c;大模型将繁荣AI应用生态&#xff0c;在生态搭建过程中&…...

通过C++调用Com接口

头文件 #include <iostream> #include <Windows.h> #include <comdef.h> #include <rpcdce.h> using namespace std; #pragma comment(lib, "Rpcrt4.lib")72C24DD5-D70A-438B-8A42-98424B88AFB8 通过Wscript.Shell来创建进程: void Wscri…...

完全背包问题

目录 1. 朴素解法 2. 优化 原题链接&#xff1a; 3. 完全背包问题 - AcWing题库 题目描述&#xff1a; 有 N 种物品和一个容量是 V 的背包&#xff0c;每种物品都有无限件可用。 第 i 种物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些…...

J2EE的N层体系结构

J2EE平台采用了多层分布式应用程序模型&#xff0c;实现不同逻辑功能的应用程序被封装到不同的构件中&#xff0c;处于不同层次的构件可被分别部署到不同的机器中。 RMI/IIOP&#xff1a;RMI&#xff08;Remote Method Invocation&#xff0c;远程方法调用&#xff09;是Java的…...

Quirks(怪癖)模式是什么?它和 Standards(标准)模式有什么区别?

目录 前言: 用法: 代码: Quirks模式示例: Standards模式示例: 理解: Quirks模式&#xff1a; Standards模式&#xff1a; 高质量讨论: 前言: "Quirks模式"和"Standards模式"是与HTML文档渲染模式相关的两种模式。它们影响着浏览器如何解释和渲染HT…...

自然语言处理---Transformer模型

Transformer概述 相比LSTM和GRU模型&#xff0c;Transformer模型有两个显著的优势&#xff1a; Transformer能够利用分布式GPU进行并行训练&#xff0c;提升模型训练效率。 在分析预测更长的文本时&#xff0c;捕捉间隔较长的语义关联效果更好。 Transformer模型的作用 基于seq…...

动画系统的前世今生(一)

掐指一算&#xff0c;五年没更新过我的CSDN账号啦&#xff0c;方向也从人工智能变成了计算机图形学&#xff0c;当然也依旧会关注AI的发展&#xff0c;之前在知乎上写了一些文章[传送门]&#xff0c;后续也会逐渐同步到CSDN上&#xff5e; 这个系列将包含五篇文章&#xff0c;内…...

11 结构型模式- 代理模式

结构性模式一共包括七种&#xff1a; 代理模式、桥接模式、装饰者模式、适配器模式、门面(外观)模式、组合模式、和享元模式。 1 代理模式介绍 软件开发中的代理&#xff1a; 代理模式中引入了一个新的代理对象,代理对象在客户端对象和目标对象之间起到了中介的作用,它去掉客…...

Unity--用户界面

目录 “使用工具栏”&#xff1a; “层次结构”窗口&#xff1a; 层次结构窗口 制作子GameObject “游戏”视图&#xff1a; “场景视图“&#xff1a; ”项目窗口“&#xff1a; 项目窗口工具栏&#xff1a; "Inspector" 窗口&#xff1a; Inspector 游戏…...

BUUCTF 乌镇峰会种图 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 乌镇互联网大会召开了&#xff0c;各国巨头汇聚一堂&#xff0c;他们的照片里隐藏着什么信息呢&#xff1f;&#xff08;答案格式&#xff1a;flag&#xff5b;答案&#xff5d;&#xff0c;只需提交答案&#xff0…...

Runner GoUI自动化测试发布

构建自动化测试体系是当下每个项目团队愿意去做的&#xff0c;自动化测试减少重复操作节省人力成本。 RunnerGo UI自动化平台 RunnerGo提供从API管理到API性能再到可视化的API自动化、UI自动化测试功能模块&#xff0c;覆盖了整个产品测试周期。 RunnerGo UI自动化基于Selen…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...