国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【逆向】03-20擴(kuò)大節(jié) c++代碼完成 ;類當(dāng)作函數(shù)參數(shù)卻調(diào)用了析構(gòu)函數(shù)疑難分析

這篇具有很好參考價(jià)值的文章主要介紹了【逆向】03-20擴(kuò)大節(jié) c++代碼完成 ;類當(dāng)作函數(shù)參數(shù)卻調(diào)用了析構(gòu)函數(shù)疑難分析。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

若要看PE結(jié)構(gòu)操作最新代碼,點(diǎn)擊主頁(yè)查看??!

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-729658.html

和上一節(jié)的代碼相比,本文章主要修復(fù)了上一篇文章代碼中PE類中的Analyze函數(shù),這樣不管是Before_Stretch_Data還是Stretch_Data,Shrink_Data,在這個(gè)函數(shù)中都可以分析出PE結(jié)構(gòu)

另外新添加了函數(shù)Expand_Section函數(shù),可以自動(dòng)擴(kuò)大最后一個(gè)節(jié),并寫入新的文件中,親測(cè)可以使用,程序可以完美運(yùn)行
Expand_Section函數(shù)的思路就是
?

擴(kuò)大節(jié):

只能擴(kuò)大最后一個(gè)節(jié)

  • 1.拉伸到內(nèi)存

  • 2.分配一塊新的空間,SizeOfImage + Ex(擴(kuò)大出來(lái)的空間)

  • 3.將最后一個(gè)節(jié)的SizeOfRawData和VirtualSize改成N SizeOfRawData=VirtualSize=N N=(原來(lái)的SizeOfRawData和VirtualSize兩者比較大的那一個(gè)內(nèi)存對(duì)齊后的值)+Ex

  • 4.修改SizeOfImage大小 SizeOfImage=SizeOfImage+Ex

?

期間我遇到一個(gè)百思不得其解的問(wèn)題:
就是我將一個(gè)類作為參數(shù)繼續(xù)函數(shù)傳值,但是程序運(yùn)行報(bào)錯(cuò)了,但是如果我傳的是引用卻不會(huì)報(bào)錯(cuò)。在文章末尾說(shuō)

上代碼先:
?

#include <windows.h>
#include <iostream>
#include <string>

#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頭結(jié)構(gòu)
	PIMAGE_FILE_HEADER my_file;//file結(jié)構(gòu)
	PIMAGE_OPTIONAL_HEADER32 my_optional;//可選PE頭結(jié)構(gòu)
	PIMAGE_SECTION_HEADER* my_section ;//節(jié)表結(jié)構(gòu)


	void* Before_Stretch_Data ; //指向拉伸前的內(nèi)容
	void* Stretch_Data ; //指向拉伸后的內(nèi)容
	void* Shrink_Data ; //指向縮小PE結(jié)構(gòu)的內(nèi)容

	Data()
	{
		my_dos = nullptr;//dos頭結(jié)構(gòu)
		my_file = nullptr;//file結(jié)構(gòu)
		my_optional = nullptr;//可選PE頭結(jié)構(gòu)
		my_section = nullptr;//節(jié)表結(jié)構(gòu)


		Before_Stretch_Data = nullptr; //指向拉伸前的內(nèi)容
		Stretch_Data = nullptr; //指向拉伸后的內(nèi)容
		Shrink_Data = nullptr; //指向縮小PE結(jié)構(gòu)的內(nèi)容
	}

	~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:




public:
	void Readfile(char* filename, Data& my_data);  //讀取pe文件

	void Analyze_PE(Data& my_data);  //分析pe結(jié)構(gòu)
	
	void Stretch_PE(Data& my_data);  //拉伸pe結(jié)構(gòu)

	void Shrink_PE(Data& my_data); //縮小pe結(jié)構(gòu)

	void New_Section(char* filename,Data& my_data);//新增節(jié),非擴(kuò)大節(jié),并寫入新的exe文件中

	void Expand_Section(Data& my_data, char* filename);  //擴(kuò)大節(jié)

	int Section_Align(int temp,Data& my_data); //返回內(nèi)存對(duì)齊后的大小

	int File_Align(int temp,Data& my_data); //返回文件對(duì)齊后的大小

	void Copy_Data(Data& my_data);
};

