외로운 Nova의 작업실

C++와 어셈블리어 본문

Computer App Penetesting/Reversing

C++와 어셈블리어

Nova_ 2023. 1. 23. 15:14

이번 문서에는 c++를 어셈블리어로 변환했을때 어떻게되는지 정리해보겠습니다.

 

- 클래스 정적 할당

#include <stdio.h>
#include <windows.h>
#include <tchar.h>

class Employee
{
public :
	int number;
	wchar_t name[128];
	long pay;
	void ShowData();
	void Test();
};
void Employee::ShowData()
{
	printf("number: %d\n", number);
	printf("name : %s\n", name);
	printf("pay : %d\n", pay);
	Test();

	return;
}
void Employee :: Test()
{
	printf("Test function\n");
	return;
}
int main() {
	
	Employee Nova;

	printf("size : %X\n", sizeof(Employee));

	Nova.number = 0x1234;
	_tcscpy_s(Nova.name, _T("Nova"));
	Nova.pay = 0x142;

	Nova.ShowData();

	return 0;

	
}
#include <stdio.h>
#include <windows.h>
#include <tchar.h>

class Employee
{
public :
	int number;
	wchar_t name[128];
	long pay;
	void ShowData();
	void Test();
};
void Employee::ShowData()
{
00007FF631FB1810  mov         qword ptr [rsp+8],rcx  
00007FF631FB1815  push        rbp  
00007FF631FB1816  push        rdi  
00007FF631FB1817  sub         rsp,0E8h  
00007FF631FB181E  lea         rbp,[rsp+20h]  
00007FF631FB1823  lea         rcx,[__F4170C15_test@cpp (07FF631FC10ACh)]  
00007FF631FB182A  call        __CheckForDebuggerJustMyCode (07FF631FB136Bh)  
	printf("number: %d\n", number);
00007FF631FB182F  mov         rax,qword ptr [this]  
00007FF631FB1836  mov         edx,dword ptr [rax]  
00007FF631FB1838  lea         rcx,[string "number: %d\n" (07FF631FB9CA8h)]  
00007FF631FB183F  call        printf (07FF631FB1190h)  
	printf("name : %s\n", name);
00007FF631FB1844  mov         rax,qword ptr [this]  
00007FF631FB184B  add         rax,4  
00007FF631FB184F  mov         rdx,rax  
00007FF631FB1852  lea         rcx,[string "name : %s\n" (07FF631FB9CB8h)]  
00007FF631FB1859  call        printf (07FF631FB1190h)  
	printf("pay : %d\n", pay);
00007FF631FB185E  mov         rax,qword ptr [this]  
00007FF631FB1865  mov         edx,dword ptr [rax+104h]  
00007FF631FB186B  lea         rcx,[string "pay : %d\n" (07FF631FB9CC8h)]  
00007FF631FB1872  call        printf (07FF631FB1190h)  
	Test();
00007FF631FB1877  mov         rcx,qword ptr [this]  
00007FF631FB187E  call        Employee::Test (07FF631FB10DCh)  

	return;
}
00007FF631FB1883  lea         rsp,[rbp+0C8h]  
00007FF631FB188A  pop         rdi  
00007FF631FB188B  pop         rbp  
00007FF631FB188C  ret  

------------------------------------------------------------
void Employee :: Test()
{
00007FF631FB18B0  mov         qword ptr [rsp+8],rcx  
00007FF631FB18B5  push        rbp  
00007FF631FB18B6  push        rdi  
00007FF631FB18B7  sub         rsp,0E8h  
00007FF631FB18BE  lea         rbp,[rsp+20h]  
00007FF631FB18C3  lea         rcx,[__F4170C15_test@cpp (07FF631FC10ACh)]  
00007FF631FB18CA  call        __CheckForDebuggerJustMyCode (07FF631FB136Bh)  
	printf("Test function\n");
00007FF631FB18CF  lea         rcx,[string "Test function\n" (07FF631FB9CD8h)]  
00007FF631FB18D6  call        printf (07FF631FB1190h)  
	return;
}
00007FF631FB18DB  lea         rsp,[rbp+0C8h]  
00007FF631FB18E2  pop         rdi  
00007FF631FB18E3  pop         rbp  
00007FF631FB18E4  ret  	

