개발 98

Thread, 싱글톤 다중 상속 하지말자!

Thread와 싱글톤 상속의 문제점싱글톤과 Thread 클래스를 동시에 상속받는 것은 초기에는 코드가 간단해 보일 수 있지만, 실제로는 런타임 오류와 메모리 관리 문제를 일으킬 수 있는 설계상 큰 위험 요소입니다. 이 두 가지 상속의 문제점과 해결책을 정리해 보았습니다.문제점수명 관리 문제싱글톤 객체는 프로그램이 종료될 때까지 유지되지만, Thread 객체는 독립적으로 실행 및 종료되어야 합니다. 두 객체를 동시에 상속받을 경우, 싱글톤 객체의 수명이 Thread의 종료 타이밍에 영향을 미칠 수 있어 DLL 언로드나 프로그램 종료 시점에서 예기치 않은 문제가 발생할 수 있습니다.컴파일 타임 검증의 부재C++에서는 기본적으로 두 클래스를 상속받는 것에 대해 명시적인 제한이 없기 때문에, 개발자는 이러한 설..

#pragma pack

#pragma pack 지시자는 구조체, 클래스, 또는 유니언의 멤버들이 메모리에 어떻게 배치되는지를 제어하는 데 사용됩니다. 기본적으로 컴파일러는 멤버들을 특정 바이트 경계에 맞추기 위해 패딩을 추가하여 최적의 성능을 보장하지만, 특정 상황에서는 이 패딩을 제거하고 메모리 사용을 최소화해야 할 필요가 있습니다. 이를 위해 #pragma pack을 사용하여 멤버들의 정렬 단위를 변경할 수 있습니다.#pragma pack 사용법#pragma pack(push, 1)과 #pragma pack(pop)은 구조체, 클래스, 유니언의 멤버 정렬을 제어하는 데 사용됩니다. 이 설정은 데이터 패딩을 줄여 메모리 사용을 최적화하거나, 파일 포맷 및 네트워크 프로토콜과 같은 특정 데이터 포맷과의 호환성을 위해 자주 사용..

개발/C,C++ 2024.10.15

DLL 시리즈 #9 커플링을 이용한 보안 방법

커플링 심화를 이용한 DLL 포인터 마스킹 후 역 마스킹하여 Caller 검증 방법요구 사항CLASS A를 만들고, 함수 BOO, FOO 구현CLASS AImpl을 new로 할당할당된 AImpl에 특정 수로 마스크 처리DLL에서 Caller에게 마스크된 포인터를 리턴Caller는 BOO, FOO 호출 시 해당 포인터를 전달DLL에서 마스킹을 풀어 리턴된 포인터가 올바른지 체크정상적이면 AImpl 내부 함수 호출코드 예제1. DLL 내 CLASS A 정의 및 포인터 마스킹 처리DLL에서 CLASS A와 AImpl을 정의하고, 포인터를 특정 값으로 마스킹 처리한 후 Caller에게 반환합니다.// MyDLL.cpp#include #include class A {public: virtual void BO..

개발/윈도우 2024.09.12

DLL 시리즈 #8 멀티스레드 세이프한 방법

NONAME을 이용한 멀티스레드 세이프한 방법 1. 멀티스레드 환경에서 발생할 수 있는 문제 동시 접근 문제: 여러 스레드가 동일한 자원에 동시에 접근할 경우, 데이터 불일치 또는 충돌이 발생할 수 있습니다. 메모리 관리 문제: 객체의 생성과 해제를 DLL 내부에서 처리하지 않으면 메모리 누수나 충돌이 발생할 수 있습니다. 전역 변수 사용: 전역 변수에 여러 스레드가 접근할 경우 동기화가 필요합니다. 2. 스레드 안전성을 확보하는 방법 객체의 독립성 유지: 각 스레드가 독립적으로 객체를 사용하고, 공유 자원에 접근할 때는 동기화를 적용합니다. 동기화 메커니즘 사용: mutex, critical section 등..

개발/윈도우 2024.09.12

DLL 시리즈 #7 NONAME을 이용한 CLASS 포인터 반환

NONAME을 이용한 CLASS 포인터 반환 1. NONAME을 이용한 CLASS 포인터 반환 개념 NONAME 기술을 이용해 DLL에서 클래스를 반환하는 방법은 함수 이름 대신 Ordinal을 사용하여 클래스를 생성하고, 그 포인터를 반환하는 방식입니다. 이 방법은 DLL 내에서 객체의 포인터를 외부로 안전하게 전달하며, 보안을 강화할 수 있습니다. 특히, 메모리 관리 측면에서 클래스 객체의 할당과 해제를 모두 DLL에서 처리해야 안전하게 사용할 수 있습니다. 2. DLL 클래스 포인터 반환 구조 DLL 내에서 클래스 객체를 생성하고, 그 포인터를 반환합니다. NONAME 방식으로 함수 이름을 숨기고, 외부에..

