Microsoft MVP성태의 닷넷 이야기
Windows: 167. CoTaskMemAlloc/CoTaskMemFree과 윈도우 Heap의 관계 [링크 복사], [링크+제목 복사],
조회: 19443
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

CoTaskMemAlloc/CoTaskMemFree과 윈도우 Heap의 관계

지난 글에서 다뤘지만,

windbg - CoTaskMemFree/FreeCoTaskMem에서 발생한 덤프 분석 사례
; https://www.sysnet.pe.kr/2/0/12058

당연히 윈도우 환경에서의 메모리 사용이니 CoTaskMemAlloc도,

CoTaskMemAlloc function
; https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cotaskmemalloc

내부적으로는 Windows Heap에 의존할 수밖에 없습니다. 그럼 어떻게 의존하는지 간단하게 살펴볼까요? ^^

#include <iostream>
#include <combaseapi.h>

int main()
{
    int size = 20;

    LPVOID pVoid = CoTaskMemAlloc(size);
    printf("pVoid == 0x%x\n", pVoid);
    memset(pVoid, 0xff, size);

    CoTaskMemFree(pVoid);

    return 0;
}

CoTaskMemFree를 호출하는 코드를 보면,

...[생략]...
00835DF4 8B F4                mov         esi,esp  
00835DF6 8B 45 E8             mov         eax,dword ptr [pVoid1]  
00835DF9 50                   push        eax  
00835DFA FF 15 58 D1 83 00    call        dword ptr [__imp__CoTaskMemFree@4 (083D158h)]  
00835E00 3B F4                cmp         esi,esp  
00835E02 E8 74 B4 FF FF       call        __RTC_CheckEsp (083127Bh)  
...[생략]...

--- onecore\com\combase\class\memapi.cxx ---------------------------------------
7623F800 8B FF                mov         edi,edi  
7623F802 55                   push        ebp  
7623F803 8B EC                mov         ebp,esp  
7623F805 A1 E4 4E 39 76       mov         eax,dword ptr [g_CMalloc (76394EE4h)] // 전역 IMalloc 인스턴스를 eax에 저장  
7623F80A 56                   push        esi   //  non-volatile 레지스터 값이므로 사용 전 push
7623F80B 8B 70 14             mov         esi,dword ptr [eax+14h]  // esi == IMalloc 인터페이스의 6번째 메서드 포인터
7623F80E 81 FE 20 F5 20 76    cmp         esi,offset CRetailMalloc_Free (7620F520h)  
7623F814 0F 85 C9 75 07 00    jne         `Microsoft::WRL::Module<1,Microsoft::WRL::Details::DefaultModule<1> >::Create'::`2'::`dynamic atexit destructor for 'moduleSingleton''+3CC3h (762B6DE3h)  
7623F81A 8B 45 08             mov         eax,dword ptr [ebp + 8]  // ebp + 8 == 첫 번째 인자 pVoid1 
7623F81D 85 C0                test        eax,eax  
7623F81F 74 0F                je          CoTaskMemFree+30h (7623F830h)  
7623F821 50                   push        eax  
7623F822 6A 00                push        0  
7623F824 FF 35 0C 50 39 76    push        dword ptr [g_hHeap (7639500Ch)]  
7623F82A FF 15 94 72 39 76    call        dword ptr [__imp__HeapFree@12 (76397294h)]  
7623F830 5E                   pop         esi  
7623F831 5D                   pop         ebp  
7623F832 C2 04 00             ret         4  

내부적으로 이미 생성해 두었던 IMalloc 전역 인스턴스(g_CMalloc)의,

g_CMalloc   {lpVtbl=0x7616d158 {combase.dll!IMallocVtbl CRetailMallocVtbl} {QueryInterface=0x76315f80 {combase.dll!CMalloc_QueryInterface(IMalloc *, const _GUID &, void * *)} ...} }   CMalloc

6번째 메서드가,

0x7616D158  76315f80  (QueryInterface)
0x7616D15C  7628e8a0  (AddRef)
0x7616D160  7628e8a0  (Release)
0x7616D164  7620f260  (IMalloc::Alloc)
0x7616D168  762781b0  (IMalloc::DidAlloc)
0x7616D16C  7620f520  (IMalloc::Free) <== eax + 14h 
0x7616D170  7626e3a0  
0x7616D174  76290f30  
0x7616D178  76315fc0  
0x7616D17C  00000000  
0x7616D180  00000001  

CRetailMalloc_Free 함수와 동일한 주소인지 체크한 후 맞는다면, HeapFree를 다음과 같은 인자로 호출합니다.

HeapFree(g_hHeap, 0, pVoid);

여기서 g_hHeap은 Win32 프로세스가 생성하는 default Heap으로 Win32 API로는 GetProcessHeap으로 구할 수 있습니다.

HANDLE hDefaultHeap = GetProcessHeap();
printf("pVoid == 0x%x\n", hDefaultHeap);