-------------------------------------------------------------------------

int main() {
00007FF631FB19D0  push        rbp  
00007FF631FB19D2  push        rdi  
00007FF631FB19D3  sub         rsp,218h  
00007FF631FB19DA  lea         rbp,[rsp+20h]  
00007FF631FB19DF  lea         rdi,[rsp+20h]  
00007FF631FB19E4  mov         ecx,4Eh  
00007FF631FB19E9  mov         eax,0CCCCCCCCh  
00007FF631FB19EE  rep stos    dword ptr [rdi]  
00007FF631FB19F0  mov         rax,qword ptr [__security_cookie (07FF631FBC008h)]  
00007FF631FB19F7  xor         rax,rbp  
00007FF631FB19FA  mov         qword ptr [rbp+1E8h],rax  
00007FF631FB1A01  lea         rcx,[__F4170C15_test@cpp (07FF631FC10ACh)]  
00007FF631FB1A08  call        __CheckForDebuggerJustMyCode (07FF631FB136Bh)  
	
	Employee Nova;

	printf("size : %X\n", sizeof(Employee));
00007FF631FB1A0D  mov         edx,108h  
00007FF631FB1A12  lea         rcx,[string "size : %X\n" (07FF631FB9CF0h)]  
00007FF631FB1A19  call        printf (07FF631FB1190h)  

	Nova.number = 0x1234;
00007FF631FB1A1E  mov         dword ptr [Nova],1234h  
	_tcscpy_s(Nova.name, _T("Nova"));
00007FF631FB1A25  lea         rdx,[string L"Nova" (07FF631FB9D00h)]  
00007FF631FB1A2C  lea         rcx,[rbp+14h]  
00007FF631FB1A30  call        wcscpy_s<128> (07FF631FB12BCh)  
	Nova.pay = 0x142;
00007FF631FB1A35  mov         dword ptr [rbp+114h],142h  

	Nova.ShowData();
00007FF631FB1A3F  lea         rcx,[Nova]  
00007FF631FB1A43  call        Employee::ShowData (07FF631FB1299h)  

	return 0;
00007FF631FB1A48  xor         eax,eax  

	
}
00007FF631FB1A4A  mov         edi,eax  
00007FF631FB1A4C  lea         rcx,[rbp-20h]  
00007FF631FB1A50  lea         rdx,[__xt_z+1E0h (07FF631FB9C80h)]  
00007FF631FB1A57  call        _RTC_CheckStackVars (07FF631FB1307h)  
00007FF631FB1A5C  mov         eax,edi  
00007FF631FB1A5E  mov         rcx,qword ptr [rbp+1E8h]  
00007FF631FB1A65  xor         rcx,rbp  
00007FF631FB1A68  call        __security_check_cookie (07FF631FB11A9h)  
00007FF631FB1A6D  lea         rsp,[rbp+1F8h]  
00007FF631FB1A74  pop         rdi  
00007FF631FB1A75  pop         rbp  
00007FF631FB1A76  ret

 

특징 : 클래스의 함수먼저 처음에 어셈블링 됩니다. 또한 클래스는 main함수 내에서 선언하면 어셈블러 입장에서 스택에 클래스를 위한 공간을 만들고 클래스의 첫번쨰 주소를 사용하여 각 변수에 접근합니다.

 

- 클래스 동적 할당

#include <stdio.h>
#include <windows.h>
#include <tchar.h>