void PE:: Expand_Section(Data& my_data,char* filename)
{
	this->Stretch_PE(my_data);
	unsigned Size = 0;//擴(kuò)大節(jié)后新的文件大小
	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);

	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;
	}

}


int PE::Section_Align(int temp, Data& my_data)
{
	return (temp / my_data.my_optional->SectionAlignment)* my_data.my_optional->SectionAlignment + my_data.my_optional->SectionAlignment;
}

int PE::File_Align(int temp, Data& my_data)
{
	return temp / my_data.my_optional->FileAlignment + my_data.my_optional->FileAlignment;
}

void PE::New_Section(char* filename, Data& my_data)
{
	unsigned int Size; //Size是新文件的大小,是原來(lái)的文件大小加上.VirtualSize和SizeOfRawData較大的那個(gè)
	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);//將原來(lái)的文件復(fù)制過(guò)來(lái)

	Analyze_PE(New_Data);//讓New_Data的dos,file,optional,section有數(shù)據(jù)
	
	//復(fù)制新的節(jié)表
	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);
	//復(fù)制新的節(jié)
	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);//復(fù)制完.text段作為新增節(jié)

	//接下來(lái)要改Header的各項(xiàng)數(shù)據(jù)
	New_Data.my_file->NumberOfSections++;
	New_Data.my_optional->SizeOfImage += my_data.my_section[0]->SizeOfRawData;

	Analyze_PE(New_Data);
	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;
	}
}


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;
		}

		//申請(qǐng)內(nèi)存空間把文件內(nèi)容保存下來(lái)
		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 << "寫入數(shù)據(jù)失敗!" << endl;
			return;
		}
		cout << "寫入數(shù)據(jù)成功,成功獲取Data!" << endl;
		return ;
	}

}

//分析PE結(jié)構(gòu)
void PE::Analyze_PE(Data& my_data)
{
	if (my_data.Before_Stretch_Data != nullptr)
	{
		DWORD* Temp_ptr = (DWORD*)my_data.Before_Stretch_Data;
		my_data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)my_data.Before_Stretch_Data + my_data.my_dos->e_lfanew);
		Temp_ptr++;
		my_data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
		my_data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)my_data.my_optional + my_data.my_file->SizeOfOptionalHeader);
		my_data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER) * my_data.my_file->NumberOfSections);
		for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
		{
			my_data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
			Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
		}
		return;
	}
	else if(my_data.Stretch_Data!=nullptr)
	{
		DWORD* Temp_ptr = (DWORD*)my_data.Stretch_Data;
		my_data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)my_data.Stretch_Data + my_data.my_dos->e_lfanew);
		Temp_ptr++;
		my_data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
		my_data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)my_data.my_optional + my_data.my_file->SizeOfOptionalHeader);
		my_data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER) * my_data.my_file->NumberOfSections);
		for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
		{
			my_data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
			Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
		}
		return;
	}
	else if (my_data.Shrink_Data != nullptr)
	{
		DWORD* Temp_ptr = (DWORD*)my_data.Shrink_Data;
		my_data.my_dos = (PIMAGE_DOS_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)my_data.Shrink_Data + my_data.my_dos->e_lfanew);
		Temp_ptr++;
		my_data.my_file = (PIMAGE_FILE_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x14);
		my_data.my_optional = (PIMAGE_OPTIONAL_HEADER)Temp_ptr;

		Temp_ptr = (DWORD*)((char*)my_data.my_optional + my_data.my_file->SizeOfOptionalHeader);
		my_data.my_section = (PIMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER) * my_data.my_file->NumberOfSections);
		for (int i = 0; i < my_data.my_file->NumberOfSections; i++)
		{
			my_data.my_section[i] = (PIMAGE_SECTION_HEADER)Temp_ptr;
			Temp_ptr = (DWORD*)((char*)Temp_ptr + 0x28);
		}
		return;
	}

	cout << "分析pe結(jié)構(gòu)失敗!" << endl;
	cout << "失敗原因,Data類里三個(gè)狀態(tài)的指針皆為空指針!" << endl;
}