개발/윈도우 2024.09.12

DLL 시리즈 #6 EXPORT NONAME 방법

DLL EXPORT 방법 중 NONAME 기술 1. NONAME 기술이란? NONAME 기술은 DLL에서 함수나 변수를 이름 대신 번호(ordinal)로 export하는 방식입니다. 이 방법을 사용하면 DLL 크기를 줄이고, 보안을 강화할 수 있지만, 사용성과 유지보수 측면에서 어려움이 있을 수 있습니다. 2. NONAME 기술의 장점 DLL 크기 감소: 함수 이름을 저장할 필요가 없기 때문에, DLL 파일의 크기가 조금 줄어듭니다. 대규모 API나 많은 함수가 있는 DLL에서 유리합니다. 보안 강화: 함수 이름이 노출되지 않으므로, 공격자가 함수 이름을 기반으로 공격하는 것을 어렵게 만들 수 있습니다. DLL의 API가..

개발/윈도우 2024.09.12

DLL 시리즈 #5 DLL EXPORT 취약점(후킹)

DLL EXPORT의 문제점 (후킹에 대한 위험) 1. 후킹(Hooking)이란? 후킹은 운영 체제나 프로그램의 API 호출 흐름을 가로채는 기술로, 특정 함수 호출이나 메시지 처리를 가로채어 조작하거나 다른 기능을 수행하도록 할 수 있습니다. 후킹은 프로그램의 정상적인 흐름을 변경해 악성 코드를 실행하거나 데이터를 탈취하는 등 여러 가지 보안 위협을 일으킬 수 있습니다. API 후킹: 프로그램이 호출하는 API 주소를 변경해 공격자가 원하는 코드가 실행되도록 하는 방법. DLL 후킹: DLL의 함수 호출을 가로채는 방식으로, 프로그램이 DLL 내 특정 함수를 호출할 때 이를 가로채 공격자의 코드를 실행하도록 유도. ..

개발/윈도우 2024.09.12

DLL 시리즈 #4 위성 DLL 취약점

위성 DLL 로드 취약점 1. 위성 DLL 로드 취약점이란? 위성 DLL 로드 취약점(Satellite DLL Load Vulnerability)은 응용 프로그램이 특정 언어 리소스나 플러그인과 같은 위성 DLL을 로드할 때 발생할 수 있는 보안 문제입니다. 위성 DLL은 프로그램의 실행 파일과 같은 경로에 있거나, 특정 경로에서 로드됩니다. 이 취약점을 악용하면, 공격자는 악성 DLL을 시스템에 배치하여 응용 프로그램이 이를 로드하게 만들 수 있습니다. 2. 위성 DLL 로드 취약점의 유형 DLL 하이재킹(DLL Hijacking): 프로그램이 특정 DLL을 로드할 때, 시스템의 경로 탐색 순서에 따라 악성 D..

개발/윈도우 2024.09.12

DLL 시리즈 #3 명시적(동적)링크 의 문제점

동적 링크에 대한 문제점1. DLL 지옥 (DLL Hell)DLL Hell은 여러 응용 프로그램이 동일한 DLL을 공유할 때 발생하는 문제입니다. 주로 다음과 같은 경우에 발생합니다:버전 충돌: 응용 프로그램이 특정 버전의 DLL을 요구하지만, 다른 응용 프로그램에서 DLL을 업데이트하거나 덮어씌우면 기존 프로그램이 비정상적으로 동작하거나 충돌할 수 있습니다.의존성 관리 문제: 응용 프로그램이 실행되기 위해 필요한 모든 DLL을 정확히 찾지 못하거나 누락된 경우, 프로그램이 정상적으로 실행되지 않을 수 있습니다.2. 보안 문제DLL 하이재킹 (DLL Hijacking): 시스템이 DLL을 로드할 때, 의도된 DLL이 아닌 악성 DLL이 먼저 로드될 수 있습니다. 공격자는 악성 DLL을 시스템 경로에 배치..

개발/윈도우 2024.09.12

DLL 시리즈 #2 명시적 연결 vs 묵시적 연결

DLL 명시적 연결 vs 묵시적 연결1. 묵시적 연결 (Implicit Linking)묵시적 연결은 프로그램이 실행될 때, 자동으로 DLL이 로드되는 방식입니다. 즉, 프로그램 시작 시 필요한 모든 DLL이 자동으로 메모리에 로드됩니다. 이를 위해서는 컴파일 시점에 DLL의 함수 시그니처가 필요하며, .lib 파일을 링크해야 합니다.묵시적 연결 코드 예시// main.cpp#include #include "MyDLL.h" // DLL에서 제공하는 헤더 파일int main() { // 묵시적 연결로 DLL의 함수를 호출 int count = GetCount(); std::cout 2. 명시적 연결 (Explicit Linking)명시적 연결은 프로그램이 실행된 후에, 필요할 때 DLL을 동..

개발/윈도우 2024.09.12
반응형