class Employee
{
public :
	int number;
	wchar_t name[128];
	long pay;
	void ShowData();
	void Test();
};
void Employee::ShowData()
{
	printf("number: %d\n", number);
	printf("name : %s\n", name);
	printf("pay : %d\n", pay);
	Test();

	return;
}
void Employee :: Test()
{
	printf("Test function\n");
	return;
}
int main() {
	
	Employee *Nova;
	Nova = new Employee;


	Nova->number = 0x1234;
	_tcscpy_s(Nova->name, _T("Nova"));
	Nova->pay = 0x142;

	Nova->ShowData();

	return 0;

	
}
int main() {
00007FF63AF41B00  push        rbp  
00007FF63AF41B02  push        rdi  
00007FF63AF41B03  sub         rsp,128h  
00007FF63AF41B0A  lea         rbp,[rsp+20h]  
00007FF63AF41B0F  lea         rcx,[__F4170C15_test@cpp (07FF63AF530ACh)]  
00007FF63AF41B16  call        __CheckForDebuggerJustMyCode (07FF63AF413F2h)  
	
	Employee *Nova;
	Nova = new Employee;
00007FF63AF41B1B  mov         ecx,108h  
00007FF63AF41B20  call        operator new (07FF63AF4103Ch)  
00007FF63AF41B25  mov         qword ptr [rbp+0E8h],rax  
00007FF63AF41B2C  mov         rax,qword ptr [rbp+0E8h]  
00007FF63AF41B33  mov         qword ptr [Nova],rax  


	Nova->number = 0x1234;
00007FF63AF41B37  mov         rax,qword ptr [Nova]  
00007FF63AF41B3B  mov         dword ptr [rax],1234h  
	_tcscpy_s(Nova->name, _T("Nova"));
00007FF63AF41B41  mov         rax,qword ptr [Nova]  
00007FF63AF41B45  add         rax,4  
00007FF63AF41B49  lea         rdx,[string L"Nova" (07FF63AF4AC70h)]  
00007FF63AF41B50  mov         rcx,rax  
00007FF63AF41B53  call        wcscpy_s<128> (07FF63AF41320h)  
	Nova->pay = 0x142;
00007FF63AF41B58  mov         rax,qword ptr [Nova]  
00007FF63AF41B5C  mov         dword ptr [rax+104h],142h  

	Nova->ShowData();
00007FF63AF41B66  mov         rcx,qword ptr [Nova]  
00007FF63AF41B6A  call        Employee::ShowData (07FF63AF412F3h)  

	return 0;
00007FF63AF41B6F  xor         eax,eax  

	
}
00007FF63AF41B71  lea         rsp,[rbp+108h]  
00007FF63AF41B78  pop         rdi  
00007FF63AF41B79  pop         rbp  
00007FF63AF41B7A  ret

동적할당으로 객체를 사용하게되면 아래 문장을 통해 클래스가 할당된 힙영역의 주소를 스택에 저장해놓고 변수에 접근하게됩니다.

	Employee *Nova;
	Nova = new Employee;
00007FF63AF41B1B  mov         ecx,108h  
00007FF63AF41B20  call        operator new (07FF63AF4103Ch)  
00007FF63AF41B25  mov         qword ptr [rbp+0E8h],rax

ecx에 동적할당할 크기를 할당하고 동적할당합니다. 이후 주소는 rax에 담기게되며 이 값은 rbp+0E8h에 담기게됩니다.

 

- 클래스 생성자와 소멸자

어세블리어는 main함수쪽만 보도록 하겠습니다. 바뀐게 main함수만 이기때문입니다.

#include <stdio.h>
#include <windows.h>
#include <tchar.h>