이게 끝입니다. 이후부터는 HeapFree의 절차를 그대로 따릅니다. 따라서 실질적인 기준으로 본다면, g_CMalloc 관련 코드도 단순히 CRetailMalloc_Free와 비교하는 것일 뿐 정작 g_CMalloc::Free 메서드를 호출하는 것도 아니기 때문에 CoTaskMemFree는 곧바로 HeapFree를 호출하는 것과 별반 다르지 않습니다.

정리하면, CoTaskMemAlloc == HeapAlloc(g_hHeap, ...)으로, CoTaskMemFree == HeapFree(g_hHeap, ...)이라고 보면 됩니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 7/7/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 136  137  138  139  140  141  142  143  144  145  146  147  148  149  [150]  ...
NoWriterDateCnt.TitleFile(s)
1303정성태6/26/201227387개발 환경 구성: 152. sysnet DB를 SQL Azure 데이터베이스로 마이그레이션
1302정성태6/25/201229361개발 환경 구성: 151. Azure 웹 사이트에 사용자 도메인 네임 연결하는 방법
1301정성태6/20/201225759오류 유형: 156. KB2667402 윈도우 업데이트 실패 및 마이크로소프트 Answers 웹 사이트 대응
1300정성태6/20/201231745.NET Framework: 329. C# - Rabin-Miller 소수 생성방법을 이용하여 RSACryptoServiceProvider의 개인키를 직접 채워보자 [1]파일 다운로드2
1299정성태6/18/201232863제니퍼 .NET: 21. 제니퍼 닷넷 - Ninject DI 프레임워크의 성능 분석 [2]파일 다운로드2
1298정성태6/14/201234398VS.NET IDE: 72. Visual Studio에서 pfx 파일로 서명한 경우, 암호는 어디에 저장될까? [2]
1297정성태6/12/201231037VC++: 63. 다른 프로세스에 환경 변수 설정하는 방법파일 다운로드1
1296정성태6/5/201227667.NET Framework: 328. 해당 DLL이 Managed인지 / Unmanaged인지 확인하는 방법 - 두 번째 이야기 [4]파일 다운로드1
1295정성태6/5/201225072.NET Framework: 327. RSAParameters와 System.Numerics.BigInteger 이야기파일 다운로드1
1294정성태5/27/201248513.NET Framework: 326. 유니코드와 한글 - 유니코드와 닷넷을 이용한 한글 처리 [7]파일 다운로드2
1293정성태5/24/201229769.NET Framework: 325. System.Drawing.Bitmap 데이터를 Parallel.For로 처리하는 방법 [2]파일 다운로드1
1292정성태5/24/201223747.NET Framework: 324. First-chance exception에 대해 조건에 따라 디버거가 멈추게 할 수는 없을까? [1]파일 다운로드1
1291정성태5/23/201230262VC++: 62. 배열 초기화를 위한 기계어 코드 확인 [2]
1290정성태5/18/201235074.NET Framework: 323. 관리자 권한이 필요한 작업을 COM+에 대행 [7]파일 다운로드1
1289정성태5/17/201239229.NET Framework: 322. regsvcs.exe로 어셈블리 등록 시 시스템 변경 사항 [5]파일 다운로드2
1288정성태5/17/201226454.NET Framework: 321. regasm.exe로 어셈블리 등록 시 시스템 변경 사항 (3) - Type Library파일 다운로드1
1287정성태5/17/201229283.NET Framework: 320. regasm.exe로 어셈블리 등록 시 시스템 변경 사항 (2) - .NET 4.0 + .NET 2.0 [2]
1286정성태5/17/201238205.NET Framework: 319. regasm.exe로 어셈블리 등록 시 시스템 변경 사항 (1) - .NET 2.0 + x86/x64/AnyCPU [5]
1285정성태5/16/201233256.NET Framework: 318. gacutil.exe로 어셈블리 등록 시 시스템 변경 사항파일 다운로드1
1284정성태5/15/201225686오류 유형: 155. Windows Phone 연결 상태에서 DRIVER POWER STATE FAILURE 블루 스크린 뜨는 현상
1283정성태5/12/201233298.NET Framework: 317. C# 관점에서의 Observer 패턴 구현 [1]파일 다운로드1
1282정성태5/12/201226094Phone: 6. Windows Phone 7 Silverlight에서 Google Map 사용하는 방법 [3]파일 다운로드1
1281정성태5/9/201233176.NET Framework: 316. WPF/Silverlight의 그래픽 단위와 Anti-aliasing 처리를 이해하자 [1]파일 다운로드1
1280정성태5/9/201226149오류 유형: 154. Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, ...'.
1279정성태5/9/201224909.NET Framework: 315. 해당 DLL이 Managed인지 / Unmanaged인지 확인하는 방법 [1]파일 다운로드1
1278정성태5/8/201226139오류 유형: 153. Visual Studio 디버깅 - Unable to break execution. This process is not currently executing the type of code that you selected to debug.
... 136  137  138  139  140  141  142  143  144  145  146  147  148  149  [150]  ...