若要看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é)好是這樣的,但也算收獲蠻多?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-729658.html
?
到了這里,關(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)!