//拉伸PE結(jié)構(gòu)   注意看PIMAGE_XXX_HEADER的定義,它們本就是指向結(jié)構(gòu)體的指針
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 = size_of_dos + size_of_file + size_of_junk + Size_Of_Optional + Size_Of_Section * my_data.my_file->NumberOfSections;//還未對(duì)齊
	memcpy_s(my_data.Stretch_Data, Memory_Size, my_data.Before_Stretch_Data, Size_Of_Header);
	void* temp_stretch_data = my_data.Stretch_Data;
	//現(xiàn)在計(jì)算head頭對(duì)齊后的大小
	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);

	//從Stretch_Data縮小

	//復(fù)制Heads
	memcpy_s(my_data.Shrink_Data, my_data.my_optional->SizeOfHeaders, my_data.Stretch_Data, my_data.my_optional->SizeOfHeaders);

	//復(fù)制節(jié)
	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]= "ceshi.exe";
	PE my_pe;
	Data my_data;
	my_pe.Readfile(filename,my_data);
	my_pe.Analyze_PE(my_data);   //char*& Data, PIMAGE_DOS_HEADER& dos, PIMAGE_FILE_HEADER& file, PIMAGE_OPTIONAL_HEADER32& optional, PIMAGE_SECTION_HEADER*& section
	my_pe.Stretch_PE(my_data);
	my_pe.Shrink_PE(my_data);

	/*char filename2[100] = "666.exe";
	my_pe.New_Section(filename2, my_data);*/

	char filename3[100] = "555.exe";
	my_pe.Expand_Section(my_data,filename3);
	return 0;
	
}

至于剛剛提到的問(wèn)題,我查看匯編代碼發(fā)現(xiàn)了些許端倪
?

004C2E4B C7 45 FC FF FF FF FF mov         dword ptr [ebp-4],0FFFFFFFFh  
004C2E52 8D 4D B8             lea         ecx,[Expand_Data]  
004C2E55 E8 08 E4 FF FF       call        Data::~Data (04C1262h)  
004C2E5A 52                   push        edx  
004C2E5B 8B CD                mov         ecx,ebp  
004C2E5D 50                   push        eax  
004C2E5E 8D 15 98 2E 4C 00    lea         edx,ds:[4C2E98h]  
004C2E64 E8 03 E4 FF FF       call        @_RTC_CheckStackVars@8 (04C126Ch)  
004C2E69 58                   pop         eax  
004C2E6A 5A                   pop         edx  
004C2E6B 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
004C2E6E 64 89 0D 00 00 00 00 mov         dword ptr fs:[0],ecx  
004C2E75 59                   pop         ecx  
004C2E76 5F                   pop         edi  
004C2E77 5E                   pop         esi  
004C2E78 5B                   pop         ebx  
004C2E79 8B 4D F0             mov         ecx,dword ptr [ebp-10h]  
004C2E7C 33 CD                xor         ecx,ebp  
004C2E7E E8 21 E3 FF FF       call        @__security_check_cookie@4 (04C11A4h)  
004C2E83 81 C4 3C 01 00 00    add         esp,13Ch  
004C2E89 3B EC                cmp         ebp,esp  
004C2E8B E8 4F E4 FF FF       call        __RTC_CheckEsp (04C12DFh)  
004C2E90 8B E5                mov         esp,ebp  
004C2E92 5D                   pop         ebp  
004C2E93 C2 08 00             ret         8  

這是我傳值引用的結(jié)果,可以看到只調(diào)用了Expand_Data這個(gè)類的析構(gòu)函數(shù),符合常理,但是一旦我將void PE:: Expand_Section(Data& my_data,char* filename)改為void PE:: Expand_Section(Data?my_data,char* filename) 我們?cè)俜磪R編,此時(shí)就有問(wèn)題了!