class Employee
{
public :
	int number;
	wchar_t name[128];
	long pay;
	void ShowData();
	void Test();
	Employee();
	~Employee();
};
Employee::Employee() 
{
	printf("constractor\n");
}
Employee::~Employee()
{
	printf("destractor\n");
}
void Employee::ShowData()
{
	printf("number: %d\n", number);
	printf("name : %s\n", name);
	printf("pay : %d\n", pay);
	Test();

	return;
}
void Employee :: Test()
{
	printf("Test function\n");
	return;
}
int main() {
	
	Employee *Nova;
	Nova = new Employee;


	Nova->number = 0x1234;
	_tcscpy_s(Nova->name, _T("Nova"));
	Nova->pay = 0x142;

	Nova->ShowData();

	Nova->~Employee();

	return 0;

	
}
int main() {
00007FF72CEF1CA0  push        rbp  
00007FF72CEF1CA2  push        rdi  
00007FF72CEF1CA3  sub         rsp,148h  
00007FF72CEF1CAA  lea         rbp,[rsp+20h]  
00007FF72CEF1CAF  lea         rcx,[__F4170C15_test@cpp (07FF72CF040ACh)]  
00007FF72CEF1CB6  call        __CheckForDebuggerJustMyCode (07FF72CEF13FCh)  
	
	Employee *Nova;
	Nova = new Employee;
00007FF72CEF1CBB  mov         ecx,108h  
00007FF72CEF1CC0  call        operator new (07FF72CEF103Ch)  
00007FF72CEF1CC5  mov         qword ptr [rbp+108h],rax  
00007FF72CEF1CCC  cmp         qword ptr [rbp+108h],0  
00007FF72CEF1CD4  je          main+4Bh (07FF72CEF1CEBh)  
00007FF72CEF1CD6  mov         rcx,qword ptr [rbp+108h]  
00007FF72CEF1CDD  call        Employee::Employee (07FF72CEF140Bh)  
00007FF72CEF1CE2  mov         qword ptr [rbp+118h],rax  
00007FF72CEF1CE9  jmp         main+56h (07FF72CEF1CF6h)  
00007FF72CEF1CEB  mov         qword ptr [rbp+118h],0  
00007FF72CEF1CF6  mov         rax,qword ptr [rbp+118h]  
00007FF72CEF1CFD  mov         qword ptr [rbp+0E8h],rax  
00007FF72CEF1D04  mov         rax,qword ptr [rbp+0E8h]  
00007FF72CEF1D0B  mov         qword ptr [Nova],rax  


	Nova->number = 0x1234;
00007FF72CEF1D0F  mov         rax,qword ptr [Nova]  
00007FF72CEF1D13  mov         dword ptr [rax],1234h  
	_tcscpy_s(Nova->name, _T("Nova"));
00007FF72CEF1D19  mov         rax,qword ptr [Nova]  
00007FF72CEF1D1D  add         rax,4  
00007FF72CEF1D21  lea         rdx,[string L"Nova" (07FF72CEFAC90h)]  
00007FF72CEF1D28  mov         rcx,rax  
00007FF72CEF1D2B  call        wcscpy_s<128> (07FF72CEF1325h)  
	Nova->pay = 0x142;
00007FF72CEF1D30  mov         rax,qword ptr [Nova]  
00007FF72CEF1D34  mov         dword ptr [rax+104h],142h  

	Nova->ShowData();
00007FF72CEF1D3E  mov         rcx,qword ptr [Nova]  
00007FF72CEF1D42  call        Employee::ShowData (07FF72CEF12F8h)  

	Nova->~Employee();
00007FF72CEF1D47  xor         edx,edx  
00007FF72CEF1D49  mov         rcx,qword ptr [Nova]  
00007FF72CEF1D4D  call        Employee::`scalar deleting destructor' (07FF72CEF147Eh)  

	return 0;
00007FF72CEF1D52  xor         eax,eax  

	
}
00007FF72CEF1D54  lea         rsp,[rbp+128h]  
00007FF72CEF1D5B  pop         rdi  
00007FF72CEF1D5C  pop         rbp  
00007FF72CEF1D5D  ret

생성자 코드는 아래와 같습니다.

00007FF6F5CD1BFD  call        Employee::Employee (07FF6F5CD140Bh)  
00007FF6F5CD1C02  mov         qword ptr [rbp+118h],rax  
00007FF6F5CD1C09  jmp         main+56h (07FF6F5CD1C16h)  
00007FF6F5CD1C0B  mov         qword ptr [rbp+118h],0  
00007FF6F5CD1C16  mov         rax,qword ptr [rbp+118h]  
00007FF6F5CD1C1D  mov         qword ptr [rbp+0E8h],rax  
00007FF6F5CD1C24  mov         rax,qword ptr [rbp+0E8h]  
00007FF6F5CD1C2B  mov         qword ptr [Nova],rax

소멸자 코드는 아래와 같습니다.

	Nova->~Employee();
00007FF72CEF1D47  xor         edx,edx  
00007FF72CEF1D49  mov         rcx,qword ptr [Nova]  
00007FF72CEF1D4D  call        Employee::`scalar deleting destructor' (07FF72CEF147Eh)

 

Comments