00AB2E0A C6 45 FC 00          mov         byte ptr [ebp-4],0  
00AB2E0E 8D 4D B8             lea         ecx,[Expand_Data]  
00AB2E11 E8 4C E4 FF FF       call        Data::~Data (0AB1262h)  
00AB2E16 C7 45 FC FF FF FF FF mov         dword ptr [ebp-4],0FFFFFFFFh  
00AB2E1D 8D 4D 08             lea         ecx,[my_data]  
00AB2E20 E8 3D E4 FF FF       call        Data::~Data (0AB1262h)  
00AB2E25 52                   push        edx  
00AB2E26 8B CD                mov         ecx,ebp  
00AB2E28 50                   push        eax  
00AB2E29 8D 15 64 2E AB 00    lea         edx,ds:[0AB2E64h]  
00AB2E2F E8 38 E4 FF FF       call        @_RTC_CheckStackVars@8 (0AB126Ch)  
00AB2E34 58                   pop         eax  
00AB2E35 5A                   pop         edx  
00AB2E36 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
00AB2E39 64 89 0D 00 00 00 00 mov         dword ptr fs:[0],ecx  
00AB2E40 59                   pop         ecx  
00AB2E41 5F                   pop         edi  
00AB2E42 5E                   pop         esi  
00AB2E43 5B                   pop         ebx  
00AB2E44 8B 4D F0             mov         ecx,dword ptr [ebp-10h]  
00AB2E47 33 CD                xor         ecx,ebp  
00AB2E49 E8 56 E3 FF FF       call        @__security_check_cookie@4 (0AB11A4h)  
00AB2E4E 81 C4 3C 01 00 00    add         esp,13Ch  
00AB2E54 3B EC                cmp         ebp,esp  
00AB2E56 E8 84 E4 FF FF       call        __RTC_CheckEsp (0AB12DFh)  
00AB2E5B 8B E5                mov         esp,ebp  
00AB2E5D 5D                   pop         ebp  
00AB2E5E C2 20 00             ret         20h  

可以看到他居然調(diào)用了my_data的析構(gòu)!這也是導(dǎo)致程序崩潰的原因,因?yàn)樵趍ain函數(shù)中,函數(shù)結(jié)束后,也會(huì)調(diào)用my_data的析構(gòu),等于調(diào)用了析構(gòu)函數(shù)兩次!

具體原因查了下資料對(duì)象作為參數(shù)按值傳遞為什么會(huì)調(diào)用析構(gòu)函數(shù)?為什么實(shí)參中的內(nèi)容會(huì)被修改?_c++ 類作為參數(shù)傳遞 在函數(shù)中被修改-CSDN博客

引用大佬的文章

對(duì)象作為參數(shù)按值傳遞為什么會(huì)調(diào)用析構(gòu)函數(shù)?為什么實(shí)參中的內(nèi)容會(huì)被修改?

因?yàn)閷?duì)象按值傳遞時(shí),編譯器自動(dòng)生成的復(fù)制構(gòu)造函數(shù)進(jìn)行了指針的簡(jiǎn)單拷貝,像指針直接賦值 str=s 一樣,而沒(méi)有拷貝指針指向的內(nèi)容,這樣當(dāng)你將對(duì)象傳遞給函數(shù)時(shí)確實(shí)會(huì)有一個(gè)拷貝,但是這個(gè)拷貝會(huì)有一個(gè)指針的拷貝,所以兩個(gè)對(duì)象中的 str 指向的內(nèi)存一樣,在退出函數(shù)時(shí),析構(gòu)銷毀了函數(shù)中對(duì)象中的指針,但不幸的是這樣實(shí)參對(duì)象 str 指向的內(nèi)容也被銷毀。

哎,c++沒(méi)學(xué)好是這樣的,但也算收獲蠻多?

?

到了這里,關(guān)于【逆向】03-20擴(kuò)大節(jié) c++代碼完成 ;類當(dāng)作函數(shù)參數(shù)卻調(diào)用了析構(gòu)函數(shù)疑難分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C++|29.純虛函數(shù)/接口(待完成)

    C++|29.純虛函數(shù)/接口(待完成)

    純虛函數(shù)是一種特殊的虛函數(shù)。 普通的虛函數(shù)允許子類的同名函數(shù)對(duì)其進(jìn)行重寫,同時(shí)普通的虛函數(shù)本身是可以單獨(dú)進(jìn)行使用的。 而純虛函數(shù)是一個(gè)空殼,強(qiáng)制要求所派生的類在繼承的過(guò)程中必要將該虛函數(shù)進(jìn)行實(shí)現(xiàn)。 如上圖,純虛函數(shù)只需要在virtual后面添加上=0即可。

    2024年01月16日
    瀏覽(15)
  • C++ 筆記 20 (STL函數(shù)對(duì)象)

    1. 函數(shù)對(duì)象 1.1 函數(shù)對(duì)象概念 概念: 重載 函數(shù)調(diào)用操作符 的類,其對(duì)象常稱為函數(shù)對(duì)象; 函數(shù)對(duì)象使用重載的()時(shí),行為類似函數(shù)調(diào)用,也叫仿函數(shù)。 本質(zhì): 函數(shù)對(duì)象(仿函數(shù))是一個(gè)類,不是一個(gè)函數(shù)。 1.2 函數(shù)對(duì)象的使用 特點(diǎn): 函數(shù)對(duì)象在使用時(shí),可以像普通函數(shù)

    2024年02月02日
    瀏覽(26)
  • Nike登錄的acw_sc__v2參數(shù)逆向詳細(xì)思路分析(非常簡(jiǎn)單,建議入手)含AST解混淆代碼

    Nike登錄的acw_sc__v2參數(shù)逆向詳細(xì)思路分析(非常簡(jiǎn)單,建議入手)含AST解混淆代碼

    最近周末閑著無(wú)事,看了一下Nike的登錄,發(fā)現(xiàn)連環(huán)境都不用補(bǔ)acw_sc__v2這個(gè)參數(shù),分享出來(lái)給大家趣味性?shī)蕵?lè)一下 打開F12抓包看看登錄 老樣子復(fù)制curl給抓到Postman里面去分析一下 具體的參數(shù)查找就不演示了(就是簡(jiǎn)單的刪參數(shù)看看啥需要啥不需要)。 最后可以發(fā)現(xiàn),cookie只

    2024年02月09日
    瀏覽(23)
  • 【C++漂流記】函數(shù)的高級(jí)應(yīng)用——函數(shù)默認(rèn)參數(shù)、占位參數(shù)、重載

    【C++漂流記】函數(shù)的高級(jí)應(yīng)用——函數(shù)默認(rèn)參數(shù)、占位參數(shù)、重載

    函數(shù)的高級(jí)應(yīng)用,側(cè)重介紹函數(shù)的默認(rèn)參數(shù)、函數(shù)的占位參數(shù)、函數(shù)重載定義解釋及使用。 函數(shù)默認(rèn)參數(shù)是指在函數(shù)聲明時(shí)為參數(shù)提供一個(gè)默認(rèn)值,這樣在調(diào)用函數(shù)時(shí)如果沒(méi)有傳入相應(yīng)的參數(shù),就會(huì)使用默認(rèn)值代替。函數(shù)默認(rèn)參數(shù)可以簡(jiǎn)化函數(shù)的調(diào)用,使得函數(shù)更加靈活。

    2024年02月09日
    瀏覽(19)
  • C++入門:函數(shù)缺省參數(shù)與函數(shù)重載

    C++入門:函數(shù)缺省參數(shù)與函數(shù)重載

    目錄 1.函數(shù)缺省參數(shù) 1.1 缺省參數(shù)概念 1.2 缺省參數(shù)分類 2.函數(shù)重載 2.1 函數(shù)重載概念 2.2 C++支持函數(shù)重載的原理 缺省參數(shù)是 聲明或定義函數(shù)時(shí) 為函數(shù)的 參數(shù)指定一個(gè)缺省值 。在調(diào)用該函數(shù)時(shí),如果沒(méi)有指定實(shí) 參則采用該形參的缺省值,否則使用指定的實(shí)參,有點(diǎn)備胎的意

    2024年02月12日
    瀏覽(23)
  • C++函數(shù)參數(shù)匹配規(guī)則

    candidate functions:函數(shù)名稱相同(f1, f2, f3, f4 都是)。 viable functions:參數(shù)個(gè)數(shù)相同(排除f1, f3),且參數(shù)可以轉(zhuǎn)換成相同類型(f2, f4都是viable function)。如果不存在viable functions,則編譯器報(bào)參數(shù)不匹配錯(cuò)誤(可以通過(guò)linting檢查)。 最后決定參數(shù)類型是否匹配,如果匹配優(yōu)先調(diào)用,不能

    2024年02月12日
    瀏覽(21)
  • 【C++初階】C++入門——缺省參數(shù)、函數(shù)重載

    【C++初階】C++入門——缺省參數(shù)、函數(shù)重載

    ?缺省參數(shù)是 聲明或定義函數(shù)時(shí)為函數(shù)的參數(shù)指定一個(gè)缺省值 。在調(diào)用該函數(shù)時(shí),如果沒(méi)有指定實(shí)參則采用該形參的缺省值,否則使用指定的實(shí)參。 ?上面代碼在 fun 函數(shù)的形參部分給了缺省值10,這意味著在調(diào)用 fun 函數(shù)的時(shí)候可以傳參,也可以不傳參,如果傳參了那形參

    2024年02月11日
    瀏覽(18)
  • 【C++】C++ 引用詳解 ① ( 變量的本質(zhì) - 引入 “ 引用 “ 概念 | 引用語(yǔ)法簡(jiǎn)介 | 引用做函數(shù)參數(shù) | 復(fù)雜類型引用做函數(shù)參數(shù) )

    【C++】C++ 引用詳解 ① ( 變量的本質(zhì) - 引入 “ 引用 “ 概念 | 引用語(yǔ)法簡(jiǎn)介 | 引用做函數(shù)參數(shù) | 復(fù)雜類型引用做函數(shù)參數(shù) )

    \\\" 引用 \\\" 語(yǔ)法 是 C++ 語(yǔ)言中 特有的 , 在 C 語(yǔ)言中是沒(méi)有 引用 這個(gè)概念的 ; 分析 引用 之前 , 先回顧下 變量 : 在 【C 語(yǔ)言】變量本質(zhì) ( 變量概念 | 變量本質(zhì) - 內(nèi)存空間別名 | 變量存儲(chǔ)位置 - 代碼區(qū) | 變量三要素 ) 博客中 , 介紹了變量的本質(zhì) : 變量 的本質(zhì)是 內(nèi)存空間 的 \\\" 別名

    2024年02月11日
    瀏覽(35)
  • C++:命名空間,缺省參數(shù),函數(shù)重載,引用,內(nèi)聯(lián)函數(shù)

    C++:命名空間,缺省參數(shù),函數(shù)重載,引用,內(nèi)聯(lián)函數(shù)

    個(gè)人主頁(yè) : 個(gè)人主頁(yè) 個(gè)人專欄 : 《數(shù)據(jù)結(jié)構(gòu)》 《C語(yǔ)言》《C++》 本篇博客作為C++知識(shí)總結(jié),我們來(lái)認(rèn)識(shí)命名空間,缺省參數(shù),函數(shù)重載,引用,內(nèi)聯(lián)函數(shù)。 那么在介紹命名空間時(shí),我們先用C++的方式打印\\\"hello world\\\"。 其中,using namespace std; 就是一種命名空間的使用。 在

    2024年02月11日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包